vim编辑器与shell命令脚本

vim与shell

编写 Shell 脚本

Shell 脚本命令的工作方式有两种:交互式和批处理

  • 交互式(Interactive):用户每输入一条命令就立即执行。

  • 批处理(Batch):由用户事先编写好一个完整的 Shell 脚本,Shell 会一次性执行脚本

中诸多的命令。

查看 SHELL 变量可以发现当前系统已经默认使用 Bash 作为命令行终端解释器了:

hwj@hwj-virtual-machine:~$ echo $SHELL
/bin/bash

如果想查看当前所在工作路径并列出当前目录下所有的文件及属性信息,实现这 个功能的脚本应该类似于下面这样:

hwj@hwj-virtual-machine:~$vim example.sh
#!/bin/bash
#For Example BY linuxprobe.com
pwd
ls -al
hwj@hwj-virtual-machine:~$bash example.sh

除了上面用 bash 解释器命令直接运行 Shell 脚本文件外,第二种运行脚本程序的方法是通过输入完整路径的方式来执行

hwj@hwj-virtual-machine:~$ chmod u+x example.sh
hwj@hwj-virtual-machine:~$ ./example.sh
接收用户的参数

其实,Linux 系统中的 Shell 脚本语言早就考虑到了这些,已经内设了用于接收参数的变量,变量之间可以使用空格间隔

$0 对应的是当前 Shell 脚本程序的名称

$#对应的是总共有几个参数

$*对应的是所有位置的参数值

$?对应的是显示上一次命令的执行返回值

而$1,$2、$3……则分别对应着第 N 个位置的参数值

判断用户的参数

按照测试对象来划分,条件测试语句可以分为 4 种:

  • 文件测试语句;

  • 逻辑测试语句;

  • 整数值比较语句;

  • 字符串比较语句。

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

下面使用文件测试语句来判断/etc/fstab 是否为一个目录类型的文件,然后通过 Shell 解释 器的内设$?变量显示上一条命令执行后的返回值。如果返回值为 0,则目录存在;如果返回值 为非零的值,则意味着目录不存在

hwj@hwj-virtual-machine:~$  [ -d /etc/fstab ]
hwj@hwj-virtual-machine:~$ echo $?
1

再使用文件测试语句来判断/etc/fstab 是否为一般文件,如果返回值为 0,则代表文件存在,且为一般文件:

hwj@hwj-virtual-machine:~$  [ -f /etc/fstab ]
hwj@hwj-virtual-machine:~$ echo $?
0

在 Shell 终端中逻辑“与”的运算符号是&&,它表示当前面的命令执行成功后才会执行它后面的命令

因此可以用来判断/dev/cdrom 文件是否存在,若存在则输出 Exist 字样。

hwj@hwj-virtual-machine:~$ [ -e /dev/cdrom ] && echo "Exist"
Exist

还有逻辑“或”,它在 Linux 系统中的运算符号为||,表示当前面的命令执行失败后才会执行它后面的命令

因此可以用来结合系统环境变量 USER 来判断当前登[ 录的用户是否为非管理员身份:

hwj@hwj-virtual-machine:~$  [ $USER = root ] || echo "user"
user
可用的整数比较运算符
运算符作用
-eq是否等于
-ne是否不等于
-gt是否大于
-lt是否小于
-le是否等于或小于
-ge是否等于或大于
[root@linuxprobe ~]# [ 10 -gt 10 ]
[root@linuxprobe ~]# echo $?
1

free 命令,它可以用来获取当前系统正在使用及可用的内存量信息。

先使用 free -m 命令查看内存使用量情况(单位为 MB),然后通过 grep Mem:命令过滤 出剩余内存量的行,再用 awk '{print $4}'命令只保留第四列,最后用 FreeMem=语句的方式把语句内执行的结果赋值给变量。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jvths5Lf-1574012202212)(C:\Users\kris\AppData\Roaming\Typora\typora-user-images\image-20191118005349968.png)]

[root@linuxprobe ~]# free -m
total used free shared buffers cached
Mem: 1826 1244 582 9 1 413
-/+ buffers/cache: 830 996
Swap: 2047 0 2047
[root@linuxprobe ~]# free -m | grep Mem:
Mem: 1826 1244 582 9
[root@linuxprobe ~]# free -m | grep Mem: | awk '{print $4}'
582
[root@linuxprobe ~]# FreeMem=`free -m | grep Mem: | awk '{print $4}'`
[root@linuxprobe ~]# echo $FreeMem
582
常见的字符串比较运算符
运算符作用
=比较字符串内容是否相同
!=比较字符串内容是否不同
-z判断字符串内容是否为空
流程控制语句

