运维工程师必会的Linux命令

1. 运维工程师必会Linux命令

1.1 其他运算工具

1.1.1 let

let是赋值运算符,支持++、--

[root@gzr ~]# let VAR=(1+2)*3; echo $VAR
9
[root@gzr ~]# x=10; y=5
[root@gzr ~]# let x++; echo $x ; let y--; echo $y
11
4

1.1.2 expr

描述:expr 乘法需要加反斜杠转义\

# 运算符两边必须有空格
[root@gzr ~]# expr 1 \* 2
2

# 使用双括号时要转义
[root@gzr ~]# expr \( 1 + 2 \) \* 2
6

# expr还可以对字符串操作
[root@gzr ~]# expr length "string"
6
# 截取字符串
[root@gzr ~]# expr substr "string" 4 6
ing
# 获取字符在字符串中出现的位置:
[root@gzr ~]# expr index "string" i
4
# 获取字符串开始字符出现的长度:
[root@gzr ~]# expr match "string" str
3

1.1.3 bc

描述:bc 计算器,支持浮点运算、平方等

# bc并非Linux CentOS自带命令,需要安装
[root@gzr ~]# yum install -y bc

# bc本身就是一个计算器,可直接输入命令,进入解释器。将管道符前面标准输出作为bc的标准输入
[root@gzr ~]# echo 1 + 2 |bc
3

[root@gzr ~]# echo 10^10 |bc
10000000000

# 用scale保留两位小数点
[root@gzr ~]# echo 'scale=2;10/3' |bc
3.33

# 由于Shell不支持浮点数比较,可以借助bc来完成需求:运算如果为真返回1,否则返回0
[root@gzr ~]# echo "1.2 < 2" |bc
1
[root@gzr ~]# echo "1.2 > 2" |bc
0

[root@gzr ~]# [ $(echo "2 > 1" |bc) -eq 1 ] && echo yes || echo no
yes

1.2 文件查看打印类

1.2.1 cat

功能:连接文件和标准输出打印
常用选项:
-b 显示非空行号
-n 显示所有行号
-T 显示 tab ,用 ^I 表示
-E 显示以 $结尾

# 连接两个文件
[root@gzr ~]# cat a.txt b.txt 
hello,world!!!
hello,shell!!!
[root@gzr ~]# cat << EOF
> hello,world!!!
> hello,shell!!!
> EOF
hello,world!!!
hello,shell!!!

# 将EOF标准输入作为cat标准输出在写到c.txt:
[root@gzr ~]# cat > c.txt << EOF
hello,boy!
hello,gril!
EOF
[root@gzr ~]# cat c.txt 
hello,boy!
hello,gril!

1.2.2 tac

功能:连接两个文件和倒序打印文件

[root@gzr ~]# tac c.txt
hello,gril!
hello,boy!

1.2.3 rev

功能:反向打印每一行

[root@gzr ~]# cat c.txt |rev
!yob,olleh
!lirg,olleh

[root@gzr ~]# echo 123 | rev
321

1.2.4 wc(word count)

功能:统计文件行数、字节、字符数

wc [OPTION]... [FILE]...
wc [OPTION]... --files0-from=F

  • 常用选项:
    -c 打印文件字节数 ,一个英文 字母 1字节,一个 字节,一个 汉字占 2-4字节 (根据 编码)
    -m 打印文件字符数 ,一个汉字占 2个字符

    -w : words

    -l 打印多少行
    -L 打印最长行的度 ,也可以统计字符串长度

[root@gzr ~]# cat python_zen.txt 
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

# 行数
[root@gzr ~]# wc -l python_zen.txt 
21 python_zen.txt
# 最长行的字数
[root@gzr ~]# wc -L python_zen.txt 
69 python_zen.txt

1.3 文件目录操作类

1.3.1 rename

功能:重命名文件,支持通配符

# 将user1~user9替换为user01~user09
[root@gzr ~]# rename user user0 user?

# 将所有以.txt1替换为txt
[root@gzr ~]# rename .txt1 .txt *.txt1

1.3.2 dirname

dirname 命令读取指定路径名删除最后一个“/”(斜杠)及其后面的字符,保留其他部分,并写结果到标准输出。如果最后一个“/”后无字符,dirname 命令使用倒数第二个“/”,并忽略其后的所有字符。

命令 dirname 和 basename 通常在 shell 内部命令替换使用,以指定一个与指定输入文件名略有差异的输出文件名。

[root@gzr ~]# dirname /usr/bin/sort 
/usr/bin
[root@gzr ~]# dirname /usr/local/nginx/  /usr/local/tomcat/
/usr/local
/usr/local

# 如果文件在当前目录下,则打印“.”
[root@gzr ~]# dirname a.txt
.

1.3.3 basename

为basename指定一个路径,basename命令会删掉所有的前缀包括最后一个slash(‘/’)字符,然后将字符串显示出来。

常用选项:

-a : 支持多个参数

-s : 删除后面的后缀

[root@gzr ~]# basename /usr/local/nginx/
nginx

[root@gzr ~]# basename /etc/rc.d .d
rc

[root@gzr ~]# basename -s .d /etc/rc.d
rc

1.3.4 cut

功能:选取文件的每一行数据

只能使用单个分隔符

常用选项:
-b 选中第几个字符
-c 选中多少个字符
-d 指定分隔符分字段 ,默认是空格
-f 显示选中字段

# 截取第2个字符
[root@gzr ~]# echo abc | cut -b 2
b

# 截取前4个字符
[root@gzr ~]# echo abcdefg | cut -b 1-4
abcd

[root@gzr ~]# cat /etc/passwd |head -n 5
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

# 显示/etc/passwd中的用户
[root@gzr ~]# cat /etc/passwd |head -n 5 |cut -d: -f1
root
bin
daemon
adm
lp

# 显示用户和使用的shell,1,7字段
[root@gzr ~]# cut -d: -f1,7 /etc/passwd
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
adm:/sbin/nologin
lp:/sbin/nologin
sync:/bin/sync
shutdown:/sbin/shutdown
halt:/sbin/halt
mail:/sbin/nologin
operator:/sbin/nologin
games:/sbin/nologin
ftp:/sbin/nologin
nobody:/sbin/nologin
systemd-network:/sbin/nologin
dbus:/sbin/nologin
polkitd:/sbin/nologin
sshd:/sbin/nologin
postfix:/sbin/nologin
nginx:/sbin/nologin
gzr:/bin/bash
wangwu:/bin/bash
ntp:/sbin/nologin
bash:/bin/bash
basher:/bin/bash
nologin:/sbin/nologin
testbash:/bin/bash

1.3.5 tr

功能:替换或删除字符
格式:Usage: tr [OPTION]... SET1 SET2]
常用选项:
-c 替换 SET1 没有 SET2 SET2的字符
-d 删除 SET1 中字符
-s 压缩 SET1 中重复的字符
-t 将 SET1 用 SET2 SET2转

# 替换字符
[root@gzr ~]# echo "aaabbbccc" | tr -c c 1
111111ccc

# 去重字符
[root@gzr ~]# echo "aaacccddd" | tr -s '[a-z]'
acd

# 删除字符
[root@gzr ~]# echo "aaabbbccc" | tr -d b
aaaccc

# 删除特殊符号,比如换行符
[root@gzr ~]# echo -e "a\nb\nc"
a
b
c
[root@gzr ~]# echo -e "a\nb\nc" |tr -d '\n'
abc

# 大小写替换
[root@gzr ~]# echo "abc" | tr '[a-z]' '[A-Z]'
ABC

1.3.6 stat

功能:显示文件或文件的系统状态
常用选项:
-Z 显示 selinux 安全上下文
-f 显示文件系统状态
-c 指定格式输出内容
-t 以简洁的形式打印

# 显示文件信息
[root@gzr ~]# stat python_zen.txt 
  File: ‘python_zen.txt’
  Size: 857           Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 34092297    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-07-02 10:50:02.328000000 +0800
Modify: 2019-07-02 10:18:59.765000000 +0800
Change: 2019-07-02 10:31:20.529000000 +0800
 Birth: -

# 显示文件修改信息
[root@gzr ~]# stat -c %y python_zen.txt 
2019-07-02 10:18:59.765000000 +0800

1.3.7 rm系

  • 删除文件用哪个命令?rm
  • 如果需要连目录及目录下文件一块删除呢?rm -r
  • 删除空文件夹用什么命令?rmdir

1.4 打印数字类

1.4.1 seq

功能:打印序列化数字
常用选项:
-f 使用 printf 样式
格-s 指定换行符,默认是 \n
-w 等宽,用 0填充

# 数字序列
[root@gzr ~]# seq 3
1
2
3

#带0的数字序列
[root@gzr ~]# seq -w 04
01
02
03
04

# 打印范围数字
[root@gzr ~]# seq 2 5
2
3
4
5

# 步长序列
[root@gzr ~]# seq 0 2 10
0
2
4
6
8
10

# 等宽并在数字前面加字符串,其中%g是默认数字位数,02是数字不足2位时用0填充
[root@gzr ~]# seq -f "str%02g" 3
str01
str02
str03

1.4.2 shuf

功能:生成随机序列
常用选项:
-i 输出数字范围
-o 结果写入文件

[root@gzr ~]# seq 5 | shuf
5
3
2
1
4
[root@gzr ~]# shuf -i 5-10
5
6
9
8
10
7

1.5 文本处理类

1.5.1 sort排序

功能:排序文本 ,默认对整列有效

sort [OPTION]... [FILE]...
sort [OPTION]... --files0-from=F

常用选项:
-f 忽略字母大小写
-M 根据月份比较 ,比如 JAN 、DEC
-h 根据易读的 单位 大小比较 ,比如 2K 、1G
-g 按照 常规数值排序
-n 根据 字符串数值 比较
-r 倒序排序

-k 位置 1, 位置 2 根据关键字排序, 在从第 位置 1开始, 位置 2结束
-t 指定分隔符
-u 去重复行(连续且相同)
-o 将结果写入文件

[root@gzr ~]# seq 5 |shuf |sort
1
2
3
4
5

[root@gzr ~]# printf "%c\n" {a..f} |shuf |sort
a
b
c
d
e
f

# 倒序排序
[root@gzr ~]# printf "%c\n" {a..f} |shuf |sort -r
f
e
d
c
b
a

# 分隔后字段排序,-k根据uid, -t指定分隔符,-n 根据字符数值大小排序
[root@gzr ~]# cat /etc/passwd |sort -t : -k 3 -n
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
......

# 去重重复行
[root@gzr ~]# echo -e "a\na\nb\nc\nc" |sort -u
a
b
c

# 按大小单位排序
[root@gzr ~]# du -h |sort -k 1 -h -r
115M    .
48M    ./tomcat-java-demo
41M    ./tomcat-java-demo/target
37M    ./.m2/repository

[root@gzr ~]# cat file
zhangsan 6 100
lisi 8 80 
wangwu 7 90 
zhaoliu 9 70
# 对file文件的第二列正序排序,在此基础上再对第三列倒序排序(多列排序)
[root@gzr ~]# sort -k 2 -n -k 3 -nr file
zhaoliu 9 70
lisi 8 80 
wangwu 7 90 
zhangsan 6 100

# 对两个文件同时排序
[root@gzr ~]# sort file1 file2

1.5.2 uniq(去重字符)

功能:报告或去除重复行 ,只会统计相邻的
常用选项:
-c 打印出现的次数
-d 只打印重复行
-u 只打印不重复行
-D 只打印重复行,并且把所有出来
-f N 比较 时跳过 前 N列
-i 忽略大小写
-s N 比较时 跳过前 N个字符
-w N 对每行第 N个字符以后内容不做比较

# 去重复行
[root@gzr ~]# cat file
abc
cde
efg
abc
cde
xyz
[root@gzr ~]# sort file |uniq
abc
cde
efg
xyz

# 打印每行重复次数
[root@gzr ~]# sort file |uniq -c
      2 abc
      2 cde
      1 efg
      1 xyz

# 打印不重复行
[root@gzr ~]# sort file |uniq -u
efg
xyz

# 打印重复行
[root@gzr ~]# sort file |uniq -d
abc
cde

# 根据前几个字符去重
[root@gzr ~]# sort file |uniq -w 2
abc
cde
efg
xyz

1.5.3 tee(从标准输入读取写到标准输出或文件)

  • 常用选项
    • -a 追加到文件
[root@gzr ~]# echo 123 |tee -a file
123
[root@gzr ~]# cat -n file
     1    abc
     2    cde
     3    efg
     4    abc
     5    cde
     6    xyz
     7    123

1.5.4 join(连接文件)

功能:连接两个文件
常用选项:
-i 忽略大小写
-o 按照指定文件栏位显示
-t 使用字符作为输入和出段分隔

[root@gzr ~]# cat file1
1 a
2 b
3 c
[root@gzr ~]# cat file2
1 x
2 y
3 z

# 将两个文件相同的字段合并成一列
[root@gzr ~]# join file1 file2
1 a x
2 b y
3 c z

# 打印file1第二列和file2第二列:
[root@gzr ~]# join -o 1.2 2.2 file1 file2
a x
b y
c z

# 使用:拼接两个文件的不同列
[root@gzr ~]# join -t ':' -o 1.1 2.1 /etc/passwd /etc/shadow 
root:root
bin:bin
daemon:daemon
adm:adm
lp:lp
sync:sync
shutdown:shutdown
halt:halt
mail:mail
operator:operator
games:games
ftp:ftp
nobody:nobody
systemd-network:systemd-network
dbus:dbus
polkitd:polkitd
sshd:sshd
postfix:postfix
nginx:nginx
gzr:gzr
zhangsan:zhangsan
lisi:lisi
wangwu:wangwu
ntp:ntp

1.5.5 paste(合并文件)

常用选项:
-d 指定分隔符,默认是 tab 键分隔
-s 将文件内容平行 合并 ,默认 tab 键分隔

[root@gzr ~]# seq 1 3 > file1
[root@gzr ~]# seq 4 6 > file2
[root@gzr ~]# paste file1 file2
1    4
2    5
3    6

# 两个文件合并,+号分隔:
[root@gzr ~]# paste -d "+" file1 file2
1+4
2+5
3+6

# 文件内容平行显示
[root@gzr ~]# paste -s file1 file2
1    2    3
4    5    6

1.5.6 head(输出文件前几行)

功能:输出文件的前几行
常用选项:
-c 打印前多少 K,M
-n 打印前多少行

[root@gzr ~]# cat file
abc
cde
efg
abc
cde
xyz
123

# 打印前3行
[root@gzr ~]# head -n 3 file
abc
cde
efg

