5

私の bash スクリプトでは、$cmd変数に格納されている外部コマンドを実行しています。(単純なbashワンライナーでさえ、何でもかまいません。)

ctrlスクリプトの実行中に+が押された場合C、現在実行中のスクリプトを強制終了したいのです$cmdが、メイン スクリプトの実行を続行する必要があります。ctrlただし、メイン スクリプトの実行中に+でメイン スクリプトを強制終了するオプションを保持したいと考えていますC

#!/bin/bash
cmd='read -p "Ooook?" something; echo $something; sleep 4 ' 
while true; do
    echo "running cmd.."
    eval "$cmd"     # ctrl-C now should terminate the eval and print "done cmd"
    echo "done cmd"
    sleep 5         # ctrl-C now should terminate the main script
done

素敵なbashの方法でそれを行う方法はありますか?

回答に基づいて適用される変更:

#! /bin/bash

cmd='read -p "Ooook1?" something; read -p "Oook2?" ; echo $something; sleep 4 ' 
while true; do
    echo "running cmd.."
    trap "echo Interrupted" INT
    eval "($cmd)"     # ctrl-C now should terminate the eval and print "done cmd"
    trap - INT
    echo "done cmd"
    sleep 5         # ctrl-C now should terminate the main script
done

では、 「おーっ1?」と言いながらctrl+を押して Cread は、その読み取りが完了した後にのみ評価を中断します。(「Oook2」の直前で中断します) ただし、「sleep 4」で即座に中断します。

どちらの場合でも、正しいことを行います-evalサブシェルを中断するだけなので、ほとんどそこにいます-ちょうどその奇妙な読み取り動作..

4

3 に答える 3

4

eval部分をサブシェルで実行する余裕がある場合は、SIGINT をトラップするだけで済みます。

#! /bin/bash

cmd='read -p "Ooook1?" something; read -p "Oook2?" ; echo $something; sleep 4 ' 
while true; do
    echo "running cmd.."
    trap "echo Interrupted" INT
    eval "($cmd)"     # ctrl-C now should terminate the eval and print "done cmd"
    trap - INT
    echo "done cmd"
    sleep 5         # ctrl-C now should terminate the main script
done

ただし、それが特定のニーズに適合するかどうかはわかりません。

$ ./t.sh 
running cmd..
Ooook1?^CInterrupted
done cmd
^C
$ ./t.sh 
running cmd..
Ooook1?qsdqs^CInterrupted
done cmd
^C
$ ./t.sh 
running cmd..
Ooook1?qsd
Oook2?^CInterrupted
done cmd
^C
$ 
GNU bash, version 4.1.9(2)-release (x86_64-pc-linux-gnu)
于 2012-02-08T15:31:49.413 に答える
0

いいえ、read外部コマンドではありませんbash。他の命令と同じプロセスで実行される内部組み込みコマンドです。したがって、Ctrl-Cでは、すべてのプロセスが強制終了されます。

PSはい。サブシェルでコマンドを実行できます。このようなもの

#!/bin/bash
cmd='trap - INT; echo $$; read -p "Ooook?" something; echo $something; sleep 4 ' 
echo $$
while true; do
    echo "$cmd" > tmpfile
    echo "running cmd.."
    trap "" INT
    bash tmpfile
    rm tmpfile  
    trap - INT
    echo "done cmd"
    sleep 5         # ctrl-C now should terminate the main script   
done
于 2012-02-08T15:40:39.240 に答える
0

最後の終了ステータスを調べることで、sleep コマンドが異常終了したかどうかを判断できますecho $?。ゼロ以外のステータスは、おそらく Ctrl-C を示しています。

于 2012-02-08T15:33:30.823 に答える