이 명령을 실행할 때 :
ls
터미널은의 출력을 표시합니다 ls
.
이 명령을 실행할 때 :
echo $(ls)
쉘은 출력을 캡처하고 워드 분할 을 $(ls)
수행 합니다. 기본값을 사용하면 줄 바꿈 문자를 포함하여 모든 공백 문자 시퀀스가 단일 공백으로 바뀝니다. 이것이 출력이 한 줄 에 나타나는 이유 입니다.IFS
echo $(ls)
단어 분리에 대한 고급 설명은 Greg의 FAQ를 참조하십시오 .
단어 분리 억제
쉘은 따옴표로 묶인 문자열에서 단어 분리를 수행하지 않습니다. 따라서 다음을 사용하여 단어 분할을 억제하고 여러 줄 출력을 유지할 수 있습니다.
echo "$(ls)"
ls
멀티 라인 출력
ls
한 줄에 여러 파일을 인쇄 하는 경우가 있습니다.
$ ls
file1 file2 file3 file4 file5 file6
출력이 ls
터미널 로 갈 때의 기본값 입니다. 출력이 터미널로 직접 이동하지 않는 경우 ls
기본값은 한 줄에 하나의 파일로 변경됩니다.
$ echo "$(ls)"
file1
file2
file3
file4
file5
file6
이 동작은에 설명되어 man ls
있습니다.
또 다른 미묘함 : 명령 대체 및 후행 줄 바꿈
$(...)
인 명령 치환 및 출력으로부터 개행 문자 후행 쉘 제거합니다 명령 대체 . 기본적 echo
으로 출력 끝에 새 줄 하나를 추가 하기 때문에 일반적으로 눈에 띄지 않습니다 . 따라서 끝에서 하나의 줄 바꿈을 잃고에서 하나 $(...)
를 얻는다면 echo
아무런 변화가 없습니다. 그러나 명령의 출력이 2 개 이상의 줄 바꾸기 문자로 끝나고 echo
하나만 다시 추가하면 출력에 하나 이상의 줄 바꿈 이 누락됩니다. 예를 들어, printf
후행 줄 바꿈 문자를 생성 하는 데 사용할 수 있습니다 . 줄 바꿈 수가 다르더라도 다음 명령은 모두 하나의 빈 줄을 출력하는 것과 같습니다.
$ echo "$(printf "\n")"
$ echo "$(printf "\n\n\n\n\n")"
$
이 동작은에 설명되어 man bash
있습니다.
또 다른 놀라움 : 경로 이름 확장, 두 번
세 개의 파일을 만들어 봅시다 :
$ touch 'file?' file1 file2
차이 관찰 ls file?
과 echo $(ls file?)
:
$ ls file?
file? file1 file2
$ echo $(ls file?)
file? file1 file2 file1 file2
의 경우에 echo $(ls file?)
, 파일 글로브는 file?
팽창 회 파일명이 발생 file1
하고 file2
출력에 두번 나타나는. Jeffiekins가 지적했듯이 경로 이름 확장 은 셸에서 먼저 ls
실행 된 다음 다시 실행 되기 전에 수행 되기 때문 echo
입니다.
큰 따옴표를 사용하면 두 번째 경로 이름 확장 을 억제 할 수 있습니다.
$ echo "$(ls file?)"
file?
file1
file2