ProgramingTip

쉘 펼쳐 비교에서 x $ VAR = xyes를 자주 사용하는 이유는 무엇입니까?

bestdevel 2020. 12. 11. 19:14
반응형

쉘 펼쳐 비교에서 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

반응형