shell脚本的基本知识

shell

shell是解释器

shell 也是操作系统中的一个软件

它包在 linux 内核的外面,为用户和内核之间的交互提供了一个接口
系统中的命令用 shell 去解释shell 接收系统回应的输出并显示其到屏幕中
bash = GNU Bourne-Again Shell

脚本是一种解释型语言
用 shell 脚本保存执行动作
用脚本判定命令的执行条件
用脚本来实现动作的批量执行

系统中常用的的shell是bash



shell 脚本的执行
1.                sh script.sh
2.                source script.sh
                   . script.sh
3.                chmod +x script.sh
                   ./script.sh
脚本没有可执行权限:sh /mnt/hello.sh
有可执行权限:/mnt/hello.sh



名称:
通常以.sh 结尾
基本内容:
Author:开发者
Version:版本
Mail:邮箱
Date:时间
Description: 描述
除了以上基础内容,文件还必须以 #!/bin/bash 开始 ,其中 #!告诉系统后面的参数是用来执行文件的,/bin/bash执行文件,#!/bin/bash 是幻数,在脚本运行时先运行bash程序
当需要写注释时,以#开头




[root@client mnt]# vim /etc/vimrc

map <F4> ms:call WESTOS()<cr>'s                              #编辑以.sh结尾的文件按F4自动添加内容,可添加多次,注释该行前面添加“
func WESTOS ()
     call append(0,"##################################")
     call append(1,"# Author:        wwy".("             #" ))
     call append(2,"# Version:          ".("             #" ))
     call append(3,"# Mail:             ".("             #" ))
     call append(4,"# Date:          ".strftime("%Y-%m-%d").("      #" ))                     #.strftime自动显示当前时间,(年月日)
     call append(5,"# Description:      ".("             #" ))
     call append(6,"#                   ".("             #" ))
     call append(7,"##################################")
     call append(8,"   ")
     call append(9,"#!/bin/bash")
endfunc



[root@client mnt]# vim file.sh
按“F4”内容出现




shell 基本命令


1. diff


diff 命令
diff 命令是用来比较两个文件或目录的不同
diff [options] target1 target2
diff file1 file2
diff direcory1 directory2


diff 在比较文件过程中结果读取方式
[num1 , num2][a|c|d][num3,num4]
num1,num2 表示在第一个文件中的行数
a 表示添加 ----add
c 表示更改 ----change
d 表示删除 ----delete
< 表示第一个文件中的内容, > 表示第二个文件中的内容, --- 分割线
num3,num4 表示在第二个文件中的行数
2,4c2,4 表示改变第一个文件中的第二行和第四行才能匹配第二个文件中
的第二行和第四行


[root@client mnt]# vim file

westos
[root@client mnt]# vim file1

westos
linux
[root@client mnt]# diff file file1                                       #对比file1,file有什么不同
1a2                                                                                    #a:添加 第一个文件的第一行添加第二个文件的第二行的linux
> linux
[root@client mnt]# vim file

westos
linux
[root@client mnt]# diff file file1
2c2                                                                                    #c:更改 第一个文件的第二行hello改为第二个文件的第二行linux
< hello
---
> linux
[root@client mnt]# vim file1

westos
[root@client mnt]# diff file file1
2d1                                                                                  #d:删除 第一个文件的第二行删除hello
< hello

diff 在比较目录过程中结果的读取
Only in directroy/: filename
directory 表示在那个目录中
filename 表示在这个目录


diff 中常用的参数
-b 或 --ignore-space-change  不检查空格字符的不同
-B 或 --ignore-blank-lines  不检查空白行
-c  显示全部内文,并标出不同之处
-i 或 --ignore-case  不检查大小写的不同
-p :若比较的文件为 C 语言的程序码文件时,显示差异所在的函数名称;
-q 或 --brief :仅显示有无差异,不显示详细的信息
-r 或 --recursive :比较子目录中的文件
-u 以合并的方式来显示文件内容的不同

pacth

用于文件不同文件打布丁


[root@client mnt]# diff -u file file1                #生成补丁
--- file    2018-06-09 22:46:33.954202981 -0400
+++ file1    2018-06-09 22:47:08.005202981 -0400
@@ -1,2 +1 @@
 westos
-hello
[root@client mnt]# diff -u file file1 > file.pcth    #生成补丁并保存在file.path
[root@client mnt]# cat file.path
--- file    2018-06-09 22:46:33.954202981 -0400
+++ file1    2018-06-09 22:47:08.005202981 -0400
@@ -1,2 +1 @@
 westos
-hello


[root@client mnt]# yum install patch -y

[root@client mnt]# patch --help


Usage: patch [OPTION]... [ORIGFILE [PATCHFILE]]

