2014-02-20 164 views
0

任何人能解释这是我发疯奇怪的回声输出

[[email protected] bin]# export test=`whois -h whois.lacnic.net 187.14.6.108 | grep -i inetnum: | awk '{print $2}'` 

[[email protected] bin]# echo $test 
187.12/14 

[[email protected] bin]# echo "iptables -I INPUT -s $test -J DROP" 

-J DROP -I INPUT -s 187.12/14 

[[email protected] bin]# 

为什么我echo搞砸了bash shell中的这种行为?它正在被$test的内容所改变。

如果您将$test更改为“ABC”,一切正常。它与斜线有关吗?

+1

我怀疑'$ test'中可能会有一些不可见的字符,例如回车符,这会导致'-J DROP'在输出中备份和覆盖'iptables'。换句话说,“187.12/14”字符串可能类似于“\ r187.12.14”或类似的东西。 – lurker

+0

@devnull - 与|无关 - 我认为mbratch是正确的 –

+0

@JimHolland格式引起反引号(命令替换)为_invisible_。我被带到认为你正在使用'''作为变量的命令。 – devnull

回答

1

为什么我的echo搞砸了?它正在被 $test的内容所改变。

因为您的test包含回车符。删除:

test=$(whois -h whois.lacnic.net 187.14.6.108 | grep -i inetnum: | awk '{print $2}' | tr -d '\r') 
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 

验证这一点。

1

这几乎肯定是回车。 echo正确地完成它的工作,并将字符串发送到您的终端;问题在于你的终端正在将字符串的一部分视为一个命令(特别是一个LF字符,$'\r',告诉它将光标发送到现有行的开头)。

如果你想看到的$test内容的方式不允许你的终端来解释转义序列或其他控制字符,运行以下(请注意,%q格式字符串是一个bash延长,不可用纯POSIX系统):

printf '%q\n' "$test" 

这将显示格式化的准确内容,并逃脱了由外壳,这将是启蒙,为什么他们是有问题的应用。

要删除$'\r',这是几乎可以肯定的性格给你的麻烦,你可以运行下面的参数扩展:

test=${test//$'\r'/} 

不像需要管道启动一个额外的过程(如tr)解决方案,这种情况发生的内部已经运行的bash shell,因此更高效。