Linux就该这么学 笔记(三)Vim编辑器与Shell命令脚本

第四章 Vim编辑器与Shell命令脚本

1 Vim 文本编辑器

三种模式
  • 命令模式:控制光标移动,可对文本进行复制、粘贴、删除和查找等工作。
  • 输入模式:正常的文本录入。
  • 末行模式:保存或退出文档,以及设置编辑环境。
image-20230508110403451
命令模式
image-20230508110305919
末行模式
image-20230508110326033 image-20230508110340448
输入模式
  • 可以分别使用 a、i、o 这 3 个键从命令模式切换到输入模式。其中,a 键与 i 键分别是在光标后面一位和光标当前位置切换到输入模式,而 o 键则是在光标的下面再创建一个空行

2 编写Shell脚本

Shell脚本命令的两种工作方式
  • 交互式:用户每输入一条命令就立即执行。
  • 批处理:由用户事先编写好一个完整的 Shell 脚本,Shell 会一次性执行脚本 中诸多的命令。
简单的Shell脚本
[root@linuxprobe~]# vim example.sh
#!/bin/bash
#For Example BY linuxprobe.com
pwd
ls -al

第一行的脚本声明(#!)用来告诉系统使用哪种 Shell 解释器来执行该脚本;第二行的注释信息(#)是对脚本功能和
某些命令的介绍信息,使得自己或他人在日后看到这个脚本内容时,可以快速知道该脚本的
作用或一些警告信息;第三、四行的可执行语句也就是我们平时执行的 Linux 命令了。
  • 脚本运行方式

    • 用Bash 解释器命令直接运行 Shell 脚本文件

       bash example.sh
      
    • 通过输入完整路径的方式来执行(默认会因为权限不足而提示报错信息)

      [root@linuxprobe~]# ./example.sh
      bash: ./Example.sh: Permission denied
      [root@linuxprobe~]# chmod u+x example.sh
      [root@linuxprobe~]# ./example.sh
      
接受用户的参数
  • 变量参数

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

    • KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲对应的是总 共有几个参数,*对应的是所有位置的参数值

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

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

[root@linuxprobe~]# vim example.sh
#!/bin/bash
echo "当前脚本名称为$0"
echo "总共有$#个参数,分别是$*。"
echo "第 1 个参数为$1,第 5 个为$5。"
[root@linuxprobe~]# bash example.sh one two three four five six
当前脚本名称为 example.sh
总共有 6 个参数,分别是 one two three four five six。
第 1 个参数为 one,第 5 个为 five。
判断用户的参数
  • 条件表达式

    • Shell 脚本中的条 件测试语法可以判断表达式是否成立,若条件成立则返回数字 0,否则便返回非零值。
    • 条件表达式两边均应有一个空格。
    image-20230508111429130
    • 4种条件测试语句:文件测试语句、逻辑测试语句、整数值比较语句、字符串比较语句
  • 文件测试语句

    image-20230508111650630
    • 判断/etc/fstab 是否为一个目录类型的文件,然后通过 Shell 解释 器的内设$?变量显示上一条命令执行后的返回值。

      [root@linuxprobe~]# [ -d /etc/fstab ]
      [root@linuxprobe~]# echo $?
      1
      
      #来判断/etc/fstab 是否为一般文件,如果返回值为 0,则代表文件存在,且为一般文件
      [root@linuxprobe~]# [ -f /etc/fstab ]
      [root@linuxprobe~]# echo $?
      0
      
      #一次搞定 判断/dev/cdrom 文件是否存在,若存在则输出 Exist 字样
      [root@linuxprobe~]# [ -e /dev/cdrom ] && echo "Exist"
      Exist
      
  • 逻辑测试语句

    与(&&)、或(||)、非(!)

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

      [root@linuxprobe~]# echo $USER
      root
      [root@linuxprobe~]# [ $USER = root ] || echo "user"
      [root@linuxprobe~]# su - linuxprobe
      [linuxprobe@linuxprobe~]$ [ $USER = root ] || echo "user"
      user
      
    • 判断当前用户是否为一个非管理员的用户

      [linuxprobe@linuxprobe~]$ exit
      logout
      [root@linuxprobe~]# [ ! $USER = root ] || echo "administrator"
      administrator
      
      #叹号应该放到判断语句的前面,代表对整个的测试语句进行取反值操作,而不应该写成“$USER != root”,因为“!=”代表的是不等于符号(≠),尽管执行效果一样,但缺少了逻辑关系
      
  • 整数值比较语句

    image-20230508112304904
    • 题外话:awk命令:逐行读取文件数据进行处理

      [root@linuxprobe~]# free -m
      total used free shared buff/cache available
      Mem: 1966 1374 128 16 463 397
      Swap: 2047 66 1981
      [root@linuxprobe~]# free -m | grep Mem:
      Mem: 1966 1374 128 16 463 397
      [root@linuxprobe~]# free -m | grep Mem: | awk '{print $4}'
      128
      
      [root@linuxprobe~]# FreeMem=`free -m | grep Mem: | awk '{print $4}'`
      [root@linuxprobe~]# echo $FreeMem
      128
      
    • 使用整数运算符来判断内存可用量的值是否小于 1024,若小 于则会提示“Insufficient Memory”(内存不足)

      [root@linuxprobe~]# [ $FreeMem -lt 1024 ] && echo "Insufficient Memory"
      Insufficient Memory
      
  • 字符串测试语句

    image-20230508112616678

    • 判断 String 变量是否为空值,进而判断是否定义了这个变量

      [root@linuxprobe~]# [ -z $String ]
      [root@linuxprobe~]# echo $?
      0
      
    • 当用于保存当前语系的环境变量值 LANG 不是英语 (en.US)时,则会满足逻辑测试条件并输出“Not en.US”(非英语)

      [root@linuxprobe~]# echo $LANG
      en_US.UTF-8
      [root@linuxprobe~]# [ ! $LANG = "en.US" ] && echo "Not en.US"
      Not en.US
      

3 流程控制语句

if测试语句
image-20230508112859388
[root@linuxprobe~]# vim chkscore.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

[root@linuxprobe~]# bash chkscore.sh
Enter your score(0-100):88
88 is Excellent
[root@linuxprobe~]# bash chkscore.sh
Enter your score(0-100):80
80 is Pass

for条件循环语句
image-20230508113139224
  • 批量创建用户
#创建用户名称的列表文件 users.txt
[root@linuxprobe~]# vim users.txt
andy
barry
carl
duke
eric
george

#批量创建脚本
[root@linuxprobe~]# vim addusers.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 "$UNAME , Already exists"
	else
		useradd $UNAME &> /dev/null
		echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
		echo "$UNAME , Create success"
	fi
done

#id命令:会显示用户以及所属群组的实际与有效 ID,若两个 ID 相同,则仅显示实际 ID,若仅指定用户名称,则显示目前用户的 ID。
#/dev/null 是一个被称作 Linux 黑洞的文件,把输出信息重定向到这个文件等同于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁。由于已经将多余的信息通过输出重定向符转移到了/dev/null 黑洞文件中,因此在正常情况下屏幕窗口除了“用户账户创建成功”(Create success)的提示后不会有其他内容。

  • 测试主机是否在线(结合双分支if)

    #创建一个主机列表文件 ipaddrs.txt
    [root@linuxprobe~]# vim ipaddrs.txt
    149
    192.168.10.10
    192.168.10.11
    192.168.10.12
    
    #测试主机是否在线脚本
    [root@linuxprobe~]# vim CheckHosts.sh
    #!/bin/bash
    HLIST=$(cat~/ipaddrs.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.
    
    #“$(命令)”是一种完全类似于第 3 章的转义字符中反引号`命令`的 Shell 操作符,效果同样是执行括号或双引号括起来的字符串中的命令
    
    • Shell 脚本中的代码缩进格式会根据不同的语句而改变。这是由 Vim 编辑器自动完成的,用户无须进行额外操作(RHEL 7前的版本无此功能)
while条件循环语句
image-20230508113927655
case条件测试语句
image-20230508114410241
  • 判断输入字符类型

    [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~
    您输入的是 空格、功能键或其他控制字符。
    

4 计划任务服务程序

一次性计划任务(at命令)

如今晚 23:30 重启网站服务。一次性计划任务只执行一次,一般用于临时的工作需求。可以用 at 命令实现 这种功能,只需要写成“at 时间”的形式就行。如果想要查看已设置好但还未执行的一次性 计划任务,可以使用 at -l 命令;要想将其删除,可以使用“atrm 任务序号”

image-20230508114725806
  • 固定时间启动
#在今晚 23:30 自动重启网站(方式1)
[root@linuxprobe~]# at 23:30
warning: commands will be executed using /bin/sh
at> systemctl restart httpd
at> 此处请同时按下<Ctrl>+<d>组合键来结束编写计划任务
job 1 at Wed Oct 14 23:30:00 2020
[root@linuxprobe~]# at -l
1 Wed Oct 14 23:30:00 2020 a root

#在今晚 23:30 自动重启网站(方式2)
[root@linuxprobe~]# echo "systemctl restart httpd" | at 23:30
warning: commands will be executed using /bin/sh
job 2 at Wed Oct 14 23:30:00 2020
[root@linuxprobe~]# at -l
1 Wed Oct 14 23:30:00 2020 a root
2 Wed Oct 14 23:30:00 2020 a root

#使用 atrm 命令轻松删除其中一条
[root@linuxprobe~]# atrm 2
[root@linuxprobe~]# at -l
1 Wed Oct 14 23:30:00 2020 a root

  • 倒计时启动
    • 使用“at now +2 MINUTE”的方式进行操作,这表示 2 分钟(MINUTE)后 执行这个任务,也可以将其替代成小时(HOUR)、日(DAY)、月(MONTH)等词汇
#把计划任务写入 Shell 脚本中,当用户激活该脚本后再开始倒计时执行
[root@linuxprobe~]# at now +2 MINUTE
warning: commands will be executed using /bin/sh
at> systemctl restart httpd
at> 此处请同时按下<Ctrl>+<d>键来结束编写计划任务
job 3 at Wed Oct 14 22:50:00 2020
周期性计划任务(crontab命令)

如:每周一的凌晨 3:25 把/home/wwwroot 目录打包备份为 backup.tar.gz。使用crontab命令。

image-20230508115205284
  • crontab参数设置口诀:“分、时、日、月、星期 命令。” 需要注意的是,如果有些字段 没有被设置,则需要使用星号( )占位。

    image-20230508115330747
image-20230508115344084 image-20230508115353168
  • 在每周一、三、五的凌晨 3:25把/home/wwwroot 目录打包备份为 backup.tar.gz

    [root@linuxprobe~]# crontab -e
    no crontab for root - using an empty one
    crontab: installing new crontab
    [root@linuxprobe~]# crontab -l
    25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot
    
    • 多个时间段除了可以用逗号(,),还可以用减号(-)表示一段连续的时间周期如“12-15”, 则表示每月的 12~15 日,此外还可以用除号(/)表示执行任务的间隔时间(例如“*/2”表示每 隔 2 分钟执行一次任务)。
  • 注意事项

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

    • ⭐️尤其 需要注意的是,在 crond 服务的计划任务参数中,所有命令一定要用绝对路径的方式来写。如果不知道绝对路径,用 whereis 命令进行查询

      [root@linuxprobe~]# whereis rm
      rm: /usr/bin/rm /usr/share/man/man1/rm.1.gz /usr/share/man/man1p/rm.1p.gz
      [root@linuxprobe~]# crontab -e
      crontab: installing new crontab
      [root@linuxprobe~]# crontab -l
      25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot
      0 1 * * 1-5 /usr/bin/rm -rf /tmp/*
      
    • 在 crond 服务的配置参数中,一般会像 Shell 脚本那样以#号开头写上注释信息,这样 在日后回顾这段命令代码时可以快速了解其功能、需求以及编写人员等重要信息。

    • 计划任务中的“分”字段必须有数值,绝对不能为空或是*号,而“日”和“星期” 字段不能同时使用,否则就会发生冲突。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值