Ctrl + C を押してもスクリプトが終了しない

Ctrl + C を押してもスクリプトが終了しない

4 つのオプションがある選択メニューがあります。Ctrl + C を押した場合、プログラムを終了する前にいくつかのファイルを削除したいです。これが私のコードです:

#!/bin/bash

ctrl_c() {
     test -f directory/file.txt && rm directory/file.txt
}

trap ctrl_c INT

PS3='Please enter your choice: '
while true; do
    clear
    options=("Option 1" "Option 2" "Option 3" "Exit")
    select opt in "${options[@]}"
    do
        case $opt in
            "Option 1")
                echo "you chose choice $REPLY which is $opt"
                break
                ;;
            "Option 2")
                echo "you chose choice $REPLY which is $opt"
                break
                ;;
            "Option 3")
                echo "you chose choice $REPLY which is $opt"
                break
                ;;
            "Exit")
                break 2
                ;;
            *) echo "invalid option $REPLY";;
        esac
    done
read -p "Press [Enter] key to continue..."
done

しかし、このコードを実行して Ctrl + C を押しても、何も起こらず、プログラムは終了せず、^c入力されるだけです。何が問題なのでしょうか?

答え1

Ctrl+ はCSIGINT 信号を送信しますが、それをキャプチャしてctrl_c関数に割り当てます。

trap ctrl_c INT

Ctrlしたがって、 +を押すとC、スクリプトは終了するのではなく関数を実行します。それが望ましくない場合は、trapコマンドを削除してください。

関数を実行して終了することが目的の場合はctrl_c、スクリプトに明示的に終了するように指示する必要があります。

ctrl_c() {
     test -f directory/file.txt && rm directory/file.txt
     exit
}

シグナルをトラップする場合、そのシグナルに応じてプログラムが何を実行するかを実装するのはあなた次第です。

posixただし、シェルオプションがアクティブ(set -o posix)でない限り、コマンドがアクティブに実行されている間はシグナルが送信されないため、期待どおりには動作しません(「'select' ループの実行中に Bash が SIGINT トラップを無視する()。

set -o posixつまり、呼び出す前にselect(そして場合によっては呼び出しset +o posixた後でも)使用する必要があるということです。

関連情報