if 条件测试语句

if 条件语句的双分支结构由 if、then、else、fi 关键词组成

hwj@hwj-virtual-machine:~$ vim chksore.sh
#!/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 Pass"
else
echo "$GRADE is Fail"
fi
hwj@hwj-virtual-machine:~$ bash chksore.sh
Enter your score(0-100):88
88 is Excellent
hwj@hwj-virtual-machine:~$ bash chksore.sh
Enter your score(0-100):60
60 is Fail
for 条件循环语句
hwj@hwj-virtual-machine:~$ vim users.txt
andy
barry
carl
duke
eric
george
hwj@hwj-virtual-machine:~$ vim e.sh
#!/bin/bash
read -p "Enter The Users Password : " PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "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 failure"
fi
fi
done

hwj@hwj-virtual-machine:~$ bash e.sh
Enter The Users Password : linuxprobe
andy , Create success
barry , Create success
carl , Create success
duke , Create success
eric , Create success
george , Create success
[root@linuxprobe ~]# tail -6 /etc/passwd
andy:x:1001:1001::/home/andy:/bin/bash
barry:x:1002:1002::/home/barry:/bin/bash
carl:x:1003:1003::/home/carl:/bin/bash
duke:x:1004:1004::/home/duke:/bin/bash
eric:x:1005:1005::/home/eric:/bin/bash
george:x:1006:1006::/home/george:/bin/bash

尝试让脚本从文本中自动读取主机列表,然后自动逐个测试这些主机是否在线。