1.5.7 tail(输出文件后几行)

常用选项:
-c 打印后 多少 K,M
-f 实时读文件,随着输出
附加-n 输出最后几行
-- pid 与-f一起使用,表示 pid 死掉后结束
-s 与-f一起使用,表示休眠多少秒输出

# 输出后3行
[root@gzr ~]# tail -n 3 file
cde
xyz
123

# 输出新增行
[root@gzr ~]# cat > file << EOF
> 456
> EOF
[root@gzr ~]# tail -f file
456

  • 如何获取文本文件的第10行
head -10 file | tail -1

1.5.8 xargs(从标准输入执行命令)

常用选项:
-a file 从指定文件读取数据作为标准输入
-0 处理包含空格的文件名 ,print0
-d delimiter 分隔符,默认是空格显示
-i 标准输入的结果以 {} 代替
-I 标准输入的结果以指定名字代替
-t 显示执行命令
-p 交互式提示是否执行命令
-n 最大命令行参数
-- show -limits 查看系统命令行长度限制

# 将find的结果作为输入,删除
[root@gzr ~]# find /root -name 1.txt | xargs /bin/rm -f

#列转行(去除换行符 )
[root@gzr ~]# cut -d: -f1 < /etc/passwd |sort |xargs echo
adm bin daemon dbus ftp games gzr halt lisi lp mail nginx nobody ntp operator polkitd postfix root shutdown sshd sync systemd-network wangwu zhangsan

# 行转列
[root@gzr ~]# echo "1 2 3 4 5"
1 2 3 4 5
[root@gzr ~]# echo "1 2 3 4 5" |xargs -n1
1
2
3
4
5

# 创建未来一周的时间
[root@gzr ~]# seq 1 7 |xargs -i date -d "{} days " +%Y-%m-%d
2019-07-03
2019-07-04
2019-07-05
2019-07-06
2019-07-07
2019-07-08
2019-07-09

# 复制多个目录,将a.txt的内容复制到dir1和dir2中
[root@gzr ~]# echo dir1 dir2 |xargs -n1 cp a.txt
[root@gzr ~]# cat a.txt 
hello,world!!!
[root@gzr ~]# ls
dir1            dir2         a.txt
[root@gzr ~]# cat dir1
hello,world!!!

写程序为用户计算主组数和显示次数和组名

[root@gzr ~]# cat /etc/passwd |cut -d: -f4 |sort |uniq -c |while read c g; do { echo $c; grep :$g: /etc/group |cut -d: -f1;} | xargs -n 2 ; done

1.5.9 nl(打印文件行号)

常用选项:
-b <a|t> 指定行号显示方式, a表示所有行都打印号, b表示空行不显号,默认是 a
-n < ln|rn|rz> 行号显示方法, ln 左对齐, rn 右对齐, rz 右边显示,左空白用 0填充。 填充。
-w 行号栏位在左边占用的宽度

# 打印行号,空行不显示
[root@gzr ~]# cat c.txt 
hello,boy!
hello,gril!
[root@gzr ~]# nl c.txt 
     1    hello,boy!
     2    hello,gril!

# 左对齐打印行号
[root@gzr ~]# nl -n ln c.txt
1         hello,boy!
2         hello,gril!

# 行号右移动5个空格
[root@gzr ~]# nl -w 5 c.txt 
    1    hello,boy!
    2    hello,gril!

1.5.10 iconv(文件字符集转换)

常用选项:
-l 列出所有已知的 字符集
-f 原始文本 编码
-t 输出 编码
-o 输出到文件
-s 关闭 警告

# 将文件内容转换UTF8: 
[root@gzr ~]#iconv -f gbk -t utf8 old.txt -o new.txt 
# 将csv文件转换GBK: 
[root@gzr ~]# iconv -f utf8 -t gbk old.txt -o new.txt 
#解决邮件乱码: 
[root@gzr ~]# echo $(echo "content" | iconv -f utf8 -t gbk) | mail -s "$(echo "title" | iconv -f utf8 -t gbk)" example@mail.com

1.5.11 diff (比较两个文件的不同之处)

NAME
diff - compare files line by line

SYNOPSIS
diff [OPTION]... FILES

常用选项:

-u 使用unified风格,即显示要修改的行的上下文,默认为3行。

(1)常用于打补丁

通过比较新文件与老文件的不同之处,然后打补丁

~]# yum install -y patch

~]# diff fstab fstab.new 
2c2
< #
---
> # comment

~]# diff fstab fstab.new > fstab.patch

~]# patch -i fstab.patch fstab
# 或
~]# patch fstab < fstab.patch

patching file fstab

# 再比较两个文件,就不会有不同的地方了
~]# diff fstab fstab.new 

# 如果补丁不合适,可以再撤回补丁,前提是补丁.patch文件存在。
~]# patch -R -i fstab.patch fstab
patching file fstab

练习:取出ifconfig eth0中的inet地址(cut)

# 采用grep匹配到行,采用sed删除行首的空白,再采用cut截取ip字段
~]# ifconfig eth0 | grep -E '\<inet\>' | sed 's/^ *//' | cut -d" " -f2

1.6 文件目录查找类

1.6.1 find(重点)

功能:目录层次结构中搜索文件
格式: find path -option actions
常用选项:
-name 文件名,支持 (‘*’, ‘?’)
-type 文件类型, d目录, f常规文件等
-perm 符合权限的文件,比如 755
-atime -/+n 在 n天以内 /过去 n天被访问过 天被访问过
-ctime -/+n 在 n天以内 /过去 n天被修改过 天被修改过
-amin -/+n 在 n天以内 /过去 n分钟被访问过 分钟被访问过
-cmin -/+n 在 n天以内 /过去 n分钟被修改过 分钟被修改过
-size -/+n 文件大小于 /大于, b、k、M、G
-maxdepth levels 目录层次显示的最大深度
-regex pattern 文件名匹配正则表达式
模-inum 通过 inode 编号查找文件
动作:
-detele 删除文件
-exec command {} ; 执行命令,花括号代表当前文件
-ls 列出当前文件, ls -dils 格式
-print 完整的文件名并添加一个回车换行符
-print0 打印完整的文件名并不添加一个回车换行符
-printf format 打印格式
其他 字符:
! 取反
-or /-o 逻辑 或
-and 逻辑 和

# 按文件名和搜索范围查询,模糊查询
[root@gzr ~]# find / -name "*http*"
/boot/grub2/i386-pc/http.mod
/etc/httpd
/root/nginx-1.17.0/src/http
......

# 查找当前目录常规文件并查看文件类型:
[root@gzr ~]# find . -type f -exec file '{}' \;

# 按文件权限来查询
[root@gzr ~]# find . -perm 600
./anaconda-ks.cfg
./.bash_history
./.viminfo

# 按文件大小查询,查找大于1024k的文件
[root@gzr ~]# find . -size -1024k

1.7 时间类

1.7.1 date(打印或设置系统日期和时间)

常用选项:
-d string 显示指定字符串所描述的时间
,而非当前-f datefile 从日期文件中按行读入时间描述
-I 输出 ISO 8601 格式的日期和时间
-r 显示文件的最后修改时间
-R 输出 RFC 2822 格式的日期和时间
-s string 设置时间所描述的字符串
-u 打印或设置 UTC 时间
控制输出格式:
%% 一个文字的 %
%a 当前 locale 的星期名缩写 (例如: 日 ,代表星期)
%A 当前 locale 的星期名全称 (如:星期日 )
%b 当前 locale 的月名缩写 (如:一,代表月 )
%B 当前 locale 的月名全称 (如:一月 )
%c 当前 locale 的日期和时间 (如: 2005 年 3月 3日 星期四 23:05:25)
%C 世纪;比如 %Y ,通常为省略当前年份的后两位数字 (例如: 20)
%d 按月计的日期 (例如: 01)
%D 按月计的日期;等于 %m/%d/%y
%e 按月计的日期,添加空格等于 %_d
%F 完整日期格式,等价于 %Y -%m -%d
%g ISO -8601 格式年份的最后两位 (参见 %G)
%G ISO -8601 格式年份 (参见 %V) ,一般只和 %V 结合使用
%h 等于 %b
%H 小时 (00 -23)
%I 小时 (00 -12)
%j 按年计的日期 (001 -366)
%k 时(0 -23)
%l 时(1 -12)
%m 月份 (01 -12)
%M 分(00 -59)
%n 换行
%N 纳秒 (000000000 -999999999)
%p 当前 locale 下的 "上午 "或者 "下午 ",未知时输出为空
%P 与%p 类似,但是输出小写字 母
%r 当前 locale 下的 12 小时钟间 (如: 11:04 下午 )
%R 24 小时间的和分,等价于 %H:%M
%s 自 UTC 时间 1970 -01 -01 00:00 以来所经过的秒数
%S 秒(00 -60)
%t 输出制表符 Tab
%T 时间,等于 %H:%M:%S
%u 星期, 1 代表星期一
%U 一年中的第几周,以日为每星期天 (00 -53)
%V ISO -8601 格式规范下的一年中第几周,以为每星期天 (01 -53)
%w 一星期中的第几日 (0 -6) ,0 代表周一
%W 一年中的第几周,以为每星期天 (00 -53)
%x 当前 locale 下的日期描述 (如: 12/31/99)
%X 当前 locale 下的时间描述 (如: 23:13:48)
%y 年份最后两位 数(00 -99)
%Y 年

# 设置系统日期和时间:
date -s "2019-07-02 00:00:00"

# 查看当前系统时间戳
[root@gzr ~]# date +%s
1562055908

# 查看当前系统时间
[root@gzr ~]# date +'%F %T'
2019-07-02 16:26:01

# 把时间戳转换成时间
[root@gzr ~]# date -d '@1562055908' '+%F %T'
2019-07-02 16:25:08
# 把时间转换成时间戳
[root@gzr ~]# date -d '2019-07-02 16:25:08' +%s
1562055908


# 显示前1秒,1分钟,1小时,1天,1周,1个月,1年
[root@gzr ~]# date -d '-1 second' +'%F %T'
2019-07-02 16:29:45
You have new mail in /var/spool/mail/root
[root@gzr ~]# date -d '-1 minute' +'%F %T'
2019-07-02 16:29:28
[root@gzr ~]# date -d '-1 hour' +'%F %T'
2019-07-02 15:30:36
[root@gzr ~]# date -d '-1 day' +'%F %T'
2019-07-01 16:30:44
[root@gzr ~]# date -d '-1 week' +'%F %T'
2019-06-25 16:30:53
[root@gzr ~]# date -d '-1 month' +%F
2019-06-02
[root@gzr ~]# date -d '-1 year' +%F
2018-07-02

# 显示前一天,后一天的日期
[root@gzr ~]# date -d yesterday +%F
2019-07-01
[root@gzr ~]# date -d tomorrow +%F
2019-07-03

1.7.2 time(执行脚本时间)

基本概况:

Linux time命令的用途,在于量测特定指令执行时所需消耗的时间及系统资源等资讯。

例如 CPU 时间、记忆体、输入输出等等。需要特别注意的是,部分资讯在 Linux 上显示不出来。这是因为在 Linux 上部分资源的分配函式与 time 指令所预设的方式并不相同,以致于 time 指令无法取得这些资料。

  • -o 或 --output=FILE:设定结果输出档。这个选项会将 time 的输出写入 所指定的档案中。如果档案已经存在,系统将覆写其内容。
  • -a 或 --append:配合 -o 使用,会将结果写到档案的末端,而不会覆盖掉原来的内容。
  • -f FORMAT 或 --format=FORMAT:以 FORMAT 字串设定显示方式。当这个选项没有被设定的时候,会用系统预设的格式。不过你可以用环境变数 time 来设定这个格式,如此一来就不必每次登入系统都要设定一次。

time 指令可以显示的资源有四大项,分别是

  • Time resources
  • Memory resources
  • IO resources
  • Command info

详细的内容如下

1、Time Resources

E 执行指令所花费的时间,格式是:[hour]:minute:second。请注意这个数字并不代表实际的 CPU 时间。

e 执行指令所花费的时间,单位是秒。请注意这个数字并不代表实际的 CPU 时间。

S 指令执行时在核心模式(kernel mode)所花费的时间,单位是秒。

U 指令执行时在使用者模式(user mode)所花费的时间,单位是秒。

P 执行指令时 CPU 的占用比例。其实这个数字就是核心模式加上使用者模式的 CPU 时间除以总时间。

2、Memory Resources

M 执行时所占用的实体记忆体的最大值。单位是 KB

t 执行时所占用的实体记忆体的平均值,单位是 KB

K 执行程序所占用的记忆体总量(stack+data+text)的平均大小,单位是 KB

D 执行程序的自有资料区(unshared data area)的平均大小,单位是 KB

p 执行程序的自有堆叠(unshared stack)的平均大小,单位是 KB

X 执行程序间共享内容(shared text)的平均值,单位是 KB

Z 系统记忆体页的大小,单位是 byte。对同一个系统来说这是个常数

3、IO Resources

F 此程序的主要记忆体页错误发生次数。所谓的主要记忆体页错误是指某一记忆体页已经置换到置换档(swap file)中,而且已经分配给其他程序。此时该页的内容必须从置换档里再读出来。

R 此程序的次要记忆体页错误发生次数。所谓的次要记忆体页错误是指某一记忆体页虽然已经置换到置换档中,但尚未分配给其他程序。此时该页的内容并未被破坏,不必从置换档里读出来

W 此程序被交换到置换档的次数

c 此程序被强迫中断(像是分配到的 CPU 时间耗尽)的次数

w 此程序自愿中断(像是在等待某一个 I/O 执行完毕,像是磁碟读取等等)的次数

I 此程序所输入的档案数

O 此程序所输出的档案数

r 此程序所收到的 Socket Message

s 此程序所送出的 Socket Message

k 此程序所收到的信号 ( Signal )数量

4、Command Info

C 执行时的参数以及指令名称

x 指令的结束代码 ( Exit Status )

-p or --portability:这个选项会自动把显示格式设定成为:

real %e user %Usys %S:这么做的目的是为了与 POSIX 规格相容。

-v or --verbose:这个选项会把所有程序中用到的资源通通列出来,不但如一般英文语句,还有说明。对不想花时间去熟习格式设定或是刚刚开始接触这个指令的人相当有用。

[root@gzr ~]# time date
Wed Jul  3 09:00:43 CST 2019

real    0m0.004s
user    0m0.002s
sys    0m0.002s

系统先执行命令"date",第2行为命令"date"的执行结果。

第3-6行为执行命令"date"的时间统计结果,其中第4行"real"为实际时间,第5行"user"为用户CPU时间,第6行"sys"为系统CPU时间。

