2013-09-26 78 views
2

如果我執行了以下操作,並且網絡已關閉,則會執行零個案例,而不應該這樣做。今天通過SSH檢查通過命令輸出的零線

case "$(ssh -n $host zfs list -t snapshot -o name -H | grep "tank/fs" | wc -l | awk '{print $1}')" in 
    0) # do something 
     ;; 
    1) # do something else 
     ;; 
    *) # fail 
esac 

在我檢查,我可以ssh來$host腳本較早,但我發現這個問題,去哪兒網我的支票後立即失敗。

如果我檢查SSH命令的返回值,那麼我將始終從awk獲取返回值,因爲它將在最後執行。

問題

如何確保我其實算零線即zfs輸出,而不是零線從失敗的SSH連接?

回答

1

說:

set -o pipefail 

在腳本(或case語句之前)的開始。

set -o pipefail 
$value=$(ssh -n $host zfs list -t snapshot -o name -H | grep "tank/fs" | wc -l | awk '{print $1}') 
if [ $? == 0 ]; then 
    case $value in 
    ... 
    esac 
fi 

manual

此外,在執行case語句之前檢查命令的返回碼

pipefail

如果設置的返回值管道是最後一個 (最右邊)命令以非零狀態退出的值,如果全部爲 管道中的命令成功退出。此選項已被 默認禁用。

+0

不適用於我,它仍然通過'情況0'。 **編輯**:你添加了代碼,'$? == 0'邏輯應該工作。 – Jite

+0

@Jite看到編輯 – devnull

+0

我認爲這是一個醜陋的解決方案,但。當* ssh失敗時,'grep' /'wc' /'awk'命令將在本地執行,而不是在遠程*執行,這就是爲什麼它不能按預期工作。我的解決方案應該更強大。 – Jite

0

這個怎麼樣(SSH命令後不應得到本地執行):

"$(ssh -n $host 'zfs list -t snapshot -o name -H | grep "tank/fs" | wc -l | awk \'{print $1}\')'" 

注意我怎麼單引號的命令SSH遠程機器上運行。對於awk,也逃脫',如\'。檢查呼叫的返回值,並僅在返回成功時執行。

+1

無法解決問題,因爲整個管道可能會失敗,並且在未檢查退出狀態而不是提前短路時發生空白情況。 –

+0

@CharlesDuffy我在本地嘗試了原始行。 ssh失敗意味着管道命令在本地執行,'case 0'由於'wc -l'回顯'0'而觸發。在我的解決方案中,''''之間的所有內容都成爲ssh的參數,'ssh'失敗時'case 0'不會觸發。但是,在進行字符串比較時恰好是這種情況。如果'ssh'打印了一個'0'行,它就會匹配'case 0'。只對'0'返回值做動作聽起來像是一個好主意,我原本計劃添加它,但由於某種原因取消了編輯:) – Jite