博客导读:
# 写作此博客的背景
# 问题的要求
# 解题思路
# 思路流程图
# 解决具体过程
# 源码
# 结果展示
初次接触shell脚本,在最近的学习中,有一道考察比较全面的试题,小编苦苦的琢磨,耐心的钻研,在掉了101根头发之后,终于让小编给琢磨透了。嘻嘻笑。感觉这道题对之前的知识点考察比较全面,所以打算总结出来,以备以后复习使用,同时也供遇到同样问题的小伙伴们参考,如有不足之处还请海涵,如有错误之处,请赐教。
这道题目是这样的:
编写一个脚本/root/bin/createuser.sh
要求:
1)脚本的执行语法必须是:createuser.sh -u username -m password,选项与参数间可支持多空格,但不能顺序颠倒。
2)当未指定正确的选项或参数时,以错误输出方式提示“createuser.sh -u username -m password ”后退出脚本。
3)用户名必须以字母开头,可包括数字和_。否则不合法。以错误输出提示用户"用户名仅包含字母数据和下划线"
4)当用户名检测合法后,判断用户名是否已存在,若存在,再判断用户是否已设置过密码,若设置过密码,直接退出,未设置,则将密码设置为所指定的密码后以正确输出方式显示“username 密码已更新后退出”
5)当用户名不存在,则创建用户,并为该用户设置所指定的密码后以正确输出方式显示“用户username已创建并更新密码”
6)要求脚本执行过程中不能有非要求的其他输出结果出现。脚本在非正确方式退出时应反回给?参数非0值。
解题思路:
罗列需要用到的知识
读完题目之后发现要用到以下几个知识:
*首先实现命令后的固定格式输入,我们需要使用到位置变量。
*我们需要对位置变量进行判断,判断其是否满足条件,变量1和变量3为固定不变的参数,可以使用字符串的比较进行判断,对于变量2和变量4,首先要判断其不为空才行,需要用到条件测试。
*对于用户名的格式进行判断,我们需要规定开头字符,既要进行限定,同时又要进行判断,我们需要使用到正则表达式和条件测试命令,可以使用[[ ]],双中括号中可以使用正则,又有判断的功能。
*该脚本中时不时会有错误或正确的提示信息,所以当然要用到echo 进行输出提示,但是规定,正确的提示以正确的输出方式提示,即标准正确输出,错误的要以标准错误方式输出,我们需要使用到输出重定向。
*判断用户是否存在,我们需要使用到某一个命令,当用户存在时返回正确的返回值,不存在时返回错误的返回值,小编这里使用id username 来进行查看用户的id,如果该用户存在则返回值为0,。
*当用户存在的时候,我们需要对用户判断有没有密码,查看密码的方式,我们可以去查看/etc/shadow这个文件,用户的密码位有三种情况,!!没有设置密码,!$..或!!$...密码被禁用,!用户被锁定没有密码,空用户密码被清空。有这么多情况我们需要使用分组的概念进行条件的排列,若有密码直接退出脚本。
*小编在这里临时加一个简单的对密码的判断,限定密码的输入不少于5位,需要使用扩展正则表达式和字符匹配。
*若用户不存在就直接进行用户的创建和密码的添加,需要使用到useradd因为我们对密码的添加不是交互式的所以,我们使用passwd --stdin对密码进行一次性写入。并以标准正确输出进行提示。
*当然,最重要的数据结构就是我们的if判断语句。
接下来小编附上结构思路
具体过程:
*判断命令执行语法是否正确:
[ "$1" == "-u" ] && [ "$2" ] && [ "$3" == "-m" ] && [ "$4" ] && [ -z "$5" ]
*判断用户名是否合法:
[[ "$2" =~ ^[[:alpha:]]([[:alnum:]]|_)* ]]
*判断密码是否符合要求:
[[ "$4" =~ .{6,} ]]
*判断用户是否存在:
id $2 &> /dev/null
*判断用户密码是否存在:
[[ "$(pwconv ;getent shadow |grep ^$2 |cut -d: -f2)" =~ ^('!$'|'!!$'|'$').* ]]
echo "$4" | passwd --stdin "$2" &> /dev/null
useradd $2 && echo "$4" |passwd --stdin $2 &> /dev/null
源码:
#!/bin/bash
#定义变量方便引用
error1='语法格式不对,请参考以下格式输入: createuser -u username -m passwd '
error2='用户名仅包含字母、数字和下划线'
right1='密码已更新'
right2='创建成功并设置密码为’
#首先判断命令语法是否合法,不合法就输出错误提示,并退出,返回值1
#判断用户名是否合法,不合法就输出错误提示,并退出,返回值1
#判断用户是否存在
#创建用户并设置密码
if [ "$1" == "-u" ] && [ "$2" ] && [ "$3" == "-m" ] && [ "$4" ] && [ -z "$5" ];then
if [[ "$2" =~ ^[[:alpha:]]([[:alnum:]]|_)* ]];then
if [[ "$4" =~ .{6,} ]];then
if [ "$(id $2 &> /dev/null && echo true || echo false)" == true ];then
if [[ "$(pwconv ;getent shadow |grep ^$2 |cut -d: -f2)" =~ ^('!$'|'!!$'|'$').* ]];then
exit
else
echo "$4" | passwd --stdin "$2" &> /dev/null && echo "用户 @H_925_404@$2 $right1 ";exit
fi
else
useradd $2 && echo "$4" |passwd --stdin $2 &> /dev/null && echo "用户 @H_925_404@$2 $right2 $4"
exit
fi
else
echo "请重新执行命令,输入不低于六位的密码!!@H_925_404@" 1>&2
exit 1
fi
else
echo "$error2" 1>&2 ;exit 1
fi
else
echo "$error1" 1>&2 ;exit 1
fi
unset error1 error2 right1 right2
执行结果展示: