Skript, das 3 Eingaben validiert

Skript, das 3 Eingaben validiert

Das ist, was ich habe. Ich versuche, 3 Eingaben zu validieren. Bei der ersten und der zweiten Eingabe werde ich nicht aufgefordert, die korrekte Eingabe einzugeben. Was ist falsch?

#!/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        

Antwort1

Ihr SkriptAusgängesobald für den Titel oder Nachnamen eine ungültige Eingabe erfolgt, was die Schleife nutzlos macht. Verwenden Sie diese Option, continueum eine Iteration erneut auszuführen.

Sie möchten den Benutzer jedoch nicht zwingen, seinen Titel und Nachnamen erneut einzugeben, nur weil er eine ungültige ID eingegeben hat. Daher benötigen Sie drei Eingabeschleifen anstelle einer großen Schleife; eine Schleife für alles, was Sie vom Benutzer lesen.

Ihr Code ist unnötig repetitiv und das Umschreiben in drei Schleifen würdeAuchunnötige Wiederholungen. Es wäre bequemer, eine separate Eingabefunktion zu haben.

Im folgenden Skript habe ich das getan. Die Eingabefunktion get_inputnimmt ein „Label“ (eine Beschreibung dessen, was der Benutzer eingeben soll) und ein Muster, dem jedes Zeichen in der Eingabe entsprechen muss. Die get_inputFunktion gibt die gültige Zeichenfolge auf der Standardausgabe aus, weshalb wir sie im Hauptteil des Skripts innerhalb einer Befehlsersetzung aufrufen.

Ich habe auch die String-Validierung in eine eigene Funktion verschoben. Dies dient dazu, die get_inputFunktion übersichtlicher zu gestalten und die Validierungslogik von der Eingabelogik zu trennen.

Die Validierung verwendet denselben Ansatz wie Sie, d. h. sie löscht alle gültigen Zeichen aus der Zeichenfolge und prüft dann, ob noch Zeichen übrig sind. In diesem Fall besteht die Zeichenfolge die Validierung nicht.

#!/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"

Um beispielsweise auch Punkte im Titel oder Nachnamen zuzulassen, ändern Sie das Muster von [[:alpha:] ]in [[:alpha:]. ]. Oder Sie können noch weniger restriktiv sein und [![:digit:]]alle nicht-stelligen Zeichen (einschließlich Satzzeichen usw.) zulassen.

Um die Ausgabe in einer Datei mit demselben Namen wie der Benutzer zu speichern, der das Skript ausführt, leiten Sie die Ausgabe des Skripts selbst um:

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

Dadurch wird das Skript ausgeführt und die Ausgabe in eine Datei namens umgeleitet $USER.txt, wobei $USERder Benutzername des aktuellen Benutzers ist (diese Variable und $LOGNAMEsind normalerweise bereits von der Shell und/oder dem System festgelegt).

Sie können dies auch innerhalb des Skripts selbst tun, indem Sie die letzten drei printfZeilen in

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

Oder, wenn Sie den vom Benutzer gelesenen „Nachnamen“ im Skript verwenden möchten:

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

ZuAuchZum Drucken auf dem Terminal verwenden Sie tee:

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

Beachten Sie, dass die Verwendung der vom Benutzer eingegebenen Daten es dem Benutzer des Skripts potenziell ermöglicht, beliebige Dateien im aktuellen Verzeichnis zu überschreiben (sofern die Berechtigungen dies zulassen).

verwandte Informationen