2014-01-07 94 views
0

考慮下面的代碼可能退出代碼:檢查後臺進程

myprocess | while read line; do logger -t mytag -p user.err $line; done & 

if [ ${PIPESTATUS[0]} -ne 0 ]; then 
    logger -t ${tag} -p user.error "CANNOT START (exit code: ${PIPESTATUS[0])" 
fi 

如果myprocess不會失敗,那麼PIPESTATUS [0]是什麼,不確定的? 如何在啓動時檢查myprocess是否啓動或死亡(缺少庫符號等),同時仍捕獲其輸出?

感謝, 丹

+1

'PIPESTATUS'適用於最新的*前景*管道。 – chepner

回答

1

如何:

{ myprocess 2>&1 || echo "CANNOT START (exit code: $?)" ; } \ 
| while read line; do logger -t mytag -p user.err $line; done 

2>&1將讓你捕獲並記錄錯誤輸出和標準輸出。

+0

如果我在完成後添加&,這似乎不起作用。該腳本需要繼續,將其留在後臺。 – dbbd

0

如果myprocess沒有失敗,${PIPESTATUS[0]}將是0

或者,set -o pipefail。那麼如果myprocess失敗,則完整命令($?)的退出狀態將不爲零,並且您不需要檢查PIPESTATUS

0

這可能會變得棘手。您需要從返回$ {PIPESTATUS [n]} 後臺工作。我通過創建一個函數並傳遞命令作爲參數運行,然後將整個事件發送到背景來做類似的事情。注意pipe_command()函數中的return語句。這會返回$ cmd的狀態,而不是讀取線循環時的狀態。您也可以使用這種技術在for循環中背景多個事物。希望這可以幫助。

例子:

#! /bin/bash 

main() 
{ 
    pids="" 
    myprocess="ssh [email protected] /bin/bash /etc/init.d/process start" 
    pipe_command "$myprocess" & 
    pids+="$! " 
    watch_pids "$pids" 
} 

pipe_command() 
{ 
    cmd="$1" 
    $cmd 2>&1 | \ 
    while read line; do 
     logger -t mytag -p user.err $line 
    done 
    return ${PIPESTATUS[0]} 
} 

watch_pids() 
{ 
    pids="$1" 
    for pid in $pids; do 
     wait $pid 
     if [ $? -ne 0 ]; then 
      logger -t ${tag} -p user.error "CANNOT START (exit code: $?)" 
      return 2 
     fi 
    done 
} 
main [email protected] 

或者更簡單地說你的例子:

myprocess | while read line; do logger -t mytag -p user.err $line; done ; return ${PIPESTATUS[0]} & 

wait 
status=$? 
if [ $status -ne 0 ]; then 
    logger -t ${tag} -p user.error "CANNOT START (exit code: $status)" 
fi