bash 스크립트 [x $ 1 = x]


21

나는 bash 스크립트를 읽고 있는데 나는 거기에 무슨 일이 일어나고 있는지 이해하지 못한다.

#!/bin/sh
[ x$1 = x ] 

두 번째 줄에서 무슨 일이 일어나고 있으며 무슨 [ x$1 = x ] 뜻입니까?

답변:


27

그 수표 $1가 (동일 인용해야하지만, 비어 [ -z "$1" ]). 아주 오래된 쉘은 빈 문자열을 제대로 처리하지 못했기 때문에 휴대용 스크립트 작성자는 이러한 스타일의 검사를 채택했습니다. 수십 년 동안 필요하지 않았지만 사람들은 여전히 ​​그렇게하므로 사람들은 여전히 ​​그렇게합니다.


예, 더 이상 이렇게하지 말고 더 현대적인 스타일을 채택하십시오. PDP11에서 작업하지 않는 한.
MacLemon

4
빈 문자열만큼 중요하지 않습니다. [ x$1 = x ]여전히 잘못이지만, [ "x$1" = x ]문제가 껍질이 될 것 $1입니다 !또는 (또는를 -n.... [ "" = "$1" ]하고 case $1 in "")도 OK하지만 것입니다.
Stéphane Chazelas 2016 년

2
@MacLemon, 멀리 갈 필요가 없습니다. [ -z "$1" ]그리고 [ "$1" = "" ]여전히 dash-0.5.4를 사용하는 Solaris 10의 / bin / sh에서는 작동하지 않습니다.
Stéphane Chazelas 2016 년

1
마지막 문장에 여분의 +1!
glenn jackman 2016 년

1
@glennjackman, 마지막 문장이 잘못되었습니다. Solaris 10은 여전히 ​​가장 널리 배포 된 Solaris 버전이며 [ "$1" = "" ]여전히 작동하지 않습니다 /bin/sh(여기서는 사용하고 싶지는 /usr/xpg4/bin/sh않지만 /bin/sh). 대시는 2009 년 1 월에 이와 관련하여 수정되었습니다.
Stéphane Chazelas

8

대괄호는 표시 테스트를 그렇게 [ x$1 = x]하지 않고 if문법적으로 확인하지만 비슷한는 의미가 없다거나.

x$1확장 하면 true로 평가되고 x그렇지 않으면 false 로 평가 되지만, 인용 되지 않았으므로 $1(예 : "hey x") 셸이 표시되므로이 x = x구성은 여전히 ​​안전하지 않습니다.

x = x검사 의 목적은 변수가 비어 있는지 확인하는 것입니다. 이 작업을 수행하는 가장 일반적인 방법은 따옴표를 사용하는 것입니다.

if [ "$1" = "" ]; then

Bash 테스트 연산자 -z-n사용할 수도 있지만 다른 유형의 쉘에는 이식성이 떨어집니다. 1

따옴표 또는의 이유 x$1는 왼쪽이 아무것도 확장되지 않기 때문에 구문 오류입니다.

if [  = x ]  # No good!
if [ "" =  "" ] # Okay.
if [ x = x ] # Also okay.

1. 실제로 test독립형 유틸리티 일 수 있지만 대부분의 쉘은이를 내장형으로 구현합니다. 차이 확인 which testtype test. GNU / 리눅스에 man test주장을 참조하기 위해 내장,하지만 당신은 호출하는 경우 (예를 들어) /usr/bin/test, 그 유틸리티가 포함 매뉴얼 페이지에 설명 된 기능을 구현하는 것 -z하고 -n.


1
[ x$1 = x ]$1예를 들어 이면 true로 평가됩니다 " -o x". 시도하십시오 sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'. [ x$1 = x ]잘못되어 이해가되지 않습니다.
Stéphane Chazelas

@ StéphaneChazelas Thanks SC-편집 됨 (2 단).
goldilocks

당신은 필요가 없습니다 if사용 test이전에 그것을 사용할 수 있습니다 &&, ||또는 후 while또는 사용하여 결과를 검토$?
Jasen

8
[ x$1 = x ]

