2010-07-06 99 views
3

在bash腳本中評估test[表達式的順序是什麼?這與它們的寫入順序是否相同?他們都被評估過嗎?什麼是bash「測試」命令評估命令?

在下面的例子:

if [ expr1 -a -n expr2 ] 

expr2的被如果expr1的是假的評估?

+0

該示例不會在bash中解析。 - 檢查文件是否存在,-n檢查字符串的非零性。該示例導致「參數太多」錯誤。 – BjoernD 2010-07-06 07:53:06

+0

我還沒有在'bash'或'test'的manpages中找到關於評估順序的任何內容,所以它似乎與實現有關。由於'test'表達式不會改變狀態或引發異常,因此評估順序和懶惰無關緊要。 – Philipp 2010-07-06 07:55:04

+1

@Bjoern,它解析得很好。我不確定你正在運行什麼bash,但它在CygWin下工作正常。這是一種老式的測試方法,使用'-a'來做「和」。 – paxdiablo 2010-07-06 08:01:54

回答

11

自從我使用特定的語法已經很長時間了。如今,我更喜歡:

if [[ expr1 && -n expr2 ]] 

,因爲我知道這些是短路。該bash手冊頁明確指出:

如果表達式的值是足以決定整個條件表達式的返回值&&||運營商不計算表達式2。

它似乎沒有清楚說明的一種方式或另一種爲[test變體(使用-a)。

但是,爲了進一步提高您的知識和我的知識(並指出爲什麼開源是一件好事),我開始使用bash源代碼。

事實證明,這是而不是在這種情況下短路。代碼的特定件(壓縮位的可讀性):

static int or() { 
    int value, v2; 
    value = and(); 
    if (pos < argc && argv[pos][0] == '-' 
     && argv[pos][1] == 'o' && !argv[pos][2]) 
    { 
     advance (0); 
     v2 = or(); 
     return (value || v2); 
    } 
    return (value); 
} 

static int and() { 
    int value, v2; 
    value = term(); 
    if (pos < argc && argv[pos][0] == '-' 
     && argv[pos][1] == 'a' && !argv[pos][2]) 
    { 
     advance (0); 
     v2 = and(); 
     return (value && v2); 
    } 
    return (value); 
} 

您可以在這兩個案例看,它繼續解釋表達式無論第一個表達式的狀態。

這是從bash 2.5,但我剛剛檢查了4.1源,以及它沒有改變。來源從horse's mouth直接拉。

所以。底線:似乎在使用-a-otest[時評估所有子表達式。

+1

Holy ...... bash!你很好 :) – Tom 2010-07-06 08:45:05