WEB*_*uju 2 bash shell-script whitespace arguments
我有一个关于在执行 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"
Run Code Online (Sandbox Code Playgroud)
如果我在没有参数的情况下执行此操作,则输出符合预期:
~$ ./block_ip.sh
usage ~/block_ip.sh (DROP/ACCEPT) '0.0.0.0' 'amsterdam'
Run Code Online (Sandbox Code Playgroud)
然而,空格似乎是“二元运算符预期”意外输出的原因:
~$ ./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
Run Code Online (Sandbox Code Playgroud)
但是尽管有意外的输出,它还是添加了它:
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP all -- 1.0.0.0/8 anywhere /* south brisbane au */
Run Code Online (Sandbox Code Playgroud)
如果这是一个引用问题,我该如何形成参数(不使用反斜杠来转义空格)?当然,我希望我可能需要更改脚本,这也是一个可以接受的解决方案。
是的,这是一个引用问题:[ ! $3 ]
扩展为[ ! south brisbane qld ]
([
和之间的四个参数]
)。当它看到四个参数时,第一个 a !
,[
期望看到类似[ ! arg1 op arg2 ]
where op
is 一个二元运算符的东西。(这又是[ .. ]
和之间的不同之处之一[[ .. ]]
;参见这个 Q和这个 Q)
brisbane
不是有效的运算符,因此它会抱怨并返回 2,这是错误的,因此if
不会执行其中的语句。要区分错误和常规失败测试,您需要针对 2 显式测试返回值。
另一方面,如果$3
为空,则测试变为[ ! ]
,一个单参数测试,用于检查唯一参数是否为非空(它是单字符串!
)。在这种情况下,它会按预期工作,尽管可能不是您期望的原因。
您希望[ ! "$3" ]
或[ -z "$3" ]
将字符串保留为 的一个参数[
。
当然你也可以颠倒测试的意义,在里面做实际的工作if
,这样测试中的错误就可以避免运行主命令。但这会使代码结构更加不清楚。