에서만 의미가 zsh있습니다. 이는 x스크립트의 첫 번째 인수와 의 연결을와 비교합니다 x. 따라서 [명령 $1이 비어 있거나 제공되지 않으면 true를 리턴합니다 .

[ $1 = "" ]

에, 때문에 작동하지 않을 것입니다 zsh비어있는 변수 목록 맥락에서 인용되지 않을 때, 그렇게하면 대신 빈 인수의 전혀 인수로 확장 $1해제 또는 비어 있었다의 [명령은 인수로받을 [, =빈 문자열 그리고 ]그것은 이해할 수 없었습니다. [ -z "$1" ]또는 [ "$1" = "" ]POSIX 쉘에서와 같이 괜찮을 것입니다.

Bourne-like / POSIX 쉘에서는 [ x$1 = x ]의미가 없습니다. 즉 어떻게 든의 연결에 적용되는 분할 + 글로브 운영자 x와 결과 및 바라고 스크립트의 첫 번째 인수 =하고 x, 그리고 ]에 대한 유효한 테스트 표현식 구성 [명령을 사용합니다.

스크립트가 하나 개 전달 된 경우 예를 들어, " = x -o x ="인수를 [그 인수를받을 것이다 : [, x, =, x, -o, x, =, x, ], 어떤 [비교로 이해할 xxxx와 true를 돌려줍니다.

경우 $1였다 "* *", 다음 쉘은에 전달할 것 [그 이름을 시작으로 현재 디렉토리에 명령 파일 목록을 x(의 글로브 확장 x*) 비 숨겨진 파일 (확장, 다음 목록 *) ... [할 수 없을 수도 있습니다 어떤 의미에서 말입니다. $1와일드 카드 나 공백 문자가 포함되지 않은 경우에 합리적 일 수 있습니다.

이제는 때때로 다음과 같은 코드를 찾습니다.

[ "x$1" = x ]

$1비어 있거나 설정되어 있지 않은지 테스트하는 데 사용됩니다 .

비어 있거나 설정되지 않은 변수를 테스트하는 일반적인 방법은 다음과 같습니다.

[ -z "$1" ]

그러나 이것은 Solaris 10 및 이전 또는 이전 버전 (최대 0.5.4) 또는 일부 BSD 에서와 같이 Bourne 쉘의 내장 된 것과 같은 일부 POSIX가 아닌 구현 에서 $1와 같은 일부 값에 대해서는 실패합니다 .=[/bin/shdashsh

그 때문입니다 [보고 [, -z, =, ]과에 인수 누락에 대해 불평 =이항 연산자 대신으로 이해 -z단항 연산자가 적용 =문자열입니다.

유사하게, [ "$1" = "" ]일부 구현에 실패 [하는 경우 $1이다 !(.

해당 쉘 / [구현에서 :

[ "x$1" = x ]

의 값에 관계없이 항상 유효한 테스트 $1이므로 다음과 같습니다.

[ "" = "$1" ]

과:

[ -z "${1:+x}" ]

case $1 in "") ...; esac

물론, 인수가 제공되지 않았는지 확인하려면 다음을 수행하십시오.

[ "$#" -eq 0 ]

즉, 스크립트에 전달 된 인수 수를 확인합니다.

요즘, 참고 [ -z "$var" ]명확하게 POSIX에 의해 지정되고 준수에 실패 할 수 없습니다 [구현 (와 bash의이 [이며, 수십 년 동안이었다). 따라서 POSIX sh 또는 bash스크립트 에서이를 사용할 수 있어야합니다 .


0

x$1두 문자열 연접된다 x$1그리고 $ 1 비어 있다면 $ 1 x는 X와 동일하고 [$ X 1 = X 그 결과에 해당 될 것이다. x = ysh에서 문자열을 비교하는 데 사용됩니다.


2
없음은 x$1, 인용 분할 있도록 글 로빙은 이들에 수행되지 않습니다.
Stéphane Chazelas

0

[ x$1 = x ]$1설정되지 않았거나 null이거나 비어 있으면 true 입니다.
자신과 시도 :
TEST= ;[ x$TEST = x] && echo "TEST is unset"

TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"


1
[ x$1 = x ]$1예를 들어있는 경우에도 마찬가지 " -o x"입니다. 시도하십시오 sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'. [ x$1 = x ]잘못되어 이해가되지 않습니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.