欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux 下 Shell 脚本的常用命令

程序员文章站 2022-03-09 11:39:43
...

Linux 下 Shell 脚本的常用命令

  • shell
    shell也是操作系统中的一个软件,它包在 linux 内核的外面,为用户和内核之间的交互提供了一个接口,系统中的命令用 shell 去解释 shell 接收系统回应的输出并显示其到屏幕上;
    可以将 Shell 终端解释器当作人与计算机硬件之间的“翻译官”它作为用户与 Linux 系统内部的通信媒介,除了能够支持各种变量与参数外,还提供了诸如循环、分支等高级编程语言才有的控制结构特性。
  • shell 脚本
    shell script (程序化脚本) 是利用 shell 的功能所写的一个“程序 (program)”,这个程序是使用纯文本文件,将一些 shell 的语法与指令(含外部指令)写在里面, 搭配正则表达式、管线命令与数据流重导向等功能,以达到我们所想要的处理目的。

1. shell 脚本的格式和最简单的脚本编写

  • shell 脚本的格式
    Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将 .sh 后缀加上,以表示是一个脚本文件。
    shell 脚本中一般会出现三种不同的元素:
    第一行的脚本声明(#!)用来告诉系统使用哪种 Shell 解释器来执行该脚本;
    第二行的注释信息(#)是对脚本功能和某些命令的介绍信息,使得自己或他人在日后看到这个脚本内容时,可以快速知道该脚本的作用或一些警告信息;
    第三、四行的可执行语句也就是我们平时执行的 Linux 命令了。

编写一个最简单的脚本

 [root@client ~]# mkdir /mybin   #建立一个目录用来存放自己编写的脚本,方便管理
 [root@client ~]# cd /mybin/
 [root@client mybin]# vim hello.sh   #编写脚本,最好以 .sh 结尾
 内容如下:
 1 #!/bin/bash    #幻数来告诉系统使用哪种 Shell 解释器来执行该脚本
 2  # Use for print hello to the screen  #描述脚本的作用等
 3 echo hello shell scripts!!!   #显示“hello shell scripts”到屏幕
 [root@client mybin]# sh /mybin/hello.sh  #执行脚本
 hello shell scripts!!!      #显示的内容
 脚本建立完成后,有两种调用方式,上面那种 sh +脚本绝对路径的方式可以执行
 还有一种直接输入脚本的绝对路径进行执行,前提是脚本文件有执行权限
 [root@client mybin]# ll  /mybin/hello.sh    #查看脚本权限
 -rw-r--r--. 1 root root 28 Jun 13 03:18 hello.sh  #无可执行权限
 [root@client mybin]# /mybin/hello.sh    #无法通过绝对路径进行执行
 -bash: /mybin/hello.sh: Permission denied  
 [root@client mybin]# chmod +x /mybin/hello.sh   #加上可执行权限 
 [root@client mybin]# /mybin/hello.sh   #执行脚本
 hello shell scripts!!!

执行如下:
建立脚本存放目录并新建脚本文件
Linux 下 Shell 脚本的常用命令
编辑内容如下
Linux 下 Shell 脚本的常用命令
修改脚本权限,以绝对路径执行脚本
Linux 下 Shell 脚本的常用命令
在添加脚本时,每次都手动添加爱脚本的描述信息,显得过于繁琐。我们可以通过编辑 vim 的配置文件,实现对描述信息的自动添加

 编辑 /etc/vimrc vim 的配置文件
 在最后添加如下内容:
 66 "map <F4> ms:call Bleach()<cr>'s      
     # "用来注释上述语句意味着,当在 vim 编辑器中进行编辑时,通过 F4 键实现对 
     如下 Bleach() 内容的调用                                          
 67 autocmd BufNewFile *.sh exec ":call Bleach()"
     # 上述语句意味着,当通过 vim 编辑任何以 .sh 结尾的文件时,都会在文件开头
     实现对如下 Bleach() 内容的调用
 68 func Bleach()
 69         call append(0,"##########################################")
 70         call append(1,"# Author:       ZR                       #")
 71         call append(2,"# Version:                               #")
 72         call append(3,"# Mail:         ZR.bleach.com            #")
 73         call append(4,"# Date:         ".strftime("%Y-%m-%d").("                   #"))
 74         call append(5,"# Description:                           #")
 75         call append(6,"#                                        #")
 76         call append(7,"##########################################")
 77         call append(8," ")
 78 endfunc

执行如下:
配置文件内容:
Linux 下 Shell 脚本的常用命令
编辑新文件,自动添加描述信息
Linux 下 Shell 脚本的常用命令

2. shell 脚本的的常用命令

2.1 diff

  • diff是用在比对两个文件之间的差异的,并且是以行为单位来比对的。一般是用在 ASCII 纯文本文件的比对上。由于是以行为比对的单位,因此 diff 通常是用在同一文件(或软件)的新旧版本差异上对比上,能够借由 diff 创建的分析档,以处理补丁(patch)功能的文件
[root@client ~]# diff  将两个文件或目录的内容进行比较
   -b:忽略一行当中,仅有多个空白的差异(例如"about me""about    me"视为相同
   -B:忽略空白行的差异。
   -i:忽略大小写的不同。
   -u:显示文件信息的不同
 显示内容的含义
 [num1,num2][a|b|c][num3,num4]
 num1,num2    #表示在第一个文件中的行数
 num3,num4    #表示在第二个文件中的行数
 a             #表示添加---add
 c             #表示更改---change
 d             #表示删除---delete
 <             #表示第一个文件中的内容,
 >             #表示第二个文件中的内容
 ---           #分割线
 如新建两个文件 test1 test2
 test1 内容为:第一行 hello;第二行 linux
 test2 内容为:第一行 hello;第二行 unix
 用 diff 比较两文件内容的不同
 [root@client mnt]# diff test1 test2  #比较文件内容的不同
 2c2            #左边文件的第二行被取代(c)成右边文件的第二行,两个文件内容就会相同
 < linux        #左边文件第二行内容
 ---            #分割线
 > unix         #右边文件第二行内容
 [root@client mnt]# diff -u test1 test2 
 --- test1  2018-06-13 19:52:02.256718234 -0400
     #test1 test2 文件的信息
 +++ test2  2018-06-13 19:52:20.267718234 -0400
 @@ -1,2 +1,2 @@     
 #新旧文件要修改数据的界定范围,旧文件在 1-2 行,新文件在 1-2 行
  hello    
 -linux      #删除linux
 +unix       #加上unix

执行如下:
test1 内容
Linux 下 Shell 脚本的常用命令
test2 内容
Linux 下 Shell 脚本的常用命令
diff test1 test2
Linux 下 Shell 脚本的常用命令
diff -u test1 test2
Linux 下 Shell 脚本的常用命令
diff 还可以用来比较目录

 [root@client mnt]# diff -r /etc/rc0.d/ /etc/rc5.d/
                  # -r:递归地比较找到的任何子目录
 Only in /etc/rc0.d/: K03rhnsd       #此文件只在/etc/rc0.d 中有          
 Only in /etc/rc0.d/: K79iprdump
 Only in /etc/rc0.d/: K80iprinit
 Only in /etc/rc0.d/: K80iprupdate
 Only in /etc/rc0.d/: K90network
 Only in /etc/rc5.d/: S10network     #此文件只在/etc/rc5.d 中有
 Only in /etc/rc5.d/: S20iprinit
 Only in /etc/rc5.d/: S20iprupdate
 Only in /etc/rc5.d/: S21iprdump
 Only in /etc/rc5.d/: S97rhnsd
 这样就比较出了两目录内容的不同

执行如下:
用 ls 命令查看指定目录
Linux 下 Shell 脚本的常用命令
用 diff 比较两目录的差异
Linux 下 Shell 脚本的常用命令

2.2 patch

  • patch
    这个指令常与 diff 配合使用,diff 可以用来分辨两个版本之间的差异,举例来说上述我们所创建的 test1 及 test2 之间就是两个不同版本的文件。如果要“升级”呢?就是“将旧的文件升级成为新的文件”时,应该要怎么做?就是“先比较先旧版本的差异,并将差异档制作成为补丁文件,再由补丁文件更新旧文件”即可。也就是我们俗称的打补丁
 [root@client ~]# yum install patch -y  #首先安装 patch 
 [root@client ~]# patch
  -p :后面可以接“取消几层目录”的意思。
  -R :代表还原,将新的文件还原成原来旧的版本
  -b :备份文件。在修补文件时,重命名或复制原始文件,而不是删除它 
 [root@client mnt]# diff -u test1 test2 > test.patch
                  #生成补丁文件 test.patch 
 [root@client mnt]# patch -b test1 test.patch 
 patching file test1          #修补文件file1

执行如下:
生成补丁文件 test.patch
Linux 下 Shell 脚本的常用命令
对文件进行修补,-b 保存源文件,可看到生成了 .orig 源文件,
Linux 下 Shell 脚本的常用命令

2.3 cut

cut 命令用于按“列”提取文本字符,格式为“cut [参数] 文本”

 [aaa@qq.com ~]# cut -d '分隔字符' -f 设置需要看的列数
 [aaa@qq.com ~]# cut -c 字符区间用于排列整齐的讯息
 选项与参数:
 -d :后面接分隔字符。与 -f 一起使用;
 -f :依据 -d 的分隔字符将一段讯息分区成为数段,用 -f 取出第几段的意思;
 -c :以字符 (characters) 的单位取出固定字符区间;
 示例:截取主机的 ip 地址
 [aaa@qq.com ~]# ifconfig | head -n 2 | tail -n 1 | cut -d " " -f 10
 #截取主机的 ip 地址,以‘空格’为分隔符,截取第 10 列

执行如下:
Linux 下 Shell 脚本的常用命令

2.4 &&,||

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

示例如下:

 编写脚本,执行 ping 命令,当 ping 同对应 ip 时显示,该 ip up,
 当 ping 不通时,显示该 ip down
 脚本编写如下
  10 #!/bin/bash            # 进行 ping 命令
  11 ping -c1 -w1 $1 && {  
  12         echo $1 up     # 可以 ping 通,显示 up
  13 } || {
  14         echo $1 down   # ping 不通,显示 down
  15 }

执行如下:
编写脚本
Linux 下 Shell 脚本的常用命令
执行脚本
Linux 下 Shell 脚本的常用命令

2.5 sort

多用于字符排序

 [aaa@qq.com  ~]$ sort [选项] [file or stdin]
 选项与参数:
 -f :忽略大小写的差异,例如 A 与 a 视为编码相同; 
 -b :忽略最前面的空白字符部分;
 -M :以月份的名字来排序,例如 JAN,DEC 等等的排序方法;
 -n :使用“纯数字”进行排序(默认是以文字体态来排序的);
 -r :反向排序;
 -u :就是 uniq,相同的数据中,仅出现一行代表;
 -t :分隔符号,默认是用 [tab] 键来分隔;
 -k :以那个区间 (field) 来进行排序的意思
 如下:
 [aaa@qq.com ~]# sort -nt ":" -k 3 /mnt/passwd
 以数字排序方式,以“:”为分隔符,对 /mnt/passwd 的第三列内容进行排序

示例如下:
取 /etc/passwd 文件的前十行内容进行测试
执行如下:
将 /etc/passwd 文件的前十行内容重定义到 /mnt/passwd
Linux 下 Shell 脚本的常用命令
用sort 及进行排序
Linux 下 Shell 脚本的常用命令
sort -nt “:” -k 3 /mnt/passwd
以数字排序方式,以“:”为分隔符,对 /mnt/passwd 的第三列内容进行排序
Linux 下 Shell 脚本的常用命令

2.6 uniq 对重复字符作相应处理,一般与排序进行连用

 [aaa@qq.com ~]# uniq 
   -u 显示唯一的以行
   -d 显示重复的行
   -c 每行显示一次并统计重复次数

示例如下:
编辑建立 /mnt/uniqtest 文件
Linux 下 Shell 脚本的常用命令
通过 uniq 进行操作
Linux 下 Shell 脚本的常用命令

2.7 test

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

test 命令和 [ ] 等同
[ "a" == "b"] 等同于 test a = b  

1. 判定字串的数据

判定方式 含义
test -z string 判定字串是否为 0 若 string 为空字串,则为 true
test -n string 判定字串是否非为 0 若 string 为空字串,则为 false -n 亦可省略
test str1 == str2 判定 str1 是否等于 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false

判定字符串是否为空
Linux 下 Shell 脚本的常用命令
对字符串进行比较
Linux 下 Shell 脚本的常用命令
2. 多重条件判定,例如: test -r filename -a -x filename

判定方式 含义
-a (and)两状况同时成立!例如 test -r file -a -x file则 file 同时具有 r 与 x 权限时,才回传 true。
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。

3.关于两个整数之间的判定,例如 test n1 -eq n2

判定方式 含义
-eq 两数值相等 (equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于等于 n2 (greater than or equal)
-le n1 小于等于 n2 (less than or equal)
 示例:编辑脚本,将输入的数字与 10 比较,若在 1-10 之间
 输出:num is between 1 - 10
 否则输出:num is not between 1 - 10
 编辑如下:
 10 #!/bin/bash
 11 [ -z  "$1" ] && {                 #判断输入是否为空,若为空,则输出如下
 12         echo "Please input a number after scripts."
 13         exit 1
 14 }
 15 [ "$1" -gt "0" -a "$1" -lt "10" ] && {   #若输入大于 0 小于 10 ,输出如下
 16         echo "$1" is between 1 - 10 
 17 } || { 
 18         echo "$1" is not between 1 - 10  #否则输出如左所示
 19 }
 20 

执行如下:
编辑脚本
Linux 下 Shell 脚本的常用命令
执行脚本
Linux 下 Shell 脚本的常用命令

4. 两个文件之间的比较,如:test file1 -nt file2

判定方式 含义
-nt (newer than)判断 file1 是否比 file2 新
-ot (older than)判断 file1 是否比 file2 旧
-ef 判断 file1 与 file2 是否为同一文件,可用在判断hard link(硬链接) 的判定上。主要意义在判定,两个文件是否均指向同一个 inode

示例如下:
一前一后建立两文件进行比较
Linux 下 Shell 脚本的常用命令

5.关于某个文件名的“文件类型”判断,如 test -e filename 表示存在否

判定方式 含义
-e 该“文件名”是否存在
-f 该“文件名”是否存在且为文件(file)
-d 该“文件名”是否存在且为目录(directory)
-b 该“文件名”是否存在且为一个 块设备(block device) 设备
-c 该“文件名”是否存在且为一个 字符串(character device) 设备
-S 该“文件名”是否存在且为一个 套接子(Socket) 文件
-L 该“文件名”是否存在且为一个 链接(软链接)文件
 建立一个脚本文件用来测试文件是否存及其属性
 内容如下:
 10 #!/bin/bash
 11 [ -z "$1" ] && {       #判断输入是否为空,若为空,则输出如下
 12         echo "Please input the file name after script"
            exit 1
 13 }
 14 [ -e "$1" ] || {       #判断文件是否存在
 15         echo "$1" is not exist!!
 16 }
 17 [ -L "$1" ] && {       #判断文件是否是连接
 18         echo "$1" is a link
 19         exit 0
 20 }
 21 [ -f "$1" ] && {       #判断文件是否为普通文件
 22         echo "$1" is a regular file
 23 }
 24 [ -d "$1" ] && {       #判断文件是否目录
 25         echo "$1" is a directory
 26 }
 27 [ -b "$1" ] && {       #判断文件是否为设备文件系统 
 28         echo "$1" is a block special
 29 }
 30 [ -c "$1" ] && {       #判断文件是否为字符设备
 31         echo "$1" is a character special
 32 }
 33 [ -S "$1" ] && {       #判断文件是否为套接字
 34         echo "$1" is a socket
 35 }

执行如下:
编辑脚本
Linux 下 Shell 脚本的常用命令
测试如下
Linux 下 Shell 脚本的常用命令

2.8 tr

tr 可以用来删除一段讯息当中的文字,或者是进行文字讯息的替换

 示例一:将 w 输出的讯息中,所有的小写变成大写字符:
 [aaa@qq.com ~]# w | tr 'a-z' 'A-Z'

执行如下:
Linux 下 Shell 脚本的常用命令

 示例二:编写脚本,当
 编写脚本将输入的单词与 HELLO 进行比较,若为 小写字符的 hello 将输出 yes 否则输出no
 其中若输入的为大写字符,将大写字符转化为小写字符

 #!/bin/bash
 WORD=`echo $1 | tr 'A-Z' 'a-z'`     #定义WORD 将其大写字符转化为小写字符
 [ "$WORD" = "hello" ]&& {           #将输入的单词与 hello 比较
         echo yes                    #若相同,输出 yes
 }|| {   
         echo no                     #若不同,输出 no
 }

执行如下:
编辑脚本
Linux 下 Shell 脚本的常用命令
执行脚本进行测试
Linux 下 Shell 脚本的常用命令