2012-03-31 6 views
31

なぜこの作品がはタイムアウト

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 

とどのように私はそれを動作させることができないだろうとの関数を実行しますか?

+0

http://stackoverflow.com/questions/12321469/retry-a-bash-command-with-timeout/35977896#35977896 –

答えて

32

timeoutはコマンドなので、bashシェルのサブプロセスで実行されています。したがって、現在のシェルで定義されている関数へのアクセス権はありません。

コマンドtimeoutが与えられているコマンドは、タイムアウトのサブプロセスとして実行されます。これは、シェルのグランドプロセスです。

echoはシェル組み込みコマンドと別のコマンドの両方であるため、混乱する可能性があります。

自分のスクリプトファイルに自分の関数を入れ、実行可能にするためにchmodを実行してからtimeoutで実行します。

また、サブ・シェルで関数を実行し、元のプロセスでは進行を監視し、サブプロセスが長時間かかるとそのプロセスを強制終了します。

+0

ソリューションをありがとう!しかし、既存のスクリプトの追加オプションとしてタイムアウトを追加したいので、タイムアウト機能のためだけに独自のファイルを作成するのは非常に不便です。これは唯一の解決策ですか? – speendo

+4

@speendo 'timeout'はシグナルを送ることによってプロセスを殺すことによって働くと考えてください。それはプロセスにしかできないものです。したがって、タイムアウトで実行するものは、それ自身のプロセスである必要があります。 –

+1

@speendoまた、bashは(AFAIK)シングルスレッドであることに注意してください。スレッドがあなたの関数を実行していると、タイムアウト機能は何ができますか? –

3

既存のスクリプト全体の追加オプションとしてtimeoutを追加したい場合は、timeout-optionのテストを行い、そのオプションを使わずに再帰的に呼び出すことができます。

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 -t -other_option # -other_option 
16

インライン代替も起動あります:1分のタイムアウトでそれを実行している

$./example.sh -other_option # -other_option 
          # YAWN... 

bashシェルのサブプロセス:

 

timeout 10s bash <<EOT 
function echoFooBar { 
    echo foo 
} 

echoFooBar 
sleep 20 
EOT 
 
8

あなたはタイムアウトとしてだけでなく、他の機能のために同じことを行うことができるようになる機能を作成することができます。

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

+0

'wait $ child'の後で最も内側のサブシェルも殺されるべきではありませんか?それは何もしません(待っているから離れて)、しかしそれはまだ子供が終了した場合でも、カウントを続けます – Blauhirn

2
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 
19

Douglas Leeder氏によると、タイムアウトするための別のプロセスが必要だと言いました。機能をサブシェルにエクスポートし、サブシェルを手動で実行することによる回避策。

export -f echoFooBar 
timeout 10s bash -c echoFooBar 
+0

輸出-fはshで動作しない、bashで動作します。 – J0hnG4lt

関連する問題