[root@linuxprobe ~]# vim ipadds.txt
192.168.10.10
192.168.10.11
192.168.10.12
[root@linuxprobe ~]# vim CheckHosts.sh
#!/bin/bash
HLIST=$(cat ~/ipadds.txt)
for IP in $HLIST
do
ping -c 3 -i 0.2 -W 3 $IP &> /dev/null
if [ $? -eq 0 ] ; then
echo "Host $IP is On-line."
else
echo "Host $IP is Off-line."
fi
done
[root@linuxprobe ~]# ./CheckHosts.sh
Host 192.168.10.10 is On-line.
Host 192.168.10.11 is Off-line.
Host 192.168.10.12 is Off-line.
while 条件循环语句
image-20191118011722618
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品实际价格为 0-999 之间,猜猜看是多少?"
while true
do
read -p "请输入您猜测的价格数目:" INT
let TIMES++
if [ $INT -eq $PRICE ] ; then
echo "恭喜您答对了,实际价格是 $PRICE"
echo "您总共猜 g $TIMES 次"
exit 0
elif [ $INT -gt $PRICE ] ; then
echo "太高了!"
else
echo "太低了!"
fi
done
商品实际价格为 0-999 之间,猜猜看是多少?
请输入您猜测的价格数目:500
太低了!
请输入您猜测的价格数目:800
太高了!
请输入您猜测的价格数目:650
太低了!
请输入您猜测的价格数目:720
太高了!
请输入您猜测的价格数目:690
太低了!
请输入您猜测的价格数目:700
太高了!
请输入您猜测的价格数目:695
太高了!
请输入您猜测的价格数目:692
太高了!
请输入您猜测的价格数目:691
恭喜您答对了,实际价格是 691
您总共猜测了 9 次
case 条件测试语句
image-20191118012023851
[root@linuxprobe ~]# vim Checkkeys.sh
#!/bin/bash
read -p "请输入一个字符,并按 Enter 键确认:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是 字母。"
;;
[0-9])
echo "您输入的是 数字。"
;;
*)
echo "您输入的是 空格、功能键或其他控制字符。"
esac
[root@linuxprobe ~]# bash Checkkeys.sh
请输入一个字符,并按 Enter 键确认:6
您输入的是 数字。
[root@linuxprobe ~]# bash Checkkeys.sh
请输入一个字符,并按 Enter 键确认:p
您输入的是 字母。
[root@linuxprobe ~]# bash Checkkeys.sh
请输入一个字符,并按 Enter 键确认:^[[15~
您输入的是 空格、功能键或其他控制字符。
计划任务服务程序

计划任务分为一次性计划任务与长期性计划任务,大家可以按照如下方式理解。

  • 一次性计划任务:今晚 11 点 30 分开启网站服务。
  • 长期性计划任务:每周一的凌晨 3 点 25 分把/home/wwwroot 目录打包备份为backup.tar.gz。

一次性计划任务只执行一次,一般用于满足临时的工作需求。我们可以用 at 命令实现这种功能,只需要写成“at 时间”的形式就可以。

如果想要查看已设置好但还未执行的一次性计划任务,可以使用“at -l”命令

要想将其删除,可以用“atrm 任务序号”

在使用 at 命令来设置一次性计划任务时,默认采用的是交互式方法。

例如,使用下述命令将系统设置为在今晚 23:30 分自动重启网站服务。

[root@linuxprobe ~]# at 23:30
at > systemctl restart httpd
at > 此处请同时按下 Ctrl + D 组合键来结束编写计划任务
job 3 at Mon Apr 27 23:30:00 2017
[root@linuxprobe ~]# at -l
3 Mon Apr 27 23:30:00 2017 a root

可以把前面学习的管道符(任意门) 放到两条命令之间,让 at 命令接收前面 echo 命令的输出信息,以达到通过非交互式的方式创 建计划一次性任务的目的。

[root@linuxprobe ~]# echo "systemctl restart httpd" | at 23:30
job 4 at Mon Apr 27 23:30:00 2017
[root@linuxprobe ~]# at -l 3 Mon Apr 27 23:30:00 2017 a root
4 Mon Apr 27 23:30:00 2017 a root

如果我们不小心设置了两个一次性计划任务,可以使用下面的命令轻松删除其中一个:

[root@linuxprobe ~]# atrm 3
[root@linuxprobe ~]# at -l 4 Mon Apr 27 23:30:00 2017 a root

如果我们希望 Linux 系统能够周期性地、有规律地执行某些具体的任务,那么 Linux 系统中默认启用的 crond 服务简直再适合不过了

创建、编辑计划任务的命令为“crontab -e”

查看当前计划任务的命令为“crontab -l”

删除某条计划任务的命令为“crontab -r”。

另外,如果您是以管理员的身份登录的系统,还可以在 crontab 命令中加上-u 参数来编辑他人计划任务。

“分、时、日、月、星期 命令”。这是使用 crond 服务设置任务的参数格式(其格式见表 4-6)

image-20191118012829944 image-20191118012904666

假设在每周一、三、五的凌晨 3 点 25 分,都需要使用 tar 命令把某个网站的数据目录进行打包处理,使其作为一个备份文件。我们可以使用 crontab -e 命令来创建计划任务。为自己创建计划任务无需使用-u 参数,具体的实现效果的参数如 crontab -l 命令结果所示:

[root@linuxprobe ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@linuxprobe ~]# crontab -l

除了用逗号(,)来分别表示多个时间段,例如“8,9,12”表示 8 月、9 月 和 12 月。还可以用减号(-)来表示一段连续的时间周期(例如字段“日”的取值为“12-15”, 则表示每月的 12~15 日)以及用号/)表示执行任务的间隔时间(例如“/2”表示每隔 2 分钟执行一次任务

如果在 crond 服务中需要同时包含多条计划任务的命令语句,应每行仅写一条。

在 crond 服务的计划任务参数中,所有命令一定要用绝对路径的方式来写,如果不知道绝对路径,请用 whereis 命令进行查询

91118012829944" style=“zoom:150%;” />

image-20191118012904666

假设在每周一、三、五的凌晨 3 点 25 分,都需要使用 tar 命令把某个网站的数据目录进行打包处理,使其作为一个备份文件。我们可以使用 crontab -e 命令来创建计划任务。为自己创建计划任务无需使用-u 参数,具体的实现效果的参数如 crontab -l 命令结果所示:

[root@linuxprobe ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@linuxprobe ~]# crontab -l

除了用逗号(,)来分别表示多个时间段,例如“8,9,12”表示 8 月、9 月 和 12 月。还可以用减号(-)来表示一段连续的时间周期(例如字段“日”的取值为“12-15”, 则表示每月的 12~15 日)以及用号/)表示执行任务的间隔时间(例如“/2”表示每隔 2 分钟执行一次任务

如果在 crond 服务中需要同时包含多条计划任务的命令语句,应每行仅写一条。

在 crond 服务的计划任务参数中,所有命令一定要用绝对路径的方式来写,如果不知道绝对路径,请用 whereis 命令进行查询

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值