1.8 上传、下载、同步类命令

1.8.1 wget (非交互式网络下载)

类似于HTTP客户端

  • 常用选项:
    -b, -- background 后台运行
    日志记录和输入文件:
    -o, -- output -file=FILE 日志写到文件
    -a, -- append -output=FILE 日志追加到文件
    -d, -- debug 打印 debug 信息 ,会包含头信息
    ,会包含头-q, -- quiet 退出 ,不输
    -i, -- input -file=FILE 从文件中读取 URL 下载
    下载 选项 :
    -t, -- tries=NUMBER 设置链接重试次数
    -O, -- output -document=FILE 写入内容到文件
    -nc, -- no -clobber 跳过下载现有的文件
    -c, -- continue 断点续传
    -- progress= TYPE 设置进度条( dot 和 bar )
    -S, -- server -response 打印服务器响应头信息
    -- spider 不下载任何内容
    -T, -- timeout=SECONDS 设置相应超时间(还有 设置相应超时间(还有 -- dns -timeout 、-- connect -timeout timeout 和 -- read -timeout )
    -w, -- wait=SECONDS 两次重试间
    隔等待时-- bind -address=ADDRESS 设置绑定地址
    -- lim it -rate=RATE 限制***
    -- user=USER 设置 ftp 和 http http用户名
    -- password=PASS 设置 ftp 和 http http密码
    目录选项:
    -P, -- directory -prefix=PREFIX 保存文件目录
    HTTP 选项:
    -- http -user=USER 设置 http 用户名
    -- http -password=PASS 设置 http 密码
    -- proxy -user=USER 设置代理用户名
    -- proxy -password=PASS 设置代理密码
    -- referer=URL 设置 Referer
    -- save -headers 保存头到文件
    -- default -page=NAME 改变默认 页面名字,index.html
    -U, -- user -agent=AGENT 设置客户端信息
    -- no -http -keep -alive 禁用 HTTP keep -alive (长连接)
    -- load -cookies=FILE 从文件加载 cookies
    -- save -cookies=FILE 保存 cookies 到文件 到文件
    -- post -data=STRING 使用 POST 方法,发送数据 方法,发送数据
    FTP 选项:
    -- ftp -user=USER 设置 ftp 用户名
    -- ftp -password=PASS 设置 ftp 密码
    -- no -passive -ftp 禁用被动传输模式
    递归下载:
    -r, -- recursive 指定递归下载
    -l, -- level=NUMBER 最大递归深度
    -A, -- accept=LIST 逗号分隔下载的扩展列表
    -R, -- reject=LIST 逗号分隔不被下载的扩展列表
    -D, -- domains=LIST 逗号分隔被下载域的列表
    -- exclude -domains=LIST 排除不被下载域的列表
# 下载单个文件到当前目录:
[root@gzr ~]# wget http://nginx.org/download/nginx-1.17.1.tar.gz

# 放到后台下载,
[root@gzr ~]# wget -b  http://nginx.org/download/nginx-1.17.1.tar.gz
Continuing in background, pid 32786.
Output will be written to ‘wget-log’.

# 对于网络不稳定的用户使用-c和--tries参数,保证下载完成,并下载到指定目录不下载任何内容,
[root@gzr ~]# wget -t 3 -c http://nginx.org/download/nginx-1.17.1.tar.gz -P down

# 判断URL是否可以访问
[root@gzr ~]# wget --spider http://nginx.org/download/nginx-1.17.1.tar.gz
Spider mode enabled. Check if remote file exists.
--2019-07-02 16:55:31--  http://nginx.org/download/nginx-1.17.1.tar.gz
Resolving nginx.org (nginx.org)... 95.211.80.227, 62.210.92.35, 2001:1af8:4060:a004:21::e3
Connecting to nginx.org (nginx.org)|95.211.80.227|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1033452 (1009K) [application/octet-stream]
Remote file exists.

# 下载内容写到文件
[root@gzr ~]# cat index.html 
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');
                </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

# 从文件中读取URL下载
[root@gzr ~]# cat url.list 
http://nginx.org/download/nginx-1.17.0.tar.gz
https://www-eu.apache.org/dist/tomcat/tomcat-8/v8.5.42/bin/apache-tomcat-8.5.42.tar.gz

[root@gzr ~]# wget -i url.list

# 下载ftp文件
[root@gzr ~]# wget --ftp-user=ftp --ftp-password=gzr_2019.lzu ftp://210.26.55.133/CentOS-7-x86_64-DVD-1810.iso

1.8.2 curl(发送数据到URL)

发送数据到 URL ,类似于 HTTP 客户端

常用选项:
-k, --insecure 允许HTTPS连接网站
-C, -- continue -at 断点续传
-b, -- cookie STRING/FILE 从文件中读取 cookie
-c, -- cookie -jar 把 cookie 保存到文件
-d, -- data 使用 POST 方式发送数据 方式发送数据
-- data -urlencode POST 的数据 URL 编码
-F, -- form 指定 POST 数据的表单
-D, -- dump -header 保存头信息到文件
-- ftp -pasv 指定 FTP 连接模式 PASV/EPSV PASV/EPSV
-P, -- ftp -port 指定 FTP 端口
-L, -- location 遵循 URL 重定向,默认不处理 重定向,默认不处理
-l, -- list -only 指列出 FTP 目录名
-H, -- header 自定义头信息发送给服务器
-I, -- head 查看 HTTP 头信息
-o, -- output FILE 输出到文件
-#, -- progress -bar 显示 bar 进度条
-x, -- proxy [PROTOCOL://]HOST[:PORT] 使用代理
-U, -- proxy -user USER[:PASSWORD] 代理用户名和密码
-e, -- referer 指定引用地址 referer
-O, -- remote -name 使用远程服务器上名字写到本地
-- connect -timeout 连接超时间,单位秒
-- retry N UM 连接重试次数
-- retry -delay 两次重试间
隔等待时-s, -- silent 静默模式,不输出任何内容
-Y, -- speed -limit 限制下载速率
-u, -- user USER[:PASSWORD] 指定 http 和 ftp ftp用户名和密码
-T, -- upload -file 上传文件
-A, -- user -agent 指定客户端信息

# 下载页面
[root@gzr ~]# curl -o badu.html http://www.baidu.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2381  100  2381    0     0  38979      0 --:--:-- --:--:-- --:--:-- 39683

# 不输出下载信息
[root@gzr ~]# curl -s -o baidu.html http://www.baidu.com

# 访问http页面
[root@gzr ~]# curl -u user:passwd https://mail.126.com/

# ftp下载文件
curl ftp://ip/filename -u user:pass -o filename

# 查看http头信息
[root@gzr ~]# curl -I http://www.baidu.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: Keep-Alive
Content-Length: 277
Content-Type: text/html
Date: Tue, 02 Jul 2019 11:55:40 GMT
Etag: "575e1f60-115"
Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
Pragma: no-cache
Server: bfe/1.0.8.18

1.8.3 scp(上传下载文件)

功能:基于 SSH 的安全远程服务器文件拷贝
常用选项:
-i 指定私钥文件
-l 限制速率,单位 Kb/s ,1024Kb=1Mb
-P 指定远程主机 SSH 端口
-p 保存修改时间、访问和权限
-r 递归拷贝目录
-o SSH 选项,有以下 几个比较 常用的:
ConnectionAttempts=NUM 连接失败后重试次数
ConnectTimeout=SEC 连接超时间
StrictHostKeyChecking=no 自动拉去主机 key 文件
PasswordAuthentication=no 禁止密码认证

# 多数安全的scp传送可能不会采用22端口,默认就是22端口,所以可以不写-P 22
[root@gzr ~]# scp -P 22 -r src_dir root@172.16.4.12:/dst_dir

#远程主机目录拉取到本地: 
[root@gzr ~]# scp -P 22 -r root@172.16.4.10:dst_dir src_dir
  • 同步文件方式一样,不用加-r参数

1.8.4 rsync(远程或本地文件同步工具)

常用选项:
-v 显示复制信息
-q 不输出错误信息
-c 跳过基础效验,不判断修改时间和大小
-a 归档模式,等效 -rlptgoD ,保留权限、属组等
-r 递归目录
-l 拷贝软连接
-z 压缩传输数据
-e 指定远程 shell ,比如 ssh 、rsh
-- progress 进度条,等同 -P
-- bwlimit=KB/s 限制速率, 0为没有限制 -- delete 删除那些 DST 中 SRC SRC没有的文件
-- exclude=PATTERN 排除匹配的文件或目录
-- exclude -from=FILE 从文件中读取要排除的或目录
-- password -file=FILE 从文件读取远程主机密码
-- port=PORT 监听端口

# 本地复制目录: 
[root@gzr ~]# rsync -avz abc /opt 
# 本地目录推送到远程主机: 
[root@gzr ~]# rsync -avz SRC root@172.168.1.120:DST 
远程主机目录拉取到本地: 
[root@gzr ~]# rsync -avz root@172.168.1.10:SRC DST 
保持远程主机目录与本地一样: 
[root@gzr ~]# rsync -avz --delete SRC root@172.168.1.120:DST 
排除某个目录: 
[root@gzr ~]# rsync -avz --exclude=no_dir SRC root@172.168.1.120:DST 
指定SSH端口: 
[root@gzr ~]# rsync -avz /etc/hosts -e "ssh -p22" root@172.168.1.120:/opt

1.8.5 sz/rz命令

rz,sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具。优点就是不用再开一个sftp工具登录上去上传下载文件。
sz:将选定的文件发送(send)到本地机器
rz:运行该命令会弹出一个文件选择窗口,从本地选择文件上传到Linux服务器

[root@gzr ~]# yum install -y lrzsz

# 从服务端发送文件到客户端
[root@gzr ~]# sz filename

# 从客户端上传文件到服务器端
[root@gzr ~]# rz

1.9 进程类

Linux 中进程有哪几种状态?在 ps 显示出来的信息中,分别用什么符号表示的?
答案:
(1)、不可中断状态:进程处于睡眠状态,但是此刻进程是不可中断的。不可中断, 指进程不响应异步信号。
(2)、暂停状态/跟踪状态:向进程发送一个 SIGSTOP 信号,它就会因响应该信号 而进入 TASK_STOPPED 状态;当进程正在被跟踪时,它处于 TASK_TRACED 这个特殊的状态。
“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。

(3)、就绪状态:在 run_queue 队列里的状态

(4)、运行状态:在 run_queue 队列里的状态
(5)、可中断睡眠状态:处于这个状态的进程因为等待某某事件的发生(比如等待 socket 连接、等待信号量),而被挂起
(6)、zombie 状态(僵尸):父亲没有通过 wait 系列的系统调用会顺便将子进程的尸体(task_struct)也释放掉
(7)、退出状态

D 不可中断 Uninterruptible(usually IO)
R 正在运行,或在队列中的进程
S 处于休眠状态
T 停止或被追踪
Z 僵尸进程
W 进入内存交换(从内核 2.6 开始无效)
X 死掉的进程

1.9.1 nohup(后台运行进程)

运行程序 ,忽略 挂起信号

# 后台运行程序,终端关闭不影响:
[root@gzr ~]# nohup bash tcp_status.sh &> tcp_status.log &
[1] 44042

1.9.2 lsof(列出打开的文件)

功能:列出打开的文件
常用选项:
-i [i] 监听的网络地址,如果没有指定,默认列出所有。
[i]来自[46][protocol][@hostname|hostaddr][:service|port]
-U 列出Unix域socket文件
-p 指定PID
-u 指定用户名或UID所有打开的文件
+D 递归搜索

[root@gzr ~]# yum install -y lsof

# 列出所有打开的监听地址和unix域socket文件
[root@gzr ~]# lsof -i -U
......
sshd       7155    root    3u  IPv4             267188      0t0    TCP gzr:ssh->210.26.55.133:socalia (ESTABLISHED)
sshd       7155    root    4u  unix 0xffffa09c25e9e000      0t0 278550 socket
sshd      40808    root    3u  IPv4             511441      0t0    TCP gzr:ssh->210.26.55.133:12594 (ESTABLISHED)
sshd      40808    root    4u  unix 0xffffa09c2af13c00      0t0 511490 socket

# 列出22端口监听的进程
[root@gzr ~]# lsof -i:22
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     4310 root    3u  IPv4  29384      0t0  TCP *:ssh (LISTEN)
sshd     4310 root    4u  IPv6  29386      0t0  TCP *:ssh (LISTEN)
sshd     7155 root    3u  IPv4 267188      0t0  TCP gzr:ssh->210.26.55.133:socalia (ESTABLISHED)
sshd    40808 root    3u  IPv4 511441      0t0  TCP gzr:ssh->210.26.55.133:12594 (ESTABLISHED)

# 列出端口1-1024之间的所有进程
[root@gzr ~]# lsof -i:1-1024
......
sshd     7155  root    3u  IPv4 267188      0t0  TCP gzr:ssh->210.26.55.133:socalia (ESTABLISHED)
sshd    40808  root    3u  IPv4 511441      0t0  TCP gzr:ssh->210.26.55.133:12594 (ESTABLISHED)

# 列出所有tcp连接
[root@gzr ~]# lsof -i tcp
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
......
sshd     7155  root    3u  IPv4 267188      0t0  TCP gzr:ssh->210.26.55.133:socalia (ESTABLISHED)
sshd    40808  root    3u  IPv4 511441      0t0  TCP gzr:ssh->210.26.55.133:12594 (ESTABLISHED)

# 列出所有udp网络连接
[root@gzr ~]# lsof -i udp
COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
snmpd    4307    root    6u  IPv4  29813      0t0  UDP *:snmp 
local   45617 postfix   16u  IPv4 548393      0t0  UDP *:33276 

# 列出进程ID打开的文件
[root@gzr ~]# lsof -p 4066

# 

1.9.3 ps

常用选项:
-a 显示所有进程
-u 选择有效的用户ID或名称
-x 显示无控制终端的进程
-e 显示所有进程
-f 全格式
-r 只显示运行的进程
-T 这个终端的所有进程
-p 指定进程ID
--sort 对某列排序
-m 线程
-L 格式化代码列表
-o 用户自定义格式
CODE NORMAL HEADER
%C pcpu %CPU
%G group GROUP
%P ppid PPID
%U user USER
%a args COMMAND
%c comm COMMAND
%g rgroup RGROUP
%n nice NI
%p pid PID
%r pgid PGID
%t etime ELAPSED
%u ruser RUSER
%x time TIME
%y tty TTY
%z vsz VSZ

# 打印系统上所有进程BSD语法
[root@gzr ~]# ps aux

# 打印系统上所有进程标准语法
[root@gzr ~]# ps -ef

# 打印进程树: 
[root@gzr ~]# ps axjf 或 ps -ejH

# 查看进程启动的线程
[root@gzr ~]# ps -Lfp 4066
UID         PID   PPID    LWP  C NLWP STIME TTY          TIME CMD
root       4066      1   4066  0    1 Jul01 ?        00:00:00 /usr/sbin/crond -n

# 查看当前用户的进程数
[root@gzr ~]# ps uxm | wc -l
216

# 自定义格式显示并对CPU排序
[root@gzr ~]# ps -eo "%U %p %C %n %x %a"

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
USER 进程 所有者
PID 进程 ID
%CPU 占用 CPU 时间
%MEM 物理 内存
VSZ 虚拟 内存大小 (kb )
RSS 驻留 集内存页数量( kb )
TTY 终端
STAT 进程 状态 ;R运行 ,S休眠 ,D不可中断 ,T停止 ,Z僵尸, N表示普通 优先级 更低的优先级
更低的START 进程 启动时间
TIME 使用 CPU 总时间
COMMAND 命令名称和参数

1.9.4 pstree(树型显示当前运行的进程)

常用选项:

  • -a 显示该行程的完整指令及参数, 如果是被记忆体置换出去的行程则会加上括号
  • -c 如果有重覆的行程名, 则分开列出(预设值是会在前面加上 *)
[root@gzr ~]# yum install -y psmisc

# 显示进程的关系
[root@gzr ~]# pstree -c

# 显示进程间的关系
[root@gzr ~]# pstree -apnh
systemd,1 --switched-root --system --deserialize 22
  ├─systemd-journal,2061
  ├─lvmetad,2076 -f
  ├─systemd-udevd,2082
  ├─auditd,4031
  │   └─{auditd},4032
  ├─dbus-daemon,4053 --system --address=systemd: --nofork --nopidfile --systemd-activation
  ├─polkitd,4057 --no-debug
  │   ├─{polkitd},4094
  │   ├─{polkitd},4095
  │   ├─{polkitd},4096
  │   ├─{polkitd},4098
  │   ├─{polkitd},4101
  │   └─{polkitd},4106
  ├─NetworkManager,4058 --no-daemon
  │   ├─{NetworkManager},4097
  │   └─{NetworkManager},4100
  ├─systemd-logind,4060
  ├─irqbalance,4061 --foreground
  ├─crond,4066 -n
  ├─agetty,4091 --noclear tty1 linux
  ├─agetty,4092 --keep-baud 115200,38400,9600 hvc0 vt220
  ├─rsyslogd,4304 -n
  │   ├─{rsyslogd},4341
  │   └─{rsyslogd},4345
  ├─snmpd,4307 -LS0-6d -f
  ├─tuned,4308 -Es /usr/sbin/tuned -l -P
  │   ├─{tuned},4674
  │   ├─{tuned},4675
  │   ├─{tuned},4676
  │   └─{tuned},4689
  ├─sshd,4310 -D
  │   ├─sshd,7155    
  │   │   └─bash,7157
  │   └─sshd,40808    
  │       └─bash,40811
  │           └─pstree,46798 -apnh
  ├─nginx,4320
  │   └─nginx,4322                   
  ├─master,4604 -w
  │   ├─qmgr,4614 -l -t unix -u
  │   └─pickup,45515 -l -t unix -u
  └─bash,5031 dir_detection.sh
      ├─inotifywait,5032 -mqr --format %f -e create /opt
      └─bash,5033 dir_detection.sh

1.9.5 job(查看后台任务)

1.10 交互登录类

1.10.1 ssh(ssh客户端)

常用选项:
-p 指定远程主机端口
-i 指定认证文件
-L [bind_address:]port:host:hostport
-R [bind_address:]port:host:hostport]
-D [bind_address:]port
-o SSH选项,有以下几个比较常用的:
ConnectionAttempts=NUM 连接失败后重试次数
ConnectTimeout=SEC 连接超时间
StrictHostKeyChecking=no 自动拉去主机 key 文件
PasswordAuthentication=no 禁止密码认证

# 登录到远程主机:
[root@gzr ~]# ssh root@172.16.4.22

# 远程主机执行命令:
[root@gzr ~]# ssh root@172.16.4.22 'df -h'
root@172.16.4.22's password: 
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   48G  3.0G   45G   7% /
devtmpfs                 7.8G     0  7.8G   0% /dev
tmpfs                    7.8G     0  7.8G   0% /dev/shm
tmpfs                    7.8G   34M  7.8G   1% /run
tmpfs                    7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/xvda1              1014M  145M  870M  15% /boot
/dev/mapper/centos-home   24G   33M   24G   1% /home
tmpfs                    1.6G     0  1.6G   0% /run/user/0

# 本地文件内容写到远程主机文件: 
[root@gzr ~]# ssh root@172.16.4.22 'cat >> file' < /etc/passwd

SSH还提供了一个非常有用的功能,就是端口转发,能帮你解决一些无法建立的连接。
1)本地端口转发
应用场景1:A不能访问C,B能访问A和C,实现通过B能让A访问C
在主机A执行:

