서브셸에서 실행되는 heredocs에서 백슬래시 개행을 유지합니다.

서브셸에서 실행되는 heredocs에서 백슬래시 개행을 유지합니다.

터미널 백슬래시가 없는 한, 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

관련 정보