需要二元运算符 - shell 脚本参数的引用问题

需要二元运算符 - shell 脚本参数的引用问题

我有一个关于如何在执行 shell 脚本时添加参数的问题。

我有一个简单的脚本可以帮助我阻止 IP 范围:

〜/ block_ip.sh:

if [ ! $3 ]
then
 echo "usage ~/block_ip.sh (DROP/ACCEPT) '0.0.0.0' 'amsterdam'"
 exit 1
fi

echo "adding $3"
sudo iptables -I INPUT -s $2 -j $1 -m comment --comment "$3"

如果我在不带参数的情况下执行此操作,输出将如预期的那样:

~$ ./block_ip.sh
usage ~/block_ip.sh (DROP/ACCEPT) '0.0.0.0' 'amsterdam'

然而,空格似乎是意外输出的原因“预期二元运算符”:

~$ ./block_ip.sh DROP '1.0.0.0/8' 'south brisbane qld'
./block_ip.sh: line 1: [: brisbane: binary operator expected
adding south brisbane au

但随后它添加了它,尽管出现了意外的输出:

Chain INPUT (policy ACCEPT)
num  target     prot opt source           destination
1    DROP       all  --  1.0.0.0/8        anywhere         /* south brisbane au */

如果这是一个引用问题,我如何形成参数(不使用反斜杠来转义空格)?当然,我预计我可能需要更改脚本,这也是一个可以接受的解决方案。

答案1

是的,这是一个引用问题:[ ! $3 ]扩展到(和[ ! south brisbane qld ]之间的四个参数)。当它看到四个参数时,第一个参数是 a ,期望看到类似where是二元运算符的内容。 (这又是和之间的不同之处之一;[]![[ ! arg1 op arg2 ]op[ .. ][[ .. ]]看到这个问题还有这个Q

brisbane不是有效的运算符,因此它会抱怨并返回 2,这是错误的,因此if不会执行 中的语句。为了区分错误和常规失败测试,​​您需要根据 2 显式测试返回值。

另一方面,如果$3为空,则测试变为[ ! ],一个单参数测试,检查唯一的参数是否为非空(它是,它是单字符字符串!)。在这种情况下,它会按预期工作,尽管可能不是出于您期望的原因。


您希望[ ! "$3" ]or[ -z "$3" ]保留该字符串作为 的一个参数[

当然,您也可以反转测试的意义,并在 中进行实际工作if,这样测试中的错误就可以避免运行主命令。但这会让代码结构变得更加不清楚。

相关内容