ssh -L 2222:主机C:22 主机B # ssh -L [绑定地址:]本地端口:主机C:C端口 主机B

将SSH绑定本地端口2222,本地2222端口数据转发主机B,主机B的所有数据转发到主机C的22端口;这样一来,只要在主机A ssh -p 2222 localhost,就等于连上了主机C的22端口。
应用场景2:一台Squid代理服务器,限制了本机可以清理缓存,但是我想从远程服务器清理
在远程服务器执行:

ssh -L 31280:localhost:3128 SquidHost

在远程服务器上执行清理命令到本机31280端口,31280收到的数据加密转发到SquidHost的SSH Server上,SSH Client解密收到的数据并转发到监听的3128端口上,最后将Squid返回的数据原路返回。
2)远程端口转发
应用场景1:A不能访问C,B能访问A和C,但A不能访问B,比如A在外网,B在内网
在主机B执行:

ssh -R 2222:主机C:22 主机A

将SSH绑定本机2222端口,与主机A建立SSH通道,当主机A访问本地2222端口,就等于访问主机B的2222端口,主机B的2222端口把数据转发到主机C的22端口。
应用场景2:公司有一台内网服务器,还有一台云主机不能SSH直接连接这台公司内网服务器,但内网服务器可以SSH连接云主机
在公司内网服务器执行:

ssh -R 2222:localhost:22 云主机

将云主机上的2222端口数据转发到内网服务器SSH Client上,SSH Client解密收到的数据并转发到监听的22端口上,最后再将返回的数据原路返回。
3)动态端口转发(不限定端口,全权代理)
应用场景:***访问国外网站
如果是MAC系统直接在终端执行:ssh -D 2222 国外云主机
如果是Windows系统可借助putty工具实现,在putty里面端口转发->本地端口转发属性里面添加一个本地端口,并勾选SOCKS4/5动态转发,连接即可。
将SSH绑定本机8080端口,SSH就会创建一个SOCKS代理服务,直接在浏览器上设置代理本机127.0.0.1的8080端口即可,当浏览器访问国外网站时,本地代理把请求转发到国外云主机的SSH Server,SSH解密并转发给指定的网站。
注意:再Linux终端执行ssh绑定命令后,默认会进入一个新的shell,只要这个shell不退出,此端口转发就一直有效。如果要想放到后台执行就加-Nf两个选项,-N是不执行命令,-f后台执行,这样就转入后台运行,就可以在本地shell执行操作了,如果想关闭后台就kill这个进程。

1.10.2 sshpass(非交互ssh登录)

常用选项:
-f 从文件中获取密码
-d 用文件描述符 数字 获取密码
-p 指定 SSH 密码
-e 密码作为环境变量传递,名是 SSHPASS

[root@gzr ~]# yum install -y sshpass

# 免交互SSH登录: 
[root@gzr ~]# sshpass -p 123456 ssh root@192.168.1.10 
# 免交互传输文件: 
[root@gzr ~]# sshpass -p 123456 scp a.txt 192.168.1.10:/root 
# 密码传入系统变量: 
[root@gzr ~]# SSHPASS=123456 rsync -avz /etc/hosts -e "sshpass -e ssh" root@192.168.1.221:/opt

1.11 socket查看类命令

1.11.1 netstat

功能:打印网络连接、路由表、接口统计信息、伪装连接和多播成员
常用选项:
-r 显示路由表
-i 显示接口表
-n 不解析名字
-p 显示程序名 PID/Program
-l 显示监听的socket
-a 显示所有socket
-o 显示计时器
-Z 显示上下文
-t 只显示tcp连接
-u 只显示udp连接
-s 显示每个协议统计信息

# 显示所有监听
[root@gzr ~]# netstat -alntu

# 显示所有tcp连接
[root@gzr ~]# netstat -atnp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:199           0.0.0.0:*               LISTEN      4307/snmpd          
......        
tcp        0      0 172.16.4.11:22          210.26.55.133:5100      ESTABLISHED 7155/sshd: root@pts 
......
tcp6       0      0 :::22                   :::*                    LISTEN      4310/sshd           

# 显示所有udp连接
[root@gzr ~]# netstat -alnu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
udp        0      0 0.0.0.0:161             0.0.0.0:*   
......

1.11.2 ss

功能:比netstat更强大的socket查看工具
格式:ss [options] [ FILTER ]
常用选项:
-n 不解析名字
-a 显示所有socket
-l 显示所有监听的socket
-o 显示计时器
-e 显示socket详细信息
-m 显示socket内存使用
-p 显示进程使用的socket
-i 显示内部TCP信息
-s 显示socket使用汇总
-4 只显示IPV4的socket
-0 显示包socket
-t 只显示TCP socket
-u 只显示UDP socket
-d 只显示DCCP socket
-w 只显示RAW socket
-x 只显示Unix域socket
-f FAMILY 只显示socket族类型( unix, inet, inet6, link, netlink)
-A 查询socket {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]
-D 将原始的TCP socket转储到文件
-F 从文件中读取过滤信息
过滤:
-o state 显示TCP连接状态信息

# 显示所有TCP连接
[root@gzr ~]# ss -t -a
State      Recv-Q Send-Q                        Local Address:Port                                         Peer Address:Port                
LISTEN     0      128                               127.0.0.1:smux                                                    *:*                    
LISTEN     0      128                                       *:http                                                    *:*                    
LISTEN     0      128                                       *:ssh                                                     *:*                    
LISTEN     0      100                               127.0.0.1:smtp                                                    *:*                    
ESTAB      0      0                               172.16.4.11:ssh                                         210.26.55.133:socalia              
ESTAB      0      0                               172.16.4.11:ssh                                         210.26.55.133:12594                
LISTEN     0      128                                      :::ssh                                                    :::*                    
LISTEN     0      100                                     ::1:smtp                                                   :::*                    

