确保用户准确输入信息的正确方法是什么,或者以正确的期望回复语句?我有一个bash脚本有4个变量,需要特定的输入形式,但我无法弄清楚如何检查他们的输入。
这些是我用来完成命令的变量:
read -p "Enter ID: " ID #SONGID can only be 10 digits long
read -p "Enter directory to search in e.g ab,cd,ef: " DIR #Directories are two letters and range from a-z
read -p "This abbreviation needs to match previous choice e.g ab, cd, ef: " FILE
read -p "Enter date of file e.g 20140503 or 201405*: " DATE
现在,无论如何,我的编写脚本的方式都会继续。
SONGID="10"
if [ $(echo "SONGID" | grep -E "[0-10") ] &&
echo "Song ID good"
else
echo "ID needs to be 10 digits"
exit
fi
答案 0 :(得分:1)
在进行检查之前尝试设置变量
INPUT_STATUS=good
然后执行检查,在发现错误时更改变量
case $SONGID in
[[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]][[:digit:]])
# this matches when song IDs are 10 digits -- do nothing here
;;
*)
# this matches when song IDs are not 10 digits -- we're bad now
INPUT_STATUS=bad
;;
esac
if [ $INPUT_STATUS = 'good' ]; then
echo "Song ID is good."
else
echo "Song IDs need to be exactly 10 digits."
fi
每次检查成功时,不要试图设置INPUT_STATUS=good
。
使用case
语句可以指定与SONGID
grep
匹配的模式。或者,现代shell可能允许我们使用conforms to POSIX。使用shell可以使用的模式给我们带来的额外好处是比调用像{{1}}之类的外部程序来进行匹配要快得多。
答案 1 :(得分:1)
您可以使用类似于以下的模式。纯粹的狂欢。您确定当您离开while
循环时数据已经过相应的功能验证 - 所以如果出现问题,您将不得不责怪该功能,而不是程序的结构 1
#!/bin/bash
validate_ID() {
# Success if and only if $1 is a string of 10 digits
[[ $1 =~ ^[[:digit:]]{10}$ ]]
}
validate_dir() {
# Success if and only if $1 is a string of 2 letters in the range [a-z]
[[ $1 =~ ^[abcdefghijklmnopqrstuvwxyz]{2}$ ]]
# Hard-coded here for security, since depending on locales, other characters
# would pass, e.g., é. Try it: [[ é =~ [a-z] ]]; echo $?
}
validate_file() {
# I didn't understand the requirements... this always succeeds for now
return 0
}
validate_date() {
# Don't know how you want to validate this... this always succeeds for now
return 0
}
while :; do
IFS= read -rep "Enter ID: " songID
history -s -- "$songID"
validate_ID "$songID" && break
echo "Bad ID"
done
while :; do
IFS= read -rep "Enter directory to search in e.g ab,cd,ef: " dir #Directories are two letters and range from a-z
history -s -- "$dir"
validate_dir "$dir" && break
echo "Bad dir"
done
while :; do
IFS= read -rep "This abbreviation needs to match previous choice e.g ab, cd, ef: " file
history -s -- "$file"
validate_file "$file" && break
echo "Bad file"
done
while :; do
IFS= read -rep "Enter date of file e.g 20140503 or 201405*: " date
history -s -- "$date"
validate_date "$date" && break
echo "Bad date"
done
history
命令:每个命令都将读入的值插入历史记录中,以便用户可以使用向上箭头(尝试使用和不使用)检索以前的值 - 注意-e
标志到read
命令使用readline。 TAB完成适用于文件名。
注意。目前有两种验证功能无法完成工作。我并不完全了解您希望如何验证数据。
1 其他一些REPL设计可能会失败,例如,
while read a; do
validate "$a" && break
echo "$a is invalid"
done
似乎很好,但如果读取中出现错误,则会失败,例如,用户可以输入任意数据,按Ctrl-D几次,您将拥有该任意数据变量a
。