4

06.命令的组合使用_愿听风成曲的技术博客_51CTO博客

 4 months ago
source link: https://blog.51cto.com/quyunlong/10680838
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

命令的组合使用

1.查询当前整个系统每个进程的线程数

我们经常遇到这样的问题,比如某台服务器的CPU 使用率飙升,通过top命令查看是某个程序(例如java)占用的cpu比较大,现在需要查询java各个进程下的线程数情况。可以通这一个命令组合实现:

for pid in $(ps -ef|grep -v grep|grep "java"|awk '{print $2}');do echo ${pid} > /tmp/a.txt ;cat /proc/${pid}/status|grep Threads > /tmp/b.txt ; paste /tmp/a.txt /tmp/b.txt;done|sort -k3 –rn

先解释下这个脚本:

#这部分是获取${pid}变量为 java 进程的 pid 号。
for pid in $(ps -ef|grep -v grep|grep java |awk '{print $2}')

这部分是将 java 进程的 pid 号都打印到/tmp/a.txt 文件中。
echo ${pid} > /tmp/a.txt 

这部分是将各个 pid 进程号下的线程信息打印到/tmp/b.txt 文件中。
cat /proc/${pid}/status|grep Threads > /tmp/b.txt

这部分是以列的形式展示a.txt和b.txt文件中的信息。
paste /tmp/a.txt /tmp/b.txt

这部分是对输出的信息进行排序,其中,-k3 表示以第三列进行排序,“-rn”表示降序排列。
sort -k3 -rn

将上面命令组合放入系统执行完毕后,输入内容如下:

06.命令的组合使用_oracle

从输出可以看出,第一列显示的是 java 的进程号,最后一列显示的每个 java 进程对应的线程数量。这个例子是一个for循环加上ps命令和sort命令综合应用的实例。

2.如何检测系统中的僵尸进程并kill掉

要查找系统中的僵尸进程,有多种方法,这里给出一种命令行探测僵尸进程的方法:

[root@qu ~]# ps -e -o stat,ppid,pid,cmd | egrep '^[Zz]'
Z	10808 10812 [java] <defunct>

介绍下用到的几个参数:

  • -e:参数用于列出所有的进程
  • -o:参数用于设定输出格式,这里只输出进程的 stat(状态信息)、ppid(父进程 pid)、pid(当前进程的 pid),cmd(即进程的可执行文件。
  • egrep:是 linux 下的正则表达式工具
  • '[Zz]':这是正则表达式,表示第一个字符的位置,[Zz],表示小写 z或者大写的Z字母,即表示第一个字符为Z或者z开头的进程数据,只所以这样是因为僵尸进程的状态信息以Z 或者z字母开头。

找到僵尸进程的 pid 后,直接通过”kill -9 pid“命令杀掉即可,但是如果僵尸进程很多的话,就会很繁琐,因此,还需要一个批量删除僵尸进程的办法:

ps -e -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9

这是个命令组合,通过管道实现命令的组合应用。“grep -e”相当于 egrep命令。“awk '{print $2}' ”是将前面命令的输出信息进行过滤,仅仅输出第二列的值,而第二列就是进程的 ppid。“xargs kill -9”这是将得到的 ppid 传给“kill -9”作为参数,也就是kill 掉这些ppid。xargs命令可以将标准输入转成各种格式化的参数,这里是将管道的输出内容作为参数传递给kill命令。

其实这个命令组合是将僵尸进程的父进程杀掉,进而关闭僵尸进程的,为什么要这么做呢,其实一般僵尸进程很难直接用kill 杀死,因为僵尸进程已经是死掉的进程,它不能再接收任何信号。所以,需要通过 kill 僵尸进程的父进程,这样父进程杀掉后,僵尸进程就成了”孤儿进程”,而所有的孤儿进程都会交给系统的 1 号进程(init 或 systemd)收养,1 号进程会周期性地去调用wait系统调用来清除这些僵尸进程。因此,我们可以发现,父进程杀掉之后,僵尸进程也跟着消失,其实是1号进程作用的结果!

3.如何查看当前占用CPU 或内存最多的几个进程

这个应用需求在服务器的问题排查和故障处理上使用率非常高,要获取这些信息,只需要一些命令组合即可实现,可以说非常简单。

1)获取当前系统占用CPU最高的前10个进程最简单的方式是通过ps命令组合实现,例如:

[root@qu ~]# ps aux|head -1;ps aux|sort -rn -k3|head -10

该命令组合主要分为两个部分:

  • ps aux|head -1
  • ps aux|sort -rn -k3|head -10

其中,第一句主要是为了获取标题(USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND)信息。而“head:-N”可以指定显示的行数,默认显示 10 行。