# 显示所有UDP连接
[root@gzr ~]# ss -u -a
State      Recv-Q Send-Q                        Local Address:Port                                         Peer Address:Port                
UNCONN     0      0                                         *:snmp                                                    *:*                    
UNCONN     0      0                                         *:55800                                                   *:*                    
# 显示socket使用汇总
[root@gzr ~]# ss -s
Total: 566 (kernel 1071)
TCP:   8 (estab 2, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0

Transport Total     IP        IPv6
*      1071      -         -        
RAW      1         0         1        
UDP      2         2         0        
TCP      8         6         2        
INET      11        8         3        
FRAG      0         0         0        

# 显示所有建立的连接
[root@gzr ~]# ss -o state established
Netid  Recv-Q Send-Q                          Local Address:Port                                           Peer Address:Port                
u_str  0      0                                           * 29986                                                     * 29987                
                                                    * 29956                
......
tcp    0      0                                 172.16.4.11:ssh                                           210.26.55.133:socalia               timer:(keepalive,14min,0)
tcp    0      8748                              172.16.4.11:ssh                                           210.26.55.133:12594                 timer:(on,071ms,0)

# 显示所有TIME——WAIT状态
[root@gzr ~]# ss -o state TIME-WAIT
Netid  Recv-Q Send-Q                          Local Address:Port                                           Peer Address:Port                
# 搜索所有本地进程连接到X Server:
[root@gzr ~]# ss -x src /tmp/.X11-unix/*
Netid  State      Recv-Q Send-Q                     Local Address:Port                                      Peer Address:Port       

1.12 系统资源命令

1.12.1 vmstat(报告虚拟内存、swap、io、上下文和CPU统计信息)

分析了这些文件:
/proc/meminfo
/proc/stat
/proc//stat
常用选项:
-a 打印活跃和不活跃的内存页
-d 打印硬盘统计信息
-D 打印硬盘表
-p 打印硬盘分区统计信息
-s 打印虚拟内存表
-m 打印内存分配(slab)信息
-t 添加时间戳到输出
-S 显示单位,默认k、KB、m、M,大写是
1024

  • 每秒刷新一次,统计5次

1562073621407

r:CPU 正在 运行的进程数
b:在等待 I/O 的进程数
swpd :已经使用的交换内存( kb )
free :空闲 的物理内存( kb )
buff :已经使用的缓冲区内存( kb );一般对 设备 数据缓存, 写入 到磁盘的数据。

cache :已经 使用 的缓冲区内存( kb );一般对 文件 数据缓存,从磁盘读取的。
si :从磁盘交换到内存的页数量( kb /s )
so :从内存交换到磁盘的页数据( kb /s )
bi :块设备 接收 的块数量( kb/s )
bo :块设备 发送的块数量 (kb/s )
in :每秒 CPU 中断 次数
cs :每秒 CPU 上下文切换次数
us :用 户进程使CPU 时间( %)
sy :系统 进程使用 CPU 时间 (%)
id :CPU 空闲 时间( %)
wa :等待 I/O 响应 所消耗的 CPU CPU时间 (%)
st :从虚拟设备中获得的时间( %)

1.12.2 iostat(报告CPU利用率和磁盘I/O)

用法: iostat [ 选项 ] [ <时间间隔> [ <次数> ] ]
常用选项:
-c 显示CPU使用率
-d 只显示磁盘使用率
-k 单位KB/s代替Block/s
-m 单位MB/s代替Block/s
-N 显示所有映射设备名字
-t 打印报告时间
-x 显示扩展统计信息

# 每秒刷新一次,统计3次cpu利用率
[root@gzr ~]# iostat -c 1 3
Linux 3.10.0-957.21.3.el7.x86_64 (gzr)     07/02/2019     _x86_64_    (2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.05    0.00    0.14    0.00    0.16   99.65

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.50    0.00    0.00    0.00    0.00   99.50

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    0.50    0.00    0.50   99.00
  • 显示磁盘I/O 统计信息

1562074133785

1.12.3 sar(查看系统资源综合方面利用率)

应用场景:

在使用 Linux系统时,常常会遇到各种各样的问题,比如系统容易死机或者运行速度突然变慢,这时我们常常猜测:是否硬盘空间不足,是否内存不足,是否 I/O出现瓶颈,还是系统的核心参数出了问题?这时,我们应该考虑使用 sar工具对系统做一个全面了解,分析系统的负载状况。

​ sar(System ActivityReporter)是系统活动情况报告的缩写。sar工具将对系统当前的状态进行取样,然后通过计算数据和比例来表达系统的当前运行状态。它的特点是可以连续对系统取样,获得大量的取样数据;取样数据和分析的结果都可以存入文件,所需的负载很小。 sar是目前 Linux上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁盘I/O、CPU效率、内存使用状况、进程活动及IPC有关的活动等。为了提供不同的信息,sar提供了丰富的选项、因此使用较为复杂。

常用选项:
-u, CPU
-r, memory
-b, disk
-n DEV, NIC traffic
-q, systemload
-b, TPS (Transaction Per Second ,每秒 事务处理量)
-o, output to file

# 每1秒执行1次,采集3次
[root@gzr ~]# sar -u 1 3
Linux 3.10.0-957.21.3.el7.x86_64 (gzr)     07/02/2019     _x86_64_    (2 CPU)

09:28:19 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
09:28:20 PM     all      0.00      0.00      0.00      0.00      0.50     99.50
09:28:21 PM     all      0.00      0.00      0.50      0.00      0.00     99.50
09:28:22 PM     all      0.00      0.00      0.50      0.00      0.00     99.50
Average:        all      0.00      0.00      0.33      0.00      0.17     99.50

# 采集结果输出到文件
[root@gzr ~]# sar -u 1 3 -o cpu.out
Linux 3.10.0-957.21.3.el7.x86_64 (gzr)     07/02/2019     _x86_64_    (2 CPU)

09:29:02 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
09:29:03 PM     all      0.00      0.00      0.50      0.00      0.50     99.00
09:29:04 PM     all      0.00      0.00      0.50      0.00      0.00     99.50
09:29:05 PM     all      0.00      0.00      1.01      0.00      0.00     98.99
Average:        all      0.00      0.00      0.67      0.00      0.17     99.17

# 从文件读取结果
[root@gzr ~]# sar -f cpu.out 
Linux 3.10.0-957.21.3.el7.x86_64 (gzr)     07/02/2019     _x86_64_    (2 CPU)

09:29:02 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
09:29:03 PM     all      0.00      0.00      0.50      0.00      0.50     99.00
09:29:04 PM     all      0.00      0.00      0.50      0.00      0.00     99.50
09:29:05 PM     all      0.00      0.00      1.01      0.00      0.00     98.99
Average:        all      0.00      0.00      0.67      0.00      0.17     99.17

CPU:all 表示统计信息为所有 CPU 的平均值。

%user:显示在用户级别(application)运行使用 CPU 总时间的百分比。

%nice:显示在用户级别,用于nice操作,所占用 CPU 总时间的百分比。

%system:在核心级别(kernel)运行所使用 CPU 总时间的百分比。

%iowait:显示用于等待I/O操作占用 CPU 总时间的百分比。

%steal:管理程序(hypervisor)为另一个虚拟进程提供服务而等待虚拟 CPU 的百分比。

%idle:显示 CPU 空闲时间占用 CPU 总时间的百分比。

  1. 若 %iowait 的值过高,表示硬盘存在I/O瓶颈
  2. 若 %idle 的值高但系统响应慢时,有可能是 CPU 等待分配内存,此时应加大内存容量
  3. 若 %idle 的值持续低于1,则系统的 CPU 处理能力相对较低,表明系统中最需要解决的资源是 CPU 。

1.12.4 dstat(重点!查看系统资源综合方面 利用率)

使用场景

dstat 是一个可以取代vmstat,iostat,netstat和ifstat这些命令的多功能产品。dstat克服了这些命令的局限并增加了一些另外的功能,增加了监控项,也变得更灵活了。dstat可以很方便监控系统运行状况并用于基准测试和排除故障。

特性:

  • 结合了vmstat,iostat,ifstat,netstat以及更多的信息
  • 实时显示统计情况
  • 在分析和排障时可以通过启用监控项并排序
  • 模块化设计
  • 使用python编写的,更方便扩展现有的工作任务
  • 容易扩展和添加你的计数器(请为此做出贡献)
  • 包含的许多扩展插件充分说明了增加新的监控项目是很方便的
  • 可以分组统计块设备/网络设备,并给出总数
  • 可以显示每台设备的当前状态
  • 极准确的时间精度,即便是系统负荷较高也不会延迟显示
  • 显示准确地单位和和限制转换误差范围
  • 用不同的颜色显示不同的单位
  • 显示中间结果延时小于1秒
  • 支持输出CSV格式报表,并能导入到Gnumeric和Excel以生成图形

常用选项:
-c cpu 统计
-d 磁盘 统计
-m 内存统计
-n 网络统计
-s swap 统计
-l 负载统计
-- tcp tcp 状态统计
-- udp udp 状态统计
-- socket 数量统计
-t 输出时间
-- output 写入 csv 文件
插件 :
-- list 支持 的插件
-- top -bio -adv 详细显示 I/O 进程写入 block block量,包括 pid 、r、w和 cpu
-- top -io -adv 进程写入磁盘 总量
-- top -cpu 占用 CPU 进程
-- top -cpu -adv 查看 最高 CPU 进程
-- top -mem 内存进程

[root@gzr ~]# yum install -y dstat
  • dstat输出默认监控、报表输出的时间间隔为3秒钟,统计10次

1562075143013

  • 查看全部内存占用最高

1562075249351

  • 显示CPU资源损耗的数据

1562075364883

  • 输出资源监控文件为CSV文件

1562075490750

1562075545353

1.13 网络配置类

1.13.1 ip(查看/操作路由表、设备、路由策略和隧道)

基本概况:

ip是iproute2软件包里面的一个强大的网络配置工具,用来显示或操作路由、网络设备、策略路由和隧道,它能够替代一些传统的网络管理工具,例如ifconfig、route等。用ip配置的设备信息,大部分会在设备重启后还原,如果想永久保留配置,请尽量进入配置文件修改。

格式:ip [ OPTIONS ] OBJECT { COMMAND | help }
常用选项:
-b, -batch <filename> 从文件或标准输入读取命令并调用他们,第一次失败将终止
-force 批量模式有错误不终止,如果有错误则状态返回非0
-s, -statistics 输出更多的统计信息
-l, -loops <count> 指定最大的循环数
操作对象(OBEJECT):
address 网络设备地址
12tp 以太网IP隧道
link 配置网络设备
maddress 多播地址
monitor 动态监控网络连接
mroute 多播路由缓存条目
mrule 角色在多播路由策略数据库
neighbour 管理ARP或NDISC缓存条目
netns 管理网络命名空间
ntable 管理neighbour缓存操作
route 路由表
rule 角色在路由策略数据库
tpc_metrics/tcpmetrics 管理TCP指标
tunnel IP隧道
tuntap 管理TUN/TAP设备
xfrm 管理IPSec策略
可通过ip OBEJECT help再查看对象的操作方法。</count></filename>

# 查看网络设备地址:
[root@gzr ~]# ip a/addr/address

# 查看网卡统计信息
[root@gzr ~]# ip -s link ls eth0    
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 6a:7e:a7:35:ab:16 brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast   
    31678007   34526    0       0       0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    12527904   23416    0       0       0       0 

# 查看ARP缓存表
[root@gzr ~]# ip n/neigh/neighbour sh/show
172.16.4.12 dev eth0 lladdr e6:74:18:70:57:59 STALE
172.16.4.1 dev eth0 lladdr 50:3d:e5:0e:b3:3f REACHABLE

# 查看路由表
[root@gzr ~]# ip route
default via 172.16.4.1 dev eth0 proto static metric 100 
172.16.4.0/24 dev eth0 proto kernel scope link src 172.16.4.11 metric 100 

# 查看路由策略
[root@gzr ~]# ip rule
0:    from all lookup local 
32766:    from all lookup main 
32767:    from all lookup default 

# 停止与激活网络设备
[root@gzr ~]# ip link set dev eth0 down/up

# 添加删除路由
[root@gzr ~]# ip r/ro/route add 172.16.4.0/24 dev eth0
[root@gzr ~]# ip r/ro/route d/del/delete 172.16.4.0/24 dev eth1

# 设置MAC地址
[root@gzr ~]# ip link set dev eth0 address 00:0c:29:52:73:8e

1.13.2 nc(TCP和UDP连接和监听)

基本概况:

NetCat,在网络工具中有“瑞士军刀”美誉,其有Windows和Linux的版本。因为它短小精悍(1.84版本也不过25k,旧版本或缩减版甚至更小)、功能实用,被设计为一个简单、可靠的网络工具,可通过TCP或UDP协议传输读写数据。同时,它还是一个网络应用Debug分析器,因为它可以根据需要创建各种不同类型的网络连接。

常用选项:
-i interval 指定间隔时间发送和接受行文本
-l 监听模式,管理传入的连接
-n 不解析域名
-p 指定本地源端口
-s 指定本地源IP地址
-u 使用udp协议,默认是tcp
-v 执行过程输出
-w timeout 连接超时时间
-x proxy_address[:port] 请求连接主机使用代理地址和端口
-z 指定扫描监听端口,不发送任何数据

[root@gzr ~]# yum install -y nc

# 端口扫描
[root@gzr ~]# nc -z 172.16.4.1 1-65535

# UDP协议连接到目的端口
[root@gzr ~]# nc -u 172.16.4.12 53
  • 收发信息:在对端先nc -l 1234创建聊天窗口,在本机或者其他服务端监听。

1562078228142

1.14 防火墙命令

1.14.1 iptables

常见几种类型防火墙?
包过滤防火墙:包过滤是IP层实现,包过滤根据数据包的源IP、目的IP、协议类型(TCP/UDP/ICMP)、源端口、目的端口等包头信息及数据包传输方向灯信息来判断是否允许数据包通过。

应用层防火墙:也称为应用层代理防火墙,基于应用层协议的信息流检测,可以拦截某应用程序的所有封包,提取包内容进行分析。有效防止SQL注入或者XSS(跨站脚本攻击)之类的恶意代码。

状态检测防火墙:结合包过滤和应用层防火墙优点,基于连接状态检测机制,将属于同一连接的所有包作为一个整体的数据流看待,构成连接状态表(通信信息,应用程序信息等),通过规则表与状态表共同配合,对表中的各个连接状态判断。

iptables是Linux下的配置防火墙的工具,用于配置Linux内核集成的IP信息包过滤系统,使增删改查信息包过滤表中的规则更加简单。
iptables分为四表五链,表是链的容器,链是规则的容器,规则指定动作。

四表:

参数 功能
filter 用于包过滤
nat 网络地址转发
mangle 对特定数据包修改
raw 不做数据包链接跟踪

五链:

参数 功能
INPUT 本机数据包入口
OUTPUT 本机数据包出口
FORWARD 经过本机转发的数据包
PREROUTING 防火墙之前,修改目的地址(DNAT)
POSTROUTING 防火墙之后,修改源地址(SNAT)

表中的链:

filter INPUT/OUTPUT/FORWARD
nat PREROUTING/POSTROUTING/OUTPUT
mangle PREROUTING/POSTROUTING/INPUT/OUTPUT/FORWARD
raw PREROUTING/OUTPUT

命令格式:iptables [-t table] 命令 [chain] 匹配条件 动作

命令
-A,append 追加一条规则
-I,insert 插入一条规则,默认链头,后跟编号,指定第几条
-D,delete 删除一条规则
-F,flush 清空规则
-L,list 列出规则
-P,policy 设置链缺省规则
-m,module 模块,比如state、multiport

匹配条件:

匹配条件 描述
-i 入口网卡
-o 出口网卡
-s 源地址
-d 目的地址
-p 协议类型
--sport 源端口
--dport 目的端口

规定动作:

动作 描述
ACCEPT 允许数据包通过
DROP 丢弃数据包不做处理
REJECT 拒绝数据包,并返回报错信息
SNAT 一般用于nat表的POSTROUTING链,进行源地址转换
DNAT 一般用于nat表的PREROUTING链,进行目的地址转换
MASQUERADE 动态源地址转换,动态IP时使用

使用模块:

模块 描述
state 包状态,有四个:NEW、RELATED、ESTABLISHED和INVALID
mac 源MAC地址
limit 包速率限制
multiport 多端口,以逗号分隔
iprange 端口范围,以逗号分隔
# 清空表规则,默认filter表
[root@gzr ~]# iptables -F

# 清空nat表
[root@gzr ~]# iptables -t nat -F

# 运行tcp 22端口访问,-A追加规则,INPUT本机数据包入口,-p指定协议,--dport指定目的端口,-j指定当前规则对应的动作为ACCEPT
[root@gzr ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 允许UDP的53端口访问,插入在第一条
[root@gzr ~]# iptables -I INPUT -p udp --dport 53 -j ACCEPT

# 删除这条规则
[root@gzr ~]# iptables -D INPUT -p tcp --dport 22:25 -j ACCEPT

# 允许多个TCP端口访问
[root@gzr ~]# iptables -A INPUT -p tcp -m multiport --dports 22,80,8080 -j ACCEPT

# 允许172.16.4.0段IP访问
[root@gzr ~]# iptables -A INPUT -s 172.16.4.0/24 -j ACCEPT 

# 对172.16.4.0数据包丢弃
[root@gzr ~]# iptables -A INPUT -s 172.16.4.0/24 -j DROP

# eth0网卡ICMP数据包丢弃,禁止ping
[root@gzr ~]# iptables -A INPUT -i eth0 -p icmp -j DROP

# 允许来自lo接口,如果没有这条规则,将不能通过127.0.0.1访问本地服务 
[root@gzr ~]# iptables -A INPUT -i lo -j ACCEPT

# 限制并发连接数,超过30个拒绝 
[root@gzr ~]# iptables -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 30 -j REJECT

# 限制每个IP每秒并发连接数最大3个 
[root@gzr ~]# iptables -I INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT

# iptables服务器作为网关时,内网访问公网 
[root@gzr ~]# iptables –t nat -A POSTROUTING -s [内网IP或网段] -j SNAT --to [公网IP]

# 访问iptables公网IP端口,转发到内网服务器端口 
[root@gzr ~]# iptables –t nat -A PREROUTING -d [对外IP] -p tcp --dport [对外端口] -j DNAT --to [内网IP:内网端口]

# 本地80端口转发到本地8080端口 
[root@gzr ~]# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

# 允许已建立及该链接相关联的数据包通过 
[root@gzr ~]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

2. 高级文本处理工具之grep

2.1 基本介绍

grep(grep, egrep, fgrep):文本过滤工具(模式:pattern)工具;

grep:Global searchREgular expression and Print out the line. 它能全文搜索每一行,显示整行文本。

作用:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本进行匹配检查;打印匹配到的行;

模式:由正则表达式的元字符及文本字符所编写出的过滤条件;

2.2 用法

grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

# 通常grep会高亮显示用户搜索字段,这是因为加了别名,实际上执行的是grep --color命令
[root@gzr ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

OPTIONS:

​ --color=auto: 对匹配到的文本高亮显示

​ -i: Ignorecase,忽略字符的大小写

​ -o: 仅显示能匹配的字符串本身,而不是整行

​ -v: --Invert-match,反向显示,不显示含有模式的字符串的行

​ -E:支持使用扩展的正则表达式元字符

​ -q: --quiet --silent 静默显示,不显示在页面,可以当做一个执行结果状态判断,不用输出任何信息

[root@gzr ~]# grep -q UUID /etc/fstab
[root@gzr ~]# echo $?
0

​ -A:After,显示能够匹配的行的某几行内容

1562313064299

  • grep 带root的行有2行记录,-A 2表示,输出2行记录的后2两行

    -B : Before, 显示能够匹配行的前几行内容。

    -C: Context, 显示能够匹配行的前后各几行内容(上下文)

2.3 egrep

注意:

  • grep默认是支持基本正则表达式,采用-E选项能够支持扩展正则表达式,-F表示不支持正则表达式;
  • egrep默认支持扩展正则表达式,采用-G选项能够支持基本正则表达式,-F表示不支持正则表达式。
  • fgrep: 不支持正则表达式

egrep [OPTIONS] PATTERN [FILE...]

选项:-i, -o, -v, -q, -A, -B, -C

-G: 支持基本正则表达式

2.4 fgrep

不支持正则表达式元字符;当无需用到元字符去编写模式时,使用fgrep会更好(几万行,几百万行)

3. 高级文本处理工具之sed

3.1 基本介绍

sed: stream editor,流编辑器; 文本编辑器,行编辑器

sed会按行读出文件内容到sed自身的pattern space(判断是符合过滤模式)进行编辑,然后输出到stdout。实际上sed还有hold space。

1562402105084

​ sed - stream editor for filtering and transforming text

SYNOPSIS
sed [OPTION]... {script-only-if-no-other-script} [input-file]...

  • {script-only-if-no-other-script} :地址定界编辑命令

常用选项:

-n : 不输出模式空间中的内容,

-e script, --expression=script :多点编辑;

-f script-file, --file=script-file /PATH/TO/SED_SCRIPT_FILE

可以把写好的命令写在一个文件中,就不用再用-e进行多点编辑了

-r, --regexp-extended:支持使用扩展的正则表达式

-i[SUFFIX], --in-place[=SUFFIX]:直接编辑源文件(慎用)

地址定界:

(1)空地址:对全文进行处理;

(2)单地址:

  • 指定行;
  • /pattern/: 被此模式所匹配到的每一行;

(3)地址范围:

  • m,n:m到n
  • m,+n:从m开始,向后n行
  • m, /part1
  • /part1/,/part2
  • $ 表示最后一行

(4)步进:~

1~2:奇数行

2~2:偶数行

3.2 编辑命令

3.2.1 d : 删除行

示例:

~]# cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Thu Apr 25 11:15:22 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0
You have new mail in /var/spool/mail/root

# 将/etc/fstab删除,即不输出1~5行的信息
~]# sed '1,5d' /etc/fstab 

# 删除/etc/fstab下又有以UUID开头的行
~]# sed '/^UUID/d' /etc/fstab 

# 删除#所在的行
~]# sed '/^#/d' /etc/fstab

