Скрипт, проверяющий 3 входа

Скрипт, проверяющий 3 входа

Вот что у меня есть. Я пытаюсь проверить 3 ввода. Первый и второй вводы не просят меня ввести правильный ввод. Что не так?

#!/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для повторного выполнения итерации.

Однако вы не хотите заставлять пользователя снова вводить свое имя и фамилию только потому, что он ввел неверный идентификатор, поэтому вам понадобятся три цикла ввода вместо одного большого цикла: по одному циклу на каждую информацию, которую вы считываете с пользователя.

Ваш код без необходимости повторяется, и переписывание его в виде трех циклов приведет ктакжебыть без необходимости повторяющимися. Было бы удобнее иметь отдельную функцию ввода.

В следующем скрипте я это сделал. Функция ввода 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, обычно уже заданы оболочкой и/или системой).

Вы также можете сделать это в самом скрипте, изменив последние три printfстроки на

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

Обратите внимание, что использование введенных пользователем данных потенциально позволяет пользователю скрипта перезаписывать произвольные файлы в текущем каталоге (при условии, что разрешения это позволяют).

Связанный контент