몇 년 동안 저를 괴롭혔던이 수수께끼를 풀어야 할 때가되었습니다 …
나는 때때로 이것을 만나고 이것이 갈 길이라고 생각했다.
$(comm "$(arg)")
그리고 내 견해는 경험에 의해 강력하게 뒷받침된다고 생각했습니다. 그러나 나는 더 이상 확신하지 못한다. Shellcheck 도 마음을 사로 잡을 수 없습니다. 둘 다입니다.
"$(dirname $0)"/stop.bash
^-- SC2086: Double quote to prevent globbing and word splitting.
과:
$(dirname "$0")/stop.bash
^-- SC2046: Quote this to prevent word splitting.
뒤에 논리는 무엇입니까?
(이것은 Shellcheck 버전 0.4.4, btw입니다.)
답변
를 사용해야 "$(somecmd "$file")"
합니다.
따옴표가 없으면 공백이있는 경로가에 인수로 분할되어 somecmd
잘못된 파일을 대상으로합니다. 내부에 따옴표가 필요합니다.
출력 결과에 공백이 somecmd
있으면 분할이 발생하므로 전체 명령 대체 외부에 따옴표가 필요합니다.
명령 대체 내부의 따옴표는 외부의 따옴표에 영향을 미치지 않습니다. Bash의 자체 참조 매뉴얼은 이것에 대해 명확하지 않지만 BashGuide는 명시 적으로 언급합니다 . POSIX 의 텍스트 에도 “유효한 쉘 스크립트” 가 허용 되므로 다음과 같은 내용이 필요합니다 $(...)
.
$(command)
형식을 사용하면 여는 괄호 다음에 일치하는 닫는 괄호 뒤에있는 모든 문자가 명령을 구성합니다. 지정되지 않은 결과를 생성하는 리디렉션만으로 구성된 스크립트를 제외하고 모든 유효한 쉘 스크립트를 명령에 사용할 수 있습니다.
예:
$ file="./space here/foo"
ㅏ. 따옴표, dirname
모두 처리되지 ./space
및 here/foo
:
$ printf "<%s>\n" $(dirname $file)
<.>
<here>
비. inside, dirname
processes ./space here/foo
, giving ./space here
을 두 개로 나눕니다.
$ printf "<%s>\n" $(dirname "$file")
<./space>
<here>
씨. 외부를 인용 하고 ,와를 dirname
모두 처리 하여 별도의 줄로 출력하지만 이제 두 줄은 단일 인수를 형성합니다 ../space
here/foo
$ printf "<%s>\n" "$(dirname $file)"
<.
here>
디. 내부와 외부를 인용하면 정답이됩니다.
$ printf "<%s>\n" "$(dirname "$file")"
<./space here>
( dirname
첫 번째 인수 만 처리하면 더 간단했을 수 있지만 사례 a와 c의 차이는 표시되지 않습니다.)
함께합니다 dirname
(다른 가능성이) 당신은 또한 추가 할 필요가 --
,이 대시로 시작하는 일 경우 옵션으로 촬영 사용 그렇게되는 파일 이름을 방지하기 위해 "$(dirname -- "$file")"
.