2、接收用户的参数
shell脚本已经内设了用于接收用户输入参数的变量,变量之间可以使用空格隔开。
如:./test.sh one two three four
- $0:对应的是当前shell脚本程序的名称,即test.sh
- $#:对应的是总共有几个参数,此条命令总共有4个参数
- $*:对应的是所有位置的参数值,分别是one two three four
- $?:对应的是显示上一次命令的执行返回值
- $1:对应的是第1个参数,即one
- $2:对应的是第2个参数,即two
3、条件表达式
shell脚本中的条件测试语句可以判断表达式是否成立,若条件成立则返回数字0,否则便返回其它随机数值。
如:[ cd /home/ln ],注意条件表达式的两边都必须要有一个空格
文件测试语句
它是使用指定条件来判断文件是否存在或权限是否满足等情况的运算符。
# 判断/home/ln是否为一个目录类型的文件[ -d /home/ln ]
echo $? # 如果返回值是0,则目录存在;如果返回值为非零值,则目录不存在
-d | 测试文件是否为目录类型 |
-e | 测试文件是否存在 |
-f | 判断是否为一般文件 |
-r | 测试当前用户是否有权限读取 |
-w | 测试当前用户是否有权限写入 |
-x | 测试当前用户是否有权限执行 |
逻辑测试语句
用于对测试结果进行逻辑分析,根据测试结果实现不同的效果。
逻辑“与”:&&。表示当前面的命令执行成功后才会执行它后面的命令。
# 先判断/home/ln是否存在,若存在则输出Exist
[ -e /home/ln ] && echo "Exist"
逻辑“或”:|| 。表示当前面的命令执行失败后才会执行它后面的命令。
# 先判断当前登录的用户是否是root管理员身份,若是,则不执行后面的命令;若不是,则执行后面的命令。
[ $USER = root ] || echo "user"
逻辑“非”:! 。表示把条件测试中的结果取相反值。
# 先判断当前登录用户是否是root用户,如果是,取反后,变为不是,则执行后面的语句
[ !$USER = root ] || echo "administrator"
由于当前登录的账号是root账号,那么第一个条件取反后为假,则不会执行 echo "user"语句,就会执行echo "root"语句。
# 当前登录的账号为root账号
[ !$USER = root ] && echo "user" || echo "root" #输出root
整数值比较语句
整数比较运算符仅是对数字的操作,不能将数字与字符串、文件等内容一起操作。
如:[ 10 -gt 10 ]
-eq | equal,是否等于 |
-ne | not equal,是否不等于 |
-gt | greater than,是否大于 |
-lt | less than,是否小于 |
-le | less equal,是否等于小于 |
-ge | greater equal,是否大于等于 |
字符串比较语句
用于判断测试字符串是否为空值,或两个字符串是否相同。经常用来判断某个变量是否未被定义(即内容为空值)。
# 当前语系的环境变量值LANG不是英语(en.US).
[ $LANG != "en.US" ] && echo "Not en.US" # 执行结果:Not en.US
= | 比较字符串内容是否相同 |
!= | 比较字符串内容是否不同 |
-z | 判断字符串内容是否为空 |
4、流程控制语句
if条件语句
单分支结构:由if、then、fi关键词组成。
#!/bin/bash
DIR="/home/LN"
if [ ! -e $DIR ] # 判断该目录是否存在,如果不存在则创建then mkdir -p $DIR
fi
双分支结构:由if、then、else、fi关键词组成。
如下所示,编写一个ping.sh脚本,执行语句:bash ping.sh 192.168.1.101。
/dev/null:
是一个被称作Linux黑洞的文件,把输出信息重定向到这个文件等同于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁。
#!/bin/bash
#-c是规定尝试ping的次数为3次;-i表示每个数据包发送间隔为0.2s;-W表示等待的超时时间为3s
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ] # $?显示上一次命令的执行返回值,如果上一条命令 成功执行,则返回0,否则,返回非0thenecho "Host $1 is on-line."
elseecho "Host $1 is off-line."
fi
多分支结构:由if、then、else、elif、fi关键词组成
如下所示例子,编写score.sh脚本:read用来读取用户输入信息的命令,它能够把接收到的用户输入信息赋值给后面的指定变量;-p参数用来向用户显示一定的提示信息。
#!/bin/bash
read -p "Enter your score(0-100):" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]then echo "$GRADE is excellent!!"
elif [$GRADE -ge 70 ] && [ $GRADE -le 84 ]then echo "$GRADE is good!"
elseecho "$GRADE is fail!"
fi
for循环语句
如下所示例子,先创建一个user.txt文档,里面有多个用户名,然后编写脚本。
#!/bin/bash
read -p "Enter the users password:" PASSWORD
for UNAME in `cat users.txt`
doid $UNAME &> /dev/nullif [ $? -eq 0 ]then echo "Username already exists."elseuserad $UNAME &> /dev/nullecho "$PASSWORD" | password --stdin $UNAME &> /dev/nullif [ $? -eq 0 ]then echo "$UNAME, creat successfully."elseecho "$UNAME, create fail."fifi
done
while循环语句
适用于在执行前不确定最终执行的次数。
如下例子所示,编写一个GuessNumber.sh脚本
#!/bin/bashNUMBER=$(expr $RANDOM % 1000) # 随机生成一个0-32767的随机数,然后对1000进行取余操作
TIMES=0
echo "数值的范围在0-999之间,猜猜看?"while true
doread -p "请输入你猜测的数字:" INTlet TIMES++if [ $INT -eq $NUMBER ]thenecho "恭喜你,猜对了。你一共猜了 $TIMES 次。"exit 0elif [ $INT -gt $NUMBER ]thenecho "你猜得太高了。"elseecho "你猜得太低了。"fi
done
case条件语句
case语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令。
如下所示例子,编写CheckKey.sh脚本。
#!/bin/bash
read -p "请输入一个字符,并按Enter键确认:" KEYcase "$KEY" in
[a-z] | [A-Z])
echo "你输入的是字母。"
;;
[0-9])
echo "您输入的是数字。"
;;
*)
echo "您输入的是空格、功能键或其他字符。"
esac
5、计划任务
一次性计划任务
只执行一次,用于满足临时的工作需求,默认采用的是交互式方法。可以用 at 命令实现,格式:at 时间,如下所示:
# 今晚23:00重启网站服务
at 23:00
at > systemctl restart httpd
at > #这里同时按下Ctrl+D来结束编写计划任务
可以通过管道符实现非交互式的方法创建一次性计划任务。
echo "systemctl restart httpd" | at 23:00
如果想要查看已设置好但还未执行的一次性计划任务,可以使用 at -l 命令;
如果想要将其删除,可以使用 atrm 任务序号。
长期性计划任务
如果想要能够周期性地、有规律地执行某些具体的任务,那么Linux系统默认启用的crond服务是最佳选择。
- crontab -e:创建、编辑计划任务
- crontab -l:查看当前计划任务
- crontab -r:删除某条计划任务
- crontab -u:以管理员身份登录系统后,编辑他人的计划任务。
使用crond服务设置任务的参数格式:分钟、小时、日、月、星期 命令。如果有些字段没有设置,则需要使用星号(*)占位。
分钟 | 0~59的任意整数 |
小时 | 0~23的任意整数 |
日 | 1~31的任意整数 |
月 | 1~12的任意整数 |
星期 | 0~7的任意整数。其中0和7均表示星期日 |
命令 | 要执行的命令或程序脚本 |
计划任务中的“分”必须要有数值,绝对不能为空或是*;
而“日”和“星期”字段不能同时使用,否则就会发生冲突。
如下例子所示:
crontab -e
crontab -l
0 2 * * 1,3,5 /home/LN/tar -czvf backup.tar.gz /home/ln #所以命令(tar)需要用绝对路径来写
除了可以使用逗号(,)来分别表示多个时间段,如“8,9,11”表示8月、9月、11月,还可以使用减号(-)来表示一段连续的时间周期,如字段“日”的取值为“11-15”,表示每月的11~15日;使用除号(/)表示执行任务的间隔时间,如“*/2”表示每隔2分钟执行一次任务。