터미널 백슬래시가 없는 한, heredoc의 출력을 변수에 캡처한 후 heredoc의 개행 문자는 유지됩니다.
var=$(cat <<-EOF
a
b
c
EOF
)
echo "$var"
a
b
c
그러나 백슬래시 개행 문자를 저장하려고 하면 개행 문자가 손실됩니다.
var=$(cat <<-EOF
a \\
b \\
c
EOF
)
echo "$var"
a \b \c
추가 이스케이프를 위해 추가 백슬래시를 추가하는 것은 도움이 되지 않습니다.
물론, 서브쉘에서 실행되지 않을 때, heredoc를 사용하여 백슬래시 개행 문자로 끝나는 줄을 생성할 수 있습니다:
$ cat <<-EOF
a \\
b \\
c
EOF
a \
b \
c
이 문제를 방지하려면 개행 문자를 추가하여 변수 변환을 통해 원하는 출력을 생성할 수 있습니다.
var=$(cat <<-EOF
a \\@
b \\@
c
EOF
)
tr -d '@' <<<"$var"
a \
b \
c
서브셸에서 실행되는 heredocs에서 백슬래시 줄 바꿈을 유지하는 더 직접적인 방법이 있습니까?
답변1
이것이 Bash의 버그인지 (또는 백슬래시 개행 동작이 정의되지 않은 것인지) 궁금합니다. 내가 시도한 다른 모든 쉘은 Bash와 다른 동작을 나타냅니다.
$ cat nl.sh
echo "1:"
cat <<EOF
a \\
b \\
c
EOF
echo "2:"
var=$(cat <<-EOF
a \\
b \\
c
EOF
)
echo "$var"
산출:
$ bash nl.sh
1:
a \
b \
c
2:
a \b \c
그리고
$ dash nl.sh
1:
a \
b \
c
2:
a \
b \
c
함수의 명령 대체에 코드를 넣을 수 있습니다. 이는 파서 관련 문제를 해결하는 데 도움이 될 수 있습니다. 예를 들면 다음과 같습니다.
f() {
cat <<EOF
a \\
b
EOF
}
var=$(f)
echo "$var"
답변2
이 문서 내에서 개행 확장을 강제하는 직접적인 방법은 없습니다. 그러나 ANSI 이스케이프 시퀀스( )를 사용하여 인코딩된 개행 문자를 포함 $'\n'
하고 구분된 문서 내에서 변수 확장이 발생하는 변수를 사용할 수 있습니다 .
이러한 형태의 이교도 확장에서는 구분 기호를 'EOF'
따옴표로 묶어야 합니다. 즉, 다음과 같습니다.
nl=$'\n'
해당 $nl
변수를 개행 문자의 자리 표시자로 사용합니다.
var=$(cat <<-EOF
a $nl
b $nl
c
EOF
)
이제 올바르게 발행됩니다.
echo "$var"
a
b
c