IT

Bash에서 길이가 0이 아닌 문자열을 테스트하십시오. [-n "$ var"] 또는 [ "$ var"]

lottoking 2020. 6. 4. 08:03
반응형

Bash에서 길이가 0이 아닌 문자열을 테스트하십시오. [-n "$ var"] 또는 [ "$ var"]


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에서 결과는 변수 [내용 이 마치 조건식의 일부인 것처럼 평가하고 있음을 나타냅니다 (결과는 "T"또는 "F"에 의해 암시 된 주장과 일치 함). 설명 열). [[를 사용 하면 (열 1b) 변수 내용이 문자열로 표시되고 평가되지 않습니다.

The errors in columns 3a and 5a are caused by the fact that the variable value includes a space and the variable is unquoted. Again, as shown in columns 3b and 5b, [[ evaluates the variable's contents as a string.

Correspondingly, for tests for zero-length strings, columns 6a, 5b and 6b show the correct ways to do that. Also note that any of these tests can be negated if negating shows a clearer intent than using the opposite operation. For example: if ! [[ -n $var ]].

If you're using [, the key to making sure that you don't get unexpected results is quoting the variable. Using [[, it doesn't matter.

The error messages, which are being suppressed, are "unary operator expected" or "binary operator expected".

This is the script that produced the table above.

#!/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


It is better to use the more powerful [[ as far as Bash is concerned.

Usual cases

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

The above two constructs look clean and readable. They should suffice in most cases.

Note that we don't need to quote the variable expansions inside [[ as there is no danger of word splitting and globbing.

To prevent shellcheck's soft complaints about [[ $var ]] and [[ ! $var ]], we could use the -n option.

Rare cases

In the rare case of us having to make a distinction between "being set to an empty string" vs "not being set at all", we could use these:

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

We can also use the -v test:

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

Related posts and documentation

There are a plenty of posts related to this topic. Here are a few:


Here are some more tests

True if string is not empty:

[ -n "$var" ]
[[ -n $var ]]
test -n "$var"
[ "$var" ]
[[ $var ]]
(( ${#var} ))
let ${#var}
test "$var"

True if string is empty:

[ -z "$var" ]
[[ -z $var ]]
test -z "$var"
! [ "$var" ]
! [[ $var ]]
! (( ${#var} ))
! let ${#var}
! test "$var"

use case/esac to test

case "$var" in
  "") echo "zero length";;
esac

An alternative and perhaps more transparent way of evaluating an empty env variable is to use...

  if [ "x$ENV_VARIABLE" != "x" ] ; then
      echo 'ENV_VARIABLE contains something'
  fi

The correct answer is the following:

if [[ -n $var ]] ; then
  blah
fi

Note the use of the [[...]], which correctly handles quoting the variables for you.

참고URL : https://stackoverflow.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var

반응형