执行功能为什么会这样工作与超时
timeout 10s echo "foo bar" # foo bar
但这不
function echoFooBar {
echo "foo bar"
}
echoFooBar # foo bar
timeout 10s echoFooBar # timeout: failed to run command `echoFooBar': No such file or directory
,并会如何我使它工作吗?
执行功能为什么会这样工作与超时
timeout 10s echo "foo bar" # foo bar
但这不
function echoFooBar {
echo "foo bar"
}
echoFooBar # foo bar
timeout 10s echoFooBar # timeout: failed to run command `echoFooBar': No such file or directory
,并会如何我使它工作吗?
timeout
是一个命令 - 因此它在你的bash shell的子进程中执行。因此它无法访问当前shell中定义的函数。
给出的命令timeout
是作为超时的子进程执行的 - 您的shell的grand-child进程。
您可能会感到困惑,因为echo
既是一个内置的shell命令,也是一个单独的命令。
你可以做的是把你的函数放在它自己的脚本文件中,chmod它是可执行的,然后用timeout
执行它。
或者fork,在子shell中执行你的函数 - 并在原始进程中监视进度,如果子进程花费太长时间,则会终止进程。
感谢您的解决方案!但是,由于我想将超时添加为现有脚本的附加选项,因此只有超时功能才拥有自己的文件是非常不方便的。这是唯一的解决方案吗? – speendo 2012-03-31 10:01:39
@speendo考虑到'timeout'通过发送信号来杀死进程 - 这是你只能对进程进行处理的东西。因此,无论你使用超时运行,都需要它是自己的过程。 – 2012-03-31 15:33:03
@speendo还要注意bash是(AFAIK)单线程的,所以如果线程正在执行你的函数,那么可以做什么呢? – 2012-03-31 15:33:56
如果您只是想将超时作为整个现有脚本的附加选项添加,您可以使其测试超时选项,然后使其无递归地自我调用。
example.sh:
#!/bin/bash
if [ "$1" == "-t" ]; then
timeout 1m $0 $2
else
#the original script
echo $1
sleep 2m
echo YAWN...
fi
运行此脚本没有超时:
$./example.sh -other_option # -other_option
# YAWN...
用一分钟超时运行它:
$./example.sh -t -other_option # -other_option
有一个内嵌的替代还推出了bash shell的子进程:
timeout 10s bash <<EOT
function echoFooBar {
echo foo
}
echoFooBar
sleep 20
EOT
您可以创建一个函数,它允许你做一样的超时也为其他功能:
function run_cmd {
cmd="$1"; timeout="$2";
grep -qP '^\d+$' <<< $timeout || timeout=10
(
eval "$cmd" &
child=$!
trap -- "" SIGTERM
(
sleep $timeout
kill $child 2> /dev/null
) &
wait $child
)
}
而且可以如下运行:
run_cmd "echoFooBar" 10
注:该解决方案来自我的其中一个问题: Elegant solution to implement timeout for bash commands and functions
不应该在'wait $ child'之后也不会杀死最内层的子shell?它没有做任何有害的事情(除了等待),但它仍然继续计数,即使孩子已经完成 – Blauhirn 2017-09-14 21:48:53
function foo(){
for i in {1..100};
do
echo $i;
sleep 1;
done;
}
cat <(foo) # Will work
timeout 3 cat <(foo) # Will Work
timeout 3 cat <(foo) | sort # Wont work, As sort will fail
cat <(timeout 3 cat <(foo)) | sort -r # Will Work
正如道格拉斯李德说,你需要一个单独的过程来超时发信号。通过将函数导出到子shell并手动运行子shell来解决此问题。
export -f echoFooBar
timeout 10s bash -c echoFooBar
导出-f在sh中不起作用,在bash中不起作用。 – J0hnG4lt 2017-05-08 22:20:26
http://stackoverflow.com/questions/12321469/retry-a-bash-command-with-timeout/35977896#35977896 – 2016-03-14 05:57:18