想要实现下使用命令获取对应IP列表里每个服务器运行的进程(因为是测试,没有加上相应获取服务器进程列表的命令,只是用不同文本来做示范达到差不多同样效果),然后分别过滤服务器是否存在软件列表里面定义的进程,如果存在的话,就在IP后面空格分割显示出来!
一、测试所使用的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
[root@imzcy while]# ll 总用量 24 -rw-r--r--. 1 root root 10 11月 3 19:32 192.168.1.1.txt -rw-r--r--. 1 root root 17 11月 3 23:18 192.168.1.2.txt -rw-r--r--. 1 root root 17 11月 3 19:32 192.168.1.3.txt -rw-r--r--. 1 root root 36 11月 3 23:13 ip.txt -rw-r--r--. 1 root root 352 11月 3 22:32 run.sh -rw-r--r--. 1 root root 29 11月 3 22:33 soft.txt [root@imzcy while]# [root@imzcy while]# cat 192.168.1.1.txt 360sd.exe [root@imzcy while]# [root@imzcy while]# cat 192.168.1.2.txt qq.exe imzcy.exe [root@imzcy while]# [root@imzcy while]# cat 192.168.1.3.txt qq.exe 360sd.exe [root@imzcy while]# [root@imzcy while]# cat ip.txt 192.168.1.1 192.168.1.2 192.168.1.3 [root@imzcy while]# [root@imzcy while]# cat soft.txt 360sd.exe qq.exe diannao.exe [root@imzcy while]# |
二、测试正常的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[root@imzcy while]# cat run.sh #!/bin/bash # author:zcy # date:2018-11-29 # from:https://www.imzcy.cn while read ip_line; do info=`cat ${ip_line}.txt` a=$ip_line while read soft_line; do #echo "$info" |(grep $soft_line >/dev/null 2>&1 && eval a="$a $soft_line") echo "$info" |grep $soft_line >/dev/null 2>&1 [ $? -eq 0 ] && a="$a $soft_line" done <soft.txt echo $a done <ip.txt [root@imzcy while]# |
执行结果:
1 2 3 4 5 |
[root@imzcy while]# sh run.sh 192.168.1.1 360sd.exe 192.168.1.2 qq.exe 192.168.1.3 360sd.exe qq.exe [root@imzcy while]# |
三、说明
最开始的时候上面第二节的脚本,使用的是第16行的配置,17行和18行没有。。然后发现脚本执行完后,只会打印三个IP,并没有软件名。但是测试在内部那个循环里面直接第16行管道符后面加上echo能看到内部那个while的变量已经赋值了的。
后来百度上查了下相关资料,才知道当使用管道的时候,会打开一个新的subshell,后边给变量a重新赋值的代码在subshell中执行。但是因为赋值的过程只在刚才subshell这个子shell中才会生效,当前循环结束后,回到主shell,变量a没有并没有被修改,相当于在第11行赋值后,直接第22行打印出来了,所以才会只显示IP。
所以后边,就把第16行给注释掉了,新增了17和18行达到同样过滤后赋值的目的,脚本即达到正常想要实现的效果。