shell基本用法二及文件查找和打包解压缩

shell 脚本语言的基本用法二

1.1 算术运算

shell 支持算术运算,但只支持整数,不支持小数

bash中的算术运算符号:

+
-
*
/
%   #取模,即取余数,示例:9%4=1,5%3=2
**  #乘方

注意:乘法符号有些场景中需要转义。

算术运算:

let var=算术表达式
((var=算术表达式)) 和上面等价
var=$[算术表达式]
var=$((算术表达式))
var=$(expr arg1 arg2 arg3 ...)
declare –i var = 数值
echo '算术表达式' | bc

范例:

#let算数运算
[root@centos7 ~]# n=10
[root@centos7 ~]# m=20
[root@centos7 ~]# sum=$n+$m     ##当成字符处理
[root@centos7 ~]# echo $sum
10+20
[root@centos7 ~]# let sum=n+m   ##let 算数运算,变量前可以不用加$
[root@centos7 ~]# echo $sum
30

#expr
[root@centos7 ~]# expr 5/3      ##符号与数值中间需要有空格
5/3
[root@centos7 ~]# expr 5 / 3    ##只能取整
1
[root@centos7 ~]# expr 5 * 2    ##乘号需要转义
expr: syntax error
[root@centos7 ~]# expr 5 \* 2
10

#declare -i
[root@centos7 ~]# i=10
[root@centos7 ~]# j=20
[root@centos7 ~]# declare -i result=i*j
[root@centos7 ~]# echo $result
200

#shell中的计算结果都是取整,可以计算时声明小数点几位。
[root@centos7 ~]# echo "20/3"|bc
6
[root@centos7 ~]# echo "scale=3;20/3"|bc
6.666

内建的随机数生成器变量:

$RANDOM 取值范围:0-32767

范例:

#生成 0 - 49 之间随机数
echo $[$RANDOM%50]
#生成 1 - 50 之间随机数
echo $[$RANDOM%50+1]
[root@centos7 ~]# echo $[RANDOM%50+1]
33
[root@centos7 ~]# echo $((RANDOM%50+1))
21
[root@centos7 ~]# ((result=RANDOM%50+1));echo $result
25
[root@centos7 ~]# let result=$RANDOM%50+1;echo $result
16

#随机字体颜色,颜色数值是31~37,对7取模,得到0~6的余数,然后加31即可。
[root@centos7 ~]# echo -e "\033[1;$[RANDOM%7+31]hello\033[0m"
hello

增强型赋值:

+=      i+=10   相当于 i=i+10
-=      i-=j    相当于 i=i-j
*=
/=
%=

范例:

[root@centos7 ~]# let i=10*2
[root@centos7 ~]# echo $i
20
[root@centos7 ~]# ((j=i+10))
[root@centos7 ~]# echo $j
30

范例:

#自增,自减
let var+=1
let var++
let var-=1
let var--

#i++和++i
[root@centos7 ~]# i=10;let j=i++;echo $j $i     #i先赋值给j,再自加1
10 11
[root@centos7 ~]# i=10;let j=++i;echo $j $i
11 11

#i--和--i
[root@centos7 ~]# i=10;let j=--i;echo $j $i
9 9
[root@centos7 ~]# i=10;let j=i--;echo $j $i
10 9

#let var+=1
[root@centos7 ~]# i=10;let l+=i;echo $i $l  #l+=i,即l=l+i(初始为0)后赋值l,l=0+10
10 10
[root@centos7 ~]# i=10;let l+=i;echo $i $l  #l=l+i,即l=10+10,再赋值给l,就是20
10 20
[root@centos7 ~]# i=10;let l+=i;echo $i $l  #同上
10 30

#let var-=1
[root@centos7 ~]# i=100;let m-=i;echo $i $m     #m-=i,即m=m-i,赋值给m,m=0-100
100 -100
[root@centos7 ~]# i=100;let m-=i;echo $i $m     #m=m-i,m=-100-100,赋值给m就是-200
100 -200
[root@centos7 ~]# i=100;let m-=i;echo $i $m     #m=-200-100
100 -300

范例:

#自加后自赋值
[root@centos7 ~]# i=10
[root@centos7 ~]# let i+=20     #相当于let i=i+20
[root@centos7 ~]# echo $i
30
[root@centos7 ~]# j=20
[root@centos7 ~]# let i*=j
[root@centos7 ~]# echo $i
600

实例1:今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?

[root@centos7 scripts]# vim chook_rabbit.sh
#!/bin/bash
HEAD=$1
FOOT=$2
RABBIT=$[($FOOT-$HEAD-$HEAD)/2]
CHOOK=$(($HEAD-$RABBIT))
echo RABBIT: $RABBIT
echo CHOOK: $CHOOK

[root@centos7 scripts]# bash chook_rabbit.sh 35 94
RABBIT: 12
CHOOK: 23

实例2:算出所有人的年龄总和

#初始化文件
[root@centos7 data]#cat nianling.txt
xiaoming=20
xiaohong=18
xiaoqiang=22
[root@centos7 data]# cut -d= -f2 nianling.txt|tr -s '\n' +
20+18+22+
[root@centos7 data]# cut -d= -f2 nianling.txt|tr -s '\n' +|grep -Eo '.*[0-9]'|bc
60
[root@centos7 data]# cat nianling.txt |cut -d= -f2|tr -s '\n' +|cut -d+ -f1,2,3|bc
60
[root@centos7 data]# grep -Eo "[0-9]+" nianling.txt |tr -s '\n' + |grep -Eo ".*[0-9]"|bc
60

1.2 逻辑运算

1.2.1 与:&:

和0相与,结果为0,和1相与,结果保留原值。也就是:都为1,结果才为1,否则为0。

1 与 1 = 1
1 与 0 = 0
0 与 1 = 0
0 与 0 = 0

1.2.2 或:|:

和1相或,结果为1,和0相或,结果保留原值。也就是:都为0,结果才为0,否则为1。

1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0

1.2.3 非:!

! 1 = 0     # ! true
! 0 = 1     # ! false

范例:

[root@centos7 scripts]# true
[root@centos7 scripts]# echo $?
0
[root@centos7 scripts]# false
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# ! true
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# ! false
[root@centos7 scripts]# echo $?
0

1.2.4 异或:^

异或的两个值,相同为假,不同为真。

两个数字X、Y异或得到结果Z,Z再和任意两者之一X异或,将得出另一个值Y;同理,Z和Y异或得到X。

1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0

范例:

#交换两个数的位置
#方法1:借助第三个变量
[root@centos7 scripts]# x=10;y=20;tmp=$x;x=$y;y=$tmp;echo x=$x y=$y
x=20 y=10
#方法2:异或
[root@centos7 scripts]# x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo $x $y
20 10
#首先x=xy的异或即10和20的异或为30;然后y就是30和20的异或得10;再然后x就是30和10的异或得20,这样就x和y就交换了。

1.2.5 短路运算

  • 短路与

    CMD1 短路与 CMD2

    第一个CMD1结果为真 (1),第二个CMD2必须要参与运算,才能得到最终的结果;

    第一个CMD1结果为假 (0),总的结果必定为0,因此不需要执行CMD2。

  • 短路或

    CMD1 短路或 CMD2

    第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2;

    第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果。

1.3 条件测试命令

条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成。

  • 若真,则状态码变量 $? 返回0
  • 若假,则状态码变量 $? 返回1

条件测试命令

test EXPRESSION
[ EXPRESSION ]      #和test 等价,建议使用 [ ]
[[ EXPRESSION ]]    #可以使用正则表达式
注意:EXPRESSION前后必须有空白字符

1.3.1 变量测试

#定义变量之前,可以通过-v或-R选项来判断此变量是否被定义过,避免对后续程序产生干扰。
[ -v NAME ]     #判断 NAME 变量是否定义,以及变量值是否为空
[ -R NAME ]     #判断 NAME 变量是否定义并且是名称引用,bash 4.4的新特性(centos8)

范例:

# -v选项  判断变量是否定义
[root@centos7 scripts]# unset name1
[root@centos7 scripts]# test -v name1
[root@centos7 scripts]# echo $?             ##没有定义,返回值为假
1
[root@centos7 scripts]# name1=100
[root@centos7 scripts]# test -v name1
[root@centos7 scripts]# echo $?             ##已定义,返回值为真
0

[root@centos7 scripts]# test -v name2
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# name2=          ##虽然定义变量值为空,但也为真
[root@centos7 scripts]# test -v name2
[root@centos7 scripts]# echo $?
0
[root@centos7 scripts]# set |grep name2
name2=

