"ls"와 "echo $(ls)"의 차이점

"ls"와 "echo $(ls)"의 차이점

두 가지 쉘 샘플을 고려하십시오.

$ ls
myDoc.html
SomeDirectory
someDoc.txt

그리고

$ echo $(ls)
myDoc.html SomeDirectory someDoc.txt

내가 이해한 바로는 수행되는 첫 번째 작업은 ls현재 작업 디렉터리의 내용을 파일에 추가하는 것입니다 stdout(이것이 터미널에 표시되는 내용입니다). 맞습니까?

두 번째는 명령의 값 ls(현재 작업 디렉터리의 내용을 의미)을 가져와서 파일에 인쇄합니다 stdout. 맞습니까?

이 두 명령이 서로 다른 출력을 제공하는 이유는 무엇입니까?

답변1

이 명령을 실행하면:

ls

터미널에 표시되는 출력입니다 ls.

이 명령을 실행하면:

echo $(ls)

쉘은 출력을 캡처 $(ls)하고 실행합니다.분사위에. IFS모든 공백 시퀀스를 의미하는 기본값을 사용하고 ,포함하다줄 바꿈은 단일 공백으로 대체됩니다. 이것이 바로 출력이 echo $(ls)한 줄에 나타나는 이유입니다.

단어 분할에 대한 고급 논의는 다음을 참조하세요.그렉 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?확장된 경우두 배, 파일 이름 file1file2출력에 두 번 표시됩니다. Jeffkins가 지적했듯이, 이는 다음과 같습니다.경로명 확장실행하기 전에 먼저 ls셸에서 실행한 다음 echo실행하기 전에 다시 실행합니다.

두번째경로명 확장큰따옴표를 사용하면 이를 억제할 수 있습니다.

$ echo "$(ls file?)"
file?
file1
file2

답변2

ls터미널로 출력을 보내고 있는지 확인하십시오.

명령 프롬프트에서 실행하면 ls의사 터미널에 기록됩니다. ls일반적으로 will의 출력을 리디렉션합니다.아니요의사 터미널을 입력하고 ls출력 형식이 다르게 지정됩니다.

관련 정보