次のようなbashスクリプトがあるとしましょう。
while :
do
foo
done
私はこのスクリプトをコンソールで実行でき、fooを2回実行する間に発生する限りいつでも終了できます。したがってCtrl、+を押すとC(これはスクリプトを終了する別の動作かもしれません。Ctrl+Cは単なる例です)、fooを実行した後に使用可能な次のポイントで終了します。
while :
do
foo
if [pressed_ctrl_c]:
break
done
ベストアンサー1
次の設定を試すことができます。
#!/bin/bash
#
INTR=
trap 'INTR=yes; echo "** INTR **" >&2' INT
while :
do
(
# Protect the subshell block
trap '' INT
# Protected code here
echo -n "The date/time is: "
sleep 2
date
read -t2 -p 'Continue (y/n)? ' YN || echo
test n = "$YN" && echo "Asked for BREAK" >&2 && exit 90
)
SS=$?
test 90 -eq $SS && echo "Matched BREAK" >&2 && break
# Ctrl/C, perhaps?
test yes = "$INTR" && echo "Matched INTR" >&2 && break
done
exit 0
いくつかのメモ
read
ペアは、test
ブロック内で保護されたコードセグメントの対話型制御を示しています( ... )
。- これはサブシェルの内部
exit 90
と同じですが、内部で発生します。break
サブシェルブロックの最後の直後にある行は、状態をtest 0 != $? ...
キャプチャし、exit 90
コードbreak
が実際に望むものを実装するために使用されます。 - サブシェルは、さまざまな終了ステータス値を使用して、さまざまな種類の所望の制御フロー(など...)
break
を表すことができます。exit
- これは、プログラムが独自のシグナルハンドラをインストールするのを防ぎません。たとえば、
gdb
()用の独自のハンドラをインストールします。ユーザーがセッションを中断するのを防ぐことが目標である場合は、割り込みキーを変更すると状況を難読化するのに役立ちます(下記のコードを参照)。エレガントではありませんが、おそらく効果的です。SIGINT
CtrlC
端末でSIGINTキーを変更する
G=$(stty -g) # Save settings
test -n "$G" && stty intr ^A # That is caret and A, not Ctrl/A
# ... SIGINT generated with Ctrl/A rather than Ctrl/C ...
test -n "$G" && stty "$G" # Restore original settings