使用管道输入进行Bash超时

时间:2012-06-10 20:21:37

标签: bash timeout pipe tar

有一个命令(比如$ run_command),必须在超时后被杀死。解决方案非常简单 - 我可以使用coreutils中的 timeout 或其他stackoverflow主题中的 timeout3 。但是我的命令从这个

的无人管道接收它的stdin
tar -xO -f "$1" | /usr/bin/time -f "%e" --output=$time_output -- $run_command

其中 $ run-command 是我的命令,也测量了执行时间(使用 time 实用程序)。

那么,问题是避免在超时实用程序中包含解除时间的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

以非常简单的形式,您可以像这样终止调用脚本:

#!/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

存在第一个脚本段中的相同潜在问题;你想要提供保险,在你杀死之前,$$仍然是你的想法。此外,信号将被发送到shell包装器,而不是直接发送到您的命令。您必须测试信号是否按预期传递到您的命令。

另请注意,此背景为timeout / kill。 &#34;等待&#34;告诉脚本等到第一个后台进程完成,所以 你的命令自己完成它会被超时杀死...然后脚本继续执行wait之后的任何事情。如果命令自行完成,则会遇到潜在的问题,其中$ pid被回收用于另一个进程。解决这个问题留给读者练习。 : - )

答案 1 :(得分:1)

我认为你在这个例子中寻找的是一个临时文件,而不是一个管道。在大多数情况下,您希望并行执行管道。在您的情况下(分析)以及在执行以后的命令之前前面的命令应该成功时,需要顺序操作。我建议使用mktemp来达到此效果。我不知道通过流程替换或mkfifo使用FIFO的方法,因为$run_command总是依赖于tar的输出。