我有一个关于如何在执行 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
,这样测试中的错误就可以避免运行主命令。但这会让代码结构变得更加不清楚。