shell程序是一个过程式的解释器,提供了编程能力,然后解释执行。对于过程式编程而言,把一行源码程序翻译成机器语言,然后执行,再翻译下一行的源码程序为机器语言,然后再执行。shell脚本其实就是以一系列命令组合起来的文本文件,这些命令组合起来完成一个或者一项功能。shell脚本可以自动化常用命令;执行系统管理和故障排除;创建简单的应用程序;处理文本或文件。因此,对于一个linux运维人员来讲,编写脚本是一个不可缺少的技能。
编写脚本: Shell脚本可以使用Vim编写。注意脚本文件的第一行一定要写”#!/bin/bash“(另外,为了增加脚本的可读性,还要添加注释,注释以#开头,以方便使用人员的阅读。)最好在注释中加上脚本的编写时间、版本号、作者、联系方式等等。方便以后的查找修改。 执行脚本: 首先给予脚本文件执行(x)权限(chmod +x 脚本路径),然后在命令行上指定脚本的绝对或相对路径(在一般文件下的执行文件时,一定要指定文件路径,即./test.sh。对于经常使用的文件,可以将它放到PATH路径下面,然后,在执行,就不用再指定再路径了!)
注意:脚本中的命令不会执行别名!示例:
编写一个脚本/root/bin/createuser.sh,脚本的执行语法必须是:createuser.sh -u username -m password,选项与参数间可支持多空格,但不能顺序颠倒。 当未指定正确的选项或参数时,以错误输出方式提示“createuser.sh -u username -m password ”后退出脚本。 用户名必须以字母开头,可包括数字和_。否则不合法。以错误输出提示用户”用户名仅包含字母数据和下划线” 当用户名检测合法后,判断用户名是否已存在,若存在,再判断用户是否已设置过密码,若设置过密码,直接退出,未设置,则将密码设置为所指定的密码后以正确输出方式显示“username 密码已更新后退出” 当用户名不存在,则创建用户,并为该用户设置所指定的密码后以正确输出方式显示“用户username已创建并更新密码” 要求脚本执行过程中不能有非要求的其他输出结果出现。脚本在非正确方式退出时应反回给?参数非0值。
解答思路:
对于该题,一定要认真读题,仔细阅读每一句话,然后理解题意。建议:认真分析题目,画一个流程图,这样有助于我们理解题意,思维逻辑会更加清晰,事半功倍。切记:磨刀不误砍柴工!另外该题的解答方法有很多,下面的只是小编的思路,仅供大家参考……
#!/bin/bash # ------------------------------------------ # Filename:creatuser.sh # Revision:1.0 # Date:2017-08-04 # Author:156 # Email:1140994710@qq.com # Description:创建用户并设置密码 # ------------------------------------------ _canshu=`echo "$@" |grep -o ^-u[[:space:]].*-m[[:space:]].*` #取出“-u username -m password”,如果格式不符合,则_canshu为空。如果格式符合,则赋值给变量_canshu; _username=`echo "$@" |egrep -o "^-u.*-m"| egrep -o "\-([um])|[[:alnum:]|_]+\>" |grep -v "^-[um]"` #取出“username”,并且只有数字、字母下划线开头的。如果格式符合,则赋值给变量_username;如果username中含有特殊字符,那么分行显示; _password=`echo "$@" | grep -o "\-m.*" | egrep -o "[^-m[:space:]*].*$"` #取出“password”,并赋值给变量_password; if [ -n "$_canshu" ];then #判断变量_canshu是否为空;如果_canshu为空,则说明格式错误,报错,并退出; _userwc=`echo "$_username" |wc -l` #查看_username中有几行内容,并赋值给_userwc if [ "$_userwc" -eq 1 ];then #判断username中是否含有特殊字符,如果含有特殊字符,则报错,并退出; _user=`cat /etc/passwd |grep -o "^$_username\>"` #查看username是否已经存在;如果已经存在则赋值给变量_user。如果不存在则_user变量值为空; if [ -n "$_user" ];then #判断变量_user的值是否为空,如果为空,则创建用户,并设置密码;如果不为空,则说明用户已经存在,需要查看该用户的密码是否已经设置并存在>; _passwd=`getent shadow "$_user" |cut -d: -f2` #查看username的密码是否已经被设置过了,并赋值给变量_passwd; if [ "$_passwd" == "!!" ];then #判断username用户的密码是否已经设置过了,如果已经被设置过了,则报错,并提示; echo $_password |passwd --stdin $_username &> /dev/null #设置密码; echo "用户"$_username"密码已更新!" exit 0 else echo "用户"$_username"已存在并且已有密码!" exit 1 fi else useradd $_username echo $_password |passwd --stdin $_username &> /dev/null echo ""$_username"已创建并更新密码!" exit 0 fi else echo "用户名仅能包含数字字母下划线" exit 1 fi else echo "选项或参数的格式错误!正确格式为:creatuser.sh -u username -m password" exit 1 fi unset _canshu _username _password _userwc _user _passwd #清空变量;提示:
脚本开头的三个参数(_canshu、_username、_password)可能不太容易理解,在此做一个说明。 _canshu=echo "$@" |grep -o ^-u[[:space:]].*-m[[:space:]].* 题目中指定选项的位置不可以改变,所以,可以线过滤出类似于“-u ### -m ###”如果_canshu为空,则说明选项的顺序错误。 _username=echo "$@" |egrep -o "^-u.*-m"| egrep -o "\-([um])|[[:alnum:]|_]+\>" |grep -v "^-[um]" 首先需要先过滤出“-u ### -m”之间的内容;然后再过滤出以字母、数字、下划线组成的字符串,为了防止username为“u”或“m”,所以连带着过滤出“-u”“-m”,方便下一步删掉。 _password=echo "$@" | grep -o "\-m.*" | egrep -o "[^-m[:space:]*].*$" 首先过滤出“-m ###”;然后再过滤出以非“-m空格”开头的字符串。其中”[^-m[:space:]*].*$”,[:space:]后面的“*”要不要都可以!
附录 脚本中命令不会执行别名
[root@CentOS7 bin]# cat test.sh #!/bin/bash # ------------------------------------------ # Filename:test.sh # Revision: # Date:2017-08-05 # Author:156 # Email:1140994710@qq.com # Website: # Description: # ------------------------------------------ rm $1 [root@CentOS7 bin]# touch /app/{2,3} [root@CentOS7 bin]# ls /app/{2,3} /app/2 /app/3 [root@CentOS7 bin]# rm /app/2 ***#执行rm命令时,会询问是否要删除。即执行了rm -i*** rm: remove regular empty file ‘/app/2’? y [root@CentOS7 bin]# test.sh /app/3 ***#执行脚本中的rm命令时,并未询问!*** [root@CentOS7 bin]#