3つの入力を検証するスクリプト

3つの入力を検証するスクリプト

これが私の状況です。3 つの入力を検証しようとしています。最初の入力と 2 番目の入力では、正しい入力を求められません。何が問題なのでしょうか?

#!/bin/bash                                                                     
while :                                                                         
        do                                                                      
        echo "Please enter your tittle:"                                        
        read TITTLE                                                             
        echo "Please enter your surname:"                                       
        read SURNAME                                                            
        echo "Please enter your ID No."                                         
        read ID                                                                 

        if [ "$TITTLE" = "" ] || [ "${TITTLE//[!0-9]}" != "" ];                 
        then                                                                    
        echo "Enter your valid tittle without special characters."              
        echo "Please try again."                                                
        exit 1                                                                  
        fi                                                                      

        if [ "$SURNAME" = "" ] || [ "${SURNAME//[!0-9]}" != "" ];               
        then                                                                    
        echo "Enter your valid surname without special characters."             
        echo "Please try again."                                                
        exit 1                                                                  
        fi                                                                      

        if [ "$ID" = "" ] || [ "${ID//[0-9]}" != "" ];                          
        then                                                                    
        echo "Enter your valid ID No. without special characters."              
        echo "Please try again"

        else                                                                    
        echo "Thank you" $TITTLE $SURNAME                                       
        break                                                                   
fi                                                                              
done        

答え1

あなたのスクリプト終了タイトルまたは姓に無効な入力が与えられるとすぐに、ループは役に立たなくなります。continue反復をやり直すために使用します。

ただし、無効な ID を入力したという理由だけで、ユーザーに肩書きと姓を再度入力させるのは望ましくありません。そのため、1 つの大きなループではなく、ユーザーから読み取った内容ごとに 1 つのループ、合計 3 つの入力ループが必要になります。

あなたのコードは不必要に繰り返しが多く、3つのループとして書き直すとまた不必要に繰り返しになります。別の入力機能があった方が便利です。

次のスクリプトでは、それを実行しました。入力関数は、get_input「ラベル」(ユーザーが入力する内容の説明) と、入力内の各文字が一致する必要があるパターンを受け取ります。関数はget_input有効な文字列を標準出力に出力します。これが、スクリプトのメイン部分のコマンド置換内でこの関数を呼び出す理由です。

また、文字列検証を独自の関数に移動しました。これは、get_input関数をよりわかりやすくし、検証ロジックを入力ロジックから分離するためです。

検証では、使用するのと同じアプローチが使用されます。つまり、有効な文字をすべて文字列から削除し、文字が残っているかどうかをテストします。残っている場合、文字列は検証に失敗します。

#!/bin/bash

# Succeeds if the first argument is non-empty and only
# consists of characters matching the pattern in the
# second argument.
is_valid () {
        local string pattern

        string=$1
        pattern=$2

        [ -n "$string" ] && [ -z "${string//$pattern}" ]
}

# Asks user for input until the given string is valid.
# The first argument is a text string describing what
# the user should enter, and the second argument is a
# pattern that all characters in the inputted data much
# match to be valid.
get_input () {
        local label pattern
        local string

        label=$1
        pattern=$2

        while true; do
                read -r -p "Please enter $label: " string

                if is_valid "$string" "$pattern"; then
                        break
                fi

                # Complain on the standard error stream.
                printf 'Invalid input, try again\n' >&2
        done

        printf '%s\n' "$string"
}

# Get data from user.
title=$(   get_input 'your title'   '[[:alpha:] ]' )    # title: only letters and spaces
surname=$( get_input 'your surname' '[[:alpha:] ]' )    # surname: same as title
id=$(      get_input 'your ID no.'  '[[:digit:]]' )     # ID: only digits

# Print what we got.
printf 'Title   = "%s"\n' "$title"
printf 'Surname = "%s"\n' "$surname"
printf 'ID      = "%s"\n' "$id"

タイトルや姓にドットなどを許可するには、パターンを から に変更します[[:alpha:] ]。または、さらに制限を緩めて を使用して、数字以外の文字 (句読点などを含む) を許可すること[[:alpha:]. ]もできます。[![:digit:]]

スクリプトを実行しているユーザーと同じ名前のファイルに出力を保存するには、スクリプト自体の出力をリダイレクトします。

$ ./script.sh >"$USER.txt"

これにより、スクリプトが実行され、出力が というファイルにリダイレクトされます$USER.txt。ここで、 は$USER現在のユーザーのユーザー名です (この変数と は$LOGNAME通常、シェルやシステムによって既に設定されています)。

スクリプト内で最後の3printf行を次のように変更することで、これを実行することもできます。

# Print what we got.
{
    printf 'Title   = "%s"\n' "$title"
    printf 'Surname = "%s"\n' "$surname"
    printf 'ID      = "%s"\n' "$id"
} >"$USER.txt"

または、スクリプト内でユーザーから読み取った「姓」を使用する場合は、次のようにします。

# Print what we got.
{
    printf 'Title   = "%s"\n' "$title"
    printf 'Surname = "%s"\n' "$surname"
    printf 'ID      = "%s"\n' "$id"
} >"$surname.txt"

また端末に印刷するには、次を使用しますtee:

# Print what we got.
{
    printf 'Title   = "%s"\n' "$title"
    printf 'Surname = "%s"\n' "$surname"
    printf 'ID      = "%s"\n' "$id"
} | tee "$surname.txt"

ユーザーが入力した内容を使用すると、スクリプトのユーザーが現在のディレクトリ内の任意のファイルを上書きできる可能性があることに注意してください (権限で許可されている場合)。

関連情報