執行功能爲什麼會這樣工作與超時
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