第二个命令是一个输出加排序组合,ps 参数的 a 指代 all,表示所有的进程,u 指代 user id,就是执行该进程的用户 id,x 指代显示所有程序,不以终端机来区分。

接下来是 sort 命令,其中:

  • r 指代 reverse,这里是指反向比较结果,输出时默认从小到大,反向后从大到小。
  • n 指代 numberic sort,根据其数值排序。
  • k 代表根据哪一列进行排序,后面的数字 3 表示按照第 3 列排序。本例中,可以看到%CPU 在第 3 个位置,因此k3 表示根据%CPU 的数值进行由大到小的排序。

接下来的“|”为管道符号,将查询出的结果导到下面的命令中进行下一步的操作。最后的“head -10”命令获取默认前 10 行数据。

2)获取当前系统占用内存最高的前10个进程

同理,要获取系统占用内存最高的前10个进程,方法与获取cpu方法一致,命令组合修改为如下即可:

[root@qu ~]# ps aux|head -1;ps aux|sort -rn -k4|head -10

这里仅仅修改了k3位k4,4代表第4列排序。本例中,可以看到%MEM在第4个位置,因此k4表示根据% MEM的数值进行由大到小的排序。

4.如何对文件进行连接、合并、排序、去重

4.1.文件连接命令 join

join 命令用于将两个文件中,指定列中内容相同的行连接起来。找出两个文件中,指定列内容相同的行,并加以合并,再输出到标准输出设备。

常用的参数以及含义如下表所示:

join 默认以空格符分隔数据,并且比对第一个字段的数据,如果两个文件相同,则将两笔数据联成一行,且第一个字段放在行首

忽略大小写的差异

这个是数字的 1 ,代表第一个文件要用哪个字段来分析的意思

代表第二个文件要用哪个字段来分析的意思

看一个例子:file1 文件的内容:

[root@localhost ~]# cat file1.txt 
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 
sync:x:5:0:sync:/sbin:/bin/sync 
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

file2文件的内容:

[root@localhost ~]# cat file2.txt 
root:x:0:
bin:x:1: 
daemon:x:2: 
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mem:x:8:

要从 file1.txt 和 file2.txt 中可以看出,file1.txt 中以“:“分割的第三列和 file2.txt 中以“:“分割的第三列内容相同,因此这两个文件可以合并整合在一起,看下面这个操作:

[root@localhost ~]#join -t ':' -1 3 file1.txt -2 3  file2.txt 
0:root:x:0:root:/root:/bin/bash:root:x: 
1:bin:x:1:bin:/bin:/sbin/nologin:bin:x: 
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x: 
3:adm:x:4:adm:/var/adm:/sbin/nologin:sys:x: 
4:lp:x:7:lp:/var/spool/lpd:/sbin/nologin:adm:x: 
5:sync:x:0:sync:/sbin:/bin/sync:tty:x:
6:shutdown:x:0:shutdown:/sbin:/sbin/shutdown:disk:x:

可以看出,通过-t选项指定了分隔符后,输出的内容是将file1.txt文件的第三列和file2.txt 文件的第三列进行整合的结果,两个文件合并后,相同的字段部分被移动到每行最前面了。

4.2.合并文件列命令paste

paste 命令用于合并文件的列。它会把每个文件以列对列的方式,一列列地加以合并。paste 比join 简单很多,它其实就是直接将两个文件中相同的两行贴在一起,且中间以 [tab]键隔开而已。

例如对上面的 file1.txt 和file2.txt 进行 paste 合并,执行结果如下:

[root@qu ~]# paste file1.txt file2.txt 
root:x:0:0:root:/root:/bin/bash 	root:x:0:
bin:x:1:1:bin:/bin:/sbin/nologin 	bin:x:1: 
daemon:x:2:2:daemon:/sbin:/sbin/nologin 	daemon:x:2: 
adm:x:3:4:adm:/var/adm:/sbin/nologin 	sys:x:3:
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 	adm:x:4:
sync:x:5:0:sync:/sbin:/bin/sync 	tty:x:5:
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown	disk:x:6:
halt:x:7:0:halt:/sbin:/sbin/halt	lp:x:7:
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin	mem:x:8:

接着,再看一个组合例子:

[root@qu ~]# cat /etc/group|paste /etc/passwd /etc/shadow -|head -n 3
root:x:0:0:root:/root:/bin/bash	root:$6$itBvz.u4iA5xf22B$LIlL6/QaOUOlEk8THDtlVYv0jU9ByBDIqyaKqaXBvpLbKnez359YtwnrRaXkHdkY9t/lhPe5xzvmfGaprwFEh/::0:99999:7:::	root:x:0:
bin:x:1:1:bin:/bin:/sbin/nologin	bin:*:18353:0:99999:7:::	bin:x:1:
daemon:x:2:2:daemon:/sbin:/sbin/nologin	daemon:*:18353:0:99999:7:::	daemon:x:2:

