任何人都可以解释这个让我疯狂的bash shell的行为
[root@ns1 bin]# export test=`whois -h whois.lacnic.net 187.14.6.108 | grep -i inetnum: | awk '{print $2}'`
[root@ns1 bin]# echo $test
187.12/14
[root@ns1 bin]# echo "iptables -I INPUT -s $test -J DROP"
-J DROP -I INPUT -s 187.12/14
[root@ns1 bin]#
为什么我的echo
搞砸了? $test
。
如果您将$test
更改为“ABC”,一切都很好。它与斜线有关吗?
答案 0 :(得分:1)
为什么我的
echo
搞砸了?它的内容正在改变$test
。
因为您的test
包含回车符。删除它:
test=$(whois -h whois.lacnic.net 187.14.6.108 | grep -i inetnum: | awk '{print $2}' | tr -d '\r')
答案 1 :(得分:1)
您的test
包含类似
1234567 -I INPUT -s 187.12/14\r-J DROP
,由于回车,仅作为
可见-J DROP -I INPUT -s 187.12/14
CR将光标移动到行首,然后它会覆盖以前的字符。
你可以尝试
echo "$test" | od -bc
验证这一点。
答案 2 :(得分:1)
这几乎可以肯定是回程。 echo
正在正常工作并将字符串发送到您的终端;问题是你的终端正在将字符串的一部分视为它要遵循的命令(具体来说,是一个LF字符$'\r'
,告诉它将光标发送到现有行的开头)。
如果要以不允许终端解释转义序列或其他控制字符的方式查看$test
的内容,请运行以下命令(请注意%q
格式字符串是一个bash扩展,在纯POSIX系统中不可用):
printf '%q\n' "$test"
这将显示格式化和转义以供shell使用的精确内容,这将是它们存在问题的原因。
要删除$'\r'
,这几乎可以肯定是给您带来麻烦的字符,您可以运行以下参数扩展:
test=${test//$'\r'/}
与需要管道启动额外进程(例如tr
)的解决方案不同,这发生在已经运行的bash shell中,因此效率更高。