일부 매개변수가 변수에서 나온 경우 명령 대체가 어떻게 작동하는지 이해할 수 없습니다.
이를 설명하기 위해 일련의 명령을 제공하겠습니다.
먼저 A B C
tmp 디렉터리 내에 디렉터리를 만들고 새 디렉터리에 새 파일을 만듭니다 abcfile
.
user@desktop /tmp
$ pwd
/tmp
user@desktop /tmp
$ mkdir "A B C"
user@desktop /tmp
$ ls
'A B C'
user@desktop /tmp
$ touch "A B C"/abcfile
user@desktop /tmp
$ ls "A B C"/
abcfile
A B C
변수에 값을 새로 할당 하고, 디렉토리의 내용을 나열하는 명령을 호출하는 다양한 방법을 $DIR
시도해 보겠습니다.ls
user@desktop /tmp
$ DIR="A B C"
변수가 인용되지 않으면 명령이 예상대로 실패합니다.
user@desktop /tmp
$ ls $DIR
ls: cannot access 'A': No such file or directory
ls: cannot access 'B': No such file or directory
ls: cannot access 'C': No such file or directory
변수를 참조한 후 예상대로 작동합니다.
user@desktop /tmp
$ ls "$DIR"
abcfile
명령의 출력을 문자열로 원하는 경우
user@desktop /tmp
$ echo $(ls "$DIR")
abcfile
이 명령은 작동하지만 왜 작동합니까? Shellcheck에 따르면 이것은 실제로 올바르지 않습니다. 변수는 큰따옴표 밖에 있어야 합니다.
user@desktop /tmp
$ echo "$(ls "$DIR")"
abcfile
내부 변수에 큰따옴표가 없으면 명령이 실패합니다.
user@desktop /tmp
$ echo "$(ls $DIR)"
ls: cannot access 'A': No such file or directory
ls: cannot access 'B': No such file or directory
ls: cannot access 'C': No such file or directory
답변1
나는 여러분이 출력 명령의 출력을 echo "$(somecommand)"
as로 바꿀 필요가 없으며 이 구성을 단지 예로 사용하고 있다는 것을 알고 있다고 가정합니다.somecommand
echo
출력이 인쇄 되므로 명령은 echo $(ls "$DIR")
"작동"합니다 .ls "$DIR"
abcfile
echo
이 경우 여기에 명령 대체를 인용해도 아무런 효과가 없습니다. 파일 이름에 있는 문자를 포함하도록 문자열 을 변경하지 않는 한 문자열에는 abcfile
따옴표가 필요하지 않습니다 (아래 이유 참조).$IFS
그러나 다음을 고려하십시오.
A B C/
|-- A*
`-- abcfile
지금:
$ echo "$(ls "$DIR")"
A*
abcfile
$ echo $(ls "$DIR")
A B C abcfile
마지막 출력에서는 파일 이름을 A*
디렉터리 이름과 일치하는 파일 이름 와일드카드 패턴으로 확장합니다 A B C
. 또한 출력에서 개행 문자가 손실되었음을 알 수 있습니다 ls
.
쉘이 손실되기 때문에 개행 문자가 손실됩니다.분사따옴표가 없는 출력에서 ls
공백, 탭 및 줄 바꿈(의 기본값 $IFS
)을 사용하여 단어로 분할합니다.
디렉토리 이름은 A B C
단어 분할에 의해 생성된 단어가 포함되어 있으므로 삽입됩니다.파일 이름 생성(와일드카드).
새 파일 이름이 이면 A* A*
디렉터리 이름이 두 번 삽입됩니다.
A B C/
|-- A* A*
`-- abcfile
$ echo $(ls "$DIR")
A B C A B C abcfile
관련된:
답변2
이것이 주된 오해인 것 같습니다.
변수는 큰따옴표 밖에 있어야 합니다.
user@desktop /tmp $ echo "$(ls "$DIR")" abcfile
변수가 큰따옴표 밖에 있지 않습니다. 쉘은 내부에서 인용을 고려합니다.$()
각기외부에서 인용하는 것보다. 즉, echo "$(ls "$DIR")"
큰따옴표 안에는 실제로중첩됨:
echo "$(ls "$DIR")"
# ^ ^ inner quotes
# ^ ^ outer quotes
일반적으로 큰따옴표로 묶인 변수는 좋기 때문에그리고전체 명세서 $()
에 이러한 인용문이 각각 필요합니다 (인용하고 싶지 않은 경우 제외).
"Quirk 2" 비교이 답변.
부가 질문:
명령의 출력을 문자열로 원하는 경우
user@desktop /tmp $ echo $(ls "$DIR") abcfile
stdout에 대한 출력에는 유형이 없으며 echo
문자열로 만들지 않습니다. 이 특별한 경우에는 echo
아무것도 바뀌지 않지만 다음을 참조하세요.무엇이 잘못되었나요 echo $(stuff)
?