[root@client mnt]# patch -b file file.path          #file加上补丁,如果不加-b,源文件将被覆盖,加-b生成源文件file.orig
patching file file
[root@client mnt]# ls
file  file1  file.orig  file.path


比较两个文件的不同


[root@client mnt]# mkdir linux
[root@client mnt]# mkdir unix
[root@client mnt]# touch linux/westos
[root@client mnt]# diff -r linux/  unix/
Only in linux/: westos


2.cut

cut 命令多用与字符截取
cut -d
指定分隔符
cut -f 1,7|1-7 指定截取的列
cut -c 1,4|1-4 指定截取的字符位置

[root@client mnt]# cut -d : -f 1 passwd                                            #指定;为分割符,截取第一列
[root@client mnt]# cut -d : -f 1,7 passwd                                         #截取第1列和第7列
[root@client mnt]# cut -d : -f 1-3 passwd                                         #截取1-3列
[root@client mnt]# cut -d : -f 3- passwd                                            #截取第三列以后
[root@client mnt]# cut -c 1-3 passwd                                               #截取1-3个字符
[root@client mnt]# cut -c 1,3 passwd                                                #截取第1个和第3个字符


执行 ip_show.sh                     显示当前主机的 ip 地址


ifconfig eth0 | awk -F " " '/inet\>/{print $2}'                      # awk:报告生成器,/inet\:过滤inet字符



[root@client mnt]# sh ip_show.sh
ip_show.sh: line 11: ifconfg: command not found
[root@client mnt]# sh -x ip_show.sh                              #-x:脚本运行过程
+ ifconfg eth0
ip_show.sh: line 11: ifconfg: command not found
+ awk -F ' ' '/inet\>/{print $2}'



&& 和 ||

&&:true
||:fault

&& true 用来执行条件成立后执行的命令
||    fault  用来执行条件不成立后执行的命令
例如:
ping -c1 -w1 172.25.254.111 && echo up
ping -c1 -w1 172.25.254.111 || echo up


测试:

[root@client mnt]# ping -c1 -w1 172.25.254.111 &> /dev/null && echo 172.25.254.111 is up || echo 172.25.254.111 is down
172.25.254.111 is up
[root@client mnt]# ping -c1 -w1 172.25.254.202 &> /dev/null && echo 172.25.254.202 is up || echo 172.25.254.202 is down
172.25.254.202 is down


练习1:编写vim ip_check.sh脚本,输入ip可以显示是否存在

[root@client mnt]# vim ip_check.sh

#!/bin/bash
ping -c1 -w1 $1 &> /dev/null &&{
       echo "$1 is up"
}||{
       echo "$1 is down"
}



[root@client mnt]# sh ip_check.sh 172.25.254.202

172.25.254.202 is up


3. sort

sort                 多用于字符排序

sort -c             显示统计个数

sort -n             纯数字排序
sort -r              倒序
sort -u             去掉重复数字
sort -o             输出到指定文件中
sort -t              指定分隔符
sort -k             指定要排序的列

测试:


[root@client mnt]# vim westos
[root@client mnt]# sort westos                                #排序                   

0
1
2
3
3
5
5
6
6
8
9
[root@client mnt]# vim westos
[root@client mnt]# sort westos

0
1
10
11
2
23
3
3
5
5
56
6
6
8
9
[root@client mnt]# sort -n westos                      #纯数字排序

0
1
2
3
3
5
5
6
6
8
9
10
11
23
56
[root@client mnt]# vim westos

56:0
4:23
3:11
10:3
9:0
8:5
6:1
2:5
5:3
6:2
6:1
2:0
3:43
3:2
1:4
5:2
6:1
6:0
7:8
8:7
8:2
[root@client mnt]# sort -t : -k 2 westos                       #指定:为分隔符,并且按第二列排序
2:0
56:0
6:0
9:0
6:1
6:1
6:1
3:11
3:2
5:2
6:2
8:2
4:23
10:3
5:3
1:4
3:43
2:5
8:5
8:7
7:8
[root@client mnt]# sort -t : -k 2 -n westos                     #指定:为分隔符,并且按第二列纯数字大小排序
2:0
56:0
6:0
9:0
6:1
6:1
6:1
3:2
5:2
6:2
8:2
10:3
5:3
1:4
2:5
8:5
8:7
7:8
3:11
4:23
3:43

[root@client mnt]# sort -rn westos                              #倒序
56
23
11
10
9
8
6
6
5
5
3
3
2
1
0

[root@client mnt]# sort -urn westos                             #去除重复数字按倒序排序
56
23
11
10
9
8
6
5
3
2
1
0


4. uniq


