spe*_*ndo 57 bash shell timeout function
为什么会这样呢?
timeout 10s echo "foo bar" # foo bar
Run Code Online (Sandbox Code Playgroud)
但这不会
function echoFooBar {
echo "foo bar"
}
echoFooBar # foo bar
timeout 10s echoFooBar # timeout: failed to run command `echoFooBar': No such file or directory
Run Code Online (Sandbox Code Playgroud)
我怎样才能让它发挥作用?
Dou*_*der 45
timeout是一个命令 - 所以它在你的bash shell的子进程中执行.因此,它无法访问当前shell中定义的函数.
timeout给出的命令作为超时的子进程执行 - shell的一个子进程.
您可能会感到困惑,因为echo它既是shell内置命令又是单独命令.
你可以做的是将你的函数放在它自己的脚本文件中,chmod它是可执行的,然后执行它timeout.
或者fork,在子shell中执行你的函数 - 在原始进程中,监视进度,如果花费太长时间就杀死子进程.
use*_*194 39
正如Douglas Leeder所说,你需要一个单独的超时过程来发信号.通过将函数导出到子壳并手动运行子shell来解决此问题.
export -f echoFooBar
timeout 10s bash -c echoFooBar
Run Code Online (Sandbox Code Playgroud)
Edu*_*lar 23
还有一个内联替代方案还可以启动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 Code Online (Sandbox Code Playgroud)
可以运行如下:
run_cmd "echoFooBar" 10
Run Code Online (Sandbox Code Playgroud)
注意:解决方案来自我的一个问题: 为bash命令和函数实现超时的优雅解决方案
如果您只想为整个现有脚本添加超时作为附加选项,您可以让它测试超时选项,然后让它在没有该选项的情况下递归调用它。
例子.sh:
#!/bin/bash
if [ "$1" == "-t" ]; then
timeout 1m $0 $2
else
#the original script
echo $1
sleep 2m
echo YAWN...
fi
Run Code Online (Sandbox Code Playgroud)
无超时运行此脚本:
$./example.sh -other_option # -other_option
# YAWN...
Run Code Online (Sandbox Code Playgroud)
以一分钟的超时运行它:
$./example.sh -t -other_option # -other_option
Run Code Online (Sandbox Code Playgroud)
小智 5
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
Run Code Online (Sandbox Code Playgroud)