[英]Filename expansion in “a=b”-like arguments of Bash built-in commands
我已經了解到在Bash中運行命令時,在命令執行之前完成了文件名擴展。 但是在嘗試下面的命令時(使用-x選項):
touch foo=3 # Create a file with name "foo=3"
+ touch foo=3
declare foo=?
+ declare 'foo=?'
alias foo=*
+ alias 'foo=*'
我得不到我的期望,因為foo =? 並且foo = *未擴展為文件名“foo = 3”:
declare -p | grep 'foo=' # => foo='?'
alias | grep 'foo=' # => alias foo='*'
但是如果我運行另一個類似cd的內置函數或接受賦值作為自己編寫的參數的函數,如show_rhs() { echo "${1%=*}='${1#*=}'"; }
show_rhs() { echo "${1%=*}='${1#*=}'"; }
我得到我所期望的(富=?和富= *展開)。
cd foo=? # => foo=3: Not a directory
show_rhs() foo=* # => foo='3'
我可以在這里看到的唯一區別是申報和別名是內置插件和接受工作任務作為參數。 根據-x選項的輸出,似乎添加了一對引用以在文件名擴展之前包含賦值。
但是如果文件名擴展在命令執行之前運行而不管命令是什么,那么傳入declare和alias的參數應該是foo = 3而不是foo =? 和foo = *由於存在文件“foo = 3”。
那么Bash在文件名擴展之前根據命令做一些特殊的事情(可能引用通配符?)到“a = b”類似的參數?
(我的環境:CentOS 5.8 64bit,GNU Bash 3.2.25)
Bash以一種不嚴格符合Posix標准的方式解析它的一些內置命令,也沒有很好地記錄。
特別是,接受這些參數( alias
, declare
, export
, local
, readonly
和typeset
)的命令中的賦值參數不受路徑名擴展或字拆分的限制。 (這是通過抑制擴展而在內部完成的,而不是通過引用元字符來完成,盡管不容易看到實現細節如何變得可見。)
即使在Posix模式下啟動bash或sh
。
請注意,抑制路徑名擴展僅適用於看起來像賦值的參數。 從問題中擴展示例:
touch foo=3 # Create a file with name "foo=3"
+ touch foo=3
declare foo=?
+ declare 'foo=?'
bar="foo=?" # Put the declare argument in a variable
+ bar='foo=?'
declare $bar
+ declare foo=3
正如預期的那樣, dash
路徑名會擴展並將字段拆分為alias
和export
參數,與Posix規范一致。 所以,顯然, zsh
。
除了在Posix模式下, bash
還會向參數的右側擴展 - 看起來像賦值。 在Posix模式下,它將此限制為上面列出的內置函數的賦值參數,盡管Posix僅在命令字之前的變量賦值中指定=
之后的波浪擴展。 這就是dash
所做的,但是zsh
將其擴展為“排版族的命令”(在zsh手冊中記錄 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.