uniq          对重复字符做相应的处理
uniq -u       显示唯一的行
uniq -d       显示重复的行
uniq -c       每行显示一次并统计重复次数

测试:


[root@client mnt]# sort -n westos | uniq -c                 #数字排序并统计重复次数每行显示一次
      1 0
      1 1
      2 2
      1 3
      1 4
      2 5
      3 6
      1 7
      2 8
      1 9
      1 10
      1 11
      1 23
      1 43
      1 56
      1 87

[root@client mnt]# sort -n westos | uniq -d                 #数字排序并只显示重复数字
2
5
6
8
[root@client mnt]# sort -n westos | uniq -u                 #数字排序并且不显示多余的重复行
0
1
3
4
7
9
10
11
23
43
56
87


5. test


test 命令和 [] 等同
test "$A" == "$B" 等同 [ "$A" == "$B" ]
[ "$A" = "$B" ]                   
[ "$A" != "$B" ]
[ "$A" -eq "$B" ]                                   等于
[ "$A" -ne "$B" ]                                   不等于
[ "$A" -le "$B" ]                                    大于等于
[ "$A" -lt "$B" ]                                     大于
["$A" -ge "$B" ]                                   小于等于
["$A" -gt "$B" ]                                    小于
["$A" -ne "$B" -a "$A" -gt "$B" ]      且,同时成立
["$A" -ne "$B" -o "$A" -gt "$B" ]      或,只有一个成立
[-z "$A" ]                                             为空
[-n "$A" ]                                             不为空
["file1" -ef "file2" ]                               是否互为硬连接
["file1" -nt "file2" ]                               file1比file2更新
["file1" -ot "file2" ]                               file1比file2更老


测试:

test与[  ]

[root@client mnt]# a=1
[root@client mnt]# b=1
[root@client mnt]# test "$a" = "$b" && echo yes || echo no
yes
[root@client mnt]# b=2
[root@client mnt]# test "$a" = "$b" && echo yes || echo no
no
[root@client mnt]# [ "$a" = "$b" ] && echo yes || echo no
no
[root@client mnt]# c=1
[root@client mnt]# [ -n "$c" ]&& echo yes || echo no
yes


[-z "$A" ]                             为空
[-n "$A" ]                             不为空


[root@client mnt]# echo $c

[root@client mnt]# [ -z "$c" ]&& echo yes || echo no
yes
[root@client mnt]# [ -n "$c" ]&& echo yes || echo no
no

练习2:编写ip_check.sh脚本,运行时后面不加id会有提示


[root@client mnt]# vim ip_check.sh


[ -z "$1" ]  &&{
        echo please give me a ipaddress !!
        exit 1
}
ping -c1 -w1 $1 &> /dev/null &&{
       echo "$1 is up"
}||{
       echo "$1 is down"
}




[root@client mnt]# sh ip_check.sh

please give me a ipaddress !!
[root@client mnt]# sh ip_check.sh 172.25.254.2
172.25.254.2 is up


练习3:编写脚本 num_check.sh ,要求能测试一个数字是否在10以内

[root@client mnt]# vim num_check.sh

#!/bin/bash
[ -z "$1" ]&& {
    echo "please input a number after script!!"
    exit 1
}
[ "$1" -gt "0" -a "$1" -lt "10" ] && {
   echo "$1 is between 1 ~ 10"
}||{
   echo "$1 is not between 1 ~ 10"
}



[root@client mnt]# sh num_check.sh
please input a number after script!!
[root@client mnt]# sh num_check.sh 2
2 is between 1 ~ 10
[root@client mnt]# sh num_check.sh 27
27 is not between 1 ~ 10


["file1" -ef "file2" ]                 是否互为硬连接


[root@client mnt]# touch file
[root@client mnt]# ln /mnt/file /mnt/file1                        #将/mnt/file连接到/mnt/file1
[root@client mnt]# ll
total 0
-rw-r--r-- 2 root root 0 Jun 10 03:33 file
-rw-r--r-- 2 root root 0 Jun 10 03:33 file1
[root@client mnt]# ls -li                                                  #查看文件结点inode
total 0
8842674 -rw-r--r-- 2 root root 0 Jun 10 03:33 file
8842674 -rw-r--r-- 2 root root 0 Jun 10 03:33 file1
[root@client mnt]# [ "/mnt/file" -ef "/mnt/file1" ]&& echo yes ||echo no
yes
[root@client mnt]# [ "/mnt/file" -ef "/etc/passwd" ]&& echo yes ||echo no
no

["file1" -nt "file2" ]                               file1比file2更新
["file1" -ot "file2" ]                               file1比file2更老


