Bash if 语句无法正常工作
Bash if statement not working properly
我有一个 bash 语句来测试命令行参数。如果传递给脚本的参数是 "clean",则脚本会删除所有 .o 文件。否则,它会构建一个程序。然而,无论传递了什么(如果有的话),脚本仍然认为正在传递参数 "clean"。
#!/bin/bash
if test "`whoami`" != "root" ; then
echo "You must be logged in as root to build (for loopback mounting)"
echo "Enter 'su' or 'sudo bash' to switch to root"
exit
fi
ARG=
if [ $ARG == "clean" ] ; then
echo ">>> cleaning up object files..."
rm -r src/*.o
echo ">>> done. "
echo ">>> Press enter to continue..."
read
else
#Builds program
fi
第一版问题的答案
在bash中,空格很重要。替换:
[ $ARG=="clean" ]
与:
[ "$ARG" = "clean" ]
bash 将 $ARG=="clean"
解释为单个字符串。如果将单个字符串放在测试语句中,则如果字符串为空则测试 returns false,如果字符串非空则测试 true。 $ARG=="clean"
永远不会为空。因此 [ $ARG=="clean" ]
将始终 return 为真。
其次,$ARG
应该被引用。否则,如果它为空,则该语句将简化为 `[ == "clean" ],这是一个错误 ("unary operator expected").
第三,最好为局部变量使用小写或混合大小写。系统使用大写 shell 变量,您不希望不小心覆盖其中之一。
最后,对于 [...]
,等于的 POSIX 运算符在字符串意义上是 =
。 Bash 将接受 =
或 ==
但 =
更便携。
首先:
每个字符串都必须用双引号引起来,否则会因缺少参数而出错。
第二个:
对于仅使用 =
或 !=
而不是 ==
以及 -n
和 -z
命令的字符串。
第三:
您可以通过 -a
和 -o
命令组合条件,但较新的使用包含在 ()
您的条件中,以免出错。逻辑运算符通过运算符进行操作,先计算-o
运算符再计算-a
!例如
[ -n "" -a = '-h' -o = '--help' ] && { usage; exit 0; }
将在传递给脚本至少 1 个参数且为 -h
或 --help
时起作用。所有 space 必须是!!!布什做短周期逻辑评估。因此,如果
在第二个条件中不存在,因为这个表达式的结果是在第一个条件中确定的,所以不要麻烦。 next 在这种情况下不要计算。但是如果你的参数可能包含 space 符号,你需要它双引号。您也必须在命令行中执行此操作!否则你会在脚本中出错或将你的论点分成两个或更多部分。
运算符 == 未在测试中使用。对于数字(不是 siring),使用 -eq 或 -ne 命令。有关完整说明,请参阅 man 1 test。测试 EXPRESSION... 相当于 [ EXPRESSIONS... ]。更多衬衫形式测试。
我有一个 bash 语句来测试命令行参数。如果传递给脚本的参数是 "clean",则脚本会删除所有 .o 文件。否则,它会构建一个程序。然而,无论传递了什么(如果有的话),脚本仍然认为正在传递参数 "clean"。
#!/bin/bash
if test "`whoami`" != "root" ; then
echo "You must be logged in as root to build (for loopback mounting)"
echo "Enter 'su' or 'sudo bash' to switch to root"
exit
fi
ARG=
if [ $ARG == "clean" ] ; then
echo ">>> cleaning up object files..."
rm -r src/*.o
echo ">>> done. "
echo ">>> Press enter to continue..."
read
else
#Builds program
fi
第一版问题的答案
在bash中,空格很重要。替换:
[ $ARG=="clean" ]
与:
[ "$ARG" = "clean" ]
bash 将 $ARG=="clean"
解释为单个字符串。如果将单个字符串放在测试语句中,则如果字符串为空则测试 returns false,如果字符串非空则测试 true。 $ARG=="clean"
永远不会为空。因此 [ $ARG=="clean" ]
将始终 return 为真。
其次,$ARG
应该被引用。否则,如果它为空,则该语句将简化为 `[ == "clean" ],这是一个错误 ("unary operator expected").
第三,最好为局部变量使用小写或混合大小写。系统使用大写 shell 变量,您不希望不小心覆盖其中之一。
最后,对于 [...]
,等于的 POSIX 运算符在字符串意义上是 =
。 Bash 将接受 =
或 ==
但 =
更便携。
首先: 每个字符串都必须用双引号引起来,否则会因缺少参数而出错。
第二个:
对于仅使用 =
或 !=
而不是 ==
以及 -n
和 -z
命令的字符串。
第三:
您可以通过 -a
和 -o
命令组合条件,但较新的使用包含在 ()
您的条件中,以免出错。逻辑运算符通过运算符进行操作,先计算-o
运算符再计算-a
!例如
[ -n "" -a = '-h' -o = '--help' ] && { usage; exit 0; }
将在传递给脚本至少 1 个参数且为 -h
或 --help
时起作用。所有 space 必须是!!!布什做短周期逻辑评估。因此,如果 在第二个条件中不存在,因为这个表达式的结果是在第一个条件中确定的,所以不要麻烦。 next 在这种情况下不要计算。但是如果你的参数可能包含 space 符号,你需要它双引号。您也必须在命令行中执行此操作!否则你会在脚本中出错或将你的论点分成两个或更多部分。
运算符 == 未在测试中使用。对于数字(不是 siring),使用 -eq 或 -ne 命令。有关完整说明,请参阅 man 1 test。测试 EXPRESSION... 相当于 [ EXPRESSIONS... ]。更多衬衫形式测试。