这个例子的重点在那个“-”的使用,那玩意代表标准输入,在这里会接收/etc/group 的内容,因为通过“cat /etc/group”将此文件内容送到了标准输入,而“-”刚好接收了这个内容。因此,这个组合其实是三部分文件内容的合并,分别是/etc/passwd、/etc/shadow和/etc/group三个文件内容合并的结果,而每行内容中通过默认的[tab]键隔开。

4.3.文本内容排序命令sort

sort 这个命令很好用,主要用做排序,基本使用格式为:

sort [-t 分隔符] [-kn1,n2] [-nru]

参数含义如下表所示:

使用纯数字进行排序,默认是以字母顺序来排序的

就是 uniq ,相同的数据中,仅出现一行代表

分隔符,默认是用 [tab] 键来分隔

以那个区间(field)来进行排序的意思

先看最简单的一个例子:

[root@qu ~]# cat /etc/passwd | sort | head 
adm:x:3:4:adm:/var/adm:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

这是最简单的一个sort排序,没指定任何参数,所以默认以英文字母顺序进行排序, head是默认显示前10行数据,要显示指定行数据,可以通过“head -N”实现。

继续看下面这个例子:

[root@qu ~]# cat /etc/passwd | sort -t ':' -k3 -n | head
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

这个例子是通过指定分隔符':',然后对指定的列进行排序,k3表示以':'作为分隔符的第三列,也就是以第三列为准进行排序,由于第三列都是数字,所以还需要“-n”参数。

4.4.检查并删除文件中的重复行命令uniq

uniq主要用于检查及删除文本文件中重复出现的行,一般与sort命令结合使用,常用参数如下表所示:

-c 或--count

在每列旁边显示该行重复出现的次数

-d:或--repeated

仅显示重复出现的行列

看下面例子:这是ixdbafile1 文件的内容:

[root@qu ~]# cat ixdbafile1 
server 188
server 188
server 188
jenkins 66
jenkins 66
oracle 90
oracle 90
oracle 90
saybye 122
saybye 122
saybye 122
saybye 122

可以看到有重复行,并且重复行都是相邻的,要删除重复行,uniq 就派上用场了,看下面例子:

[root@qu ~]# uniq ixdbafile1
server 188
jenkins 66
oracle 90
saybye 122

可以看到,已经删除了重复行。如果要统计重复行出现的次数,加上“-c”参数即可,看下面这个例子:

[root@qu ~]# uniq ixdbafile1 -c
      3 server 188
      2 jenkins 66
      3 oracle 90
      4 saybye 122

上面的 ixdbafile1 文件有些特殊,因为实际使用中,重复行不可能都是相邻在一起的,那继续来看另一个文件内容:

[root@qu ~]# cat ixdbafile2 
server 188
saybye 122
jenkins 66
server 188
saybye 122
jenkins 66
server 188
saybye 122
jenkins 66
oracle 90
redis 126

这是个重复行不相邻的文件,实际环境中,很多都是类似这样的文件,再通过uniq看看是否能够删除重复行,执行如下操作:

[root@qu ~]# uniq ixdbafile2
server 188
saybye 122
jenkins 66
server 188
saybye 122
jenkins 66
server 188
saybye 122
jenkins 66
oracle 90
redis 126

可以看到,文件原样输出了,也就是说 uniq 对这些重复行不相邻的内容无能为力了,怎么办呢,现在是时候该sort出场了,sort 我们知道是排序用的,那就先把这个文件进行排序,这样,重复行不就自动相邻了吗,看下面操作:

[root@qu ~]# sort ixdbafile2 
jenkins 66
jenkins 66
jenkins 66
oracle 90
redis 126
saybye 122
saybye 122
saybye 122
server 188
server 188
server 188

经过 sort 排序后,重复行相邻了,接着通过管道后面接 uniq 命令即可过滤删除重复行了,看下面操作:

[root@qu ~]# sort ixdbafile2|uniq
jenkins 66
oracle 90
redis 126
saybye 122
server 188

果然,经过sort排序后,uniq又可以正常工作了,这也是为什么sort经常和uniq一起使用的原因了。

下面这个是使用了 uniq 的“-d”参数,也就是显示重复行有哪些:

[root@qu ~]# sort ixdbafile2|uniq -d
jenkins 66
saybye 122
server 188

几个简单例子,发现 uniq 很简单。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK