답변:
나는 일반적으로 true
루프에서 사용합니다 . 나는 그것이 더 분명하다고 생각합니다.
while true; do
...
done
내가 찾은 한 가지 점 :
은 무언가를 일치시켜야하지만 실제로는 아무것도하고 싶지 않다면 경우에 대한 진술입니다. 예를 들면 다음과 같습니다.
case $answer in
([Yy]*) : ok ;;
(*) echo "stop."; exit 1 ;;
esac
true
조건, :
NOP.
case a in a ) ;; esac
합니다. 이것을 받아들이지 않는 껍질이 있습니까?
case ${var} in value);; *) do_something;; esac
수용. :
명령은 비어있는 경우에 필요하지 않습니다.
원래는 C 컴파일 된 프로그램과 달리 Bourne 쉘 프로그램인지 판별하는 데 사용되었습니다. 이것은 shebang 이전과 여러 스크립트 언어 (csh, perl) 이전이었습니다. 다음과 같이 시작하여 스크립트를 계속 실행할 수 있습니다 :
.
$ echo : > /tmp/xyzzy
$ chmod +x /tmp/xyzzy
$ ./xyzzy
일반적으로 $SHELL
(또는 /bin/sh
) 에 대해 스크립트를 실행합니다 .
그 이후로 주요 용도는 인수를 평가하는 것입니다. 나는 여전히 사용합니다 :
: ${EDITOR:=vim}
스크립트에서 기본값을 설정합니다.
쉘 스크립팅에서 "unless"문을 원할 경우, "not"조건을 사용하여 테스트 중 일부를 구피 할 수 있거나 true 절에서 ':'를 사용하고 실제 코드는 false로 절.
if [ some-exotic-condition ]
then
:
else
# Real code here
fi
"이국적 조건"은 부정하고 싶지 않은 것이거나 "부정적 논리"를 사용하지 않는 경우 훨씬 더 명확합니다.
autoconf
대한 기본값을 추가하는 것이 훨씬 쉽기 때문에 생성 된 스크립트에 표시됩니다 :
.
!
앞에서 [ some-exotic-condition ]
바보를 짓는 것이 얼마나 구피 : else
인지 알 수 없지만, 구피가 아닌 후에 불필요 합니다.
!
토큰 전체 명령 파이프 요소를 부정. while ! grep ... ; do ... done
또는 if ! [ ... ] ; then ... fi
. 기본적으로 test/[]
구문 외부 입니다. 참조 : pubs.opengroup.org/onlinepubs/9699919799/utilities/…
:
유용하다고 생각되는 두 가지 경우가 있습니다 .
#!/bin/sh
# set VAR to "default value" if not already set in the environment
: "${VAR=default value}"
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR}"
이것은 쉘 스크립트 사용자가 스크립트를 편집하지 않고 설정을 무시할 수있는 편리한 방법입니다. 그러나 사용자에게 내 보낸 환경에서 사용하는 변수가 우연히있을 경우 예기치 않은 동작의 위험이 발생하지 않기 때문에 명령 줄 인수 가 더 좋습니다. 다음은 사용자가 설정을 재정의하는 방법입니다.
VAR="other value" ./script
${VAR=value}
구문은 세트로 말한다 VAR
에 value
경우 VAR
아직 설정되어 있지 않은 경우, 변수의 값으로 확장합니다. 우리는 아직 변수의 값에 신경 쓰지 않기 때문에 변수 :
를 버릴 수 있는 no-op 명령 에 인수로 전달됩니다 .
비록 :
, 확장이 쉘에 의해 수행된다 (안 무 연산 명령입니다 :
실행하기 전에 명령!) :
(해당하는 경우) 변수 할당이 계속 발생 있도록 명령.
true
또는 대신 다른 명령 을 사용하는 것도 :
좋지만 의도가 덜 명확하기 때문에 코드를 읽기가 더 어려워집니다.
다음 스크립트도 작동합니다.
#!/bin/sh
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR=default value}"
그러나 위의 내용은 유지하기가 훨씬 어렵습니다. 사용중인 라인 ${VAR}
이 해당 printf
라인 위에 추가 되면 기본 할당 확장을 이동해야합니다. 개발자가 해당 과제를 옮기는 것을 잊어 버린 경우 버그가 발생합니다.
빈 조건부 블록은 일반적으로 피해야하지만 때로는 유용합니다.
if some_condition; then
# todo: implement this block of code; for now do nothing.
# the colon below is a no-op to prevent syntax errors
:
fi
어떤 사람들은 빈 if
블록 이 비어 있으면 테스트를 부정하는 것보다 코드를 쉽게 읽을 수 있다고 주장합니다 . 예를 들면 다음과 같습니다.
if [ -f foo ] && bar || baz; then
:
else
do_something_here
fi
다음보다 읽기 쉽습니다.
if ! [ -f foo ] || ! bar && ! baz; then
do_something_here
fi
그러나 빈 참 블록보다 나은 몇 가지 대안이 있다고 생각합니다.
조건을 함수에 넣으십시오.
exotic_condition() { [ -f foo ] && bar || baz; }
if ! exotic_condition; then
do_something_here
fi
부정하기 전에 조건을 중괄호 안에 넣거나 괄호 안에 괄호를 사용하면 서브 쉘 프로세스가 생성되고 서브 쉘 내부 환경에 대한 변경 사항이 서브 쉘 외부에 표시되지 않습니다.
if ! { [ -f foo ] && bar || baz; } then
do_something_here
fi
||
대신에 사용하십시오 if
:
[ -f foo ] && bar || baz || {
do_something_here
}
반응이 주장 조건과 같은 간단한 단일 라이너 일 때이 접근법을 선호합니다.
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$@"; exit 1; }
[ -f foo ] && bar || baz || fatal "condition not met"