有效地超时命令并将输出捕获到bash脚本中的变量

时间:2013-06-29 17:01:58

标签: linux bash timeout

我需要在bash脚本中运行命令并在运行时间过长时将其终止。我还需要将所有输出捕获到变量。如果命令首先完成,我需要释放/终止看门狗进程(例如睡眠),因为我可能会运行这样的命令列表。

不幸的是,“超时”命令对我来说是不可用的,否则我可以这样做:

output=`timeout -s 9 $TIMEOUT my-command`

并检查退出代码124以查看是否有超时。

因此,我选择的解决方案是by @Dmitry to a similar question

( my_command ) & pid=$!
( sleep $TIMEOUT && kill -HUP $pid ) 2>/dev/null & watcher=$!
wait $pid 2>/dev/null && pkill -HUP -P $watcher

不幸的是,以下内容并未捕获$ output的任何内容:

( output=`my_command` ) & pid=$!

我可以将输出转储到文件中,然后像这样将它加载到变量中,但我宁愿没有文件:

( `my_command >$outfile` ) & pid=$!
...
output=`cat $outfile`
rm -f $outfile

我的问题:有更好的方法吗?理想情况下,在不使用文件的情况下将stderr捕获到另一个变量?

1 个答案:

答案 0 :(得分:1)

幸运的是,$()表示法允许多个命令,因此您可以这样做:

output=$(
    ( my_command ) & pid=$!
    ( sleep $TIMEOUT && kill -HUP $pid ) 2>/dev/null & watcher=$!
    wait $pid 2>/dev/null && pkill -HUP -P $watcher
)

您还可以使用常规()对命令进行分组,然后重定向其所有输出。将stderr重定向到stdout可以使用2>&1完成,所以你最终得到这个:

output=$(
    (
        ( my_command ) & pid=$!
        ( sleep $TIMEOUT && kill -HUP $pid ) 2>/dev/null & watcher=$!
        wait $pid 2>/dev/null && pkill -HUP -P $watcher
    ) 2>&1
)