#[]等价于test;但要注意[ -v NAME ]需要空格,否则会报错误。
[root@centos7 ~]# [-v name]
-bash: [-v: command not found
[root@centos7 ~]# [ -v name ]
[root@centos7 ~]# echo $?
1

1.3.2 数值测试

arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,-lt, -le, -gt, or -ge.

-eq     #是否等于
-ne     #是否不等于
-gt     #是否大于
-ge     #是否大于等于
-lt     #是否小于
-le     #是否小于等于

范例:

[root@centos7 ~]#i=10
[root@centos7 ~]#j=8
[root@centos7 ~]#[ $i -lt $j ]
[root@centos7 ~]#echo $?
1
[root@centos7 ~]#[ $i -gt $j ]
[root@centos7 ~]#echo $?
0
[root@centos7 ~]#[ i -gt j ]                ##不能省略$,而且里面的值也必须是数字,不能是字符
-bash: [: i: integer expression expected

[root@centos7 ~]# i=10
[root@centos7 ~]# j=a                       ##同样,数字也不能和字符比较
[root@centos7 ~]# [ $i -lt $j ]
-bash: [: a: integer expression expected

1.3.3 字符串测试

1)test和[ ]的用法
-z STRING               #字符串是否为空,没定义或空为真,不空为假
-n STRING               #字符串是否不空,不空为真,空为假
   STRING               #同上
STRING1 = STRING2       #是否等于,注意 = 前后有空格
STRING1 != STRING2      #是否不等于
>                       #ascii码是否大于ascii码
<                       #是否小于

2)[[  ]]    #双中括号的用法,建议,当使用正则表达式或通配符使用,一般情况使用 [ ]
==                      #左侧字符串是否和右侧的PATTERN相同
                            #注意:此表达式用于[[ ]]中,PATTERN为通配符
!=                      #左侧字符串是否和右侧的PATTERN不同
=~                      #左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
                            #注意: 此表达式用于[[ ]]中;扩展的正则表达式

范例:

#-z
[root@centos7 ~]# unset name
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [ -z $name ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# name=
[root@centos7 ~]# [ -z $name ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# name=''
[root@centos7 ~]# [ -z $name ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# name=' '
[root@centos7 ~]# [ -z $name ]          ##变量未加""
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [ -z "$name" ]        ##变量加上""
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# name=1
[root@centos7 ~]# [ -z $name ]
[root@centos7 ~]# echo $?
1

#-n STRING或STRING
[root@centos7 ~]# name=1
[root@centos7 ~]# [ $name ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# unset name
[root@centos7 ~]# [ $name ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# name=
[root@centos7 ~]# [ $name ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# name=''
[root@centos7 ~]# [ $name ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# name=' '
[root@centos7 ~]# [ $name ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [ "$name" ]
[root@centos7 ~]# echo $?
0

# =和!=
[root@centos7 ~]# title1=ceo
[root@centos7 ~]# title2=cto
[root@centos7 ~]# [ $title1 = $title2 ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [ $title1 != $title2 ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# title1=cto
[root@centos7 ~]# [ $title1 = $title2 ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [ $title1 != $title2 ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [ $title1!=$title2 ]      ##比较前后都要有空格
[root@centos7 ~]# echo $?
0

#[]中的STRING变量,最好加上双引号,即"STRING",变量是字符串时,会报错。

范例:在比较字符串时,建议变量放在""中

[root@centos7 ~]# NAME="I love linux"
[root@centos7 ~]# [ $NAME ]
-bash: [: love: binary operator expected
[root@centos7 ~]# [ "$NAME" ]
[root@centos7 ~]# echo $?
0

[root@centos7 ~]# [ $NAME ]             ##不加"",相当于把变量I love linux直接放在[]中执行了
[root@centos7 ~]# [ I love linux ]
-bash: [: love: binary operator expected

#如果变量里是一条命令
[root@centos7 ~]# NAME="cat /etc/redhat-release"
[root@centos7 ~]# [ $NAME ]
-bash: [: cat: unary operator expected      ##应为一元运算符
##变量中是数学运算
[root@centos7 ~]# NAME="10 -lt 20"
[root@centos7 ~]# [ $NAME ]             ##执行的是[ 10 -lt 20 ]
[root@centos7 ~]# echo $?
0

范例:

#通配符
[root@centos7 ~]# File=test.log
[root@centos7 ~]# [[ "$File" == *.log ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [[ "$File" == *.txt ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [[ "$File" != *.txt ]]
[root@centos7 ~]# echo $?
0

#正则表达式,变量最好加""
[root@centos7 ~]# [[ "$File" =~ .txt ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [[ "$File" =~ \.log$ ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# N=100
[root@centos7 ~]# [[ "$N" =~ ^[0-9]+$ ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# N=Magedu10
[root@centos7 ~]# [[ "$N" =~ ^[0-9]+$ ]]
[root@centos7 ~]# echo $?
1

#IP地址匹配
[root@centos7 ~]# IP=1.2.3.4
[root@centos7 ~]# [[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]  #这样表述ip地址不严谨,超出255的范围了
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# IP=999.300.555.333
[root@centos7 ~]# [[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]  #超出范围的都能匹配上
[root@centos7 ~]# echo $?
0

##.未转义,表示任意一个字符
[root@centos7 ~]# IP=257.326h444.898
[root@centos7 ~]# [[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$  ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$  ]]  ##.未转义,表示任意一个字符
[root@centos7 ~]# echo $?
0

[root@centos7 ~]# IP=25m32d33.88
[root@centos7 ~]# [[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$  ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$  ]]     
[root@centos7 ~]# echo $?
1

root@centos7 ~]# IP=1.2.3.4567      ##最后一位超出了3位数的范围
[root@centos7 ~]# [[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]
[root@centos7 ~]# echo $?
1

#通配符
[root@centos7 ~]# Name="I love linux"
[root@centos7 ~]# [[ "$N" == linux ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# Name="I love linux"
[root@centos7 ~]# [[ "$N" == *linux* ]]
[root@centos7 ~]# echo $?
0

[root@centos7 ~]# N="linux1"
[root@centos7 ~]# [[ "$N" == linux* ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [[ "$N" == "linux*" ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [[ "$N" == linux\* ]]
[root@centos7 ~]# echo $?
1

[root@centos7 ~]# N="linux*"
[root@centos7 ~]# [[ "$N" == linux\* ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [[ "$N" == "linux*" ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [[ "$N" == linux* ]]
[root@centos7 ~]# echo $?
0
#结论:[[ == ]] == 右侧的 * 做为通配符,不要加"",只想做为*, 需要加""或转义

范例:匹配IP地址

#把IP地址限定在255的范围内
0-9:[0-9]
10-99:[1-9][0-9]    ##前两项可以合并为[1-9]?[0-9],这样会匹配上0
100-199:1[0-9]{2}
#200-255:2[0-5]{2};这样尾数只能是[0-5],没有[6-9]
200-249:2[0-4][0-9]
250-255:25[0-5]

[root@centos7 ~]# IP=0.0.0.0
[root@centos7 ~]# [[ "$IP" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@centos7 ~]# echo $?
0

[root@centos7 ~]# IP=0.255.33.255
[root@centos7 ~]# [[ "$IP" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# IP=25.32.33.254
[root@centos7 ~]# [[ "$IP" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# IP=25.32.33.256
[root@centos7 ~]# [[ "$IP" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# IP=25.444.33.255
[root@centos7 ~]# [[ "$IP" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@centos7 ~]# echo $?
1
[root@centos8 ~]#IP=999.300.555.333
[root@centos8 ~]#[[ "$IP" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@centos8 ~]#echo $?
1

1.3.4 文件测试

存在性测试

-a FILE:同 -e
-e FILE:文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件

范例:

#判断是否为字符文件
[root@centos7 ~]# [ -b /dev/zero ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# [ -c /dev/zero ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# ll /dev/zero
crw-rw-rw- 1 root root 1, 5 Jan  5 20:04 /dev/zero

#判断文件是否存在
[root@centos7 ~]# [ -a /etc/nologin ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# ! [ -a /etc/nologin ]     ##取反,把!放在[]里面也可以
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [ ! -a /etc/nologin ]     ##结果同上
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# ll /etc/nologin
ls: cannot access /etc/nologin: No such file or directory

#判断是否是目录
[root@centos7 ~]# [ -d /etc ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# ll -d /etc
drwxr-xr-x. 77 root root 8192 Jan  5 20:05 /etc

[root@centos7 ~]# [ -d /etc/issue ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# ll /etc/issue
-rw-r--r-- 1 root root 23 Apr  8  2020 /etc/issue

#判断是否为链接文件
[root@centos7 ~]# [ -L /bin ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [ -L /bin/ ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# ll /bin       ##显示目录信息
lrwxrwxrwx. 1 root root 7 Jul  7  2019 /bin -> usr/bin
[root@centos7 ~]# ll /bin/      ##显示目录中的文件信息    
total 357748
-rwxr-xr-x  1 root root       41488 Aug 20  2019 [
-rwxr-xr-x  1 root root      107848 Apr  2  2020 a2p
-rwxr-xr-x  1 root root       29104 May 12  2020 addr2line
-rwxr-xr-x  1 root root          29 Apr  1  2020 alias

##判断的是软链接指向的文件类型
[root@centos7 ~]# [ -f /etc/redhat-release ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# ll /etc/redhat-release
lrwxrwxrwx 1 root root 14 May 19  2020 /etc/redhat-release -> centos-release

文件权限测试:

-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限

注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

范例:

#-x测试
[root@centos7 scripts]# [ -x systeminfo.sh ]
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# chmod +x systeminfo.sh
[root@centos7 scripts]# [ -x systeminfo.sh ]
[root@centos7 scripts]# echo $?
0

[root@centos7 ~]# [ -w /etc/shadow ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# [ -x /etc/shadow ]
[root@centos7 ~]# echo $?
1

#-r测试
[root@centos7 scripts]# touch file
[root@centos7 scripts]# ll file
-rw-r--r-- 1 root root 0 Dec 28 14:04 file
[root@centos7 scripts]# chmod 0 file
[root@centos7 scripts]# ll file
---------- 1 root root 0 Dec 28 14:04 file
[root@centos7 scripts]# [ -x file ]
[root@centos7 scripts]# echo $?
1

##判断的是文件真实的权限,因为root是所有者,对file文件可读写,所以为真。
[root@centos7 scripts]# [ -r file ]
[root@centos7 scripts]# echo $?
0
[root@centos7 scripts]# [ -w file ]
[root@centos7 scripts]# echo $?
0
[root@centos7 scripts]# echo hello >file
[root@centos7 scripts]# cat file
hello

#chattr锁定文件
[root@centos7 ~]# [ -w test.txt ]
[root@centos7 ~]# echo $?
0
[root@centos7 ~]# chattr +i test.txt
[root@centos7 ~]# lsattr test.txt
----i-------------- test.txt
[root@centos7 ~]# [ -w test.txt ]
[root@centos7 ~]# echo $?
1
[root@centos7 ~]# chattr -i test.txt
[root@centos7 ~]# [ -w test.txt ]
[root@centos7 ~]# echo $?
0

1.4 关于 () 和 {}

(CMD1;CMD2;...)和 { CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行。

  • ( list ) 会开启子shell,并且可以继承括号外的变量值,当list中变量赋值及内部命令执行后,不影响后续的环境。

  • { list; } 不会启子shell,在当前shell中运行,会影响当前shell环境。

范例:() 和 {}

#1、()
[root@centos7 ~]# name=mage;(echo name1:$name;name=wang;echo name2:$name);echo name3:$name
name1:mage
name2:wang
name3:mage
#因为小括号会开启一个子进程,但可以继承外面的变量,所以name1为mage;
#小括号里name又赋值wang,所以name2为wang;
#小括号执行完毕,括号里的变量不能传递给父进程,所以name3还是mage。

#umask
[root@centos7 ~]# (umask 666;umask);umask
0666
0022

[root@centos7 ~]#umask
0022
[root@centos7 ~]# (umask 66;touch file)
[root@centos7 ~]# ll file
-rw------- 1 root root 0 Dec 28 14:48 file
[root@centos7 ~]#umask
0022

#()会开启子shell
[root@centos7 ~]# echo $BASHPID
23892
[root@centos7 ~]# ( echo $BASHPID;sleep 100 )
24472
[root@centos7 ~]# pstree -p
├─sshd(944)─┬─sshd(23879)───bash(23892)───bash(24472)───sleep(24473)

#2、{}在当前shell中运行,影响后续环境。
[root@centos7 ~]# name=mage;{ echo name1=$name;name=wang;echo name2=$name; };echo name3=$name
name1=mage
name2=wang
name3=wang

#{}开头要有空格,结尾可有可无,但结尾必须有;
[root@centos7 ~]# name=mage;{ echo name1=$name;name=wang;echo name2=$name;};echo name3=$name
name1=mage
name2=wang
name3=wang
[root@centos7 ~]# name=mage;{echo name1=$name;name=wang;echo name2=$name; };echo name3=$name
-bash: syntax error near unexpected token `}'
[root@centos7 ~]# name=mage;{echo name1=$name;name=wang;echo name2=$name;};echo name3=$name
-bash: syntax error near unexpected token `}'
[root@centos7 ~]# name=mage;{ echo name1=$name;name=wang;echo name2=$name };echo name3=$name
> ;
-bash: syntax error near unexpected token `;'

#{ } 不会开启子shell
[root@centos7 ~]# echo $BASHPID
23892
[root@centos7 ~]# { echo $BASHPID;sleep 100; }
23892

#3)目录比较
[root@centos7 ~]# ( cd /scripts; ls )
file  systeminfo.sh
[root@centos7 ~]# pwd
/root
[root@centos7 ~]# { cd /scripts; ls; }
file  systeminfo.sh
[root@centos7 scripts]# pwd
/scripts

1.5 组合测试条件

1.5.1 第一种方式 [ ]

[ EXPRESSION1 -a EXPRESSION2 ]      #并且,EXPRESSION1和EXPRESSION2都是真,结果才为真
[ EXPRESSION1 -o EXPRESSION2 ]      #或者,EXPRESSION1和EXPRESSION2只要有一个真,结果就为真
[ ! EXPRESSION ]                    #取反

说明: -a 和 -o 需要使用测试命令进行,只能用在[]中,[[ ]] 不支持

范例:

#-a与
[root@centos7 scripts]# ll test.sh
-rw-r--r-- 1 root root 0 Dec 28 15:16 test.sh
[root@centos7 scripts]# FILE="test.sh"
[root@centos7 scripts]# [ -f $FILE -a -x $FILE ]
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# chmod +x test.sh
[root@centos7 scripts]# [ -f $FILE -a -x $FILE ]
[root@centos7 scripts]# echo $?
0
#-o或
[root@centos7 scripts]# [ -f $FILE -o -x $FILE ]
[root@centos7 scripts]# echo $?
0

[root@centos7 scripts]# chmod -x test.sh        ##取消执行权限
[root@centos7 scripts]# ll test.sh
-rw-r--r-- 1 root root 0 Dec 28 15:16 test.sh
[root@centos7 scripts]# [ -x $FILE ]            ##不是执行文件
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# [ -f $FILE -o -x $FILE ]    ##-o或判断
[root@centos7 scripts]# echo $?
0

#!非
[root@centos7 scripts]# [ ! -x $FILE ]
[root@centos7 scripts]# echo $?
0
[root@centos7 scripts]# ! [ -x $FILE ]
[root@centos7 scripts]# echo $?
0

1.5.2 第二种方式 [[ ]]

COMMAND1 && COMMAND2    #并且,短路与,代表条件性的AND THEN
                        #如果COMMAND1 成功,将执行COMMAND2,否则将不执行COMMAND2
COMMAND1 || COMMAND2    #或者,短路或,代表条件性的OR ELSE
                        #如果COMMAND1 成功,将不执行COMMAND2,否则将执行COMMAND2
! COMMAND               #非,取反

范例:轮盘赌

[root@centos7 ~]#[ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "click"
click

范例:

[root@centos7 scripts]# test "A" = "B" && echo "Strings are equal"
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# [ "A" = "B" ] && echo "Strings are equal"
[root@centos7 scripts]# echo $?
1

[root@centos7 scripts]# test "A"="B" && echo "Strings are equal"    ##字符串比较=前后有空格,连在一起就是一个字符串了
Strings are equal
[root@centos7 scripts]# [ "A"="B" ] && echo "Strings are equal"
Strings are equal
[root@centos7 scripts]# [ "A" = "B" ] && echo "Strings are equal"
[root@centos7 scripts]# echo $?
1

#-eq等是数值比较,要对变量赋值
[root@centos7 scripts]# test "A" -eq "B" && echo "Strings are equal"
-bash: test: A: integer expression expected
[root@centos7 scripts]# [ "A" -eq "B" ] && echo "Strings are equal"
-bash: [: A: integer expression expected
[root@centos7 scripts]# [ "$A" -eq "$B" ] && echo "Strings are equal"
-bash: [: : integer expression expected
[root@centos7 scripts]# A=10
[root@centos7 scripts]# B=20
[root@centos7 scripts]# [ "$A" -eq "$B" ] && echo "Strings are equal"
[root@centos7 scripts]# echo $?
1

[root@centos7 scripts]# [ "" -eq "" ] && echo "Strings are equal"
-bash: [: : integer expression expected
[root@centos7 scripts]# [  -eq  ] && echo "Strings are equal"
Strings are equal

###其他范例:
[root@centos7 scripts]# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/issue
\S
Kernel \r on an \m

[root@centos7 scripts]# [ -z "$HOSTNAME" -o "$HOSTNAME" = "localhost.localdomain" ] && hostname www.magedu.com
[root@centos7 scripts]# echo $?
1
[root@centos7 scripts]# echo $HOSTNAME
centos7.6

##判断用户是否存在,不存在创建用户
[root@centos7 scripts]# id wang     ##wang用户存在
uid=2007(wang) gid=2007(wang) groups=2007(wang),2024(g1)
[root@centos7 scripts]# id wang &> /dev/null || useradd wang    ##用户存在,就不执行useradd,不存在就add用户
[root@centos7 scripts]# echo $?
0
[root@centos7 scripts]# id zhang    ##zhang用户不存在
id: zhang: no such user
[root@centos7 scripts]# id zhang &> /dev/null || useradd zhang
[root@centos7 scripts]# id zhang
uid=2011(zhang) gid=2011(zhang) groups=2011(zhang)

[root@centos7 scripts]# id wange &> /dev/null || echo 'no such user'
no such user
[root@centos7 scripts]# grep -q no_such_user /etc/passwd || echo 'no such user'
no such user

范例:

[root@centos7 scripts]# ll
-rw-r--r-- 1 root root 0 Dec 28 10:47 systeminfo.sh
[root@centos7 scripts]# FILE=systeminfo.sh; [ -f "$FILE" ] && [[ "$FILE" =~ .*\.sh$ ]] && chmod +x $FILE
[root@centos7 scripts]# ll
-rwxr-xr-x 1 root root 0 Dec 28 10:47 systeminfo.sh

范例:&& 和 || 组合使用

##判断ip地址是否能ping通
[root@centos7 ~]# hostname -I
192.168.209.11
[root@centos7 scripts]# IP=192.168.209.111;ping -c1 -W1 $IP &> /dev/null && echo "$IP is up" ||echo "$IP is down"
192.168.209.111 is up
[root@centos7 scripts]# IP=192.168.209.112;ping -c1 -W1 $IP &> /dev/null && echo "$IP is up" ||echo "$IP is down"
192.168.209.112 is down

## &&和||组合时的前后比较
[root@centos7 scripts]# NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist"
wang is exist
[root@centos7 scripts]# NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist"
wange is not exist
[root@centos7 scripts]# NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" ||echo "$NAME is not exist"
wange is not exist
[root@centos7 scripts]# NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" ||echo "$NAME is not exist"
wang is exist
[root@centos7 scripts]# NAME=wang; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist"
wang is exist
[root@centos7 scripts]# NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist"
wange is not exist
wange is exist
#结论:如果&& 和 || 混合使用,&& 要在前,|| 放在后

#创建用户的实例
[root@centos7 scripts]# NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" ||(useradd $NAME;echo "$NAME is created")
wang is exist           ###wang用户已存在

[root@centos7 scripts]# NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" ||useradd $NAME
[root@centos7 scripts]# id wange                        ###虽然创建了wange,但没有提示信息
uid=2012(wange) gid=2012(wange) groups=2012(wange)

[root@centos7 scripts]# NAME=wanggege; id $NAME &> /dev/null && echo "$NAME is exist" ||(useradd $NAME;echo "$NAME is created")
wanggege is created                     ###增加了创建成功的提示信息
[root@centos7 scripts]# id wanggege
uid=2013(wanggege) gid=2013(wanggege) groups=2013(wanggege)

范例:磁盘空间的判断

[root@centos8 ~]#cat /data/script40/disk_check.sh
#!/bin/bash
WARNING=80
SPACE_USED=`df|grep '^/dev/sd'|tr -s ' ' %|cut -d% -f5|sort -nr|head -1`
[ "$SPACE_USED" -ge $WARNING ] && echo "disk used is $SPACE_USED,will be full"
| mail -s diskwaring root

范例:磁盘空间和Inode号的检查脚本

[root@centos8 scripts]#cat disk_check.sh        ##王老师加了发送邮件
#!/bin/bash
WARNING=80
SPACE_USED=`df | grep '^/dev/sd'|grep -oE '[0-9]+%'|tr -d %| sort -nr|head -1`
INODE_USED=`df -i | grep '^/dev/sd'|grep -oE '[0-9]+%'|tr -d %| sort -nr|head
-1`
[ "$SPACE_USED" -gt $WARNING -o "$INODE_USED" -gt $WARNING ] && echo "DISK
USED:$SPACE_USED%, INODE_USED:$INODE_USED,will be full" | mail -s "DISK Warning"
[email protected] 

##编写脚本,测试
#1)查看磁盘和节点号
[root@centos7 scripts]# df -h|grep '/dev/sd'
/dev/sda3        20G  1.1G   19G   6% /
/dev/sda1       497M  225M  273M  46% /boot
[root@centos7 scripts]# df -i|grep '/dev/sd'
/dev/sda3      10485760  26800 10458960    1% /
/dev/sda1        256000 200326    55674   79% /boot
#2)编写脚本,只判断磁盘或节点号是否超过80%,显示提示信息,但不发送邮件
[root@centos7 scripts]# cat disk_check.sh
#!/bin/bash
WARNING=80
DISK_USED=`df|grep '^/dev/sd'|grep -Eo '[0-9]+%'|tr -d %|sort -nr |head -1`
INODE_USED=`df -i |grep '^/dev/sd'|tr -s " " %|cut -d% -f5|sort -nr |head -1`
[ "$DISK_USED" -gt $WARNING -o "$INODE_USED" -gt $WARNING ] && echo -e "WARNING!!!\nDisk used: $DISK_USED%\nInode used: $INODE_USED%" || echo -e "Disk used: $DISK_USED%\nInode used: $INODE_USED%"
#3)测试
[root@centos7 scripts]# chmod a+x disk_check.sh
[root@centos7 scripts]# . disk_check.sh
Disk used: 46%
Inode used: 79%
[root@centos7 scripts]# touch /boot/file{1..10000}.f
[root@centos7 scripts]# . disk_check.sh
WARNING!!!
Disk used: 47%
Inode used: 83%

#进一步优化,加上颜色
[root@centos7 scripts]# cat color.sh
RED="echo -e \033[1;31m"
GREEN="echo -e \e[1;32m"
END="\033[0m"
[root@centos7 scripts]# cat disk_check.sh
#!/bin/bash
. /scripts/color.sh
WARNING=80
DISK_USED=`df|grep '^/dev/sd'|grep -Eo '[0-9]+%'|tr -d %|sort -nr |head -1`
INODE_USED=`df -i |grep '^/dev/sd'|tr -s " " %|cut -d% -f5|sort -nr |head -1`
[ "$DISK_USED" -gt $WARNING -o "$INODE_USED" -gt $WARNING ] && $RED"WARNING!!!\nDisk used: $DISK_USED%\nInode used: $INODE_USED%$END" || $GREEN"Disk used: $DISK_USED%\nInode used: $INODE_USED%$END"
[root@centos7 scripts]# . disk_check.sh
WARNING!!!
Disk used: 47%
Inode used: 83%
[root@centos7 scripts]# rm /boot/file* -rf
[root@centos7 scripts]# . disk_check.sh
Disk used: 25%
Inode used: 1%

练习:
1、编写脚本 argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数。

[root@centos7 scripts]# vi argsnum.sh
#!/bin/bash
[ $# -lt 1 ] &&  { echo "请输入至少一个文件";exit; } || echo "空白行数 `grep ^$ $1|wc -l`"

[root@centos7 scripts]# bash argsnum.sh
请输入至少一个文件
[root@centos7 scripts]# bash argsnum.sh /etc/issue /etc/yum.conf
空白行数 1
[root@centos7 scripts]# bash argsnum.sh /etc/yum.conf /etc/is
空白行数 3
[root@centos7 scripts]# bash argsnum.sh /etc/yum.con /etc/issue
grep: /etc/yum.con: No such file or directory
空白行数 0

2、编写脚本 hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”。

[root@centos7 scripts]# cat color.sh
RED="echo -e \033[1;31m"
GREEN="echo -e \e[1;32m"
END="\033[0m"

[root@centos7 scripts]# cat hostping.sh
#!/bin/bash
. /scripts/color.sh
read -p "please input IP address:" IP
ping -c1 -w1 $IP &> /dev/null
[ $? -eq 0 ] && $GREEN"$IP is up$END" || $RED"$IP is down$END"

[root@centos7 scripts]# bash hostping.sh
please input IP address:192.168.100.2
192.168.100.2 is up
[root@centos7 scripts]# bash hostping.sh
please input IP address:192.168.100.100
192.168.100.100 is down

3、编写脚本 per.sh,判断当前用户对指定参数文件,是否不可读并且不可写。

[root@centos7 scripts]# cat per.sh
#!/bin/bash
read -p "please input a file: " FILE
[ -r $FILE -a -w $FILE ] && $GREEN"This $FILE is reader and writer$END" || $RED"This $FILE is not readed and writed$END"

[root@centos7 scripts]# touch file
[root@centos7 scripts]# chmod a= file
[root@centos7 scripts]# ll file
----------. 1 root root 0 Jan 11 07:48 file
[root@centos7 scripts]# bash per.sh
please input a file: file
This file is reader and writer
[root@centos7 scripts]# su wang
[wang@centos7 scripts]$ bash per.sh
please input a file: file
This file is not readed and writed
[wang@centos7 scripts]$

5、编写脚本 excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件。

[root@centos7 scripts]# cat excute.sh
#!/bin/bash
. /scripts/color.sh
read -p "please input a file: " FILE
[ -f "$FILE" ] && [[ "$FILE" =~ .*\.sh ]] &> /dev/null
[ $? -eq 0 ] && (chmod a+x $FILE;$GREEN"$FILE is a sh file$END") || $RED"This $FILE is not scripts file$END"

#测试
[root@centos7 scripts]# ll createuser.sh
-rw-r--r--. 1 root root 220 Jan 10 22:53 createuser.sh
[root@centos7 scripts]# bash excute.sh
please input a file: createuser.sh
createuser.sh is a sh file

二、文件查找和打包压缩

2 文件查找

在文件系统上查找符合条件的文件

  • 文件查找:locate, find
  • 非实时查找(数据库查找):locate
  • 实时查找:find

2.1 locate

locate 查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db

索引的构建是在系统较为空闲时自动进行(周期性任务),执行updatedb可以更新数据库

索引构建过程需要遍历整个根文件系统,很消耗资源

locate passwd
locate: can not stat() `/var/lib/mlocate/mlocate.db`: No such file or directory

ll /var/lib/mlocate/mlocate.db
ls: cannot access '/var/lib/mlocate/mlocate.db': No such file or directory

updatedb
ll /var/lib/mlocate/mlocate.db  存在了

locate passwd就能查到包含passwd的文件了

工作特点:

  • 查找速度快
  • 模糊查找
  • 非实时查找
  • 搜索的是文件的全路径,不仅仅是文件名
  • 可能只搜索用户具备读取和执行权限的目录

格式:

locate [OPTION]... [PATTERN]...

常用选项:

-i      #不区分大小写的搜索
-n N    #只列举前N个匹配项目
-r      #使用基本正则表达式

范例:

#搜索名称或路径中包含“conf”的文件
locate conf
#使用Regex来搜索以“.conf”结尾的文件
locate -r '\.conf$'

范例:

[root@centos8 ~]#locate -n 10 -ir '\.CONF$'
/boot/loader/entries/5b85fc7444b240a992c42ce2a9f65db5-0-rescue.conf
/boot/loader/entries/5b85fc7444b240a992c42ce2a9f65db5-4.18.0-147.el8.x86_64.conf
/etc/autofs.conf
/etc/autofs_ldap_auth.conf
/etc/dracut.conf
/etc/fuse.conf
/etc/host.conf
/etc/idmapd.conf
/etc/kdump.conf
/etc/krb5.conf

2.2 find

find 是实时查找工具,通过遍历指定路径完成文件查找

工作特点:

  • 查找速度略慢
  • 精确查找
  • 实时查找
  • 查找条件丰富
  • 可能只搜索用户具备读取和执行权限的目录

格式:

find [OPTION]... [查找路径] [查找条件] [处理动作]
#查找路径:指定具体目标路径;默认为当前目录
#查找条件:指定的查找标准,可以文件名、大小、类型、权限等标准进行;默认为找出指定路径下的所有文件
#处理动作:对符合条件的文件做操作,默认输出至屏幕

2.2.1 指定搜索目录层级

-maxdepth level     #最大搜索目录深度,指定目录下的文件为第1级
-mindepth level     #最小搜索目录深度

范例:

find /etc -maxdepth 2 -mindepth 2   ##只是二级目录

2.2.2 目录或文件优先级

  • 默认是先处理目录,再处理目录内的文件;
  • -depth或-d #建议用-depth,先处理目录内的文件,再处理目录本身。

范例:

[root@centos7 data]#tree /data/test
/data/test
├── f1.txt
├── f2.txt
└── test2
    └── test3
        ├── f3.txt
        └── f4.txt
4 directories, 2 files
[root@centos7 data]#find /data/test
/data/test
/data/test/f1.txt
/data/test/f2.txt
/data/test/test2
/data/test/test2/test3
/data/test/test2/test3/f3.txt
/data/test/test2/test3/f4.txt
[root@centos7 data]#find /data/test -depth
/data/test/f1.txt
/data/test/f2.txt
/data/test/test2/test3/f3.txt
/data/test/test2/test3/f4.txt
/data/test/test2/test3
/data/test/test2
/data/test

2.2.3 根据文件名和inode查找

-name "文件名称"        #支持使用glob,如:*, ?, [], [^],建议通配符要加双引号引起来,否则会出现莫名其妙的错误。
-iname "文件名称"       #不区分字母大小写
-inum n                #按inode号查找
-samefile name          #相同inode号的文件
-links n                #链接数为n的文件
-regex "PATTERN"        #以PATTERN匹配整个文件路径,而非文件名称

范例:

[root@centos7 ~]# find /etc -name *passwd*      ##不加双引号,有时查询到的文件不全
/etc/passwd
/etc/pam.d/passwd
[root@centos7 ~]# find /etc -name "*passwd*"
/etc/security/opasswd
/etc/passwd-
/etc/passwd
/etc/pam.d/passwd

[root@centos7 ~]# find / -inum 125 -ls      ##查找125这个节点编号,并显示详细属性信息
   125    0 -rw-r--r--   1 root     root         4096 Jan  4 20:25 /sys/devices/system/memory/memory1/power/control
   125    0 -rw-r--r--   1 root     root            0 Jan  4 19:53 /sys/kernel/debug/tracing/trace_stat/function81
   125    4 -rw-r--r--   1 root     root         1202 Oct 31  2018 /usr/lib/kbd/keymaps/legacy/i386/dvorak/dvorak-r.map.gz

[root@centos7 ~]# find / -links 66 -ls      ##查找链接数是66的文件,并显示详细属性信息
   953    0 drwxr-xr-x  66 root     root            0 Jan  4 19:53 /sys/bus/pci/slots

[root@centos8 data]#find -regex ".*\.txt$"
./script40/b.txt
./f1.txt

2.2.4 根据属主、属组查找

-user USERNAME      #查找属主为指定用户(UID)的文件
-group GRPNAME      #查找属组为指定组(GID)的文件
-uid UserID         #查找属主为指定的UID号的文件
-gid GroupID        #查找属组为指定的GID号的文件
-nouser             #查找没有属主的文件
-nogroup            #查找没有属组的文件

范例:

[root@centos7 ~]# find / -user wang -ls
50389486    0 -rw-rw----   1 wang     mail        0 Dec 13 17:03 /var/spool/mail/wang
50333271    0 drwx------   2 wang     wang       99 Dec 13 17:20 /home/wang
50389483    4 -rw-r--r--   1 wang     wang       18 Apr  1  2020 /home/wang/.bash_logout
50389484    4 -rw-r--r--   1 wang     wang      193 Apr  1  2020 /home/wang/.bash_profile
50389485    4 -rw-r--r--   1 wang     wang      231 Apr  1  2020 /home/wang/.bashrc
50389487    4 -rw-------   1 wang     wang      416 Dec 13 22:36 /home/wang/.bash_history
50389488    0 -rw-rw-r--   1 wang     wang        0 Dec 13 17:20 /home/wang/wang.txt
50389452    0 drwxr-xr-x   4 wang     g1        322 Dec 27 11:20 /data
[root@centos7 ~]#

[root@centos7 ~]# useradd test
[root@centos7 ~]# userdel test
[root@centos7 ~]# find / -nouser
/var/spool/mail/test
/home/test
/home/test/.bash_logout
/home/test/.bash_profile
/home/test/.bashrc

2.2.5 根据文件类型查找

-type TYPE
#TYPE可以是以下形式:
f:  #普通文件
d:  #目录文件
l:  #符号链接文件
s:  #套接字文件
b:  #块设备文件
c:  #字符设备文件
p:  #管道文件

范例:

#查看/home的目录
find /home –type d -ls

[root@centos7 ~]# find /home -type d -ls
33682265    0 drwxr-xr-x   6 root     root           54 Jan 10 22:54 /home
16777612    0 drwx------   2 wang     wang           83 Jan 11 07:52 /home/wang
33574987    0 drwx------   2 mage     mage           62 Jan 10 10:38 /home/mage
50763320    0 drwx------   2 dong     dong           62 Jan 10 10:38 /home/test
50767969    0 drwx------   2 dong     dong           62 Jan 10 22:54 /home/dong

2.2.6 空文件或目录

#选项:-empty
find /app -type d -empty

[root@centos7 ~]# find /etc -type d -empty -maxdepth 1 -ls
   63786    0 drwxr-xr-x   2 root     root            6 Sep  6  2017 /etc/terminfo
16785718    0 drwxr-xr-x   2 root     root            6 Aug  4  2017 /etc/chkconfig.d
16953125    0 drwxr-xr-x   2 root     root            6 Nov  2  2018 /etc/dracut.conf.d
50490609    0 drwxr-xr-x   2 root     root            6 Oct 30  2018 /etc/binfmt.d
  346524    0 drwxr-xr-x   2 root     root            6 Oct 30  2018 /etc/modules-load.d
16793775    0 drwxr-xr-x   2 root     root            6 Oct 30  2018 /etc/tmpfiles.d
  279246    0 drwxr-xr-x   2 root     root            6 Apr 11  2018 /etc/opt
16793782    0 drwxr-xr-x   2 root     root            6 Apr 11  2018 /etc/xinetd.d
50351466    0 drwxr-xr-x   2 root     root            6 Jun 10  2014 /etc/popt.d
16959808    0 drwxr-xr-x   2 root     root            6 Oct 30  2018 /etc/statetab.d
16816917    0 drwxr-xr-x   2 root     root            6 Nov  2  2018 /etc/krb5.conf.d
   88019    0 drwxr-xr-x   2 root     root            6 Aug  2  2017 /etc/gcrypt
33784614    0 drwxr-xr-x   2 root     root            6 Jun  9  2014 /etc/cron.weekly
16962199    0 drwxr-xr-x   2 root     root            6 Jun  9  2014 /etc/cron.monthly
50568686    0 drwxr-xr-x   2 root     root            6 Jul 13  2018 /etc/gnupg
50745343    0 drwxr-x---   2 root     root            6 Oct 30  2018 /etc/sudoers.d
[root@centos7 ~]#

2.2.7 组合条件

与:-a ,默认多个条件是与关系
或:-o
非:-not或!

范例:

-a与的优先级高于-o或的优先级。
[root@centos7 ~]# find /etc -type d -o -type l|wc -l
687
##-type l -ls也就是-type l -a -ls,只详细列出l类型的链接文件,没有列出目录。
[root@centos7 ~]# find /etc -type d -o -type l -ls |wc -l
91

[root@centos7 ~]# find /etc \( -type d -o -type l \) -ls |wc -l
687
[root@centos7 ~]#

德·摩根定律:

  • (非 A) 或 (非 B) = 非(A 且 B)
  • (非 A) 且 (非 B) = 非(A 或 B)

示例:

  • !A -a !B = !(A -o B)
  • !A -o !B = !(A -a B)

范例:

find -user joe -group joe
find -user joe -not -group joe
find -user joe -o -user jane
find -not \( -user joe -o -user jane \)
find / -user joe -o -uid 500

[root@centos7 ~]# find /etc ! \( -type d -a -empty \)|wc -l
2280
[root@centos7 ~]# find /etc ! -type d -o ! -empty|wc -l
2280

[root@centos7 ~]# find /home ! -user wang -a ! -user mage
/home
/home/test
/home/test/.bash_logout
/home/test/.bash_profile
/home/test/.bashrc
[root@centos7 ~]# find /home ! \( -user wang -o -user mage \)
/home
/home/test
/home/test/.bash_logout
/home/test/.bash_profile
/home/test/.bashrc
[root@centos7 ~]#

#找出/tmp目录下,属主不是root,且文件名不以f开头的文件
find /tmp ( -not -user root -a -not -name 'f*' ) -ls
find /tmp -not ( -user root -o -name 'f*' ) –ls

2.2.8 排除目录

范例:

#查找/etc/下,除/etc/sane.d目录的其它所有.conf后缀的文件
find /etc -path '/etc/sane.d' -a -prune -o -name "*.conf"

#查找/etc/下,除/etc/sane.d和/etc/fonts两个目录的所有.conf后缀的文件
find /etc \( -path "/etc/sane.d" -o -path "/etc/fonts" \) -a -prune -o -name "*.conf"
[root@centos7 ~]# find /etc \( -path "/etc/dbus-1" -o -path "/etc/security" \) -a -prune -o -name "*.conf"
/etc/resolv.conf
/etc/rsyslog.d/listen.conf
/etc/host.conf
...省略...
[root@centos7 ~]#

#排除/proc和/sys目录
[root@centos7 ~]# find / \( -path "/proc" -o -path "/sys"  \) -a -prune -o -type f -a -mmin -1|wc -l
622

2.2.9 根据文件大小来查找

-size [+|-]#UNIT
    常用单位:k, M, G,c(byte),注意大小写敏感
#UNIT: (#-1, #]
    如:6k 表示(5k,6k]
-#UNIT:[0,#-1]
    如:-6k 表示[0,5k]
+#UNIT:(#,∞)
    如:+6k 表示(6k,∞)

-size 1024k     #表示1023k到1024k
-size 1M        #表示0M到1M

范例:


[root@centos7 data]# dd if=/dev/zero of=/data/10M.txt bs=1M count=10
[root@centos7 data]# dd if=/dev/zero of=/data/9M.txt bs=1M count=9
[root@centos7 data]# dd if=/dev/zero of=/data/7M.txt bs=1M count=7
[root@centos7 data]# dd if=/dev/zero of=/data/15M.txt bs=1M count=15
[root@centos7 data]# ll -h *M.txt
-rw-r--r--. 1 root root  10M Jan 23 12:18 10M.txt
-rw-r--r--. 1 root root  15M Jan 23 12:18 15M.txt
-rw-r--r--. 1 root root 7.0M Jan 23 12:18 7M.txt
-rw-r--r--. 1 root root 9.0M Jan 23 12:18 9M.txt

[root@centos7 data]# find -size 10M -ls
50763318 10240 -rw-r--r--   1 root     root     10485760 Jan 23 12:18 ./10M.txt
[root@centos7 data]# find -size -10M -ls
50767991    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f1.log
50767992    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f2.log
50767993    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f3.log
50767994    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f4.log
50767995    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f5.log
50763319 9216 -rw-r--r--   1 root     root      9437184 Jan 23 12:18 ./9M.txt
50763321 7168 -rw-r--r--   1 root     root      7340032 Jan 23 12:18 ./7M.txt
[root@centos7 data]# find -size +10M -ls
50763322 15360 -rw-r--r--   1 root     root     15728640 Jan 23 12:18 ./15M.txt
[root@centos7 data]#

2.2.10 根据时间戳

以“天”为单位
-atime [+|-]#
#: [#,#+1)
    7: [7,8)
+#: [#+1,∞]
    +7: [8,)
-#: [0,#)
    -7: [0,7)
-mtime
-ctime
以“分钟”为单位
-amin
-mmin
-cmin

范例:

#查找/data目录下180天前的文件
find /data -mtime +180
#查找/data目录下1分钟内的文件
find /data -mmin -1

#创建一周内、第7天和第8天前的文件
[root@centos7 data]# date   #今天的日期是2021年1月23日
Sat Jan 23 11:55:15 CST 2021
[root@centos7 data]# date 011611552021  #第7天前
Sat Jan 16 11:55:00 CST 2021
[root@centos7 data]# touch file{1..10}.txt
[root@centos7 data]# ll
-rw-r--r--. 1 root root 0 Jan 16 11:55 file10.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file1.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file2.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file3.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file4.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file5.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file6.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file7.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file8.txt
-rw-r--r--. 1 root root 0 Jan 16 11:55 file9.txt
[root@centos7 data]# date 011711552021  #一周内
Sun Jan 17 11:55:00 CST 2021
[root@centos7 data]# touch f{1..5}.log
[root@centos7 data]# ll *.log
-rw-r--r--. 1 root root 0 Jan 17 11:55 f1.log
-rw-r--r--. 1 root root 0 Jan 17 11:55 f2.log
-rw-r--r--. 1 root root 0 Jan 17 11:55 f3.log
-rw-r--r--. 1 root root 0 Jan 17 11:55 f4.log
-rw-r--r--. 1 root root 0 Jan 17 11:55 f5.log
[root@centos7 data]# date 010111112021  #第8天以前
Sat Jan  1 11:11:00 CST 2011
[root@centos7 data]# touch f{1..5}.old
[root@centos7 data]# ll *.old
-rw-r--r--. 1 root root 0 Jan  1 11:11 f1.old
-rw-r--r--. 1 root root 0 Jan  1 11:11 f2.old
-rw-r--r--. 1 root root 0 Jan  1 11:11 f3.old
-rw-r--r--. 1 root root 0 Jan  1 11:11 f4.old
-rw-r--r--. 1 root root 0 Jan  1 11:11 f5.old

[root@centos7 data]# clock -s
[root@centos7 data]# find -mtime 7 -ls  #查找前第7天的文件
50767974    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file1.txt
50767977    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file2.txt
50767982    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file3.txt
50767984    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file4.txt
50767985    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file5.txt
50767986    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file6.txt
50767987    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file7.txt
50767988    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file8.txt
50767989    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file9.txt
50767990    0 -rw-r--r--   1 root     root            0 Jan 16 11:55 ./file10.txt
[root@centos7 data]# find -mtime -7 -ls     #查找一周内(不包含第7天)的文件
50767991    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f1.log
50767992    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f2.log
50767993    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f3.log
50767994    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f4.log
50767995    0 -rw-r--r--   1 root     root            0 Jan 17 11:55 ./f5.log
[root@centos7 data]# find -mtime +7 -ls     #查找前第8天开始的文件
50767996    0 -rw-r--r--   1 root     root            0 Jan  1 11:11 ./f1.old
50767997    0 -rw-r--r--   1 root     root            0 Jan  1 11:11 ./f2.old
50767998    0 -rw-r--r--   1 root     root            0 Jan  1 11:11 ./f3.old
50767999    0 -rw-r--r--   1 root     root            0 Jan  1 11:11 ./f4.old
50763317    0 -rw-r--r--   1 root     root            0 Jan  1 11:11 ./f5.old

#新建一个用户,查看
[root@centos7 data]# useradd mmin
[root@centos7 data]# find / \( -path '/proc' -o -path '/sys' \) -a -prune -o -mmin -1
/dev/pts/0
/dev/ptmx
/proc
/run/log/journal/ddad9c1521794511b34803a48eb50139/system.journal
/sys
/etc
/etc/group
/etc/gshadow
/etc/passwd
/etc/shadow
/etc/subgid
/etc/subuid
/var/log/tallylog
/var/log/lastlog
/var/log/audit/audit.log
/var/log/secure
/var/spool/mail
/var/spool/mail/mmin
/home
/home/mmin

2.2.11 根据权限查找

-perm [/|-]MODE
MODE        #精确权限匹配
/MODE       #任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+ 从CentOS 7开始淘汰
-MODE       #每一类对象都必须同时拥有指定权限,与关系
0           #表示不关注

说明:

  • find -perm 755 会匹配权限模式恰好是755的文件
  • 只要当任意人有写权限时,find -perm /222就会匹配
  • 只有当每个人都有写权限时,find -perm -222才会匹配
  • 只有当其它人(other)有写权限时,find -perm -002才会匹配,此时-002和/002相同

范例:

[root@centos7 data]# find /data/ -perm 600 -ls
50389503    4 -rw-------   1 root     root           10 Dec 22 20:10 /data/f1.txt

[root@centos7 data]# ll
-rw-------  1 root root  10 Dec 22 20:10 f1.txt
-rw-r--r--  1 root root  19 Dec 19 19:21 f1.txt.orig
-rw-r--r--  1 root root 157 Dec 19 19:33 f.patch

[root@centos7 data]# find /data/ -perm -444     ##只有每个人都有r权限才能匹配上
/data/
/data/f.patch
/data/f1.txt.orig
[root@centos7 data]# find /data/ -perm /444     ##只要包含r权限就能匹配上
/data/
/data/f.patch
/data/f1.txt.orig
/data/f1.txt
[root@centos7 data]# find -perm -400        ##只有所有者有r权限即可,所属组和other不限
./f.patch
./f1.txt.orig
./f1.txt

#生成环境中,需要查找other用户有w权限的文件,防止被***修改。
[root@centos7 data]# chmod 002 f.patch
[root@centos7 data]# ll f.patch
--------w- 1 root root 157 Dec 19 19:33 f.patch
[root@centos7 data]# find -perm /002
./f.patch
[root@centos7 data]# find -perm -002
./f.patch

2.2.12 处理动作

-print      #默认的处理动作,显示至屏幕
-ls         #类似于对查找到的文件执行“ls -l”命令
-fls file   #查找到的所有文件的长格式信息保存至指定文件中,相当于 -ls > file
-delete     #删除查找到的文件,慎用!
-ok COMMAND {} \; 
#对查找到的每个文件执行由COMMAND指定的命令,对于每个文件执行命令之前,都会交互式要求用户确认
-exec COMMAND {} \;     #对查找到的每个文件执行由COMMAND指定的命令
{}          #用于引用查找到的文件名称自身

范例:

#备份文件,添加.bak扩展名
[root@centos7 data]# cd /data
[root@centos7 data]# touch f{1..10}.txt
[root@centos7 data]# find -name "*.txt" -exec cp {} {}.bak \;
[root@centos7 data]# ll
-rw-r--r--. 1 root root  0 Jan 22 18:21 10.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 10.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 1.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 1.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 2.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 2.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 3.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 3.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 4.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 4.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 5.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 5.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 6.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 6.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 7.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 7.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 8.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 8.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 9.txt
-rw-r--r--. 1 root root  0 Jan 22 18:21 9.txt.bak
[root@centos7 data]#
[root@centos7 data]# find -name "*.txt" -exec rm {} \;
[root@centos7 data]# ll
-rw-r--r--. 1 root root  0 Jan 22 18:21 10.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 1.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 2.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 3.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 4.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 5.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 6.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 7.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 8.txt.bak
-rw-r--r--. 1 root root  0 Jan 22 18:21 9.txt.bak

#1)在主目录中寻找可被其它用户写入的文件,并去掉w权限
find ~ -perm -002 -exec chmod o-w {} \;
#初始化文件
[root@centos7 data]# ll
-rw-r--r--. 1 root root 1048576 Jan 23 18:23 1M.txt
-rw-r--r--. 1 root root 2097152 Jan 23 18:22 2M.txt
[root@centos7 data]# chmod o+w 1M.txt
[root@centos7 data]# ll
-rw-r--rw-. 1 root root 1048576 Jan 23 18:23 1M.txt
-rw-r--r--. 1 root root 2097152 Jan 23 18:22 2M.txt
#查找并修改权限
[root@centos7 data]# find /data -perm -002 -ok chmod o-w {} \;
< chmod ... /data/1M.txt > ? y
[root@centos7 data]# ll
total 3072
-r--r--r--. 1 root root 1048576 Jan 23 18:23 1M.txt
-rw-r--r--. 1 root root 2097152 Jan 23 18:22 2M.txt
[root@centos7 data]#

#2)查找/data下的权限为644,后缀为sh的普通文件,增加执行权限
find /data –type f -perm 644 -name "*.sh" –exec chmod 755 {} \;
#初始化文件
[root@centos7 scripts]# ll
total 24
-rw-r--r--. 1 root root  64 Jan 11 17:54 color.sh
-rw-r--r--. 1 root root 220 Jan 11 11:53 createuser.sh
drw-r--r--. 2 root root   6 Jan 23 18:29 dir.sh
-rw-r--r--. 1 root root 750 Jan 11 17:53 disk_check.sh
-rw-r--r--. 1 root root 233 Jan 11 19:45 excute.sh
----------. 1 root root   0 Jan 11 20:48 file
-r--r--r--. 1 root root   0 Jan 23 18:29 file.sh
-rw-r--r--. 1 root root 163 Jan 11 20:54 hostping.sh
-rw-r--r--. 1 root root 162 Jan 11 20:42 per.sh
#查找并修改权限
[root@centos7 scripts]# find /scripts -type f -perm 644 -name "*.sh" -exec chmod 755 {} \;  #-f排除了dir.sh,644排除了file.sh和file
[root@centos7 scripts]# ll
total 24
-rwxr-xr-x. 1 root root  64 Jan 11 17:54 color.sh
-rwxr-xr-x. 1 root root 220 Jan 11 11:53 createuser.sh
drw-r--r--. 2 root root   6 Jan 23 18:29 dir.sh         #未匹配上,这是目录
-rwxr-xr-x. 1 root root 750 Jan 11 17:53 disk_check.sh
-rwxr-xr-x. 1 root root 233 Jan 11 19:45 excute.sh  
----------. 1 root root   0 Jan 11 20:48 file           #未匹配上,不是sh文件,权限不是644
-r--r--r--. 1 root root   0 Jan 23 18:29 file.sh        #未匹配上,权限不是644
-rwxr-xr-x. 1 root root 163 Jan 11 20:54 hostping.sh
-rwxr-xr-x. 1 root root 162 Jan 11 20:42 per.sh

2.3 参数替换 xargs

由于很多命令不支持管道|来传递参数,xargs用于产生某个命令的参数,xargs 可以读入 stdin 的数据,并且以空格符或回车符将 stdin 的数据分隔成为参数。

另外,许多命令不能接受过多参数,命令执行可能会失败,xargs 可以解决。

注意:文件名或者是其他意义的名词内含有空格符的情况

find 和 xargs 的组合:

find | xargs COMMAND

范例:

#显示10个数字
[root@centos7 scripts]# seq 10
1
2
3
4
5
6
7
8
9
10
[root@centos7 scripts]# seq 10|xargs
1 2 3 4 5 6 7 8 9 10

#删除当前目录下的大量文件
ls | xargs rm

#查找.sh文件并按大小排序
[root@centos7 scripts]# find -name "*.sh"|xargs ls -Sl
-rw-r--r-- 1 root root 887 Dec 26 19:06 ./systeminfo.sh
-rw-r--r-- 1 root root 490 Dec 26 21:28 ./dir/arg.sh
-rwxr-xr-x 1 root root 425 Dec 26 18:11 ./father.sh
-rw-r--r-- 1 root root 423 Dec 26 15:53 ./link.sh

#-n选项
[root@centos8 data]#echo {1..10} |xargs
1 2 3 4 5 6 7 8 9 10
[root@centos8 data]#echo {1..10} |xargs -n1
1
2
3
4
5
6
7
8
9
10
[root@centos7 scripts]# echo {1..10} |xargs -n2
1 2
3 4
5 6
7 8
9 10

#批量创建和删除用户
echo user{1..10} |xargs -n1 useradd
echo user{1..100} | xargs -n1 userdel -r
[root@centos7 scripts]# echo user{1..10}|xargs -n1 useradd
[root@centos7 scripts]# getent passwd |grep 'user*'
user1:x:2013:2013::/home/user1:/bin/bash
user2:x:2014:2014::/home/user2:/bin/bash
user3:x:2015:2015::/home/user3:/bin/bash
user4:x:2016:2016::/home/user4:/bin/bash
user5:x:2017:2017::/home/user5:/bin/bash
user6:x:2018:2018::/home/user6:/bin/bash
user7:x:2019:2022::/home/user7:/bin/bash
user8:x:2020:2023::/home/user8:/bin/bash
user9:x:2021:2024::/home/user9:/bin/bash
user10:x:2022:2025::/home/user10:/bin/bash
[root@centos7 scripts]# echo user{1..10}|xargs -n1 userdel -r
[root@centos7 scripts]# getent passwd |grep 'user*'
[root@centos7 scripts]#

#这个命令是错误的,ls不支持标准输入
find /sbin/ -perm /700 | ls -l
#查找有特殊权限的文件,并排序
find /bin/ -perm /7000 | xargs ls -Sl   ## /7000是所有者、所属组、其他组有一个有特殊权限就能匹配
[root@centos7 scripts]# find /bin/ -perm /7000 |xargs ls -Sl
50650229  376 ---x--s--x   1 root     nobody     382216 Aug  9  2019 /bin/ssh-agent
50650238  144 ---s--x--x   1 root     root       147336 Apr  1  2020 /bin/sudo
50356563   80 -rwsr-xr-x   1 root     root        78408 Aug  9  2019 /bin/gpasswd
50356546   76 -rwsr-xr-x   1 root     root        73888 Aug  9  2019 /bin/chage
50523241   60 -rwsr-xr-x   1 root     root        57656 Aug  9  2019 /bin/crontab
50730230   44 -rwsr-xr-x   1 root     root        44264 Apr  1  2020 /bin/mount
50356566   44 -rwsr-xr-x   1 root     root        41936 Aug  9  2019 /bin/newgrp
50479782   32 -rwsr-xr-x   1 root     root        32128 Apr  1  2020 /bin/su
50485690   32 -rwsr-xr-x   1 root     root        31984 Apr  1  2020 /bin/umount
...省略...

find /bin/ -perm -7000 | xargs ls -Sl   ##-7000是这三者必须都有特殊权限才能匹配
[root@centos7 scripts]# find /bin/ -perm -7000  #搜索不到
[root@centos7 scripts]# touch /bin/test.txt     
[root@centos7 scripts]# chmod 7755 /bin/test.txt    #赋予test.txt权限
[root@centos7 scripts]# ll /bin/test.txt
-rwsr-sr-t 1 root root 0 Jan  6 21:46 /bin/test.txt
[root@centos7 scripts]# find /bin/ -perm -7000 -ls
51116070    0 -rwsr-sr-t   1 root     root            0 Jan  6 21:46 /bin/test.txt

练习
1、查找/var目录下属主为root,且属组为mail的所有文件

find /var -user root -group mail

2、查找/var目录下不属于root、lp、gdm的所有文件

find /var ! \( -user root -o -user lp -o -user gdm \)
find /var ! -user root -a ! -user lp ! -user gdm

3、查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是postfix的文件

find /var -type f -ctime -7 ! -user root -a ! -user postfix 
[root@centos7 etc]# find /var -type f -ctime -7 ! -user root ! -user postfix -ls
50763322    4 -rw-r--r--   1 chrony   chrony        42 Jan 10 02:26 /var/lib/chrony/drift
50763323    0 -rw-rw----   1 wang     mail           0 Jan 10 10:38 /var/spool/mail/wang
50763325    0 -rw-rw----   1 mage     mail           0 Jan 10 10:38 /var/spool/mail/mage
50767938    0 -rw-rw----   1 1002     mail           0 Jan 10 10:38 /var/spool/mail/test

4、查找当前系统上没有属主或属组,且最近一个周内曾被访问过的文件

##多个搜索条件时,又有与,又有或的情况下,把所有的或都放在()里,再与其他条件想与,才能匹配正确

[root@centos7 etc]# find / -type f -atime -7 -nouser -o -nogroup -ls
50763320    0 drwx------   2 1002     1002           62 Jan 10 10:38 /home/test

[root@centos7 etc]# find / -type f -atime -7 \( -nouser -o -nogroup \) -ls
50767938    0 -rw-rw----   1 1002     mail        0 Jan 10 10:38 /var/spool/mail/test
50763327    4 -rw-r--r--   1 1002     1002       18 Oct 30  2018 /home/test/.bash_logout
50767936    4 -rw-r--r--   1 1002     1002      193 Oct 30  2018 /home/test/.bash_profile
50767937    4 -rw-r--r--   1 1002     1002      231 Oct 30  2018 /home/test/.bashrc
[root@centos7 etc]#

5、查找/etc目录下大于1M且类型为普通文件的所有文件

find /etc -type f -size +1M
[root@centos7 ~]# find /etc -type f -size +1M -ls
33574980 7760 -r--r--r--   1 root     root      7942570 Jan  9 11:20 /etc/udev/hwdb.bin
17107935 3808 -rw-------   1 root     root      3896194 Nov  2  2018 /etc/selinux/targeted/active/policy.kern
50724178 1380 -rw-r--r--   1 root     root      1412826 Nov  2  2018 /etc/selinux/targeted/contexts/files/file_contexts.bin
33905264 3808 -rw-r--r--   1 root     root      3896194 Nov  2  2018 /etc/selinux/targeted/policy/policy.31
[root@centos7 ~]#

6、查找/etc目录下所有用户都没有写权限的文件

find /etc ! -perm /222
[root@centos7 ~]# find /etc ! -perm /222 -ls
16904912    4 ----------   1 root     root          383 Jan 10 10:38 /etc/gshadow-
16777618    4 ----------   1 root     root          374 Jan 10 10:39 /etc/gshadow
16793769    4 ----------   1 root     root          666 Jan 10 10:38 /etc/shadow-
33574980 7760 -r--r--r--   1 root     root      7942570 Jan  9 11:20 /etc/udev/hwdb.bin
16959779    4 -r--r--r--   1 root     root           33 Jan  9 11:13 /etc/machine-id
16777294    4 ----------   1 root     root          639 Jan 10 10:39 /etc/shadow
 71980  152 -r--r--r--   1 root     root       154279 Jan  9 11:12 /etc/pki/ca-trust/extracted/java/cacerts
16816862  252 -r--r--r--   1 root     root       257889 Jan  9 11:12 /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
33689292  208 -r--r--r--   1 root     root       211658 Jan  9 11:12 /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
33689293  176 -r--r--r--   1 root     root       177221 Jan  9 11:12 /etc/pki/ca-trust/extracted/pem/email-ca-bundle.pem
33689294    0 -r--r--r--   1 root     root            0 Jan  9 11:12 /etc/pki/ca-trust/extracted/pem/objsign-ca-bundle.pem
17053677    4 -r--r--r--   1 root     root           63 Nov  8  2018 /etc/ld.so.conf.d/kernel-3.10.0-957.el7.x86_64.conf
160063    4 -r--------   1 root     root           45 Jan  9 11:12 /etc/openldap/certs/password
17129718    8 -r--r-----   1 root     root         4328 Oct 30  2018 /etc/sudoers
[root@centos7 ~]#

7、查找/etc/init.d目录下,所有用户都有执行权限,且其它用户有写权限的文件

find /etc/init.d -perm /111 -perm -002

[root@centos7 etc]# touch /etc/init.d/file.sh
[root@centos7 etc]# chmod a+x,o+w /etc/init.d/file.sh
[root@centos7 etc]# ll init.d/
total 40
-rwxr-xrwx. 1 root root     0 Jan 10 22:41 file.sh
-rw-r--r--. 1 root root 18281 Aug 24  2018 functions
-rwxr-xr-x. 1 root root  4569 Aug 24  2018 netconsole
-rwxr-xr-x. 1 root root  7923 Aug 24  2018 network
-rw-r--r--. 1 root root  1160 Oct 30  2018 README
[root@centos7 etc]# find /etc/init.d/ -perm /111 -perm -002 -type f -ls
50767968    0 -rwxr-xrwx   1 root     root  0 Jan 10 22:41 /etc/init.d/file.sh
[root@centos7 etc]#

3 压缩和解压缩

3.1 compress和uncompress

格式:

compress Options [file ...]
uncompress file.Z       #解压缩

常用选项:

-d  #解压缩,相当于uncompress
-c  #结果输出至标准输出,不删除原文件
-v  #显示详情

范例:

#compress压缩比不高,不常用,安装时搜索compress,显示此工具来自于ncompress包。

[root@centos7 ~]# compress
-bash: compress: command not found
[root@centos7 ~]# yum provides compress
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
docker-ce-stable/x86_64/filelists_db                     |  23 kB     00:00
epel/x86_64/filelists_db                                 |  12 MB     00:06
ncompress-4.2.4.4-3.1.el7_8.x86_64 : Fast compression and decompression
                                   : utilities
Repo        : base
Matched from:
Filename    : /usr/bin/compress

[root@centos7 ~]# yum install -y ncompress

#压缩文件,不加选项,删除了源文件
[root@centos7 data]# ll -h
-rwxr-xr-x  1 root root 98M Jan  7 07:17 dockerd
[root@centos7 data]# compress dockerd
[root@centos7 data]# ll dockerd.Z
-rwxr-xr-x 1 root root 48957429 Jan  7 07:17 dockerd.Z
[root@centos7 data]# ll -h dockerd.Z
-rwxr-xr-x 1 root root 47M Jan  7 07:17 dockerd.Z

#解压缩
[root@centos7 data]# compress -d dockerd.Z
[root@centos7 data]# ll do*
-rwxr-xr-x 1 root root 102122240 Jan  7 07:17 dockerd
[root@centos7 data]# ll -h do*
-rwxr-xr-x 1 root root 98M Jan  7 07:17 dockerd

#使用-c选项,保留源文件,但需要指定压缩后的文件名
[root@centos7 data]# compress -c dockerd >dockerd.z
[root@centos7 data]# ll -h do*
-rwxr-xr-x 1 root root 98M Jan  7 07:17 dockerd
-rw-r--r-- 1 root root 47M Jan  7 07:24 dockerd.z
#使用-d选项,解压缩,-c保留源文件
[root@centos7 data]# compress -dc dockerd.z >dockerd2
[root@centos7 data]# ll -h do*
-rwxr-xr-x 1 root root 98M Jan  7 07:17 dockerd
-rw-r--r-- 1 root root 98M Jan  7 07:33 dockerd2
-rw-r--r-- 1 root root 47M Jan  7 07:31 dockerd.z
[root@centos7 data]#

zcat file.Z 不显式解压缩的前提下查看文本文件内容

zcat file.Z         #直接查看文件内容
zcat file.Z >file   #输出到文件中

3.2 gzip和gunzip

gzip压缩比高,常用

格式:

gzip [OPTION]... FILE ...

常用选项:

-k  #keep保留原文件,CentOS 8 新特性
-d  #解压缩,相当于gunzip
-c  #结果输出至标准输出,保留原文件不改变
-#  #指定压缩比,#取值为1-9,值越大压缩比越大

范例:

#解压缩
gunzip file.gz
#不显式解压缩的前提下查看文本文件内容
zcat file.gz

范例:

gzip -c messages >messages.gz
gzip -c -d messages.gz > messages
zcat messages.gz > messages
cat messages | gzip > m.gz

[root@centos7 data]# gzip -c dockerd >dockerd.gz
[root@centos7 data]# ll -h do*
-rwxr-xr-x 1 root root 98M Jan  7 07:17 dockerd
-rw-r--r-- 1 root root 28M Jan  7 08:22 dockerd.gz

[root@centos7 data]# cat /var/log/messages |gzip >message.gz
[root@centos7 data]# ll -h /var/log/messages message.gz
-rw-r--r-- 1 root root 101K Jan  7 08:27 message.gz
-rw------- 1 root root 1.1M Jan  7 08:27 /var/log/messages

3.3 bzip2和bunzip2

来自于 bzip2 包,压缩比更高

格式:

bzip2 [OPTION]... FILE ...

常用选项:

-k      #keep, 保留原文件
-d      #解压缩
-c      #结果输出至标准输出,保留原文件不改变
-#      #1-9,压缩比,默认为9

范例:

bunzip2 file.bz2    #解压缩
bzcat file.bz2      #不显式解压缩的前提下查看文本文件内容

范例:

[root@centos7 data]# bzip2 messages messages.bz2        ##直接用bzip2 file即可
bzip2: Input file messages.bz2 already has .bz2 suffix.
[root@centos7 data]# ll
-rw------- 1 root root     18002 Jan  7 08:43 messages.bz2
[root@centos7 data]# bzip2 -d -c messages.bz2 >messages01
[root@centos7 data]# ll messages*
-rw-r--r-- 1 root root 141890 Jan  7 08:52 messages01
-rw-r--r-- 1 root root  18002 Jan  7 08:46 messages.bz2

#与gzip对比
[root@centos7 data]# bzip2 -k dockerd
[root@centos7 data]# ll -h do*
-rwxr-xr-x 1 root root 98M Jan  7 08:23 dockerd
-rwxr-xr-x 1 root root 25M Jan  7 08:23 dockerd.bz2     ##bzip2压缩比更高
-rw-r--r-- 1 root root 28M Jan  7 08:22 dockerd.gz
[root@centos7 data]#

3.4 xz和unxz

如果没有xz命令,需要yum安装 xz即可。

格式:

xz [OPTION]... FILE ...

常用选项:

-k      #keep, 保留原文件
-d      #解压缩
-c      #结果输出至标准输出,保留原文件不改变
-#      #压缩比,取值1-9,默认为6

范例:

unxz file.xz        #解压缩
xzcat file.xz       #不显式解压缩的前提下查看文本文件内容

范例:

#xz压缩比最高,但压缩的时间很长,cpu占用高
[root@centos7 data]# xz -k dockerd
[root@centos7 data]# ll -h do*
-rwxr-xr-x 1 root root 98M Jan  7 08:23 dockerd
-rwxr-xr-x 1 root root 25M Jan  7 08:23 dockerd.bz2
-rw-r--r-- 1 root root 28M Jan  7 08:22 dockerd.gz
-rwxr-xr-x 1 root root 20M Jan  7 08:23 dockerd.xz
[root@centos7 data]#

以上compress、gzip、bzip2、xz压缩软件只能压缩单个文件,不能压缩文件夹。

[root@centos7 data]# ll mess*
-rw------- 1 root root 141890 Jan  7 08:43 messages
-rw-r--r-- 1 root root 141890 Jan  7 08:52 messages01
[root@centos7 data]# xz mess*
[root@centos7 data]# ll mess*
-rw-r--r-- 1 root root 15928 Jan  7 08:52 messages01.xz
-rw------- 1 root root 15928 Jan  7 08:43 messages.xz
[root@centos7 data]# unxz mess*
[root@centos7 data]# ll mess*
-rw------- 1 root root 141890 Jan  7 08:43 messages
-rw-r--r-- 1 root root 141890 Jan  7 08:52 messages01

3.5 zip和unzip

zip 可以实现打包目录和多个文件成一个文件并压缩,但可能会丢失文件属性信息,如:所有者和组信
息,一般建议使用 tar 代替。

yum安装zip 和 unzip 包

范例:

#打包多个文件
[root@centos7 data]# zip mess*
  adding: messages01 (deflated 86%)
[root@centos7 data]# ll mess*
-rw------- 1 root root 141890 Jan  7 08:43 messages
-rw-r--r-- 1 root root 141890 Jan  7 08:52 messages01
-rw-r--r-- 1 root root  19820 Jan  7 09:52 messages.zip

#-r 打包并压缩,zip -r file.zip directory,压缩包包含directory本身。
[root@centos7 tmp]# zip -r ./backup.zip /etc/sysconfig/
  adding: etc/sysconfig/ (stored 0%)
  adding: etc/sysconfig/network-scripts/ifcfg-eth0 (deflated 24%)
 ...省略...
  adding: etc/sysconfig/network (stored 0%)
[root@centos7 tmp]# ll
total 76
-rw-r--r-- 1 root root 76434 Jan  7 10:06 backup.zip

[root@centos7 tmp]# unzip backup.zip
Archive:  backup.zip
   creating: etc/sysconfig/         ##创建etc目录
...省略...
[root@centos7 tmp]# ll
total 76
-rw-r--r-- 1 root root 76434 Jan  7 10:06 backup.zip
drwxr-xr-x 3 root root    23 Jan  7 10:10 etc       ##解压缩后创建etc目录

#不包括目录本身,只打包目录内的文件和子目录
[root@centos7 tmp]# cd /etc/sysconfig;zip -r /data/tmp/backup.zip *
  adding: anaconda (deflated 40%)
...省略...
[root@centos7 tmp]# unzip backup.zip    ##就把文件解压缩到当前目录了

#-d 解压缩至指定目录,如果指定目录不存在,会在其父目录(必须事先存在)下自动生成
[root@centos7 tmp]# unzip /data/tmp/backup.zip -d /tmp/config

[root@centos7 tmp]# cat /var/log/messages |zip messages -
  adding: - (deflated 91%)
[root@centos7 tmp]# ll
-rw-r--r-- 1 root root 30586 Jan  7 10:59 messages.zip

[root@centos7 data]# unzip ./tmp/messages.zip -d ./tmp/
Archive:  ./tmp/messages.zip
  inflating: ./tmp/-
[root@centos7 data]# ll ./tmp
total 360
-rw------- 1 root root 333605 Jan  7 11:10 -
-rw-r--r-- 1 root root  31242 Jan  7 11:10 messages.zip

#-p 表示管道
[root@centos7 tmp]# unzip -p messages.zip > message
[root@centos7 tmp]# ll
total 688
-rw------- 1 root root 333605 Jan  7 11:10 -
-rw-r--r-- 1 root root 333605 Jan  7 11:13 message
-rw-r--r-- 1 root root  31242 Jan  7 11:10 messages.zip

4 打包和解包

4.1 tar

tar 即 Tape ARchive 磁带归档,可以对目录和多个文件打包一个文件,并且可以压缩(压缩比不大),保留文件属性不丢失,常用于备份功能,推荐使用

格式:

tar [OPTION]...
-c  #创建打包
-t  #查看归档文件
-x  #解压缩
-v  #显示详细信息
-p  #保留权限
-C  #指定解压路径

(1) 创建归档,保留权限

tar -cpvf /PATH/FILE.tar FILE...

(2) 追加文件至归档: 注:不支持对压缩文件追加

tar -rf /PATH/FILE.tar FILE...

(3) 查看归档文件中的文件列表

tar -t -f /PATH/FILE.tar

(4) 展开归档,xf通用解包选项,无论后缀是什么格式的

tar xf /PATH/FILE.tar
tar xf /PATH/FILE.tar -C /PATH/

范例:

#tar解压缩保留文件权限
[root@centos7 tmp]# su - mage
Last login: Sun Dec 13 17:30:28 CST 2020 on pts/0
[mage@centos7 ~]$ cp /etc/hosts .
[mage@centos7 ~]$ chmod 0 hosts
[mage@centos7 ~]$ ll
---------- 1 mage mage 373 Jan  7 11:19 hosts
[mage@centos7 ~]$ exit
logout
[root@centos7 tmp]# tar cvf home.tar /home
tar: Removing leading `/' from member names
/home/
[root@centos7 tmp]# ll
-rw-r--r-- 1 root root  71680 Jan  7 11:20 home.tar

[root@centos7 tmp]# tar xvf home.tar
home/
[root@centos7 tmp]# ll
drwxr-xr-x 18 root root    220 Jan  6 21:27 home
-rw-r--r--  1 root root  71680 Jan  7 11:20 home.tar
[root@centos7 tmp]# ll home/mage
---------- 1 mage mage 373 Jan  7 11:19 hosts

[root@centos7 tmp]# tar xvf home.tar -C /data
[root@centos7 tmp]# ll /data/home/mage
total 4
---------- 1 mage mage 373 Jan  7 11:19 hosts

#tar命令不能保留acl权限,需要再单独设置
[root@centos7 tmp]# cd /home
[root@centos7 home]# ll
drwx------  2 mage      mage      96 Jan  7 11:19 mage
drwx------  2 jieti     jieti     62 Jan  4 20:43 test
drwx------  2 wang      wang      99 Dec 13 17:20 wang
[root@centos7 home]# setfacl -m u:mage:rwx test
[root@centos7 home]# getfacl test
# file: test
# owner: jieti
# group: jieti
user::rwx
user:mage:rwx
group::---
mask::rwx
other::---
[root@centos7 home]# rm /data/tmp/* -rf
[root@centos7 home]# cd /data/tmp
[root@centos7 tmp]# tar cpvf home.tar /home
tar: Removing leading `/' from member names
[root@centos7 tmp]# tar xf home.tar
[root@centos7 tmp]# ll
total 72
drwxr-xr-x 18 root root   220 Jan  6 21:27 home
-rw-r--r--  1 root root 71680 Jan  7 11:58 home.tar
[root@centos7 tmp]# ll home
drwx------ 2 mage      mage      96 Jan  7 11:19 mage
drwxrwx--- 2 jieti     jieti     62 Jan  4 20:43 test
drwx------ 2 wang      wang      99 Dec 13 17:20 wang
[root@centos7 tmp]# ll /home
drwxrwx---+ 2 jieti     jieti     62 Jan  4 20:43 test
[root@centos7 tmp]# getfacl home/test
# file: home/test
# owner: jieti
# group: jieti
user::rwx
group::rwx
other::---

[root@centos7 tmp]#

(5) 结合压缩工具实现:归档并压缩

-z      #相当于gzip压缩工具
-j      #相当于bzip2压缩工具
-J      #相当于xz压缩工具

范例:

[root@centos8 ~]#tar zcvf etc.tar.gz /etc/
[root@centos8 ~]#tar jcvf etc.tar.bz2 /etc/
[root@centos8 ~]#tar Jcvf etc.tar.xz /etc/
[root@centos8 ~]#ll etc.tar.*
-rw-r--r-- 1 root root 3645926 Dec 20 22:00 etc.tar.bz2
-rw-r--r-- 1 root root 5105347 Dec 20 21:59 etc.tar.gz
-rw-r--r-- 1 root root 3101616 Dec 20 22:00 etc.tar.xz

#只打包目录内的文件,不包括目录本身,需要进入目录内再打包
[root@centos8 ~]#cd /etc
[root@centos8 etc]#tar zcvf /root/etc.tar.gz *

#利用 tar 进行文件复制
[root@centos7 tmp]# du -sh /usr
1.7G    /usr
[root@centos7 tmp]# time cp -a /usr ./      ##1.7G的目录cp用时2分多钟
real    2m13.297s
user    0m0.332s
sys     0m16.881s
[root@centos7 tmp]# rm * -rf
[root@centos7 tmp]# time tar c /usr |tar x -C ./        ##tar用时43s
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets

real    0m42.667s
user    0m0.859s
sys     0m16.059s

--exclude 排除文件

范例:

tar zcvf /root/a.tar.gz --exclude=/app/host1 --exclude=/app/host2 /app

-T 选项指定输入文件 -X 选项指定包含要排除的文件列表

范例:

tar zcvf mybackup.tar.gz -T /root/includefilelist -X /root/excludefilelist

==压缩比:xz>bzip2>gzip>zip,但xz压缩过程时间长,推荐使用bzip2和gzip==

==tar打包压缩时,调用压缩工具,如果压缩工具不存在,就不能完成。同样适合解压缩命令==

4.2 split

split 命令可以分割一个文件为多个文件

范例:

#分割大的 tar 文件为多份小文件
split -b Size tar-file-name prefix-name(分割后的文件名前缀)
[root@centos7 tmp]# ll
-rw-r--r-- 1 root root 29316766 Jan  7 14:23 dockerd.gz
[root@centos7 tmp]# split -b 1M dockerd.gz ./docker-part
[root@centos7 tmp]# ll -h
total 56M
-rw-r--r-- 1 root root  28M Jan  7 14:23 dockerd.gz
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partaa
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partab
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partac
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partad
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partae
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partaf
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partag
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partah
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partai
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partaj
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partak
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partal
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partam
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partan
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partao
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partap
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partaq
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partar
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partas
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partat
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partau
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partav
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partaw
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partax
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partay
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partaz
-rw-r--r-- 1 root root 1.0M Jan  7 14:24 docker-partba
-rw-r--r-- 1 root root 982K Jan  7 14:24 docker-partbb

范例:

#切换成的多个小分文件使用数字后缀
split -b 1M –d mybackup.tgz mybackup-parts
[root@centos7 tmp]# ll -h
total 28M
-rw-r--r-- 1 root root 28M Jan  7 14:23 dockerd.gz
[root@centos7 tmp]# split -b 2M -d dockerd.gz docker_num
[root@centos7 tmp]# ll -h
total 56M
-rw-r--r-- 1 root root  28M Jan  7 14:23 dockerd.gz
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num00
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num01
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num02
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num03
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num04
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num05
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num06
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num07
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num08
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num09
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num10
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num11
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num12
-rw-r--r-- 1 root root 2.0M Jan  7 14:28 docker_num13
[root@centos7 tmp]#

将多个切割的小文件合并成一个大文件

cat mybackup-parts* > mybackup.tar.gz

[root@centos7 tmp]# cat docker_num* >dockerd01.gz
[root@centos7 tmp]# ll -h
-rw-r--r-- 1 root root  28M Jan  7 14:29 dockerd01.gz

4.3 cpio

cpio 是历史悠久的打包和解包工具,不过目前也已较少使用

cpio命令是通过重定向的方式将文件进行打包备份,还原恢复的工具,它可以解压以“.cpio”或者“.tar”结尾的文件

格式:

cpio [选项] > 文件名或者设备名
cpio [选项] < 文件名或者设备名

常用选项:

-o output模式     #打包,将标准输入传入的文件名打包后发送到标准输出
-i input模式      #解包,对标准输入传入的打包文件名解包到当前目录
-t          #预览,查看标准输入传入的打包文件中包含的文件列表
-d          #解包生成目录,在cpio还原时,自动的建立目录
-v          #显示打包过程中的文件名称
-A          #向已存在的归档文件中追加文件
-O filename #输出到指定的归档文件名
-I filename #对指定的归档文件名解压
-F filename #使用指定的文件名替代标准输入或输出

范例:

#将etc目录备份
find ./etc -print | cpio -ov > bak.cpio
#将/data内容追加bak.cpio
find /data | cpio -oA -F bak.cpio
#内容预览
cpio –tv < etc.cpio
#解包文件
cpio –idv < etc.cpio

#将按原目录结构解包展开到当前所在目录下。若以相对路径打包的,当解包展开时,也是以相对路径存放展开的文件数据;若以绝对路径打包的,当解包展开时,也是以绝对路径存放展开的文件数据。因此注意若为相对路径,应先进入相应的目录下再展开。 

#打包data下的文件到tmp下的2.cpio
[root@centos7 data]# find ./ |cpio -ov >/tmp/2.cpio 
./
./fa.txt
./a.txt
./b.txt
./f.patch
./f1.txt.orig
./f1.txt
./f-a.txt
./out2.txt
./kq.txt
./2021-01-22.tar
./1.cpio
./d.txt
1614 blocks
[root@centos7 data]# ll /tmp
-rw-r--r-- 1 root root 826368 Jan 22 13:44 2.cpio
#查看2.cpio包的文件
[root@centos7 data]# cpio -tv </tmp/2.cpio
drwxr-xr-x   2 root     root            0 Jan 22 13:36 ./
-rw-r--r--   1 root     root           16 Dec 16 16:11 fa.txt
-rw-r--r--   1 root     root           18 Dec 17 13:35 a.txt
-rw-r--r--   1 root     root           20 Dec 17 13:35 b.txt
-rw-r--r--   1 root     root          157 Dec 17 16:50 f.patch
-rw-r--r--   1 root     root           19 Dec 17 16:49 f1.txt.orig
-rw-r--r--   1 root     root            0 Dec 28 10:47 f1.txt
-rw-r--r--   1 root     root            0 Dec 28 10:47 f-a.txt
-rw-r--r--   1 root     root            0 Dec 28 10:47 out2.txt
-rw-r--r--   1 root     root            0 Dec 28 10:47 kq.txt
-rw-r--r--   1 root     root       296960 Jan 22 13:15 2021-01-22.tar
-rw-r--r--   1 root     root       528384 Jan 22 13:32 1.cpio
-rw-r--r--   1 root     root            0 Jan 22 13:36 d.txt
1614 blocks
#直接解压缩到当前目录
[root@centos7 tmp]# cpio -idv </tmp/2.cpio
.
fa.txt
a.txt
b.txt
f.patch
f1.txt.orig
f1.txt
f-a.txt
out2.txt
kq.txt
2021-01-22.tar
1.cpio
d.txt
1614 blocks
[root@centos7 tmp]# ll /tmp
total 1636
-rw-r--r-- 1 root root 528384 Jan 22 13:45 1.cpio
-rw-r--r-- 1 root root 296960 Jan 22 13:45 2021-01-22.tar
-rw-r--r-- 1 root root 826368 Jan 22 13:44 2.cpio
-rw-r--r-- 1 root root     18 Jan 22 13:45 a.txt
-rw-r--r-- 1 root root     20 Jan 22 13:45 b.txt
-rw-r--r-- 1 root root      0 Jan 22 13:45 d.txt
-rw-r--r-- 1 root root      0 Jan 22 13:45 f1.txt
-rw-r--r-- 1 root root     19 Jan 22 13:45 f1.txt.orig
-rw-r--r-- 1 root root      0 Jan 22 13:45 f-a.txt
-rw-r--r-- 1 root root     16 Jan 22 13:45 fa.txt
-rw-r--r-- 1 root root    157 Jan 22 13:45 f.patch
-rw-r--r-- 1 root root      0 Jan 22 13:45 kq.txt
-rw-r--r-- 1 root root      0 Jan 22 13:45 out2.txt

#解压缩到/cpio目录下,必须进入cpio目录下才能解压缩
[root@centos7 tmp]# mkdir /cpio
[root@centos7 tmp]# cd /cpio/
[root@centos7 cpio]# cpio -idv </tmp/2.cpio
.
fa.txt
a.txt
b.txt
f.patch
f1.txt.orig
f1.txt
f-a.txt
out2.txt
kq.txt
2021-01-22.tar
1.cpio
d.txt
1614 blocks
[root@centos7 cpio]# ll
total 828
-rw-r--r-- 1 root root 528384 Jan 22 13:57 1.cpio
-rw-r--r-- 1 root root 296960 Jan 22 13:57 2021-01-22.tar
-rw-r--r-- 1 root root     18 Jan 22 13:57 a.txt
-rw-r--r-- 1 root root     20 Jan 22 13:57 b.txt
-rw-r--r-- 1 root root      0 Jan 22 13:57 d.txt
-rw-r--r-- 1 root root      0 Jan 22 13:57 f1.txt
-rw-r--r-- 1 root root     19 Jan 22 13:57 f1.txt.orig
-rw-r--r-- 1 root root      0 Jan 22 13:57 f-a.txt
-rw-r--r-- 1 root root     16 Jan 22 13:57 fa.txt
-rw-r--r-- 1 root root    157 Jan 22 13:57 f.patch
-rw-r--r-- 1 root root      0 Jan 22 13:57 kq.txt
-rw-r--r-- 1 root root      0 Jan 22 13:57 out2.txt
[root@centos7 cpio]#

#如果使用绝对路径,那么压缩文件没有问题,但解压缩时,不能解压缩到当前目录
[root@centos7 data]# find /etc/ -name "*.conf" |cpio -ov >conf.cpio
/etc/resolv.conf
/etc/libaudit.conf
...省略...
435 blocks
[root@centos7 data]# ll
-rw-r--r-- 1 root root 222720 Jan 22 16:36 conf.cpio
[root@centos7 data]# cd /cpio
[root@centos7 cpio]# ll
total 0
[root@centos7 cpio]# cpio -idv </data/conf.cpio     ##解压缩时,会以绝对路径来解开
cpio: /etc/resolv.conf not created: newer or same age version exists
/etc/resolv.conf
cpio: /etc/libaudit.conf not created: newer or same age version exists
/etc/libaudit.conf
...省略...
435 blocks
[root@centos7 cpio]#

5 实例

1、编写脚本createuser.sh,实现如下功能:使用一个用户名做为参数,如果 指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息。

[root@centos7 scripts]# vi createuser.sh
#!/bin/bash
read -p "Please input username: " NAME
id $NAME &> /dev/null && echo "The username already exists." || { useradd $NAME;echo "user created successfully"; }
echo "The username is: `getent passwd |grep $NAME` "

[root@centos7 scripts]# bash createuser.sh
Please input username: wang
The username already exists.
The username is: wang:x:1000:1000::/home/wang:/bin/bash
[root@centos7 scripts]# bash createuser.sh
Please input username: dong
user created successfully
The username is: dong:x:1002:1002::/home/dong:/bin/bash

2、编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等。

##shell脚本注释规范
[root@centos7 ~]# vim .vimrc
set nu
set ignorecase
set cursorline
set autoindent
set expandtab
set ts=4
autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
    if expand("%:e") == 'sh'
    call setline(1,"#!/bin/bash")
    call setline(2,"#")
    call setline(3,"#***************************************")
    call setline(4,"#Author:        dong")
    call setline(5,"#QQ:            25448779")
    call setline(6,"#Date:          ".strftime("%Y-%m-%d"))
    call setline(7,"#FileName:      ".expand("%"))
    call setline(8,"#URL:           http://www.magedu.com")
    call setline(9,"#Description:   The test script")
    call setline(10,"#Copyright (C):        ".strftime("%Y")." All rights reserved")
    call setline(11,"#***************************************")
    call setline(12,"")
    endif
endfunc
autocmd BufNewFile * normal G

[root@centos7 scripts]# vim hello.sh
  1 #!/bin/bash
  2 #
  3 #***************************************
  4 #Author:        dong
  5 #QQ:            25448779
  6 #Date:          2020-12-26
  7 #FileName:      hello.sh
  8 #URL:           http://www.magedu.com
  9 #Description:   The test script
 10 #Copyright (C): 2020 All rights reserved
 11 #***************************************
 12

3、查找/etc目录下大于1M且类型为普通文件的所有文件。

[root@centos7 ~]# find /etc -type f -size +1M -ls
33574980 7760 -r--r--r--   1 root     root      7942570 Jan  9 11:20 /etc/udev/hwdb.bin
17107935 3808 -rw-------   1 root     root      3896194 Nov  2  2018 /etc/selinux/targeted/active/policy.kern
50724178 1380 -rw-r--r--   1 root     root      1412826 Nov  2  2018 /etc/selinux/targeted/contexts/files/file_contexts.bin
33905264 3808 -rw-r--r--   1 root     root      3896194 Nov  2  2018 /etc/selinux/targeted/policy/policy.31
[root@centos7 ~]#

4、打包/etc/目录下面所有conf结尾的文件,压缩包名称为当天的时间,并拷贝到/usr/local/src目录备份。

[root@centos7 ~]# find /etc -name "*.conf"|xargs tar cf /data/`date +%F`.tar|cpio -ov >/usr/local/src/bak_`date +%F`.tar.cpio
tar: Removing leading `/' from member names
1 block
[root@centos7 ~]# ll /data
total 312
-rw-r--r-- 1 root root 296960 Jan 22 13:15 2021-01-22.tar
-rw-r--r-- 1 root root     18 Dec 17 13:35 a.txt
-rw-r--r-- 1 root root     20 Dec 17 13:35 b.txt
-rw-r--r-- 1 root root      0 Dec 28 10:47 f1.txt
-rw-r--r-- 1 root root     19 Dec 17 16:49 f1.txt.orig
-rw-r--r-- 1 root root      0 Dec 28 10:47 f-a.txt
-rw-r--r-- 1 root root     16 Dec 16 16:11 fa.txt
-rw-r--r-- 1 root root    157 Dec 17 16:50 f.patch
-rw-r--r-- 1 root root      0 Dec 28 10:47 kq.txt
-rw-r--r-- 1 root root      0 Dec 28 10:47 out2.txt
[root@centos7 ~]# ll /usr/local/src/
total 4
-rw-r--r-- 1 root root 512 Jan 22 13:15 bak_2021-01-22.tar.cpio
[root@centos7 ~]#

5、查找当前系统上没有属主或属组,且最近一个周内曾被访问过的文件或目录。

#初始化文件
[root@centos7 ~]# useradd test
[root@centos7 ~]# getent passwd|grep test
test:x:1002:1002::/home/test:/bin/bash
[root@centos7 ~]# getent group|grep test
test:x:1002:
[root@centos7 ~]# userdel test      ##不加r选项,只删除用户,但家目录还在
[root@centos7 ~]# ll /home
total 0
drwx------. 2 mage mage 62 Jan 10 10:38 mage
drwx------. 2 1002 1002 62 Jan 10 10:38 test
drwx------. 2 wang wang 62 Jan 10 10:38 wang

[root@centos7 ~]# find / \( -nouser -o -nogroup \) -ls
50767938    0 -rw-rw----   1 1002     mail       0 Jan 10 10:38 /var/spool/mail/test
50763320    0 drwx------   2 1002     1002      62 Jan 10 10:38 /home/test
50763327    4 -rw-r--r--   1 1002     1002      18 Oct 30  2018 /home/test/.bash_logout
50767936    4 -rw-r--r--   1 1002     1002     193 Oct 30  2018 /home/test/.bash_profile
50767937    4 -rw-r--r--   1 1002     1002     231 Oct 30  2018 /home/test/.bashrc
[root@centos7 ~]# find / \( -nouser -o -nogroup \) -mtime -7 -ls
50767938    0 -rw-rw----   1 1002     mail       0 Jan 10 10:38 /var/spool/mail/test
50763320    0 drwx------   2 1002     1002      62 Jan 10 10:38 /home/test

6、查找/etc目录下至少有一类用户没有执行权限的文件。

[root@centos7 etc]# ll file*.txt
-rwxr--r--. 1 root root 0 Jan 10 22:02 file1.txt
-rw-r-xr--. 1 root root 0 Jan 10 22:02 file2.txt
-rw-r--r-x. 1 root root 0 Jan 10 22:02 file3.txt
-rwxr-xr--. 1 root root 0 Jan 10 22:02 file4.txt
-rw-r-xr-x. 1 root root 0 Jan 10 22:02 file5.txt
-rwxr-xr-x. 1 root root 0 Jan 10 22:27 file6.txt

[root@centos7 etc]# find /etc -type f -maxdepth 1 \( ! -perm /100 -o ! -perm /010 -o ! -perm /001 \) -ls
#共计96个文件,只列出了其中一部分。
16777282    4 -rw-r--r--   1 root     root          501 Jan  9 11:12 /etc/fstab
16777283    0 -rw-------   1 root     root            0 Jan  9 11:12 /etc/crypttab
16821203    4 -rw-r-----   1 root     root          191 Jun 19  2018 /etc/libaudit.conf
16904911    0 -rw-------   1 root     root            0 Jan  9 11:12 /etc/.pwd.lock
16904912    4 ----------   1 root     root          383 Jan 10 10:38 /etc/gshadow-
16777618    4 ----------   1 root     root          374 Jan 10 10:39 /etc/gshadow
16793769    4 ----------   1 root     root          666 Jan 10 10:38 /etc/shadow-
16777294    4 ----------   1 root     root          639 Jan 10 10:39 /etc/shadow
16816866    4 -rw-r--r--   1 root     root           23 Nov 23  2018 /etc/issue
16962200    4 -rw-r--r--   1 root     root          451 Jun  9  2014 /etc/crontab
16985017    4 -rw-r--r--   1 root     root          970 Nov  4  2018 /etc/yum.conf
16777615    4 -rw-r--r--   1 root     root            8 Jan 10 10:34 /etc/hostname
16777660    0 -rwxr--r--   1 root     root            0 Jan 10 22:02 /etc/file1.txt
16777661    0 -rw-r-xr--   1 root     root            0 Jan 10 22:02 /etc/file2.txt
16777662    0 -rw-r--r-x   1 root     root            0 Jan 10 22:02 /etc/file3.txt
16777663    0 -rwxr-xr--   1 root     root            0 Jan 10 22:02 /etc/file4.txt
16959780    0 -rw-r-xr-x   1 root     root            0 Jan 10 22:02 /etc/file5.txt

[root@centos7 etc]# find /etc -type f -maxdepth 1 \( ! -perm /100 -o ! -perm /010 -o ! -perm /001 \) |wc -l
96
[root@centos7 etc]# find /etc -type f -maxdepth 1 ! \( -perm /100 -a -perm /010  -perm /001 \) |wc -l
96
[root@centos7 etc]# find /etc -type f -maxdepth 1 ! -perm /111 |wc -l
91  ###不能匹配上file1~file5这5个文件。

猜你喜欢

转载自blog.51cto.com/puppydong/2603675