2014-02-20 227 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,因此更高效。