# 显示偶数行
~]# sed '1~2d' /etc/fstab 

3.2.2 p(显示内容)

显示模式空间中的内容

# -p不仅显示默认输出,还会显示编辑的内容,会重复显示
~]# sed '1~2p' /etc/fstab


#
# /etc/fstab
# /etc/fstab
# Created by anaconda on Thu Apr 25 11:15:22 2019
#
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

# 加入-n,只显示编辑后的内容。
~]# sed -n '1~2p' /etc/fstab

# /etc/fstab
#
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
/dev/mapper/centos-root /                       xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0
You have new mail in /var/spool/mail/root

3.2.3 i 和 a(插入和追加)

-a \text :在行后面追加文本“text”, 支持\n,实现多行追加;

-i \text : 在行前面追加文本“text”, 支持\n,实现多行插入;

# 在/etc/fstab的第3行插入new line文本,注意:即使中间有空格等,也不需要转义,其他行按次序往下移一行
~]# sed '3i \new line' /etc/fstab

# 在/etc/fstab的第3行后追加插入new line文本
~]# sed '3a \new line' /etc/fstab

# -i和-a都支持多行插入或追加内容,采用\n
~]# sed '3a \new line\nanother line' /etc/fstab

# 在以UUID为行首字符的前面,加一行注释行:# add new device base on UUID
~]# sed '/^UUID/i \# add new device base on UUID ' /etc/fstab

3.2.4 -c (把匹配的到行替换)

是整行替换

3.2.5 w /PATH/TO/FILE

保存模式空间匹配到的行到指定的文件中。

# 显示所有非#号开头的行
~]# sed -n '/^[^#]/p' /etc/fstab
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

# 将上述/etc/fstab所有非#号开头的行保存到/tmp/fstab.new下
~]# sed -n '/^[^#]/w /tmp/fstab.new' /etc/fstab

3.2.6 r (文件合并)

读取指定文件的内容到当前文件被模式匹配到的行后。

~]# cat /etc/issue
\S
Kernel \r on an \m

# 把/etc/issue的内容,插入到/etc/fstab的第三行,
~]# sed '3r /etc/issue' /etc/fstab

#
# /etc/fstab
\S
Kernel \r on an \m

# Created by anaconda on Thu Apr 25 11:15:22 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

3.2.7 =

为模式匹配到的行打印行号

~]# sed '/^UUID/=' /etc/fstab

3.2.8 !(条件取反)

用法:地址定界! 一定要放在模式的后面

# 删除以非#号开头的行,可以采用取反的方式实现
~]# sed '/^#/!d' /etc/fstab
或
~]# sed '/^[^#]/d' /etc/fstab

3.2.9 s///(查找并替换 重点!!!)

查找替换,其分隔符可自行指定,常用的有s@@@,s###等;

  • 替换标记:
    • g: 全局替换;
    • w /PATH/TO/SOMEFILE:将替换成功的结果保存到指定文件中;
    • p: 显示替换成功的行

练习:

(1)删除/boot/grub/grub2.cfg文件中所有以空白字符开头的行的行首的所有空白字符;

~]# sed 's@^[[:space:]]\+@@' /etc/grub2.cfg

(2)删除/etc/fstab文件中所有以#开头的行的行首的#号及#号后面的所有空白字符;

~]# sed 's@^#[[:space:]]*@@' /etc/fstab

扩展:同时删除以UUID为首的行,采用多点编辑

~]# sed -e 's@^#[[:space:]]*@@' -e '/^UUID/d' /etc/fstab

(3)输出一个绝对路径给sed命令,取出其目录名,其行为类似于dirname;

# 显示锚定非行尾的非斜线字符,然后替换为空
~]# echo "/var/log/messges/" | sed 's@[^/]\+/\?$@@'
/var/log/
或
~]# echo "/var/log/messges/" | sed -r 's@[^/]+/?$@@'

3.3 高级编辑命令

  • h

把模式空间中的内容覆盖至保持空间中

  • H

把模式空间中的内容追加至保持空间中

  • g

把保持空间中的内容覆盖至模式空间中

  • G

把保持空间中的内容追加至模式空间中

  • x

把模式空间中的内容与保持空间中的内容互换

  • n

覆盖读取匹配行的下一行至模式空间中;

  • N

追加读取匹配到的行的下一行至模式空间中

  • d

删除模式空间中的行

  • D

删除多行模式空间中的所有行

示例:

[root@gzr ~]# cat -n /etc/fstab 
     1    
     2    #
     3    # /etc/fstab
     4    # Created by anaconda on Thu Apr 25 11:15:22 2019
     5    #
     6    # Accessible filesystems, by reference, are maintained under '/dev/disk'
     7    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
     8    #
     9    /dev/mapper/centos-root /                       xfs     defaults        0 0
    10    UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0
    11    /dev/mapper/centos-swap swap                    swap    defaults        0 0
You have new mail in /var/spool/mail/root

(1)sed -n 'n;p' FILE 显示偶数行

# 显示偶数行
[root@gzr ~]# sed -n 'n;p' /etc/fstab 
#
# Created by anaconda on Thu Apr 25 11:15:22 2019
# Accessible filesystems, by reference, are maintained under '/dev/disk'
#
UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0

(2)~]# sed '1!G;h$!d' FILE 逆序输出

# 1!G 如果是第1行,不做G操作,h: 把模式空间中的内容覆盖至保存空间;$!d,最后一行不做删除操作,如果不是最后一行,则删除。
~]# sed '1!G;h$!d' /etc/fstab

(3)sed '$!d' FILE: 取出最后一行 等同于tail -1

~]# sed '$!d' /etc/fstab 

(4)sed '!D' FILE

# 读取到倒数第2行时,先做next操作,即读取下一行(最后一行) ,由于是最后一行,则不做删除操作,那么就显示了倒数两行的内容
[root@gzr ~]# sed '$!N;$!D' /etc/fstab 

(5)sed '/^$/d;G' FILE :删除原有文件中的空白行,而后统一追加空白行

[root@gzr ~]# sed '/^$/d;G' /etc/fstab

(6)sed ‘n;d’ FILE: 显示奇数行

~]# sed 'n;d' /etc/fstab

(7)sed 'G' FILE :在文件的每一行都加空白行,包括原先有空白行的行

[root@gzr ~]# sed 'G' /etc/issue

4. 高级文本处理工具之awk

4.1 基本概况

Linux上实现为gawk,文本报告生成器(格式化文本)

AWK: Aho Weinberger, Kernighan

GNU awk: gwak Server: New awk (NAWK)

# 我们在Linux上用的awk,实际上是gawk, 两者做了软链接
[root@gzr ~]# ls -l /usr/bin/awk
lrwxrwxrwx. 1 root root 4 Apr 25 11:15 /usr/bin/awk -> gawk

gawk: 支持条件判断,它是一个过程式编程语言,有内置变量(模式扫描)

NAME
gawk - pattern scanning and processing language

SYNOPSIS
gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
gawk [ POSIX or GNU style options ] [ -- ] program-text file ...

​ pgawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
​ pgawk [ POSIX or GNU style options ] [ -- ] program-text file ...

​ dgawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...

4.2 基本用法

gawk [options] 'program' FILE .....

program: PATTERN{ACTION STATEMENTS}

​ 语句之间用分号分隔

​ print, printf

常用选项:

-F : 用于指明输入时用到的字段分隔符;

-v : var=value: 自定义变量;

4.2.1 awk处理文本的流程:

一次读取一行文本,读入后,按照分隔符进行切片(2.....),如此一来就可以显示一行内容的某些列(字段)还可以做一些其他处理(遍历,循环等),当然如果要显示整行,则用$0表示。

4.2.2 print

[root@gzr ~]# tail -3 /etc/fstab | awk '{print $2,$4}'
/ defaults
/boot defaults
swap defaults

(1) print item1, item2, .....

要点:

  • 逗号分隔符;
  • 输出的各item可以是字符串,数值,当前记录的字段、变量或awk的表达式;
  • 如省略item,相当于print$0;

4.2.3 变量

(1)内建变量

  • FS:input field seperator,默认为空白字符;
[root@gzr ~]# gawk -v FS=':' '{print $1}' /etc/passwd
或
[root@gzr ~]# awk -F: '{print $1}' /etc/passwd
  • OFS:output field seperator, 默认为空白字符;
# 每一个-v指定一个变量
[root@gzr ~]# awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd
  • RS: 一行称为一个Record, input record seperator,输入时的换行符;
  • ORS:output record seperator,输出时的换行符
  • NF:Number of Field,字段数量,注意{print NF}和{print $NF}的区别。
  • NR:Number of Record, 行数量(打印的是行号)
  • FNR:各文件的分别计数,行数;
  • FILENAME:文件名
  • ARGC:命令行参数的个数
  • ARGV:数组,保存的是命令行所给定的各参数;
[root@gzr ~]# cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Thu Apr 25 11:15:22 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

[root@gzr ~]# awk '{print NF}' /etc/fstab
0
1
2
10
1
9
12
1
6
6
6

[root@gzr ~]# awk '{print NR}' /etc/fstab
1
2
3
4
5
6
7
8
9
10
11

[root@gzr ~]# awk 'BEGIN{print ARGC}' /etc/fstab /etc/issue
3
[root@gzr ~]# awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/issue
awk
[root@gzr ~]# awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/issue
/etc/fstab
[root@gzr ~]# awk 'BEGIN{print ARGV[2]}' /etc/fstab /etc/issue
/etc/issue

(2)自定义变量

-v var=value

  • 变量名区分大小写;
  • 在BEGIN或者program中直接定义
# 此处自定义变量后,实际上/etc/issue只是起到了提供行数的作用
[root@gzr ~]# awk -v test='hello gawk' '{print test}' /etc/issue
hello gawk
hello gawk
hello gawk

# 如果不想指定文件可以采用BEGIN
[root@gzr ~]# awk -v test='hello gawk' 'BEGIN{print test}'
hello gawk
或
[root@gzr ~]# awk 'BEGIN{test="hello gawk";print test}'
hello gawk

4.2.4 printf命令

