bash 쉘과 다른 쉘 사이에서 test 또는 [또는 [[더 이식성이 좋은가? 수있는 걸

내가 할 수있는 걸 봤어

$ [ -w /home/durrantm ] && echo "writable"
writable

또는

$ test -w /home/durrantm && echo "writable"
writable

또는

$ [[ -w /home/durrantm ]] && echo "writable"
writable

세 번째 구문을 사용하는 것이 좋습니다. 그것들은 모든면에서 그리고 모든 부정적인 경우와 동등한 경우에 동등합니까? Ubuntu의 bash와 OS X 또는 이전 / 이후 bash 버전 (예 : 4.0 이전 / 이후) 간의 이식성에 차이가 있습니까? 둘 다 같은 방식으로 식을 확장합니까?



답변

[test명령의 동의어 이며 동시에 bash 내장 명령 과 별도 명령입니다. 그러나 [[A는 bash는 키워드 및 일부 버전에서 작동합니다. 따라서 이식성의 이유로 단일 []또는test

[ -w "/home/durrantm" ] && echo "writable"


답변

예, 차이점이 있습니다. 가장 휴대용은 test또는 [ ]입니다. 이것들은 모두 POSIX test사양의 일부입니다 .

if ... fi구조체는 또한 POSIX로 정의 완전 이식한다.

[[ ]]A는 ksh또한 일부 버전에 존재하는 기능 bash( 모든 현대적인 것들 에) zsh아마 다른 사람이 아니라에 존재하지 않는 sh거나 dash또는 다양한 다른 간단한 포탄입니다.

그래서, 스크립트가 휴대용하게 사용하는 [ ], test또는 if ... fi.


답변

즉,주의 사항 [] && cmd과 동일하지 않습니다 if .. fi건설.

때로는 그 동작이 매우 비슷하기 때문에 [] && cmd대신 사용할 수 있습니다 if .. fi. 그러나 때때로. if 조건을 실행할 명령이 하나 이상 있거나 if .. else .. fi조심하고 논리 가 필요한 경우.

몇 가지 예 :

[ -z "$VAR" ] && ls file || echo wiiii

와 동일하지 않습니다

if [ -z $VAR ] ; then
  ls file
else
  echo wiii
fi

ls실패 echo하면으로 실행 되지 않기 때문에 실행됩니다 if.

또 다른 예:

[ -z "$VAR" ] && ls file && echo wiii

와 같지 않다

if [ -z "$VAR" ] ; then
   ls file
   echo $wiii
fi

이 구조는 동일하게 작동하지만

[ -z "$VAR" ] && { ls file ; echo wiii ; }

참고 ;에코 후이 중요하고이 있어야합니다.

위의 진술을 다시 시작하면

[] && cmd == 첫 번째 명령이 성공하면 다음 명령을 실행하십시오.

if .. fi == 조건 (테스트 명령 일 수도 있음)이면 명령을 실행합니다.

따라서 휴대 [성과 이식성 에만 [[사용하십시오 [.

ifPOSIX와 호환됩니다. 그래서 만약 당신이 사이에서 선택을 [하고 if귀하의 작업과 예상되는 동작을보고 선택합니다.


답변

그것은 사실이다 &&를 대체하는 if,하지 test: if명령이 “성공”(영) 종료 상태를 반환 여부 쉘 스크립트 테스트에서 문; 귀하의 예에서 명령은 [입니다.

따라서 실제로 테스트를 실행하는 데 사용되는 명령과 해당 테스트 결과를 기반으로 코드를 실행하는 데 사용되는 구문의 두 가지가 있습니다.

테스트 명령 :

  • test표준화 된 명령 문자열 및 파일의 특성을 평가하는이; 귀하의 예에서, 당신은 명령을 실행하고 있습니다test -w /home/durrantm
  • [똑같이 표준화 된 명령의 별명이며 ], 괄호로 묶은 표현식처럼 보이기 위해 필수 마지막 인수가 있습니다 . 속지 말고 여전히 명령 일뿐입니다 (시스템에이라는 파일이 있음을 알 수 있습니다 /bin/[)
  • [[일부 쉘에 내장 된 테스트 명령의 확장 버전이지만 동일한 POSIX 표준의 일부는 아닙니다. 여기에 사용하지 않는 추가 옵션이 포함되어 있습니다.

조건식 :

  • &&(오퍼레이터 여기 표준화는 ) 두 명령을 평가하고 (참 나타내는) 0을 반환하여, 논리 AND 연산을 수행하는 경우 그들은 모두 복귀 0; 첫 번째 명령이 0을 반환하면 두 번째 명령 만 평가하므로 간단한 조건부로 사용할 수 있습니다.
  • if ... then ... fi(구조체 여기 표준화는 ) “진실”을 판정하는 방법과 동일한 방법을 사용하지만, 경고문의 화합물에서 허용 then오히려에 의해 제공되는 하나의 명령이 아닌, 절 &&, 단락 및 제공 elif하고 else쓰기에 어려운 조항, 만 사용 &&하고 ||. 명령문 의 조건 주위에는 괄호가 없습니다if .

따라서 다음은 예제와 동일하게 이식 가능하며 완전히 동등한 렌더링입니다.

  • test -w /home/durrantm && echo "writable"
  • [ -w /home/durrantm ] && echo "writable"
  • if test -w /home/durrantm; then echo "writable"; fi
  • if [ -w /home/durrantm ]; then echo "writable"; fi

다음은 비표준 적 특성으로 인해 동등하지만 휴대 성이 떨어집니다 [[.

  • [[ -w /home/durrantm ]] && echo "writable"
  • if [[ -w /home/durrantm ]]; then echo "writable"; fi

답변

이식성을 위해 test/를 사용하십시오 [. 그러나 이식성을 필요로하지 않는다면, 자신과 다른 사람들이 당신의 스크립트를 읽는 것을 위해 건강을 유지하기 위해 [[. 🙂

또한 참조 What is the difference between test, [ and [[ ?BashFAQ .


답변

Bourne과 같은 세계 밖에서 이식성을 원한다면 :

test -w /home/durrantm && echo writable

가장 휴대용입니다. 그것은 Bourne의 껍질 cshrc가족 에서 작동합니다 .

test -w /home/durrantm && echo "writable"

겠습니까 출력 "writable"대신 writable의 껍질에 rc가족 ( rc, es, akanga, 어디 "특별하지 않습니다).

[ -w /home/durrantm ] && echo writable

명령 이없는 시스템 의 일부 csh또는 rc패밀리의 쉘에서는 작동 하지 않습니다 (일부는 별칭이 없는 것으로 알려져 있음 ).[$PATHtest[

if [ -w /home/durrantm ]; then echo writabe; fi

Bourne 가족의 껍질에서만 작동합니다.

[[ -w /home/durrantm ]] && echo writable

ksh(원산지) zshbash(본 가족의 3 명 ) 에서만 작동합니다 .

fish필요한 쉘에서는 아무것도 작동 하지 않습니다.

[ -w /home/durrantm ]; and echo writable

또는:

if [ -w /home/durrantm ]; echo writable; end


답변

중 하나를 선택하는 나의 가장 중요한 이유 if foo; then bar; fi또는 foo && bar전체 명령의 종료 상태가 중요 여부입니다.

비교:

#!/bin/sh
set -e
foo && bar
do_baz

와:

#!/bin/sh
set -e
if foo; then bar; fi
do_baz

그들이 같은 것을 생각할 수도 있습니다. 그러나 foo실패하면 (또는 사용자의 관점에 따라 false 인 경우 ) 첫 번째 예제에서 스크립트가 종료 될 때 do_baz가 실행되지 않습니다 … set -e명령이 false 상태를 리턴하면 쉘이 즉시 종료되도록 지시합니다. 다음과 같은 일을 할 때 매우 유용합니다.

cd /some/directory
rm -rf *

cd어떤 이유로 든 실패 할 경우 스크립트가 계속 실행되는 것을 원하지 않습니다 .