Linux

超時而不殺死bash中的程序

  • October 26, 2019

我有一個正在執行的主腳本,從它我有第二個“慢程序”我想開始,如果它沒有在時間限制內完成,則在主腳本中“做某事” - 取決於關於它是否完成。注意如果“緩慢的過程”在我的時間限制之前完成,我不想等待整個時間限制。

我希望“緩慢的過程”繼續下去,這樣我就可以收集有關其性能的統計數據和取證。

我已經研究過使用timeout,但是完成後它會殺死我的腳本。

假設這個簡化的例子。

main.sh

result=`timeout 3 ./slowprocess.sh`
if [ "$result" = "Complete" ]
then
echo "Cool it completed, do stuff..."
else
echo "It didn't complete, do something else..."
fi

slowprocess.sh

#!/bin/bash
start=`date +%s`
sleep 5
end=`date +%s`
total=`expr $end - $start`
echo $total >> /tmp/performance.log
echo "Complete"

在這裡,它使用了超時——所以腳本死了,所以什麼都沒有結束/tmp/performance.log——我想slowprocess.sh完成,但是,我想main.sh繼續下一步,即使它沒有在 3 秒內完成。

使用 ksh/bash/zsh:

{
 (./slowprocess.sh >&3 3>&-; echo "$?") |
   if read -t 3 status; then
     echo "Cool it completed with status $status, do stuff..."
   else
     echo "It didn't complete, do something else..."
   fi
} 3>&1

我們將原始 stdout 複製到 fd 3 ( 3>&1) 上,以便我們可以為slowprocess.sh( >&3) 恢復它,而子shell 其餘部分的 stdout(...)則通過管道傳輸到read -t 3.

或者,如果你想使用timeout(這裡假設 GNU timeout):

timeout --foreground 3 sh -c './slowprocess.sh;exit'

將避免slowprocess.sh被殺死(對於通過在 shell 程序中執行最後一個命令進行優化的實現;exit是必要的)。sh

引用自:https://unix.stackexchange.com/questions/84973