有一个命令(比如$ run_command),必须在超时后被杀死。解决方案非常简单 - 我可以使用coreutils中的 timeout 或其他stackoverflow主题中的 timeout3 。但是我的命令从这个
的无人管道接收它的stdintar -xO -f "$1" | /usr/bin/time -f "%e" --output=$time_output -- $run_command
其中 $ run-command 是我的命令,也测量了执行时间(使用 time 实用程序)。
那么,问题是避免在超时实用程序中包含解除时间的最佳方法是什么?
答案 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
的输出。