形似賦值語句的參數

咱們知道,在 Bash 中,當變量出如今一個賦值語句的右側時,變量只會展開,不會分詞,即使變量兩邊沒有引號: 面試

$ foo="1                       2"app

$ bar=$foo # 不會被拆分紅 bar=1 和 2 兩個詞函數

$ echo "$bar"ui

1                       2spa

可是,當一個形似賦值語句的詞,做爲參數傳給一個命令時,這時分詞步驟就不會少了:code

$ foo="1                       2"blog

$ printf '%s\n' bar=$fooit

bar=1table

2class

bar=$foo 雖然看起來像是賦值語句,但由於它出如今了命令名稱的後面,因此它就是個普通的參數。它會先展開成 bar=1                       2,而後被拆分紅 bar=1 和 2 兩個參數傳給 printf。外部命令也同樣:

$ valueOfa="1 b=2"

$ env -i a=$valueOfa env # 你覺得傳給 env 的第二個參數是 "a=1 b=2",但實際上是 "a=1" 和 "b=2" 兩個參數

a=1

b=2

但是,有一些命令倒是特殊的,好比 alias:

$ valueOfa="1 b=2"

$ alias a=$valueOfa # 傳給 alias 命令的會是 "a=1" 和 "b=2" 兩個參數?

$ alias

alias a='1 b=2'  # 並非,valueOfa 這個變量竟然沒有被分詞!

像 alias 這樣的內部命令一共有 6 個,分別是:alias、declare、typeset、export、readonly、local,它們的功能都是聲明一個什麼東西,變量或者別名。Bash 對它們的參數作了特殊對待,若是知足賦值語句的格式,則不對其中的變量進行分詞。固然你也能夠就把它們當作是賦值語句,反正賦值語句的效果是建立一個變量,這些參數的效果也是建立一個變量(除了 alias 命令)。Bash 手冊也直接把它們說成是賦值語句:

Assignment statements may also appear as arguments to the aliasdeclaretypeset,exportreadonly, and local builtin commands. 

在 Bash 的實現裏,是專門用一個函數對這樣的參數作了特殊處理:

/* This is a hack to suppress word splitting for assignment statements
   given as arguments to builtins with the ASSIGNMENT_BUILTIN flag set. */
static void
fix_assignment_words (words)
     WORD_LIST *words;
{
...

等等,還沒完。上面說,若是知足賦值語句的格式,這些參數纔會被特殊對待,那若是不知足呢?

咱們知道,賦值語句的左邊必須是合法的標識符,合法的標識符得符合「字母下劃線開頭後跟若干個字母數字下劃線」。這樣的話 1=$foo 就一定不是個合法的賦值語句了,下面試一把:

$ foo="1 2=2"

$ alias 1=$foo

$ alias

alias 1='1'

alias 2='2'

果真,被當成普通的參數了。

相關文章
相關標籤/搜索