이 두 Bash if 문의 차이점은 무엇입니까? 예를 들어
if [ "$FOO" = "true" ]; then
비교됨
if [ $FOO = "true" ]; then
차이점이 뭐야? 이 두 진술은 동일한 효과를 갖는 것 같습니다.
답변1
값이 $FOO
와일드카드 문자를 포함하지 않는 단일 단어 인 경우 둘은 동일합니다 \[*?
.
$FOO
따옴표가 없는 버전 은 할당되지 않았거나 비어 있거나 두 개 이상의 단어가 있는 경우 (예: 공백 또는 가 포함된 경우) $IFS
구문 오류입니다 . 올바른 단어 순서(예: )인 경우 0 -eq 0 -o false
결과는 임의적일 수 있습니다. 따라서 쉘 스크립트에서는 항상 변수를 인용하는 것이 가장 좋습니다.
그런데 "true"
인용은 필요하지 않습니다.
답변2
이로 인해 발생할 수 있는 문제를 설명하기 위해 다음과 같은 몇 가지 예가 있습니다.
다음과 같은 두 가지 변수가 있다고 가정합니다.
FOO="some value"
BAR="some value"
이제 정확히 동일한 문자열/값을 보유하는 두 개의 변수가 있습니다. 귀하의 경우 결과를 테스트하기 위해 if 문을 만드는 경우:
if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi
이 시점에서 bash: [: too many arguments
따옴표 없이 .$FOO에는 세 개의 값이 포함됩니다. 즉, '[ , some , value'
test [
키워드는 첫 번째 또는 두 번째 인수가 연산자일 것으로 예상하기 때문에 무엇을 해야할지 모릅니다.
if
"$FOO"를 참조할 때 토큰화가 발생하지 않은 올바른 값을 보도록 명시적으로 지시됩니다 .
다른 예시:
my_file="A random file.txt"
- 이렇게 하면
rm $my_file
"A" "random" "file.txt"를 삭제하여 3개의 파일이 됩니다. - 이렇게 하면
rm "$my_file"
파일을 생성하는 "임의의 file.txt"가 삭제됩니다.
이러한 예를 들어 여러분을 혼동하지 않았으면 좋겠습니다.
답변3
여기서 중요한 것은 if
명령문 내의 참조가 아니라 모든 명령의 매개변수 내의 참조이며, 특정 경우에는 명령 입니다 [
.
이 [
명령은 다른 명령과 유사하며(비록 대부분의 Bourne 유사 쉘에 내장되어 있음) 명령문 외부는 물론 명령문의 if
, then
, elif
, else
부분 내에서 사용할 수 있습니다 .if...fi
if...fi
zsh
이외 의 Bourne형 쉘에는분할+전역운영자.
$FOO
는 복잡한 규칙을 사용하여 문자를 기준으로 분할되며 $IFS
결과 단어는 파일 이름 생성의 영향을 받습니다. [
이는 정확히 하나의 인수를 예상하지만 명령에서 가변 개수의 인수를 생성합니다.
따라서 명령에 대한 인수와 마찬가지로 $FOO
해당 내용이 인수로 전달되도록 따옴표로 묶어야 합니다.
[
명령 중 하나입니다비판적인변수를 인용하는 것을 잊지 마십시오. 그렇게 하지 않으면 [
많은 구현에서 임의의 명령 주입이 됩니다(변수의 내용이 공격자의 제어 하에 들어갈 가능성이 있는 경우).
여기에는 , 및 파생 항목(및 /emulation에 있는 경우)에 대한 내장 유틸리티 [
뿐만 아니라 내장 래퍼 스크립트로 구현되는 Solaris( , ... )와 같은 시스템용 독립 실행형 유틸리티도 포함됩니다.bash
ksh88
ksh93
pdksh
zsh
sh
ksh
[
/bin/[
/usr/xpg4/bin/[
ksh
[
이러한 [
구현(예: 셸의 모든 내장 명령)은 경우에 따라 산술 표현식을 해석하거나 변수 이름에 대해 연산을 수행하여 궁극적으로 코드를 실행할 수 있습니다.
예를 들어, bash
셸(GNU 프로젝트의 셸 및 sh
일부 시스템의 구현)에서 기본값은 다음과 같습니다 $IFS
.
bash-5.0$ FOO='-v x[$(reboot)] -o true'
bash-5.0$ if [ $FOO = "true" ]; then echo yes; fi
System rebooting now!
yes
따옴표가 없고 $IFS
기본적으로 SPC 문자가 포함되어 있기 때문에 , , $FOO
로 나누어져 있습니다 . 이 중 두 번째에만 전역 연산자( )가 포함되어 있습니다. 내 경우에는 어떤 파일과도 일치하지 않았으므로(예: 현재 디렉토리에 파일이 있으면 상황이 달라질 수 있음) 그대로 두었습니다(Bourne과 같은 쉘의 또 다른 특성, 대부분의 다른 쉘은 전역에 대해 불평합니다. 불일치).-v
x[$(reboot)]
-o
true
[...]
xo
[
따라서 배열이 $x
index 로 설정되어 해당 산술 표현식 평가의 일부로 실행되는지 또는 $(reboot)
( )가 같으면 출력이 되는지 묻는 메시지가 표시됩니다 .reboot
-o
true
true
yes
추가 자료:
답변4
이 특정한 경우에는 차이가 없습니다.
하지만 $FOO
공백이나 특수 문자가 포함되어 있으면 문제가 발생합니다.
이 "$FOO"
경우 일치로 인해 공간 문제가 발생하지 않도록 총 변수를 사용합니다.
그러나 $FOO
and를 사용할 때 특별한 상황이 있는 경우 if 문에 영향을 미칩니다.