[root@client mnt]# [ "/mnt/file" -ot "/mnt/file1" ]&& echo yes ||echo no
yes
[root@client mnt]# [ "/mnt/file" -nt "/mnt/file1" ]&& echo yes ||echo no
no


练习4:编写脚本 check_file.sh /mnt,要求能输出/mnt里最大的文件


[root@client mnt]# ls -Sl /mnt/ |grep -v total |awk -F " " 'NR==1{print $9}'


test测试文件类型


[-e "file" ]           是否存在
[-f "file" ]            是否为普通文件
[-L "file" ]           是否为软连接
[-S "file" ]           是否为套接子
[-b "file" ]           是否为块设备
[-d "file" ]           是否为目录
[-c "file" ]           是否为文字设备




[root@client mnt]# vim file.sh

#!/bin/bash
[ "$1" "/mnt/file" ] && echo yes || echo no


测试:

[root@client mnt]# rm -fr file
[root@client mnt]# sh file.sh -e
no
[root@client mnt]# touch file
[root@client mnt]# sh file.sh -e
yes


[root@client mnt]# sh file.sh -L
no
[root@client mnt]# rm -fr file
[root@client mnt]# touch westos
[root@client mnt]# ln -s westos file                                                            #建立软连接
[root@client mnt]# ll
total 4
lrwxrwxrwx 1 root root   6 Jun 10 03:52 file -> westos
-rw-r--r-- 1 root root 340 Jun 10 03:44 file.sh
-rw-r--r-- 1 root root   0 Jun 10 03:51 westos
[root@client mnt]# sh file.sh -L
yes



[root@client mnt]# sh file.sh -S
no
[root@client mnt]# yum install mariadb-server -y
[root@client mnt]# systemctl start mariadb
[root@client mnt]# ls /var/lib/mysql
aria_log.00000001  ibdata1      ib_logfile1  mysql.sock          test
aria_log_control   ib_logfile0  mysql        performance_schema
[root@client mnt]# rsync -D /var/lib/mysql/mysql.sock /mnt/file
[root@client mnt]# ls
file  file.sh  westos
[root@client mnt]# sh file.sh -S
yes


[root@client mnt]# sh file.sh -b
no
[root@client mnt]# rm -fr file
[root@client mnt]# rsync -D /dev/vdb /mnt/file
[root@client mnt]# ls
file  file.sh  westos
[root@client mnt]# sh file.sh -b
yes



[root@client mnt]# sh file.sh -d
no
[root@client mnt]# rm -fr file
[root@client mnt]# mkdir file
[root@client mnt]# sh file.sh -d
yes



[root@client mnt]# sh file.sh -c
no
[root@client mnt]# rm -fr file
[root@client mnt]# rsync -D /dev/pts/ /mnt/file
skipping directory .
[root@client mnt]# rsync -D /dev/pts/1 /mnt/file
[root@client mnt]# ll
total 4
crw------- 1 root root 136, 1 Jun 10 04:02 file
-rw-r--r-- 1 root root    340 Jun 10 03:44 file.sh
-rw-r--r-- 1 root root      0 Jun 10 03:51 westos
[root@client mnt]# sh file.sh -c
yes


练习5:编写脚本,要求输入文件名称可以判断文件是否存在,若存在请说明该文件是什么格式


#!/bin/bash

[ -z "$1" ]&&{
     echo "please input a file name after script!!"
     exit 1
}
[ -e "$1" ]||{
     echo "$1 is not exist!!"
     exit 0
}
[ -f "$1" ]&&{
     echo "$1 is a common file"
     exit 0
}
[ -L "$1" ]&&{
     echo "$1 is a link"
     exit 0
}
[ -S "$1" ]&&{
     echo "$1 is a socket"
     exit 0
}
[ -b "$1" ]&&{
     echo "$1 is a block"
     exit 0
}
[ -d "$1" ]&&{
     echo "$1 is a directory"
     exit 0
}
 [ -c "$1" ]&&{
     echo "$1 is a text"
     exit 0
}






5. tr    大小写字母转换


[root@client mnt]# vim test.sh

#!/bin/bash

[ "$1" = "hello" ] && {
   echo yes
}||{
   echo no
}




[root@client mnt]# vim test.sh
[root@client mnt]# sh test.sh hello                         #输入hello显示yes
yes
[root@client mnt]# sh test.sh HELLO                    #输入HELLO显示no
no


[root@client mnt]# vim test.sh


WORD=$(echo $1 | tr 'A-Z' 'a-z')                          #将所有的大写转换为小写
[ "$WORD" = "hello" ] && {
   echo yes
}||{
   echo no
}


[root@client mnt]# sh test.sh hello
yes
[root@client mnt]# sh test.sh HELLO
yes













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值