Bash 스크립트가 두 가지 방법으로 길이가 0이 아닌 문자열을 테스트하는 것을 보았습니다. 대부분의 스크립트는 다음 -n
옵션을 사용합니다 .
#!/bin/bash
# With the -n option
if [ -n "$var" ]; then
# Do something when var is non-zero length
fi
그러나 -n 옵션은 실제로 필요하지 않습니다.
# Without the -n option
if [ "$var" ]; then
# Do something when var is non-zero length
fi
어느 쪽이 더 좋은 방법입니까?
마찬가지로 길이가 0 인 테스트를위한 더 좋은 방법입니다.
if [ -z "$var" ]; then
# Do something when var is zero-length
fi
또는
if [ ! "$var" ]; then
# Do something when var is zero-length
fi
답변
편집 : 이것은 [
(일명 test
)과 ( 와)의 차이점을 더 보여주는 더 완전한 버전입니다 [[
.
다음 표는 변수의 인용 여부, 단일 또는 이중 괄호 사용 여부 및 변수에 공백 만 포함되는지 여부는 테스트를 사용하거나 사용하지 않고 -n/-z
변수를 확인하는 데 적합한 지 여부에 영향을주는 요소를 보여줍니다 .
| 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b
| [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"
-----+------------------------------------+------------------------------------
unset| false false true false true true | false false false false true true
null | false false true false true true | false false false false true true
space| false true true true true false| true true true true false false
zero | true true true true false false| true true true true false false
digit| true true true true false false| true true true true false false
char | true true true true false false| true true true true false false
hyphn| true true true true false false| true true true true false false
two | -err- true -err- true -err- false| true true true true false false
part | -err- true -err- true -err- false| true true true true false false
Tstr | true true -err- true -err- false| true true true true false false
Fsym | false true -err- true -err- false| true true true true false false
T= | true true -err- true -err- false| true true true true false false
F= | false true -err- true -err- false| true true true true false false
T!= | true true -err- true -err- false| true true true true false false
F!= | false true -err- true -err- false| true true true true false false
Teq | true true -err- true -err- false| true true true true false false
Feq | false true -err- true -err- false| true true true true false false
Tne | true true -err- true -err- false| true true true true false false
Fne | false true -err- true -err- false| true true true true false false
변수의 길이가 0이 아닌지 확인하려면 다음 중 하나를 수행하십시오.
- 단일 괄호로 변수를 인용하십시오 (열 2a)
-n
단일 괄호로 변수를 사용 하고 인용하십시오 (열 4a)- 인용 부호가 있거나없는 이중 열 괄호 사용
-n
(열 1b-4b)
“2”로 표시된 행에서 시작하는 열 1a에서 결과는 변수 [
의 내용 이 마치 조건식의 일부인 것처럼 평가하고 있음을 나타냅니다 (결과는 설명 열). [[
를 사용 하면 (열 1b) 변수 내용이 문자열로 표시되고 평가되지 않습니다.
열 3a 및 5a의 오류는 변수 값에 공백이 포함되고 변수의 인용 부호가 없기 때문에 발생합니다. 다시 3 열과 5b 열에 표시된 것처럼 [[
변수의 내용을 문자열로 평가합니다.
이에 따라 길이가 0 인 문자열에 대한 열 6a, 5b 및 6b는 올바른 방법을 보여줍니다. 부정이 반대 연산을 사용하는 것보다 분명한 의도를 나타내는 경우 이러한 테스트 중 하나라도 부정 할 수 있습니다. 예를 들면 다음과 같습니다 if ! [[ -n $var ]]
..
을 사용하는 경우 [
예기치 않은 결과가 발생하지 않도록하는 열쇠는 변수를 인용하는 것입니다. 를 사용하면 [[
중요하지 않습니다.
억제되는 오류 메시지는 “단항 연산자 예상”또는 “이진 연산자 예상”입니다.
위의 테이블을 생성 한 스크립트입니다.
#!/bin/bash
# by Dennis Williamson
# 2010-10-06, revised 2010-11-10
# for http://stackoverflow.com/q/3869072
# designed to fit an 80 character terminal
dw=5 # description column width
w=6 # table column width
t () { printf '%-*s' "$w" " true"; }
f () { [[ $? == 1 ]] && printf '%-*s' "$w" " false" || printf '%-*s' "$w" " -err-"; }
o=/dev/null
echo ' | 1a 2a 3a 4a 5a 6a | 1b 2b 3b 4b 5b 6b'
echo ' | [ [" [-n [-n" [-z [-z" | [[ [[" [[-n [[-n" [[-z [[-z"'
echo '-----+------------------------------------+------------------------------------'
while read -r d t
do
printf '%-*s|' "$dw" "$d"
case $d in
unset) unset t ;;
space) t=' ' ;;
esac
[ $t ] 2>$o && t || f
[ "$t" ] && t || f
[ -n $t ] 2>$o && t || f
[ -n "$t" ] && t || f
[ -z $t ] 2>$o && t || f
[ -z "$t" ] && t || f
echo -n "|"
[[ $t ]] && t || f
[[ "$t" ]] && t || f
[[ -n $t ]] && t || f
[[ -n "$t" ]] && t || f
[[ -z $t ]] && t || f
[[ -z "$t" ]] && t || f
echo
done <<'EOF'
unset
null
space
zero 0
digit 1
char c
hyphn -z
two a b
part a -a
Tstr -n a
Fsym -h .
T= 1 = 1
F= 1 = 2
T!= 1 != 2
F!= 1 != 1
Teq 1 -eq 1
Feq 1 -eq 2
Tne 1 -ne 2
Fne 1 -ne 1
EOF
답변
Bash에 관한 한 더 강력한 것을 사용하는 것이 좋습니다 [[
.
일반적인 경우
if [[ $var ]]; then # var is set and it is not empty
if [[ ! $var ]]; then # var is not set or it is set to an empty string
위의 두 구성은 깨끗하고 읽기 가능해 보입니다. 대부분의 경우 충분합니다.
단어 분할 및 globbing의[[
위험이 없으므로 변수 확장을 인용 할 필요 가 없습니다 .
방지하기 위해 shellcheck을 ‘에 대한 소프트 불만이야 [[ $var ]]
하고 [[ ! $var ]]
, 우리가 사용할 수있는 -n
옵션을 선택합니다.
드문 경우
“빈 문자열로 설정”과 “전혀 설정하지 않음”을 구분해야하는 드문 경우에는 다음을 사용할 수 있습니다.
if [[ ${var+x} ]]; then # var is set but it could be empty
if [[ ! ${var+x} ]]; then # var is not set
if [[ ${var+x} && ! $var ]]; then # var is set and is empty
-v
테스트를 사용할 수도 있습니다 .
if [[ -v var ]]; then # var is set but it could be empty
if [[ ! -v var ]]; then # var is not set
if [[ -v var && ! $var ]]; then # var is set and is empty
if [[ -v var && -z $var ]]; then # var is set and is empty
관련 게시물 및 문서
이 주제와 관련된 게시물이 많이 있습니다. 몇 가지가 있습니다 :
답변
몇 가지 테스트가 더 있습니다.
문자열이 비어 있지 않은 경우 참 :
[ -n "$var" ]
[[ -n $var ]]
test -n "$var"
[ "$var" ]
[[ $var ]]
(( ${#var} ))
let ${#var}
test "$var"
문자열이 비어 있으면 참 :
[ -z "$var" ]
[[ -z $var ]]
test -z "$var"
! [ "$var" ]
! [[ $var ]]
! (( ${#var} ))
! let ${#var}
! test "$var"
답변
정답은 다음과 같습니다.
if [[ -n $var ]] ; then
blah
fi
의 사용을 참고 [[...]]
올바르게에 대한 변수를 인용 처리합니다.
답변
빈 환경 변수를 평가하는 대안적이고 아마도 더 투명한 방법은 다음을 사용하는 것입니다.
if [ "x$ENV_VARIABLE" != "x" ] ; then
echo 'ENV_VARIABLE contains something'
fi
답변
case/esac
테스트에 사용 :
case "$var" in
"") echo "zero length";;
esac