验证 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重新进行迭代。

但是,您不想仅仅因为用户输入了无效 ID 就强制用户再次输入其头衔和姓氏,因此您将需要三个输入循环而不是一个大循环;你从用户那里读到的每一件事都需要一个循环。

您的代码是不必要的重复,将其重写为三个循环会进行不必要的重复。如果有单独的输入功能会更方便。

在下面的脚本中我已经做到了这一点。输入函数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,通常已由 shell 和/或系统设置)。

您还可以在脚本本身中执行此操作,方法是将最后三行更改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"

请注意,使用用户给出的输入可能允许脚本用户覆盖当前目录中的任意文件(假设权限允许这样做)。

相关内容