shell中的[多]条件测试


搜索关键字:
  • shell test and/or
  • shell multi test and/or
参考解答:
推荐使用 && 和 || 将多个简单的测试语句连接起来:
if [ -n "$var"] && [ -e "$var"]; then
    echo "\$var is not null and a file named $var exists!"
fi

使用了AND和OR的测试语句的返回值是列表中最后一个执行的命令的返回值。

  • 当执行 command1 && command2 时,只有当 command1 执行成功后才会执行 command2 ;
  • 当执行 command1 || command2 时,只有当 command1 执行失败后才会执行 command2 。
使用”[[“关键字(不推荐):

[[ is a new improved version of “test/[“, and is a keyword, not a program. This makes it easier to use, as shown below. [[ is understood by KornShell, Zsh and BASH (e.g. 2.03), but not by other POSIX shell implementations (like posh, yash or dash) or the BourneShell .

[[ 是一个关键字,但只能被 KornShell、Zsh和Bash 所解释,不支持其他的POSIX shell实现,比如:posh、yash、dash或BourneShell,这样的话就不能做到通用,因此不推荐使用。

$ if [[ -n "/tmp" && -d "/tmp" ]]; then echo true; fi
true

$ if [ -n "/tmp" && -d "/tmp" ]; then echo true; fi
-bash: [: missing `]'
在 test/[ 中使用-a和-o(不推荐):

测试命令的 AND 和 OR 逻辑操作符是 -a 和 -o :

if [ -n "$var" -a -e "$var" ] ; then
    echo "\$var is not null and a file named $var exists"
fi

这里没有 && 和 || 的说法:

$ if [ -n "/tmp" && -d "/tmp" ]; then echo true; fi  # DOES NOT WORK
bash: [: missing `]'

In any case, avoid the -a/-o test operators which are deprecated and unreliable in the general case .

尽量避免在测试操作时使用 -a/-o 来进行多条件判断,因为它们将会被废弃,进而导致你的脚本出现问题,所以不建议在test/[中使用-a/-o进行多条件判断。

==

I want to check if [[ $var == foo || $var == bar || $var == more ]] without repeating $var n times.

The portable solution uses case:

# Bourne
case $var in
    foo|bar|more) ... ;;
esac

In Bash and ksh, Extended globs can also do this within a [[ command:

# bash/ksh
if [[ $var == @(foo|bar|more) ]]; then
    ...
fi

Alternatively, you may loop over a list of patterns, checking each individually.

# bash/ksh93
[[ -v BASH_VERSION ]] && shopt -s extglob
# usage: pmatch string pattern [ pattern ... ]
function any {
    [[ -n $1 ]] || return
    typeset pat match=$1
    shift

    for pat; do
        [[ $match == $pat ]] && return
    done

    return 1
}

var='foo bar'
if any "$var" '@(bar|baz)' foo\* blarg; then
    echo 'var matched at least one of the patterns!'
fi

For logical conjunction (return true if $var matches all patterns), ksh93 can use the & pattern delimiter.

# ksh93 only
[[ $var == @(foo&bar&more) ]] && ...

For shells that support only the ksh88 subset (extglob patterns), you may DeMorganify the logic using the negation sub-pattern operator.

# bash/ksh88/etc...
[[ $var == !(!(foo)|!(bar)|!(more)) ]] && ...

But this is quite unclear and not much shorter than just writing out separate expressions for each pattern.

参考链接:

=EOF=

, ,

《“shell中的[多]条件测试”》 有 1 条评论

  1. Shell script: if multiple conditions
    https://unix.stackexchange.com/questions/297180/shell-script-if-multiple-conditions/297187#297187
    `
    # method 1
    if
    [ ! -d “/home/unix/POSTagger2” ] ||
    [ ! -d “/home/unix/POSTagger2/stanford-parser-full-2015-12-09” ] ||
    [ ! -d “/home/unix/POSTagger2/stanford-corenlp-full-2015-12-09” ]
    then
    echo “Nope”
    fi

    # method 2
    Bash offers an alternative [[ that is implemented as en expression. [[ uses &&, ||, etc. instead of -a, -o as operators.
    `

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注