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는 일반적으로 셸 및/또는 시스템에 의해 이미 설정되어 있습니다).

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"

사용자가 제공한 입력을 사용하면 잠재적으로 스크립트 사용자가 현재 디렉터리의 임의 파일을 덮어쓸 수 있습니다(권한이 이를 허용하는 경우).

관련 정보