답변:
짧은 답변
다른 사람들이 말했듯이 이상한 행동을 막기 위해 항상 변수를 인용해야합니다. 사용 그래서 "$ foo는"에코 대신에 단지 $ foo는 에코 .
긴 대답
나는이 예가 그 얼굴에 보이는 것보다 더 많은 일이 있기 때문에 더 많은 설명이 필요하다고 생각합니다.
첫 번째 예제를 실행 한 후 쉘이 분명히하고 있다고 생각했기 때문에 혼란이 어디에서 발생했는지 알 수 있습니다.
첫 번째 예에서 :
me$ FOO="BAR * BAR"
me$ echo $FOO
매개 변수 확장 후는 다음과 같습니다.
me$ echo BAR * BAR
그리고 파일 이름 확장 후 다음과 같습니다.
me$ echo BAR file1 file2 file3 file4 BAR
그리고 echo BAR * BAR
명령 행에 입력하면 그것들이 동등한 것을 볼 수 있습니다.
"*를 피하면 파일 이름 확장을 막을 수 있습니다."
두 번째 예에서 :
me$ FOO="BAR \* BAR"
me$ echo $FOO
매개 변수 확장 후는 다음과 같아야합니다.
me$ echo BAR \* BAR
파일 이름 확장 후 다음과 같아야합니다.
me$ echo BAR \* BAR
명령 행에 "echo BAR \ * BAR"을 직접 입력하면 이스케이프로 파일 이름 확장이 방지되므로 실제로 "BAR * BAR"이 인쇄됩니다.
그렇다면 왜 $ foo를 사용할 수 없었습니까?
견적 제거라는 세 번째 확장이 있기 때문입니다. bash 수동 따옴표 제거는 다음과 같습니다.
앞의 확장 후에는 위의 확장 중 하나에서 발생하지 않은 인용되지 않은 문자 '\', '' '및' " '가 모두 제거됩니다.
따라서 명령 행에 명령을 직접 입력하면 이스케이프 문자는 이전 확장의 결과가 아니므로 에코 명령으로 보내기 전에 BASH가이를 제거하지만 두 번째 예에서는 "\ *" 이전 매개 변수 확장의 결과이므로 제거되지 않습니다. 결과적으로 echo는 "\ *"를 수신하고 인쇄됩니다.
첫 번째 예의 차이점- "*"는 따옴표 제거로 제거 될 문자에 포함되지 않습니다.
이것이 의미가 있기를 바랍니다. 결국 같은 결론-따옴표 만 사용하십시오. 방금 매개 변수 및 파일 이름 확장 만 작동하는 경우 논리적으로 작동 해야하는 탈출이 작동하지 않는 이유를 설명하려고 생각했습니다.
BASH 확장에 대한 자세한 설명은 다음을 참조하십시오.
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
이 오래된 스레드에 약간을 추가하겠습니다.
보통은
$ echo "$FOO"
그러나이 구문에도 문제가 있습니다. 다음 스크립트를 고려하십시오.
#!/bin/bash
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1"
에 *
그대로 전달해야 curl
하지만 같은 문제가 발생합니다. 위의 예제는 작동하지 않으며 (현재 디렉토리의 파일 이름으로 확장됩니다) 어느 것도 작동하지 않습니다 \*
. 또한 $curl_opts
단일 (유효하지 않은) 옵션으로 인식되므로 인용 할 수 없습니다 curl
.
curl: option -s --noproxy * -O: is unknown
curl: try 'curl --help' or 'curl --manual' for more information
따라서 전역 패턴에 적용하거나 내장 플래그를 사용하는 경우 파일 이름 확장을 방지하기 위해 bash
변수 $GLOBIGNORE
를 사용하는 것이 좋습니다 set -f
.
#!/bin/bash
GLOBIGNORE="*"
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1" ## no filename expansion
원래 예제에 적용 :
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
me$ set -f
me$ echo $FOO
BAR * BAR
me$ set +f
me$ GLOBIGNORE=*
me$ echo $FOO
BAR * BAR
SELECT * FROM etc.
이것이 유일한 방법입니다.