シェルスクリプト で[yes], [no]の選択して、分岐処理をしたい

シェルスクリプトで「yes/no」で分岐する

シェルスクリプトで「yes/no」の選択をさせて分岐処理をしたいケースが有るかと思います。
分岐する方法は色々とありますが、この記事では、read コマンドを使用してユーザー入力を取得した値を、if , cese, select を利用して分岐する方法を紹介します。

if 文を使う方法

readコマンドでユーザーが入力した値を、answer の変数に入力して、if文で分岐処理をしています。但し、小文字のみ対応となっているので大文字で「Yes」等は対応していないです。その場合は、case を利用したほうが良いです

#!/bin/bash

read -p "処理を実行しますか? (yes/no): " answer

if [[ "$answer" == "yes" ]]; then
    echo "処理を実行します。"
    # ここに実行する処理を書く
elif [[ "$answer" == "no" ]]; then
    echo "処理をキャンセルしました。"
else
    echo "無効な入力です。yes か no を入力してください。"
fi

画面出力例

$ sh test.sh 
処理を実行しますか? (yes/no): yes
処理を実行します。

# 大文字でYesだと無効な値になります
$ sh test.sh 
処理を実行しますか? (yes/no): Yes
無効な入力です。yes か no を入力してください。

case を使う方法(大文字・小文字を区別しない)

こちらもif文と同じで、read ~ answer で入力した値を変数にいれて、case文で分岐していますが、こちらは大文字・小文字で違いでも対応できています

#!/bin/bash

read -p "処理を実行しますか? (yes/no): " answer
case "$answer" in
    [Yy] | [Yy][Ee][Ss] )  # "y" または "yes" にマッチ
        echo "処理を実行します。"
        # ここに実行する処理を書く
        ;;
    [Nn] | [Nn][Oo] )  # "n" または "no" にマッチ
        echo "処理をキャンセルしました。"
        ;;
    * )
        echo "無効な入力です。yes か no を入力してください。"
        ;;
esac

画面出力例

# 小文字のyesでも対応可能
$ sh test.sh 
処理を実行しますか? (yes/no): yes
処理を実行します。

# 大文字・小文字のYesでも対応可能
$ sh test.sh 
処理を実行しますか? (yes/no): Yes
処理を実行します。

# 大文字のYESでも対応可能
$ sh test.sh 
処理を実行しますか? (yes/no): YES
処理を実行します。

select を使って対話的に選択させる方法

select ~ caseを利用すると、選択肢に番号が自動で付与されます。

#!/bin/bash

echo "処理を実行しますか?"
select answer in "Yes" "No"; do
    case "$answer" in
        Yes)
            echo "処理を実行します。"
            # ここに実行する処理を書く
            break
            ;;
        No)
            echo "処理をキャンセルしました。"
            break
            ;;
        *)
            echo "無効な選択です。1 または 2 を選んでください。"
            ;;
    esac
done

画面出力例

# case の場合は、yes/no の入力ではなく番号入力で分岐になります
$ sh test.sh 
処理を実行しますか?
1) Yes
2) No
#? 1
処理を実行します。

# Yes と入力すると無効な選択になります
$ sh test.sh 
処理を実行しますか?
1) Yes
2) No
#? Yes
無効な選択です。1 または 2 を選んでください。

if , cese, select のうち、どの方法がいい?

  • 簡単に済ませたいif を使う

  • 大文字・小文字の違いを吸収したいcase を使う

  • 選択肢を明示的に見せたいselect を使う

どの方法がいいかは用途次第ですが、個人的には caseselect をおすすめします!