管道输入的Bash超时

管道输入的Bash超时,bash,timeout,pipe,tar,Bash,Timeout,Pipe,Tar,有一个命令(比如$run_命令),必须在超时后终止。解决方案非常简单-我可以使用coreutils中的timeout或其他stackoverflow主题中的timeout3。但我的命令从untar pipe smth接收到它的stdin,如下所示 tar -xO -f "$1" | /usr/bin/time -f "%e" --output=$time_output -- $run_command 其中$run command是我的命令,它的执行时间也被测量(使用time实用程序) 因此,问

有一个命令(比如$run_命令),必须在超时后终止。解决方案非常简单-我可以使用coreutils中的timeout或其他stackoverflow主题中的timeout3。但我的命令从untar pipe smth接收到它的stdin,如下所示

tar -xO -f "$1" | /usr/bin/time -f "%e" --output=$time_output -- $run_command
其中$run command是我的命令,它的执行时间也被测量(使用time实用程序)


因此,问题是什么是避免在timeout实用程序中包含无误时间的最佳方法?

我认为您在本例中寻找的是一个临时文件,而不是管道。在大多数情况下,您希望并行执行管道。在您的情况下(分析),以及当前面的命令在执行后面的命令之前应该成功时,需要进行顺序操作。我建议使用
mktemp
实现此效果。我不知道如何通过进程替换或使用
mkfifo
来使用fifo,因为
$run\u命令
总是依赖于
tar

的输出,我认为在这个示例中,您要寻找的是一个临时文件,而不是管道。在大多数情况下,您希望并行执行管道。在您的情况下(分析),以及当前面的命令在执行后面的命令之前应该成功时,需要进行顺序操作。我建议使用
mktemp
实现此效果。我不知道如何通过进程替换或使用
mkfifo
来使用fifo。在本例中,由于
$run\u command
始终依赖于
tar

的输出,您可以这样终止调用脚本:

#!/bin/bash

( sleep $timeout_period && kill $$ ) &

tar -xO -f "$1" | ...
当然,这只是一个例子;您需要提供一些保险,确保在运行
kill
时$$仍然是相同的脚本

这当然会杀死整个脚本,包括
time
(如果脚本被杀死,这将是$timeout\u 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
第一个脚本段中存在相同的潜在问题;你需要提供保险,保证在你杀死它之前,$$仍然是你所认为的。此外,信号将发送到shell包装器,而不是直接发送到您的命令。您必须测试信号是否按预期传递给您的命令


还请注意,这会影响超时/终止。“wait”告诉脚本等待,直到第一个后台进程完成,因此您的命令要么自行完成,要么被超时杀死。。。然后脚本继续执行
wait
之后的任何操作。如果该命令自行完成,则可能会遇到$pid被回收用于另一个进程的潜在问题。解决这个问题留给读者作为练习。:-)

以非常简单的形式,您可以如下方式终止调用脚本:

#!/bin/bash

( sleep $timeout_period && kill $$ ) &

tar -xO -f "$1" | ...
当然,这只是一个例子;您需要提供一些保险,确保在运行
kill
时$$仍然是相同的脚本

这当然会杀死整个脚本,包括
time
(如果脚本被杀死,这将是$timeout\u 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
第一个脚本段中存在相同的潜在问题;你需要提供保险,保证在你杀死它之前,$$仍然是你所认为的。此外,信号将发送到shell包装器,而不是直接发送到您的命令。您必须测试信号是否按预期传递给您的命令


还请注意,这会影响超时/终止。“wait”告诉脚本等待,直到第一个后台进程完成,因此您的命令要么自行完成,要么被超时杀死。。。然后脚本继续执行
wait
之后的任何操作。如果该命令自行完成,则可能会遇到$pid被回收用于另一个进程的潜在问题。解决这个问题留给读者作为练习。:-)

为此,我通常使用
tempfile
,但我不知道为什么。
mktemp
更好吗?您建议将$1的内容解压到tempfile中,然后像这样使用smth
/usr/bin/time-f“%e”--output=$time\u output--$run\u命令<$tempfile\u name
?是的,我会首先使用
mktemp
将安全文件解压到tempfile中,然后按照您的说法执行
$run\u命令
。@stepheniedzielski:+1。谁知道呢?作为未来读者的参考,Russ Allbery对该主题的想法见。(顺便说一句,奥尔贝里先生在几乎任何主题上写的几乎任何东西都值得一读。)我通常使用
tempfile
来达到这个目的,尽管我真的不知道为什么。
mktemp
更好吗?您建议将$1的内容解压到tempfile中,然后像这样使用smth
/usr/bin/time-f“%e”--output=$time\u output--$run\u命令<$tempfile\u name
?是的,我会首先使用
mktemp
将安全文件解压到tempfile中,然后按照您的说法执行
$run\u命令
。@stepheniedzielski:+1。谁知道呢?作为未来读者的参考,Russ Allbery对该主题的想法见。(顺便说一句,奥尔贝里先生在几乎任何主题上写的几乎任何东西都值得一读。)“有剧本”还不清楚。超时后需要终止的是调用脚本还是$run_命令?不,需要终止的是$run_命令。谢谢,我会编辑问题“有剧本”不清楚。超时后需要终止的是调用脚本还是$run_命令?不,需要终止的是$run_命令。谢谢,我将编辑此示例中的问题,tar执行时间也将出现在$timeout\u期间。这是我想要避免的情况。当然,在你澄清你想要杀什么之前,我写了这篇文章。如果要完全排除tar对时间的影响,则需要将数据存储在临时文件中。我会更新。。