이것이 내가 가진 것입니다. 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"
사용자가 제공한 입력을 사용하면 스크립트 사용자가 현재 디렉터리에 있는 임의의 파일을 덮어쓸 수 있습니다(권한이 이를 허용한다고 가정).