2011-05-10 35 views
9

擊:我想運行一個命令和管道通過一些過濾的結果,但如果命令失敗,我想回到命令的誤差值,而不是過濾器的無聊的返回值:bash腳本:如何保存管道中第一條命令的返回值?

如:

if !(cool_command | output_filter); then handle_the_error; fi 

或者:

set -e 
cool_command | output_filter 

在這兩種情況下,這是我關心的cool_command返回值 - 在第一種情況下的「如果」條件,或在第二種情況下退出腳本。

這是否有一些乾淨的習語呢?

回答

0

如果您並不需要顯示命令的錯誤輸出,你可以不喜歡

if ! echo | mysql $dbcreds mysql; then 
    error "Could not connect to MySQL. Did you forget to add '--db-user=' or '--db-password='?" 
    die "Check your credentials or ensure server is running with /etc/init.d/mysqld status" 
fi 

在這個例子中,錯誤和模具定義功能。腳本中的其他地方。 $ dbcreds也被定義,儘管這是從命令行選項構建的。如果該命令沒有生成錯誤,則不返回任何內容。如果發生錯誤,文本將由此特定命令返回。

糾正我,如果我錯了,但我得到你真正希望做的東西有點超過費解的印象

[ `id -u` -eq '0' ] || die "Must be run as root!" 

,你實際上是if語句之前搶奪用戶ID,然後執行測試。這樣做,你可以顯示結果,如果你選擇。這將是

UID=`id -u` 
if [ $UID -eq '0' ]; then 
    echo "User is root" 
else 
    echo "User is not root" 
    exit 1 ##set an exit code higher than 0 if you're exiting because of an error 
fi 
15

使用PIPESTATUS內建變量。

man bash

PIPESTATUS

一個數組變量包含來自過程中 的最近最常執行的前臺退出 狀態的值的列表(見陣列下面 ) 管道(可能只包含一個 單個命令)。

+2

只是爲了完成答案''[[$ {PIPESTATUS [0]} -ne 0]] && handle_the_error' – jozxyqk 2014-07-29 04:49:59

0

以下腳本使用fifo在單獨的進程中篩選輸出。與其他答案相比,這具有以下優點。首先,它不是特定的。特別是它不依賴PIPESTATUS。其次,在命令完成之前,輸出不會停滯。

$ cat >test_filter.sh <<EOF 
#!/bin/sh 

cmd() 
{ 
    echo $1 
    echo $2 >&2 
    return $3 
} 

filter() 
{ 
    while read line 
    do  
      echo "... $line" 
    done 
} 

tmpdir=$(mktemp -d) 
fifo="$tmpdir"/out 
mkfifo "$fifo" 

filter <"$fifo" & 
pid=$! 
cmd a b 10 >"$fifo" 2>&1 
ret=$? 
wait $pid 
echo exit code: $ret 
rm -f "$fifo" 
rmdir "$tmpdir" 
EOF 
$ sh ./test_filter.sh 
... a 
... b 
exit code: 10