2013-11-23 107 views
32

我感到困惑的是什麼錯誤代碼執行變量賦值明明與命令替換命令將返回:擊:變量賦值的退出代碼,命令替換

a=$(false); echo $? 

它輸出1,這讓我覺得該變量賦值不會在最後一次掃描或產生新的錯誤代碼。但是,當我嘗試這樣做:

false; a=""; echo $? 

它輸出0,顯然這是什麼a=""回報,它會覆蓋false返回1

我想知道爲什麼發生這種情況,變量賦值中是否有任何特殊性與其他常規命令不同?或者只是因爲a=$(false)被認爲是一個單一的命令,只有命令替換部分是有意義的?

- 更新 -

謝謝大家,從答案和意見,我得到了點。「當你使用命令替換爲變量賦值,退出狀態是命令的狀態」 (by @Barmar),這個解釋非常清晰易懂,但對於程序員來說講話不夠精確,我想從TLDP或GNU man page等權威機構那裏看到這一點的參考,請幫我找到它出來,再次感謝!

+0

TLDP不是權威來源--ABS完全是臭名昭着的,因爲它展示了bash中的不好實踐,就像w3schools在JavaScript世界中一樣。 –

回答

44

一旦執行一個命令爲$(command)允許output of the command to replace itself

當你說:

a=$(false)    # false fails; the output of false is stored in the variable a 

由命令false產生的輸出被存儲在變量a。而且,退出代碼與命令產生的代碼相同。 help false會告訴:

false: false 
    Return an unsuccessful result. 

    Exit Status: 
    Always fails. 

在另一方面,他說:

$ false    # Exit code: 1 
$ a=""     # Exit code: 0 
$ echo $?    # Prints 0 

導致的分配a要返回這是0退出代碼。


編輯:

manual引用:

如果擴展的一個包含一個命令替換的命令的退出 狀態爲最後一個命令 的退出狀態進行替換。

BASHFAQ/002引用:

如何可以存儲在一個變量 返回值和/或命令的輸出?

...

output=$(command)

status=$?

分配給outputcommand的退出狀態,這 仍處於$?沒有效果。

+0

非常好的答案:)!你能幫我找出'退出代碼與命令產生的相同'的參考,我花了很多時間,但沒有得到結果:( – Reorx

+0

@Reorx在上面的編輯中添加了幾個參考。 – devnull

+0

謝謝,這已經足夠清楚了:D – Reorx

0

(不是答案,原來的問題,但過長評論)

注意export A=$(false); echo $?輸出0!顯然devnull's answer中引用的規則不再適用。要有點背景的添加到報價(重點礦山):

3.7.1簡單的命令擴展

...

如果有命令名擴展後離開,則繼續執行描述爲,低於否則,該命令退出。如果其中一個擴展包含命令替換,則該命令的退出狀態是最後執行的命令替換的退出狀態。如果沒有命令替換,則該命令以狀態0退出。

3.7.2命令搜索和執行[ - 這是在 「下面」 的情況下]

IIUC該手冊介紹var=foo command...語法var=foo特殊情況下(非常混亂!)。 「最後的命令替換的退出狀態」規則僅適用於無命令的情況。

儘管export var=foo被認爲是一個「修改後的賦值語法」,但它並不是 - export是一個內置命令(剛好恰好採用賦值類型的參數)。

=>如果要導出一個VAR和捕獲命令替換狀態,做到在2個階段:

A=$(false) 
# ... check $? 
export A 

這種方式也適用於set -e模式 - 如果命令替換返回非0立即退出。