Bash - IF [..] ||令人烦恼的结果[..]

时间:2012-02-26 02:09:40

标签: bash if-statement

我似乎可以理解为什么这不起作用:

#!/bin/bash

if [ $# -ne 1 ] || [ $# -ne 2 ]; then 
# Should run if there are either 1 or 2 options specified
  echo "usage: ${0##*/} <username>"
  exit
fi

在测试时是否有效:

root@ubuntu:~# testing.sh optionone optiontwo
...Correct output...
root@ubuntu:~# testing.sh optionone
usage: testing.sh <username>

3 个答案:

答案 0 :(得分:5)

更改布尔逻辑:

if [ $# -ne 1 ] && [ $# -ne 2 ]; then

或者

if ! ( [ $# -eq 1 ] || [ $# -eq 2 ] ); then

顺便说一句,您可以使用Shell-Arithmetic ((...))

if (( $#!=1 && $#!=2 )); then

答案 1 :(得分:2)

请注意,您正在执行以下命令:

[ $# -ne 1 ] || [ $# -ne 2 ]

[ $# -ne 1 ]是第一个命令,[ $# -ne 2 ]命令仅在前一个|| shell运算符之前具有非零错误代码时执行。

在你的情况下,它并不重要,但在下面的情况下,它是:

[ $? -eq 0 ] || [ $? -eq 1 ]

第二个命令将始终为true,因为第二个$?[ $? -eq 0 ]的返回码。您可以使用下面的两行打印true来测试它:

function f() { return $1; }
f 1
{ [ $? -eq 0 ] || [ $? -eq 1 ]; } && echo "true"
f 2
{ [ $? -eq 0 ] || [ $? -eq 1 ]; } && echo "true"

在单个命令中执行or的正确方法是:

[ $? -eq 0 -o $? -eq 1 ]

这样,下面只会打印true一次:

function f() { return $1; }
f 1
{ [ $? -eq 0 -o $? -eq 1 ]; } && echo "true"
f 2
{ [ $? -eq 0 -o $? -eq 1 ]; } && echo "true"

关于你原来的问题,kev已经指出你的测试中存在逻辑错误。 [ $# -eq 1 ] || [ $# -eq 2 ]的否定为NOT [ $# -eq 1 ] && NOT [ $# -eq 2 ],这将变为[ $# -ne 1 ] && [ $# -ne 2 ]或在单个命令中:

[ $# -ne 1 -a $# -ne 2 ]

答案 2 :(得分:0)

实现此功能的一种方法是为-ne-lt切换-gt比较运算符(小于大于) 用于条件语句。像这样:

#!/bin/bash

#Should run if there are either 1 or 2 options specified
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
    echo "usage: ${0##*/} <username>"
    exit
fi