ユーザー入力用のBash Whileループと最大試行回数カウンタを持つエラープロンプト

ユーザー入力用のBash Whileループと最大試行回数カウンタを持つエラープロンプト

ユーザー入力を受けてエラーが発生した場合は、プロンプトを繰り返すためにwhileループを作成しました。

while true; do
        read -p "Enter hostname : " fqdn
        pattern="(^[^\.]*\.[^\.]*\.[^\.]*$)"
        
        if [[ -z "$fqdn" ]]; then   #if fqdn input is empty
                echo "Error! Hostname cannot be empty"
                continue
        elif [[ ! "${fqdn}" =~ ${pattern} ]]; then
                echo "Error! Format incorrect"
                continue
        else
                echo "hostname is $fqdn"
                break
        fi
done

私の目標:

  1. の場合もし/エリーフプロンプトを2回だけ表示してから終了する方法を示します。
  2. 上記のwhileループを改善する方法はありますか?例えば ケーススイッチ。ケースの切り替えを理解するのは難しいですか?

オペレーティングシステム:Ubuntu 20.04(ヘッドレス)

ベストアンサー1

次のbashスクリプトはユーザーから文字列を読み取り、その文字列が適用するホスト名の条件を満たしているかどうかをテストします。

ステートメントで使用されている2つのパターンの最初のものは、間にcase文字がない2つの点の病理学的ケースをテストします(これは私たちが行動しないパターンです)。 2番目のパターンに複数の点があり、両端に点のない文字列が含まれていることをテストします。fdqn2番目のパターンが文字列と一致する場合にのみ、ホスト名変数はその文字列に設定されます。この文字列はfoo..bar2 番目のパターンと一致するため、2 つのドットの部分文字列を 1 番目のパターンと前提に一致させます。

#!/bin/bash

unset -v count fdqn

while true; do
        read -p 'Enter hostname: ' -r

        case $REPLY in (*..*) ;; ([!.]*.*.*[!.]) fdqn=$REPLY; break; esac

        echo 'Invalid format' >&2

        count=$(( count + 1 ))
        [ "$count" -eq 2 ] && break
done

if [ -z "$fdqn" ]; then
        echo 'No valid hostname entered' >&2
        exit 1
fi

printf 'The hostname is "%s"\n' "$fdqn"

このcount変数は、ユーザーが文字列を入力しようとした回数を追跡します。この変数の値が2に達すると、ループを終了します。

case移植可能なスクリプトにしたくない限り(この場合は文を別々に実行する必要がありますsh)、ここで実際に文を使用する必要はありません。readglobbing演算子を使用する==場合、ステートメントbashcase次のようになります。

if [[ $REPLY == *..* ]]; then
        :
elif [[ $REPLY == [!.]*.*.*[!.] ]]; then
        fdqn=$REPLY
        break
fi

&&これら2つのテストは、最初のテストが音声の場合に接続するためにも使用できます。

if [[ $REPLY != *..* ]] && [[ $REPLY == [!.]*.*.*[!.] ]]; then
        fdqn=$REPLY
        break
fi

3つのドットを含むホスト名を取得したくない場合は、一致しないように$REPLY一致しないことを確認してください。*.*.*.**..*

おすすめ記事