2013-03-19 24 views
5

我發現波浪線擴展不適用於下列情況下工作:殼波浪線擴展不工作時,作爲一個選項傳遞

$ set -x 

$ ./print_arg.pl destdir=~/test 
+ ./print_arg.pl 'destdir=/root/test' 
destdir=/root/test 

$ ./print_arg.pl dest-dir=~/test 
+ ./print_arg.pl 'dest-dir=~/test' 
dest-dir=~/test 

$ ./print_arg.pl -destdir=~/test 
+ ./print_arg.pl '-destdir=~/test' 
dest-dir=~/test 

print_arg.pl的內容是

#!/usr/bin/perl 
print $ARGV[0],"\n"; 

Order of Shell processing ,殼牌將在「波浪擴張」之前分詞。我注意到,分詞實際上是不同的。造成不同結果的原因是什麼?

回答

4

Tilde擴展也發生在shell變量賦值中,這與destdir=~/test類似。 dest-dir=~/test-destdir=~/test不是,因爲-不是變量名中的有效字符。儘管shell並沒有將destdir=~/test作爲變量賦值(如果使用set -k),它似乎仍然將解析器視爲變量,並在RHS上執行波形擴展。

http://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html#Tilde-Expansion

每個變量分配檢查未引用的波浪線前綴緊跟在「:」或第一「=」。在這些情況下,也會執行波浪擴展。因此,可以在PATH,MAILPATH和CDPATH的賦值中使用帶有波形符的文件名,並且shell會分配擴展值。

注意與-k選項設置,正確的變量賦值處理本身和從傳遞給print_arg.pl參數列表中刪除:

~ $ set -kx 
~ $ ./print_arg.pl destdir=~/bin foo 
+ destdir=/Users/clint/bin 
+ ./print_arg.pl foo 
foo 
~ $ ./print_arg.pl dest-dir=~/bin foo 
+ ./print_arg.pl 'dest-dir=~/bin' foo 
dest-dir=~/bin 
+0

我也注意到了一句「解析器具有顯着的話作爲變量賦值(**命令名**之前的那些)和重定向保存以供以後處理。「因此,命令之後的「destdir =〜/ test」可能不會被標記爲可變賦值。那如何解釋呢? – lisper 2013-03-19 16:13:08

+0

由於'set -k' shell選項,它*可能*是一個變量賦值。我的猜測是解析器不檢查是否設置了該選項,並標記任何可能是有效賦值的東西。解析完成後(包括代字符擴展),負責評估解析命令的代碼可以根據'set -k'檢查是否應評估命令後面的賦值。有人可能會爭辯說,在第一次識別變量賦值時忽略'set -k'是'bash'中的一個錯誤。 – chepner 2013-03-19 16:16:37

+1

我明白了。謝謝你的非常好的解釋。 – lisper 2013-03-19 16:25:25