我有一个关于在执行 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 */
如果这是一个引用问题,我如何形成论点(不使用反斜杠来转义空格)?当然,我希望我可能需要更改脚本,这也是一个可以接受的解决方案。
是的,这是一个引用问题:
[ ! $3 ]
扩展为(和[ ! south brisbane qld ]
之间的四个参数)。当它看到四个参数时,第一个是 a ,期望看到类似where is a binary operator 的东西。(这又是and之间的不同之处之一;参见这个 Q和这个 Q)[
]
!
[
[ ! arg1 op arg2 ]
op
[ .. ]
[[ .. ]]
brisbane
不是有效的运算符,因此它会抱怨并返回 2,这是错误的,因此if
不会执行内部的语句。要区分错误和常规失败测试,您需要针对 2 显式测试返回值。另一方面,如果
$3
为空,则测试变为[ ! ]
,一个单参数测试,检查唯一的参数是否为非空(它是单字符字符串!
)。在这种情况下,它会按预期工作,尽管可能不是出于您期望的原因。您希望
[ ! "$3" ]
或[ -z "$3" ]
将字符串作为[
.当然你也可以颠倒测试的意义,在里面做实际的工作
if
,这样测试中的错误就可以避免运行主命令。但这会使代码结构更加不清楚。