需求分析
用户总是无视操作指南,输入一些不一致、格式错误或语法有问题的数据。作为一名shell脚本开发人员,你得在这些错误引发问题之前将其找出并标记出来。
一种典型的情况涉及文件名和数据库键名。你的程序要提示用户输入的字符应该仅限字母数字,只能包含大写字母、小写字母和数字,不能有标点符号、特殊字符和空格。用户输入的字符串是否有效?
代码实现
#!/bin/bash
# name:validAlphaNum
# description:确保输入内容仅限于字母和数字
validAlphaNum(){
# 返回值:如果输入内容全部都是字母和数字,那么返回0;否则返回1
# 删除所有不符合要求的字符。
# [:alnum:]是POSIX的正则表达式简写,代表所有的字母数字字符
validchars="$(echo $1 | sed -e 's/[^[:alnum:]]//g')"
if [ "$validchars" = "$1" ];then
echo 0
else
return 1
fi
}
# 主脚本开始:如果要将改脚本包含到其他脚本之内,那么删除或注释掉本行以下的所有内容。
/bin/echo -n "Enter input:"
read input
# 输入验证
if ! validAlphaNum "$input" ; then
echo "Your input must consist of only letters and numbers." >&2
exit 1
else
echo "Input is valid"
fi
exit 0
工作原理
这个脚本的逻辑直截了当。首先,使用基于sed的转换移除输入中所有的无效字符,创建一个新版本的输入信息。然后,将结果与最初的输入相比较。
- 如果两者相同,那么皆大欢喜;
- 如果不同,则说明在转换过程中被移除的属于不可接受的字符(字母和数字),输入无效。
这种做法奏效的原因在于sed会删除所有不在[:alnum:]中的字符,[:alnum:]是POSIX的正则表达式简写,代表所有的字母数字字符。如果转换后的值和最初的输入不一致,就意味着输入字符串中存在非字母数字字符,从而表明输入无效。该函数会返回非0值表明这一情况。记住,我们只接受ASCII文本。
运行脚本
这是一个独立的脚本。它提示用户输入,然后告诉用户输入是否有效。函数validAlphaNum更为典型的用法是将其复制并粘贴到其他shell脚本的顶部,或是像脚本#12那样以库的形式引用该函数。
validalnum也很好地演示了一种通用的shell脚本编程技术。编写函数,然后在将其并入更大、更复杂的脚本之前先进行测试。这样做能为你免去不少麻烦。
shell脚本validalnum用起来很简单,它会让用户输入要验证的字符串。以下代码展示了该脚本是如何处理有效输入和无效输入的。
$ validalnum
Enter input: valid123SAMPLE #-> Input is valid.
$ validalnum
Enter input:this is most assuredly NOT valid, 12345
#-> Please enter only letters and numbers.
精益求精
因为灵活性好,所以这种“删除有问题的字符,然后看看剩下什么”的方法很受用,特别要记得将输入变量和匹配模式(或是干脆没有模式)放入双引号中,以避免空输入错误。空模式在脚本编程中一直都是个问题,因为它会使有效的条件测试变成一个产生错误信息的不完整语句。零长度的引用字符串和空白是不一样的,牢记这句话,你肯定不会吃亏。
如果除了大写字母之外,还需要空格、逗号和点号,该怎么办?修改替换模式就可以了:
sed 's/[^[:upper:] ,.]//g'
你也可以像下面这样验证电话号码输入(允许整数值、空格、括号和连字符,但是不允许前导空格或连续多个空格):sed 's/[^- [:digit:]\(\)]//g'
但如果你想限制输入仅为整数值,一定要小心陷阱。例如,你可能会这样做:sed 's/[^[:digit:]]//g'
这行代码处理正数没有问题,但要是你还想处理负数呢?如果你仅在有效字符集中加入一个负号,那-3-4也算是有效输入了,但它显然不是一个合法的整数。