格式化输出:printf FORMAT, item1, item2, .......

  • FORMAT必须要给出;

  • 不会自动换行,需要显示给出换行控制符,\n;

  • FORMAT中需要分别为后面的每个item指定一个格式化符号;

    • 格式符:

      %c : 显示字符的的ASCII码;

      %d, %i:显示十进制整数;

      %e, %E:科学计数法数值显示;

      %f:显示为浮点数;

      %g, %G:以科学计数法数值显示;

      %s:显示字符串;

      %u:无符号整数;

      %%:显示%自身;

    • 修饰符:对格式符进行修饰

      [.#]:第一个#号是数字控制显示宽度;第二个#表示小数点后的精度;

      ​ 例如:%3.1f

      -:左对齐

      +:显示数值符号

示例:

# 默认不会换行
[root@gzr ~]# awk -F: '{printf "%s",$1}' /etc/passwd
rootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodysystemd-networkdbuspolkitdsshdpostfixnginxgzrwangwuntpbashbashernologintestbash

# 显示加入换行符
[root@gzr ~]# awk -F: '{printf "%s\n",$1}' /etc/passwd

# 加入字段
[root@gzr ~]# awk -F: '{printf "username:%s\n",$1}' /etc/passwd
username:root
......
username:testbash

# 多字段格式化显示
[root@gzr ~]# awk -F: '{printf "username:%s,uid:%d\n",$1,$3}' /etc/passwd
username:root,uid:0
......
username:gzr,uid:1000

# 格式化宽度,默认是右对齐
[root@gzr ~]# awk -F: '{printf "username:%15s,uid:%d\n",$1,$3}' /etc/passwd
username:           root,uid:0
......
username:            gzr,uid:1000

# 采用-进行左对齐
[root@gzr ~]# awk -F: '{printf "username:%-15s,uid:%d\n",$1,$3}' /etc/passwd
username:root           ,uid:0
......
username:gzr            ,uid:1000

# 

4.2.5 操作符

算数运算,比较运算

  • 算数操作符:

    x+y, x-y, x*y, x/y, x^y, x%y

    -x 单目运算符

    +x:转换为数值

  • 字符串操作符:没有符号的操作符,字符串连接

  • 赋值操作符

    =,+=,-=,*=,/=,%=,^=,++,--

  • 比较操作符

    <,>, >=, <=, !=, ==

  • 模式匹配符

    ~ 表示左侧字符串是否能被右侧模式匹配

    !~

  • 逻辑操作符

    && || !

  • 函数调用:

    bash中 function_name(arg1,arg2)

  • 条件表达式:

    selector? if-true-expression: if-false-expression

# 用户ID>=1000的是普通用户,否则则为系统用户或者系统管理员,格式化输出,此处采用条件选择器
[root@gzr ~]# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
           root:Sysadmin or SysUser
            ......
            gzr:Common User

4.2.6 PATTERN

  • empty:空模式,匹配每一行;
  • /regular expression/:仅能够被此模式匹配到的行;
[root@gzr ~]# awk '/^UUID/{print $1}' /etc/fstab 
UUID=be9bf6be-8766-436b-9079-45281abed73b

# 取反操作
[root@gzr ~]# awk '!/^UUID/{print $1}' /etc/fstab 

  • 关系表达式(结果有真有假),为真才会被处理
    • 结果为非0值为真,非空字符串也为真
[root@gzr ~]# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
root /bin/bash
gzr /bin/bash
......
  • 地址定界:行范围:指明起始行和结束行
    • 不支持直接给出数字的格式
    • /part1 /part2
    • NR
# 以root开始的行,以gzr为结束的行
[root@gzr ~]# awk -F: '/^root/,/^gzr/{print $1}' /etc/passwd
root
......
gzr

# 采用NR定界,打印2~10行的用户名
[root@gzr ~]# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

  • BEGIN/END模式
    • BEGIN{}: 仅在开始处理文件中的文本之前执行一次
    • END{}: 仅在文本处理完成之后执行一次;
[root@gzr ~]# awk -F: 'BEGIN{printf "Username%-s,Uid%-d\n======================\n",$1,$3}{printf "%-s,%-10d\n",$1,$3}END{print "=======================\nthis is the end"}' /etc/passwd
Username,Uid0
======================
root,0         
bin,1         
daemon,2         
adm,3         
lp,4         
sync,5         
shutdown,6         
halt,7         
mail,8         
operator,11        
games,12        
ftp,14        
nobody,99        
systemd-network,192       
dbus,81        
polkitd,999       
sshd,74        
postfix,89        
nginx,998       
gzr,1000      
wangwu,1003      
ntp,38        
bash,1004      
basher,1005      
nologin,1006      
testbash,1007      
=======================
this is the end

4.2.7 action

(1): Expression

(2): Control statements: if,while等

(3): Compound statements:组合语句;

(4): input statements

(5): output statements

  • 控制语句

    if(condition) {statements}

    if(condition) {statements} else {statements}

    while(condition) {statements}

    do {statements} while(condition)

    for(expr1;expr2;expr3) {statements}

    break

    continue

    delete array[index] 删除数组中的某个元素

    delete array删除整个数组

    exit

    { statements }

4.3 if-else

语法:if(condition) {statements} else {statements}

[root@gzr ~]# awk -F: '{if($3>=1000){printf "Common User: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd
root or Sysuser: root
......
Common User: gzr

使用场景:对awk的一整行,或者某个字段做条件判断:

[root@gzr ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
root
gzr
wangwu
bash
basher
testbash

# 当一行记录数的空白符大于5,则打印该行
[root@gzr ~]# awk '{if(NF>5) print $0}' /etc/fstab 

# 打印输出磁盘利用率大于等于20%,且以/dev开头的文件系统名
[root@gzr ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   26G  2.4G   24G  10% /
devtmpfs                 1.9G     0  1.9G   0% /dev
tmpfs                    1.9G     0  1.9G   0% /dev/shm
tmpfs                    1.9G   25M  1.9G   2% /run
tmpfs                    1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/xvda1              1014M  232M  783M  23% /boot
tmpfs                    377M     0  377M   0% /run/user/0
You have new mail in /var/spool/mail/root
[root@gzr ~]# df -h | awk -F% '/^/dev{print $1}'
Filesystem               Size  Used Avail Use
/dev/mapper/centos-root   26G  2.4G   24G  10
devtmpfs                 1.9G     0  1.9G   0
tmpfs                    1.9G     0  1.9G   0
tmpfs                    1.9G   25M  1.9G   2
tmpfs                    1.9G     0  1.9G   0
/dev/xvda1              1014M  232M  783M  23
tmpfs                    377M     0  377M   0
[root@gzr ~]# df -h | awk -F% '/^/dev{print $1}' | awk '{if($NF>=20) print $1}'
Filesystem
/dev/xvda1

4.4 while循环

语法:while(condition) {statements}

条件“真”,进入循环;条件为“假”,退出循环;

使用场景:对一行内的多个字段逐一类似处理时使用;对数组中各元素逐一处理时使用;

统计字符的个数:length()

# 统计/etc/grub2.cfg下以空白符(空白符没有)紧接linux16开头的行中的字段的长度
[root@gzr ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<NF) {print $i,length($i);i++}}' /etc/grub2.cfg 
linux16 7
......
rd.lvm.lv=centos/swap 21
rhgb 4

#在上述结果中,将字段字符长度大于7的字段才输出
[root@gzr ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<NF) {if(length($i)>=7) {print $i,length($i)};i++}}' /etc/grub2.cfg 
linux16 7
......
rd.lvm.lv=centos/root 21
rd.lvm.lv=centos/swap 21

4.5 do while 循环(至少循环一次)

语法:do statement while(condition)

4.6 for循环

语法:for(expr1; expr2;expr3) statement

for(variable assignment; condition; iteration process) {for-body}

# 功能同 while循环第一个案例
[root@gzr ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<NF;i++){print $i, length($i)}}' /etc/grub2.cfg
linux16 7
......
rhgb 4

# 功能同 while循环第二个案例
[root@gzr ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<NF;i++){if(length($i)>=7){print $i, length($i)}}}' /etc/grub2.cfg 
linux16 7
......
rd.lvm.lv=centos/root 21
rd.lvm.lv=centos/swap 21

  • 特殊用法:
    • 能够遍历数组中的元素:
      • 语法:for(var in array) {for-body}

4.7 switch语句

语法:switch(expression) {case VALUE1 or /REGEXP/ statement; case VALUE2 or /REGEXP2/: statement; ......; default: statement}

4.8 break 和continue

break[n]

continue

4.9 next

提前结束对本行的处理而直接进行下一行;

# 打印uid为偶数的用户名和uid
[root@gzr ~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
root 0
daemon 2
lp 4
shutdown 6
mail 8
games 12
ftp 14
systemd-network 192
sshd 74
nginx 998
gzr 1000
ntp 38
bash 1004
nologin 1006

4.10 函数

4.10.1 内置函数

(1)数值处理

rand():返回一个0和1之间的一个随机数;

(2)字符串处理:

length([s]):返回指定字符串的长度

sub(r,s,[t]):以r表示的模式来查找t所表示的字符串中匹配的内容,并将其第一次出现替换为s所表示的内容:

[root@gzr ~]# awk '{sub(o,O,$0)}' /etc/passwd | echo $?
0

gsub(r,s,[t]):以r表示的模式来查找t所表示的字符串中匹配的内容,并将其所有出现替换为s所表示的内容:

split(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中;

[root@gzr ~]# netstat -ant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:199           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp        0      0 172.16.4.11:22          172.16.15.34:37790      ESTABLISHED
tcp        0     52 172.16.4.11:22          210.26.55.133:12467     ESTABLISHED
tcp        0      0 172.16.4.11:22          172.16.4.20:44634       ESTABLISHED
tcp        0      0 172.16.4.11:22          172.16.4.19:40228       ESTABLISHED
tcp        0      0 172.16.4.11:22          172.16.4.18:42722       ESTABLISHED
tcp        0      0 172.16.4.11:22          172.16.15.34:37796      ESTABLISHED
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     

# 以split分隔第5列,采用冒号分隔,保存在ip数组中,然后通过count数组对ip第一列相加,最后统一打印ip和次数
[root@gzr ~]# netstat -ant | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'
172.16.4.18 1
172.16.4.19 1
0.0.0.0 4
172.16.4.20 1
172.16.15.34 2
210.26.55.133 1

推荐书籍: 《Linux命令行与Shell编程指南》,《sed与awk》

4.10.2 自定义函数

5. Shell正则表达式

5.1 基本概念和特点

正则表达式(Regular Expression,RGEEXP)是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression)。

给定一个正则表达式和另一个字符串,我们可以达到如下的目的:

  1. 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
  2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。

正则表达式的特点:

  1. 灵活性、逻辑性和功能性非常的强;
  2. 可以迅速地用极简单的方式达到字符串的复杂控制。
  3. 对于刚接触的人来说,比较晦涩难懂。
    由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、Visual Studio等大型编辑器,都可以使用正则表达式来处理文本内容。

5.2 正则表达式的组成

5.2.1 字符类

字符类(Character Class):在模式中表示一个字符,但是取值范围是一类字符中的任意一个。

RE字符 意义和范例
^word 意义:待查找的字符串(word)在行首
范例:查找行首为#开始的那一行,并列出行号。
grep -n '^#' python_zen.txt
word$ 意义:待查找的字符串(word)在行尾
范例:将行尾为!的那一行打印出来,并列出行号。
grep -n '!$' python_zen.txt
. 意义:一定有一个任意字符的字符
范例:查找e和e中间仅有一个字符,而空格符也是字符。
grep -n 'e.e'python_zen.txt
\ 意义:转义符,将特殊符号的特殊意义去除
范例:查找含有单引号 ‘ 的那一行。
grep -n \' python_zen.txt
* 意义:重复任意个的前一个RE字符
范例:找出含有(es)、(ess)、(esss)等的字符串,注意:因为可以是0个,所以es也是符合待查找字符串,另外,由于*为重复前一个RE字符的符号,所以,在*之前必须紧接一个RE字符。例如任意字符则为.\
grep -n 'ess*' python_zen.txt
[list] 意义:匹配[]内任意一个字符
范例:查找含有gl或gd的那一行
grep -n 'g[ld]' python_zen.txt
[n1-n2] 意义:截取[]范围内的字符
范例:比如,截取所有数字[0-9],所有小写字符[a-z],大写字母[A-Z]
grep -n '[A-Z]' python_zen.txt
[^list] 意义:列出不在list内的字符串或范围
范例:注意^在括号内,表示反向选择的意思,而在括号外表示匹配行首。比如不要大写字母,[ ^A-Z ] 例如,oo之后匹配不带t的字符串
grep -n 'oo[ ^t ]' python_zen.txt
\{n,m\} 意义:连续n到m个的【前一个RE字符】
意义:若为\{n\}则是连续n个的前一个RE字符
意义:若是\{n,\}则是连续n个以上的前一个RE字符

范例:在g和g之间有2到3个的o存在的字符串,即(goog)(gooog)
grep -n 'go\{2,3\}g' python_zen.txt

示例1:

1562314894488

  • 匹配r和t之间任意两个字符。

示例2:[^]

常用:数字:[:digit:]、小写字母 [:lower:]、大写字母 [:upper]、所有字母[:alpha]、字母和数字[:alnum:]、[:punct:]、[:space:]

1562315411526

  • 匹配r和t之前只能出现两个字母的行。
  • 注意,正则表达式的特殊字符与一般在命令行输入命令的通配符并不相同,例如:

在通配符当中的代表的是【0~无限多个字符】,而在正则表达式中, *则表示【重复0到无穷多个前一个RE字符】的意思。

  • 举例来说,不支持正则表达式的ls命令中,若我们使用【ls -l 】代表的是任意文件名的文件,而【ls l a\】则表示以a为开头的任何文件名的文件,但在正则表达式中,若要找到含有以a为开头的文件,必须这样写:
ls | grep -n '^a.*'        

例子:在/etc/下找出文件类型为链接文件属性的文件名

思路:由于ls -l会列出链接文件表头会是【lrwxrwxrwx】,因此使用如下命令即可找到

ls -l /etc | grep -n '^l'

5.2.2 数量限定符(匹配次数)

场景:数量限定符(Quantifier): 邮件地址的每一部分可以有一个或多个x字符,IP地址的每一部 分可以有1-3个y字符

字符 意义和范例
? 意义:匹配问号前的字符0次或1次
+ 意义:匹配+号前的单元至少1次,可以多次
范例:[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+匹配email地址
* 意义:匹配*前面的字符任意次,可以是0次或多次
范例:[0-9]*匹配任意位数字
特殊用法:.*表示匹配任意长度的任意字符
{N} 意义:匹配紧跟着它前面的单元N次
{N, } 意义:匹配紧跟着它前面的单元至少N次
{ ,M} 意义:匹配紧跟着它前面的单元至多M次
{N,M} 意义:匹配紧跟着它前面的字符至少N次,最多M次

1562295128828

5.2.3 位置限定符(位置锚定)

位置限定符(Anchor):描述各种字符类以及普通字符之间的位置关系,例如邮件地址分三部分,用普通字符@和.隔 开,IP地址分四部分,用.隔开,每一部分都可以用

字符类和数量限定符 描述。为了表示位置关系,需要位置限定符的概念,将在下面介绍:

字符 意义和范例
^ 意义:匹配行首的位置(行首锚定)
范例:^content配置行首为content的行
$ 意义:匹配行尾的位置(行尾锚定)
范例:;则是匹配空行(所谓空白行,是空格都不能有)
^root
\<或\b 意义:匹配单词(非特殊字符组成的连续字符串)开头的位置(词首锚定)
范例:\<th 匹配 this 但不匹配 tenth
\>或\b 意义:匹配单词词尾的位置(词尾锚定)
范例:p\> 匹配leap, 但是不匹配parent等
注意:\<PATTERN\>:匹配完整单词。
\b 意义:匹配单词的开头或结尾的位置
范例:\bat\b匹配 at 但不匹配 cat、batch等
\B 匹配非单词开头或结尾的位置
范例:\Bat\B 匹配 battery, 但不匹配 ... attend、hat ...
[root@gzr ~]# cat test.sh 
hello world!
hello shell!
hello boy;
hello gril;
I am a handsome boy;

1562296464610

1562296627121

  • 用^PATTERN$:用PATTERN来匹配整行。

练习:

(1)显示/etc/passwd文件中不以/bin/bash结尾的行;

grep -v /bin/bash$ /etc/passwd

(2)找出/etc/passwd文件中两位数或三位数;

grep -n "\<[[:digit:]]\{2,3\}\>" /etc/passwd
或
grep -n "\<[0-9]\{2,3\}\>" /etc/passwd
或
grep -n "\b[0-9]\{2,3\}\b" /etc/passwd
或使用扩展正则表达式
grep -En "\<[0-9]{2,3}\>" /etc/passwd

(3)找出/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面有非空白字符的行;

grep -n "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
或使用扩展正则表达式
grep -En "^[[:space:]]+[^[:space:]]*$" /etc/grub2.cfg

  • space包含空格和tab之类的键

(4)找出“netstat -tan”命令的结果中以“LISTEN”后跟0、1或多个空白字符结尾的行;

netstat -ant |grep -n 'LISTEN[[:space:]]*$' 

5.2.4 特殊字符

字符 意义和范例
\ 意义:转义字符
( ) 意义:将正则表达式的一部分括起来组成一个单元,可以对整个单元使用数量限定符,注意,需要使用转义字符。
范例:如果匹配xy这两个字符任意次
grep -n "\(xy\)*ab" file
| 意义:连接两个子表达式,表示或的关系
\d 意义 :匹配数字
\w 意义:匹配字母或数字或下划线或汉字 等价于 '[ ^A-Za-z0-9_ ]'。
\s 意义:匹配任意的空白符

分组及引用:

\(\):将一个或多个字符捆绑在一起,当做一个整体进行处理;

Note: 分组括号中的模式匹配到的内容会被正则表达式引擎自动记录于内部的变量中,这些变量为:

\1:模式从左侧起,第一个括号以及与之匹配的右括号之间的模式所匹配到的字符;

\2: 模式从左侧起,第二个括号以及与之匹配的右括号之间的模式所匹配到的字符;

......

例子:

[root@gzr ~]# cat lovers.txt 
He likes his lover.
He loves his lover.
She likes her liker.
She loves her liker.

1562333260273

  • 上述的例子,引用内部变量,从而能够保持一致。此称为“后向引用”,即引用前面的分组括号中的模式所匹配到字符;

5.2.5 常用的正则表达式

1.匹配非负整数(正整数 + 0): ^\d+

3.匹配非正整数(负整数 + 0): ^((-\d+)|(0+))  

5.匹配整数: ^-?\d+  

7.匹配正浮点数: ^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9]*.[0-9]+)|([0-9][1-9][0-9]*))  \

