쉘 펼쳐 비교에서 x $ VAR = xyes를 자주 사용하는 이유는 무엇입니까?
autotools (autoconf, automake)를 사용하는 프로젝트의 빌드 펼쳐보기에서 자주 볼 수 있습니다. 누군가 쉘 변수의 값을 확인하고 싶을 때 다음 관용구를 자주 사용합니다.
if test "x$SHELL_VAR" = "xyes"; then
...
다음과 같이 가치를 확인하는 것보다 이것의 장점은 무엇입니까?
if test $SHELL_VAR = "yes"; then
...
이걸 자주 보는 이유가있을 것 같지만 그게 뭔지 모르겠어요.
단순 대체 를 수행하는 셸을 사용 중이고 SHELL_VAR
변수가 존재하지 않거나 비어있는 경우, 엣지 케이스를주의해야합니다. 다음 번역이 수행됩니다.
if test $SHELL_VAR = yes; then --> if test = yes; then
if test x$SHELL_VAR = xyes; then --> if test x = xyes; then
첫 번째 인수 test
가 누락 되었기 때문에 첫 번째는 오류를 생성합니다 . 두 번째는 그 문제가 없습니다.
귀하의 사례는 다음과 같이 번역됩니다.
if test "x$SHELL_VAR" = "xyes"; then --> if test "x" = "xyes"; then
는 x
따옴표가 빈 인수 한 모두 포함하는 공간이 하나의 개체로 해석되는 것을 찾다 때문에, POSIX 호환 쉘에 대한 최소한, 실제로는 있습니다.
아무도 아직 언급하지 않은 또 다른 이유는 처리와 관련이 있습니다. 당신이 쓰는 경우 :
if [ "$1" = "abc" ]; then ...
$ 1의 값이 '-n'이고 테스트 명령의 구문이 모호합니다. 무엇을 테스트했는지 명확하지 않습니다. 앞쪽의 'x'는 선행 대시가 문제를 예방합니다.
테스트 명령이 -n
또는 지원하지 않는 쉘을 설치하면 정말 오래된 쉘을 만나게 -z
됩니다. 버전 7 (1978) test
명령에 포함되었습니다. 그다지 중요하지 않습니다. 일부 버전 6 UNIX 항목이 BSD로 이스케이프 요즘에는 현재 사용중인 오래된 항목을 찾기가 매우 어렵습니다.
많은 다른 사람들이 지적했듯이 값 주위에 큰 따옴표를 사용하지 않는 것은 위험합니다. 파일 이름에 공백이있을 가능성이있는 경우 (MacOS X와 Windows는 모두 어느 정도이를 권장하며 Unix는 다음과 같은 도구에도 불구하고 항상이를 지원합니다. 더 어렵게 만듭니다 . xargs
), 이름을 사용할 수 있습니다. 때마다 큰 따옴표로 묶어야합니다. (예 : 옵션 처리 중에 변수를 시작시 'no'로 설정하고 명령 줄에 플래그가 포함되어있을 때 'yes'로 설정) 인용되지 않은 형태의 변수를 사용하는 것은 안전하지 않습니다. . 안전하고 있다는 것을 증명할 때까지-그리고 여러 목적을 위해 항상 그렇게하는 것이 좋습니다. 또는 사용자가 이름에 공백이있는 파일을 처리하려고 시도하면 끔찍하게 실패 문서화하십시오. (그리고 걱정할 다른 캐릭터도 있습니다. 예를 들어 백틱도 다소 불쾌 할 수 있습니다.)
이 대회에 대해 제가 아는 두 가지 이유가 있습니다.
http://tldp.org/LDP/abs/html/comparison-ops.html
에서만 사용할 수 있습니다. [-n "$ string"-o "$ a"= "$ b"] $ string이 비어있는 경우 일부 버전의 Bash에서 오류가 보관 수 있습니다. 안전한 방법은 빈 변수에 추가 문자를 추가하는 것입니다. [ "x $ 문자열"! = x -o "x $ a"= "x $ b"] ( "x 's"취소).
둘째, Bash 이외의 다른 셸, 오래된 셸에서는 빈 변수를 테스트하는 '-z'와 같은 테스트 조건이 존재하지 않습니다.
if [ -z "$SOME_VAR" ]; then
echo "this variable is not defined"
fi
기본 쉘이 Bash이고 -z 테스트 조건을 지원하는지 여부를 확신 할 수있는 다양한 UNIX 환경에서 이식성을 목표로하는 경우 BASH에서 잘 작동합니다. if [ "x $ SOME_VAR"= "x"] 항상 의도 한 효과를 갖기 때문입니다. 기본으로이 빈 변수를 찾기위한 오래된 쉘 스크립팅 트릭이며, 더 확실한 방법을 사용할 수 있음에도 불구하고 이전 버전과의 사용을 위해 사용됩니다.
대신 다음을 권장합니다.
if test "yes" = "$SHELL_VAR"; then
추악한 것을 없애고 https://stackoverflow.com/a/174288/895245 에서 x
언급 한 문제를 해결하기 옵션으로 시작 하고 읽을 수 있습니다.$SHELL_VAR
-
나는 그것 때문에 믿습니다
SHELLVAR=$(true)
if test $SHELLVAR = "yes" ; then echo "yep" ; fi
# bash: test: =: unary operator expected
만큼 잘
if test $UNDEFINEDED = "yes" ; then echo "yep" ; fi
# bash: test: =: unary operator expected
과
SHELLVAR=" hello"
if test $SHELLVAR = "hello" ; then echo "yep" ; fi
# yep
그러나 일반적으로 작동합니다
SHELLVAR=" hello"
if test "$SHELLVAR" = "hello" ; then echo "yep" ; fi
#<no output>
그러나 다른 곳에서 출력에 대해 불평 할 때, 제가 생각하기에 불평하는 것을 말하기가 어렵습니다.
SHELLVAR=" hello"
if test "x$SHELLVAR" = "xhello" ; then echo "yep" ; fi
마찬가지로 작동하지만 디버깅하기가 더 쉽습니다.
나는 SHELL_VAR이 정의되지 않을 때 DOS에서 그것을 사용했습니다.
"x $ SHELL_VAR"작업을 수행하지 않으면 $ SHELL_VAR이 정의되지 않은 경우 "="가 모나 딕 연산자가 아닙니다. 또는 이와 유사한 오류가 발생합니다.
참고 URL : https://stackoverflow.com/questions/174119/why-do-shell-script-comparisons-often-use-xvar-xyes
'ProgramingTip' 카테고리의 다른 글
Numpy의 평균 제곱 오차? (0) | 2020.12.11 |
---|---|
Docker Compose 파일에서 $ 달러 기호를 어떻게 이스케이프 할 수 있습니까? (0) | 2020.12.11 |
scala Iterable # map 대 Iterable # flatMap (0) | 2020.12.11 |
IIS7의 클래식 ASP : 500 내부 서버 오류에서 브라우저로 오류 전송 거부 (0) | 2020.12.11 |
동작 (0) | 2020.12.11 |