good job!
總算有人看得懂了。
不過,要細說的話,要扯上 shell 在 interpret 一個 command line 時的 priority 。
基本上,其順序如下:
1,將 line 拆成 words (IFS很重要)
2,括展 alias
3,擴展 { }
4,擴展 ~
5,擴展 $variable, $(command), `command`
6,重組再拆成 words
7,括展 wildcards
8,處理 I/O redirection
9,載入命令運行
如果大家有O'Reilly英文版的 Learning the Bash(2nd)的話,請多端詳p178的圖(細節(jié)略異)
回到LZ的問題,看上面 5 跟 6 的順序然後才是 9 。
也就是在 6 重組命令時 $A 已經(jīng)完成替換,當時的 environment 是沒賦值,
因此重組後就是 A=B echo
然後在第 9 的步驟運行命令時, A=B 是給 echo 命令的 local environment,
不管是否 built-in command,都不影響當前的 shell (不同的 shell 在實作上或有差異)
所以第二行的 echo $A 也是得到?jīng)]賦值
我通過eval說明賦值是成功的,而不是65樓所說的賦值不成功。
第一步使用 metacharacter,與IFS沒有關系
|
The following is a brief description of the shell's operation when it
reads and executes a command. Basically, the shell does the following:
1. Reads its input from a file (*note Shell Scripts::), from a string
supplied as an argument to the `-c' invocation option (*note
Invoking Bash::), or from the user's terminal.
2. Breaks the input into words and operators, obeying the quoting
rules described in *Note Quoting::. These tokens are separated by
`metacharacters'. Alias expansion is performed by this step
(*note Aliases::).
`IFS'
A list of characters that separate fields; used when the shell
splits words as part of expansion.
`metacharacter'
A character that, when unquoted, separates words. A metacharacter
is a `blank' or one of the following characters: `|', `&', `;',
`(', `)', `<', or `>'.
8.05 命令行的評價(evaluation)
下面是C shell 解釋命令行的順序:
1. 歷史替換
2. 分裂詞(包括特殊字符)
3. 更新歷史表
4. 解釋單引號(') 和 雙引號(")
5. 別名替換
6. 輸入和輸出的重定向(如 > < 和 |)
7. 變量替換
8. 命令替換
9. 文件名擴展
(Bourne shell 的解釋順序本質(zhì)上是一樣的,除了它不執(zhí)行歷史替換和別名替換之外)
所以
A=B echo $A
的執(zhí)行過程應該是這樣的:
1. 沒有歷史操作符, 因此不進行歷史替換(Bourne shell 不執(zhí)行這一步)
2. 分裂詞,每碰到未加引號的空白字符就會產(chǎn)生一個新“詞”。這些詞是 A=B、echo、$A。
3. shell 將命令行放到歷史列表中。(Bourne shell 不執(zhí)行這一步)
4. 沒有引號需要解釋
5. 沒有別名需要替換
6. 沒有輸入或輸出重定向需要處理
7. shell注意到變量$A,并把它替換成空
8. shell尋找左單引號,執(zhí)行左單引號中的任何命令,并且將命令的輸出插入到命令行中。在本例中,沒有這方面的事需要做。(如果左單引號內(nèi)有通配符或者變量,那么在shell運行左單引號中的命令之前它們是不會被解釋的)
9. shell尋找通配符。本例中沒有,不需要處理
10. shell 執(zhí)行 A=B, 執(zhí)行 echo 。
8.05 命令行的評價(evaluation)
下面是C shell 解釋命令行的順序:
1. 歷史替換
2. 分裂詞(包括特殊字符)
3. 更新歷史表
4. 解釋單引號(') 和 雙引號(")
5. 別名替換
6. 輸入和輸出的重定向(如 > < 和 |)
7. 變量替換
8. 命令替換
9. 文件名擴展
(Bourne shell 的解釋順序本質(zhì)上是一樣的,除了它不執(zhí)行歷史替換和別名替換之外)
所以
A=B echo $A
的執(zhí)行過程應該是這樣的:
1. 沒有歷史操作符, 因此不進行歷史替換(Bourne shell 不執(zhí)行這一步)
2. 分裂詞,每碰到未加引號的空白字符就會產(chǎn)生一個新“詞”。這些詞是 A=B、echo、$A。
3. shell 將命令行放到歷史列表中。(Bourne shell 不執(zhí)行這一步)
4. 沒有引號需要解釋
5. 沒有別名需要替換
6. 沒有輸入或輸出重定向需要處理
7. shell注意到變量$A,并把它替換成空
8. shell尋找左單引號,執(zhí)行左單引號中的任何命令,并且將命令的輸出插入到命令行中。在本例中,沒有這方面的事需要做。(如果左單引號內(nèi)有通配符或者變量,那么在shell運行左單引號中的命令之前它們是不會被解釋的)
9. shell尋找通配符。本例中沒有,不需要處理
10. shell 執(zhí)行 A=B, 執(zhí)行 echo 。