
나는 bash 스크립트를 읽고 있는데 거기에 무슨 일이 일어나고 있는지 이해하지 못합니다.
#!/bin/sh
[ x$1 = x ]
두 번째 줄에서는 무슨 일이 일어나고 있으며 그 [ x$1 = x ]
의미는 무엇입니까?
답변1
$1
따옴표로 묶어야 하지만 비어 있는 수표 입니다( 와 동일 [ -z "$1" ]
). 일부 아주 오래된 쉘은 빈 문자열을 제대로 처리하지 못했기 때문에 이식 가능한 스크립트 작성자는 이러한 검사 스타일을 채택했습니다. 수십년 동안은 필요하지 않았지만 사람들이 여전히 그렇게 하기 때문에 사람들은 여전히 그렇게 합니다.
답변2
대괄호는시험, 따라서 구문상으로는 괜찮지 [ 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 test
와 의 차이점을 확인하세요 type test
. GNU/Linux에서는 man test
내장을 참조한다고 주장하지만 (예를 들어) 을 호출하면 해당 유틸리티는 및 를 /usr/bin/test
포함하여 매뉴얼 페이지에 문서화된 기능을 구현하는 것으로 보입니다 .-z
-n
답변3
[ x$1 = x ]
에서만 의미가 있습니다 zsh
. 이는 x
스크립트의 첫 번째 인수와 의 연결을 와 비교합니다 x
. 따라서 이 [
명령은 비어 있거나 제공되지 않은 경우 true를 반환합니다 $1
.
[ $1 = "" ]
zsh
빈 변수가 목록 컨텍스트에서 인용되지 않으면 빈 인수 대신 전혀 인수가 없는 것으로 확장되므로 작동하지 않습니다. 따라서 $1
설정되지 않거나 비어 있으면 명령은 빈 문자열인 [
인수로만 수신됩니다 [
. =
그리고 ]
그것은 이해가 되지 않았습니다. [ -z "$1" ]
아니면 [ "$1" = "" ]
POSIX 쉘처럼 괜찮을 것입니다.
Bourne-like/POSIX 쉘에서는 [ x$1 = x ]
의미가 없습니다. 이는 x
결과 및 =
및 x
가 명령 ]
에 대한 유효한 테스트 표현식을 구성하기 를 바라는 스크립트의 첫 번째 인수와 연결에 어떻게든 적용되는 분할+글로브 연산자입니다 [
.
예를 들어, 스크립트에 하나 " = x -o x ="
의 인수가 전달되면 [
, [
, x
, =
, x
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , -o
, , x
, , =
, , , , x
, , , , , , , ]
, , , , , , , , , , , 등의 인수 가 스크립트에 전달된 경우 와 비교 [
하여 true 를 반환합니다.x
x
x
x
이면 쉘은 이름이 (glob 확장 ) 로 시작하는 현재 디렉토리의 파일 목록을 명령 에 전달한 다음 숨겨지지 않은 파일 목록(확장 )...을 $1
전달 합니다. 어떤 의미로든. 이것이 의미 있는 작업을 수행할 수 있는 유일한 경우는 와일드카드나 공백 문자가 포함되지 않은 경우입니다."* *"
[
x
x*
*
[
$1
이제 때때로 다음과 같은 코드를 발견하게 됩니다.
[ "x$1" = x ]
$1
이는 비어 있는지 또는 설정되지 않았는지 테스트하는 데 사용됩니다 .
비어 있거나 설정되지 않은 변수를 테스트하는 일반적인 방법은 다음과 같습니다.
[ -z "$1" ]
그러나 이는 Solaris 10 및 이전 버전이나 일부 이전 버전 (최대 0.5.4) 또는 일부 BSD 에서 발견된 Bourne 쉘의 내장 구현과 같은 일부(POSIX가 아닌) 구현 $1
과 같은 일부 값에서는 실패합니다.=
[
/bin/sh
dash
sh
그 이유는 , , 및 [
가 문자열 에 적용된 단항 연산자 로 이해하는 대신 이항 연산자 에 대한 인수 누락에 대해 불평하기 때문입니다 .[
-z
=
]
=
-z
=
마찬가지로 if is 또는 [ "$1" = "" ]
의 일부 구현에서는 실패합니다 .[
$1
!
(
해당 쉘/ [
구현에서:
[ "x$1" = x ]
는 값에 관계없이 항상 유효한 테스트이므로 $1
다음과 같습니다.
[ "" = "$1" ]
그리고:
[ -z "${1:+x}" ]
그리고
case $1 in "") ...; esac
물론 인수가 제공되지 않았는지 확인하려면 다음을 수행합니다.
[ "$#" -eq 0 ]
즉, 스크립트에 전달된 인수 수를 확인합니다.
요즘에는 [ -z "$var" ]
POSIX에 의해 명확하게 지정되어 있으며 준수 구현에 실패할 수 없습니다 [
(및 bash
는 [
수십 년 동안 그래왔습니다). 따라서 POSIX sh 또는 bash
스크립트 에서 이를 사용할 수 있어야 합니다 .
답변4
[ x$1 = x ]
$1
설정되지 않았거나/null/비어 있거나 그렇지 않은 경우 true입니다 .
다음을 사용해 보십시오:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
및
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"