9.匹配负浮点数: ^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9]*.[0-9]+)|([0-9][1-9][0-9]*)))  

11.匹配由26个英文字母组成的字符串^[A-Za-z]+  

13.匹配由26个英文字母的小写组成的字符串: ^[a-z]+  

15.匹配由数字、26个英文字母或者下划线组成的字符串: ^\w+$  
16.匹配中文字符的正则表达式: [\u4e00-\u9fa5]

17.匹配双字节字符(包括汉字在内):[^\x00-\xff]
18.匹配空行的正则表达式:\n[\s| ]*\r

19.匹配HTML标记的正则表达式:/<(.)>.</\1>|<(.) />/
20.匹配首尾空格的正则表达式:(^\s
)|(\s*$)

21.中国身份证:(^\d{15})
22.邮箱:^[0-9a-zA-Z]+@(([0-9a-zA-Z]+)[.])+[a-z]{2,4}$

23.手机号码:^(1(([35][0-9])|(47)|[8][01236789]))\d{8})|(^[1358]d{10}$)

25.实现手机号前带86或是+86的情况:^((+86)|(86))?(13)\d{9}|(13[0-9]{9})

27.网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\|/|.)+('|"| *|>)?
28.图片链接:(s|S)(r|R)(c|C) *= *('|")?(\w|\|/|.)+('|"| *|>)?

29.中国固定电话号码:((\d{3,4})|\d{3,4}-|\s)?\d{8}
30.中国电话号码(包括移动和固定电话):((\d{3,4})|\d{3,4}-|\s)?\d{7,14}

31.中国邮政编码:[1-9]{1}(\d+){5}
32.ip地址:^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]).(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0).(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0).(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$

33.简单的日期判断(YYYY/MM/DD):^\d{4}(-|/|.)\d{1,2}\1\d{1,2})|(^\d{4}年\d{1,2}月\d{1,2}日

35.时间yyyy-MM-dd HH:MM:SS :^[1-9][0-9]{3}-(0?[1-9]|1[0|1|2])-(0?[1-9]|[1|2][0-9]|3[0|1]) (0?[1-9]|1[0-9]|2[0-3]):(0?[0-9]|[1|2|3|4|5][0-9]):(0?[0-9]|[1|2|3|4|5][0-9])$

36.匹配网址URL的正则表达式:((http|ftp|https|file)://([\w-]+.)+[\w-]+(/[\w\u4e00-\u9fa5-./?@%!&=+~:#;,]*)?)

  1. IPv4地址的正则表达式
iPv4的ip地址都是(1~255).(0~255).(0~255).(0~255)的格式

下面给出相对应的正则表达式:

"^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"

上面的一个不漏就是正确的验证ip的正则表达式,简单的讲解一下

\\d表示0~9的任何一个数字

{2}表示正好出现两次

[0-4]表示0~4的任何一个数字

| 的意思是或者

( )上面的括号不能少,是为了提取匹配的字符串,表达式中有几个()就表示有几个相应的匹配字符串

1\\d{2}的意思就是100~199之间的任意一个数字

2[0-4]\\d的意思是200~249之间的任意一个数字

25[0-5]的意思是250~255之间的任意一个数字

[1-9]\\d的意思是10~99之间的任意一个数字

[1-9])的意思是1~9之间的任意一个数字

\\.的意思是.点要转义(特殊字符类似,@都要加\\转义)

说到这里应该已经很清楚的知道了上面的正则表达式的意思。

5.3 正则表达式的种类

在Linux中,有两种流行的表达式引擎:

POSIX基础正则表达式(Basic Regular Expression, BRE)

POSIX扩展正则表达式(Extended Regular Expression, ERE)

5.3.1 扩展正则表达式

(1)字符匹配

.: 任意单个字符

[]: 指定范围内的任意单个字符

[^] : 指定范围外的任意单个字符

(2)次数匹配

*: 任意次

?: 0次或1次,其前的字符是可有可无的;

+: 其前字符至少1次;

{m}: 其前字符m次

{m,n}: 其前字符至少m次,至多n次;

{0,n}: 至多n次

{m,}: 至少m次

(3)位置锚定

^ : 行首锚定

$ : 行尾锚定

\<, \b: 词首锚定

\>, \b: 词尾锚定

(4)分组及引用

(): 分组;括号内的模式匹配到字符会被记录于正则表达式引擎内部变量中;

后向引用:\1,\2,.....

(5)或

a|b: a或b;

C|cat: C或cat

(c|C)at: cat或Cat

练习:

  • 找出/proc/meminfo文件中,所有在大写或小写S开头的行;至少有三种实现方式;
grep -En "^(s|S)" /proc/meminfo   或 grep -En "^(s|S)+" /proc/meminfo
或
grep -En "(^s)|(^S)" /proc/meminfo
或
grep -i "^[sS]" /proc/meminfo
或
grep "^[sS]" /proc/meminfo
  • 显示当前系统上root、gzr或wangwu用户的相关信息;
grep -En "^(root|gzr|wangwu)\>" /etc/passwd
  • 找出/etc/rc.d/init.d/functions文件中某单词后面跟一个小括号的行
grep -E "[_[:alnum:]]+\(\)" /etc/rc.d/init.d/functions 
# 如果只想匹配到的内容本身,可以加-o参数
grep -E -o "[_[:alnum:]]+\(\)" /etc/rc.d/init.d/functions 
  • 使用echo命令输出一条绝对路径,使用egrep取出基名(类似于取出bashname);
# 从右往左,锚定词尾的非斜线字符,但是这个非斜线字符得出现在行尾
echo /etc/sysconfig/network-scripts/ifcfg-eth0 | grep -E -o "[^/]+/?$"

1562378819468

扩展:取出路径名(类似于执行dirname的结果)

  • 找出ifconfig命令结果中的1-255之间的数值
ifconfig | grep -E -o "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
或

  • 找出ifconfig命令结果中的IP地址;
  • 添加用户bash,testbash,basher以及nologin(其shell为/sbin/nologin);而后找出/etc/passwd文件中用户名同shell名相同的行,即,开头和结尾字符相同
[root@gzr ~]# useradd bash
[root@gzr ~]# useradd basher
[root@gzr ~]# useradd -s /sbin/nologin nologin
[root@gzr ~]# useradd testbash

(1)首先锚定以非冒号开头行首

grep -E "^[^:]+\>" /etc/passwd

(2)采用后向引用,进行行尾定值

1562380090250

6. vim的高级用法

6.1 Vim内置组合键用法

:h key-notation查看

6.63332000521

6.2 技巧

6.2.1 认识 . 命令

(1)在普通模式下,按x,可以删除当前字符,按.则可以执行重复操作。

输入u撤销上述修改,相当于Windows下的Ctrl+Z.

(2) dd命令删除整行操作,然后再按 . 执行上述操作。

(3)shift + > + G,增加从当前行到末尾处的缩进层级,使用.则表示重复上述操作。其中>>可以实现当前行的缩进。

6.2.2 不要自我重复

比如我们需要给一个20行左右的文件的末尾,都加一个分号,那么可以

减少无关移动,在普通模式下输入按住Shift + A,,此处的A相当于$a, 可以快速跳到行尾,添加;然后返回普通模式,执行"j.",可以快速添加;

当然更简洁的方法是:

6.2.3 以退为进

我们使用Vim,有一种常用的习惯就是在一个字符前后各添加一个空格。

foo = "method("+argument1+","+argument2+")";

假设上述例子,需要在+号前后添加一个空格。

(1)使修改可重复

那么可以这样操作:

  • 首先按f然后按+号,快速定位这一行的第一个+号。

  • 然后先后按s、按空格、按+号、再按空格,则+前后完后出现两个空格,s命令的作用是把两个操作合并成一个,它先删除光标下的字符,然后进入插入模式。在删除+号后,先输入空格、+号、空格,然后退出插入模式

    这是先退一步,然后前进三步。

  • 然后我们按;分号,快速跳到下一个+号上,再按.点号,就可以重复快速执行上述操作了。

(2)使移动可重复

f{char}命令让Vim查找下一处指定字符串出现的位置,如果找到就直接把光标定位到那里。因此,输入f+,光标就会快速直接移动的第一个+加号所在的位置,执行完修改后,我们可以通过再按f+加号,跳到下一个+加号,但是此处

7. 数组array

关联数组:array[index-expression]

  • index-expression:

    • 可使用任意字符串;字符串需要使用双引号;
    • 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”:

    若要判断数组中是否存在某元素,要使用“index in array”格式进行;

    [root@gzr ~]# awk 'BEGIN{week["mon"]="Monday";week["tue"]="Tuesday";print week["mon"]}'
    Monday
    
  • 要遍历数组中的每个元素,采用for循环

    for(var in array) {for-body}

    [root@gzr ~]# awk 'BEGIN{week["mon"]="Monday";week["tue"]="Tuesday";for(i in week) {print week[i]}}'
    Tuesday
    Monday
    

注意:var变量会遍历array的每个索引;

[root@gzr ~]# netstat -ant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:199           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp        0      0 172.16.4.11:80          210.26.55.133:12596     TIME_WAIT  
tcp        0      0 172.16.4.11:80          172.16.4.25:53629       ESTABLISHED
tcp        0     52 172.16.4.11:22          210.26.55.133:12467     ESTABLISHED
tcp        0      0 172.16.4.11:80          172.16.4.25:53499       ESTABLISHED
tcp        0      0 172.16.4.11:80          172.16.4.25:53626       ESTABLISHED
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     
[root@gzr ~]# netstat -ant | awk '/^tcp\>/{state[$NF]++}END{for(i in state) {print i,state[i]}}'
LISTEN 4
ESTABLISHED 4
TIME_WAIT 1

# 以统计nginx的日志中ip访问数量为例,可以进行倒序排序
[root@gzr ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/nginx/access.log |sort -t" " -k 2 -n -r
172.16.4.18 21
210.26.55.133 17
172.16.4.25 16
172.16.4.12 14
172.16.4.13 11

练习1:统计/etc/fstab文件中每个文件系统类型出现的次数:

[root@gzr ~]# cat /etc/fstab 
......
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=be9bf6be-8766-436b-9079-45281abed73b /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

# 统计文件系统出现次数
[root@gzr ~]# awk '/^[UUID|/dev]/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab
swap 1
xfs 2

练习2:统计指定文件中指定文件中单词出现的次数;(要做行内字段遍历)

# 第一层循环,遍历所有行,count[$i]表示记录该单词,第二层循环,打印每个单词即次数
[root@gzr ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab | sort -k 2 -nr
# 7
......

11:15:22 1
/ 1


[^A-Z]:

全部评论

相关推荐

点赞 评论 收藏
分享
10-09 22:05
666 C++
找到工作就狠狠玩CSGO:报联合国演讲,报电子烟设计与制造
点赞 评论 收藏
分享
评论
2
9
分享
牛客网
牛客企业服务