0

CTRL+Cをトラップして関数 ctrl_c を呼び出すbash トラップを作成しました。この関数は、メッセージを表示してカウンターを開始し、メイン関数に戻ります。

トラップは最初の実行時には正常に機能しますが、2 回目に試行すると C^ が表示されますが、CTRL + C は無効になりますが、関数は再度呼び出されません。

最初のインスタンスのように実行するようにトラップをリセットする方法はありますか?

前もって感謝します。

コード;

function ctrl_c() {
    clear
    echo "** Trapped CTRL-C"
    echo -n "Press [ Enter ] to continue."
    read
    for i in $(seq 1 5);
    do
            let timer="5 - $i + 1"
            clear
            echo "Returning to main menu in.. $timer"
            sleep 1
    done
    main
}

trap ctrl_c INT
4

3 に答える 3

1

割り込みハンドラの実行中は、シグナルは常にブロックされます。このコードでは、ハンドラーが返らないため、シグナルはブロックされたままです。

戻らないシグナルハンドラーは一般的に悪い考えです。シグナルの後に関数を再起動したいだけの場合は、ループ内のサブシェルで関数を実行し、ハンドラーを終了させることができます。これにより、サブシェルからのみ終了します。

編集:エイドリアンの提案で更新されました。

    #!/bin/bash

    function ctrl_c() {
            clear
            echo "Trapped CTRL-C"
            echo
            for ((timer=5; timer>0; timer--)); do
                    printf "\rRetunring to main menu in $timer seconds"
                    sleep 1
            done
            exit 10
    }

    function main() {
            trap ctrl_c INT
            # Doing main stuff
            echo "Exiting normally"
            exit 0;
    }

    while ( main ); (($? == 10)); do :; done
于 2015-02-26T14:34:09.923 に答える
0

メイン関数に「戻る」のではなく、メイン関数を再度呼び出すため、技術的にはトラップ ハンドラ内にとどまっています。ハンドラーの最後で「main」呼び出しを除外すると、bash は実行フローで中断されたコマンドの後に NEXT コマンドに戻り、さらに割り込みをキャッチし続けることができます。bashでSIGINTをキャッチし、ハンドルして無視するを参照してください

function main() {
    echo sleeping...
    sleep 60
    main
}

function ctrl_c() {
    echo "** Trapped CTRL-C"
}

trap ctrl_c INT

main

あなたの場合、失敗したのが単に読み取り操作(ユーザーからメニュー選択を取得するため)である場合は、入力が空であるかどうかを確認し、さらに入力するためにループバックします。

于 2015-02-26T14:37:11.560 に答える