[英]Bash timeout with piped input
有一個命令(例如$ run_command),必須在超時后終止。 解決方案非常簡單-我可以只使用coreutils中的超時或其他stackoverflow主題中的timeout3 。 但是我的命令從這樣的untar管道接收到了stdin
tar -xO -f "$1" | /usr/bin/time -f "%e" --output=$time_output -- $run_command
$ run-command是我的命令,其中還測量了執行時間(使用time實用程序)。
因此,問題是,避免在超時實用程序中包含無限時間的最佳方法是什么?
以非常簡單的形式,您可以像這樣殺死調用腳本:
#!/bin/bash
( sleep $timeout_period && kill $$ ) &
tar -xO -f "$1" | ...
當然,這僅是示例。 您需要提供一些保證,即在運行kill
時,$$仍然是相同的腳本。
當然,這將殺死整個腳本,包括time
(如果腳本被殺死,則為$ timeout_period)。
更新#1 :
使用臨時文件的示例。
tmpfile=$(/usr/bin/mktemp /tmp/temp.XXXXX)
tar -xO -f "$1" > $tmpfile
trap "rm -f $tmpfile" 0 1 2 3 15
/usr/bin/time -f "%e" --output=$time_output -- $run_command < $tmpfile
請注意,由於文件系統的速度/性能,這仍然會出錯。
更新#2 :
除了免除tar
時間之外,這還添加了超時功能:
(
tmpfile=$(/usr/bin/mktemp /tmp/temp.XXXXX)
tar -xO -f "$1" > $tmpfile
trap "rm -f $tmpfile" 0 1 2 3 15
/usr/bin/time -f "%e" --output=$time_output -- $run_command < $tmpfile
) &
pid=$!
( sleep $timeout_period && kill $pid ) &
wait %1
第一個腳本段中存在相同的潛在問題; 您需要提供保險,確保$$仍然是您認為的,然后再殺死它。 同樣,信號將被發送到外殼包裝器,而不是直接發送到您的命令。 您必須測試信號是否按預期傳遞給您的命令。
另請注意,這會導致超時/終止。 “等待”告訴腳本要等到第一個后台進程結束,所以其本身或者您的命令完成,或者得到由超時殺死......然后腳本后進入任何wait
。 如果命令本身完成,那么您可能會遇到潛在的問題,因為$ pid會被循環用於另一個進程。 解決問題留給讀者練習。 :-)
我認為您在此示例中要查找的是臨時文件,而不是管道。 在大多數情況下,您希望並行執行管道。 在您的情況下(分析),以及在執行后續命令之前先執行命令之前,應該執行順序操作。 我建議使用mktemp
達到此效果。 在這個示例中,我不知道通過進程替換還是通過mkfifo
使用FIFO的方法,因為$run_command
始終取決於tar
的輸出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.