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