簡體   English   中英

Bash超時與管道輸入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM