내 명령 대체에서 후행 개행 문자는 어디로 갔습니까?

내 명령 대체에서 후행 개행 문자는 어디로 갔습니까?

아래 코드는 이러한 상황을 가장 잘 설명합니다. 마지막 줄에서 후행 개행 문자가 출력되지 않는 이유는 무엇입니까? 각 줄의 출력은 주석에 표시됩니다. 나는 그것을 사용하고 있다GNU 배쉬, 버전 4.1.5

     echo -n $'a\nb\n'                  | xxd -p  # 610a620a  
           x=$'a\nb\n'   ; echo -n "$x" | xxd -p  # 610a620a
     echo -ne "a\nb\n"                  | xxd -p  # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p  # 610a62

답변1

명령 대체 함수 $()(및 가까운 사촌 역따옴표)는 특히 후행 줄 바꿈을 제거합니다. 이것은기록된 행동이며 이 구성을 사용할 때는 항상 이를 알고 있어야 합니다.

텍스트 본문 내의 개행 문자는 대체 연산자로 제거되지 않지만 쉘에서 단어 분리 시 제거될 수도 있으므로 결과는 따옴표 사용 여부에 따라 달라집니다. 다음 두 가지 사용법의 차이점에 유의하세요.

$ echo -n "$(echo -n 'a\nb')"
a
b

$ !! | xxd -p
610a62

$ echo -n  $(echo -n 'a\nb')
a b

$ !! | xxd -p   
612062

두 번째 예에서는 출력이 인용되지 않고 개행 문자가 단어 구분으로 해석되어 출력에서 ​​공백으로 표시됩니다!

답변2

명령 대체를 사용할 때 쉘은 하위 쉘에서 명령을 실행하고 표준 출력을 반환합니다. 이 과정에서 명령이 간단한 분할 단어를 반환하고 그에 따라 후행 문자가 제거되기 때문에 IFS 문자는 의미를 잃습니다(인용되지 않은 경우). 예를 들어:

$ echo "$(echo -e '\n')" | wc
 1       0       1

$ echo -e '\n' | wc
2       0       2

보다 실질적으로 pwd이것은 디렉터리 이름 사이에 개행 문자가 있어도 작동하지만 $(pwd)그렇지 않습니다.

일반적인 수정 방법은 명령 끝에 무언가를 추가한 다음 제거하는 것입니다.

관련 정보