2013-07-08 57 views
4

我正在爲應用程序編寫bash包裝。這個包裝器負責更改用戶,運行軟件並記錄其輸出。 我也希望它傳播SIGINT信號。防止在處理SIGINT後終止bash腳本

這是到目前爲止我的代碼:

#!/bin/bash 
set -e; set -u 

function child_of { 
    ps --ppid $1 -o "pid" --no-headers | head -n1 
} 

function handle_int { 
    echo "Received SIGINT" 
    kill -int $(child_of $SU_PID) 
} 

su myuser -p -c "bash /opt/loop.sh 2>&1 | tee -i >(logger -t mytag)" & 
SU_PID=$! 

trap "handle_int" SIGINT 

wait $SU_PID 
echo "This is the end." 

我的問題是,當我送一個SIGINT給這個包裝,handle_int被調用但隨後的腳本已經結束了,而我希望它繼續等待$SU_PID

有沒有辦法捕捉int信號,做一些事情,然後阻止腳本終止?

+0

如果我明白你的問題:接收後'SIGINT'你希望你的包裹腳本要等到你'su'命令退出之前死亡? – rkyser

+0

@rkyser是的,這正是我想要的。 – mistyrouge

回答

3

你有一個問題:在Ctrl-C之後,「這是結束。」是預料之中的,但它永遠不會出現,因爲劇本已經過早退出。原因是wait已經(意外地)在set -e下運行時返回非零值。

據「人的bash」:

如果bash等待命令完成並接收針對其陷阱已經設定的信號時,陷阱 不會直到命令完成執行。當bash經由 等待異步命令等待內建,針對其陷阱已設置將導致等待內置到具有退出狀態立即返回 一個信號的接收大於128 ,之後立即執行陷阱。

你應該換你wait呼叫set +e讓你的程序可以繼續處理捕獲的信號,同時等待異步命令後運行。

像這樣:

# wait function that handles trapped signal on asynchronous commands. 
function safe_async_wait { 
    set +e 
    wait $1 # returns >128 on asynchronous commands 
    set -e 
} 
#... 
safe_async_wait $SU_PID