Shell脚本命令是否有助于缩短?

yc0p9oo0  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(135)

我有个命令是这样的:

/bin/netstat -an | /usr/bin/awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="0.0.0.0" && a[1]!="127.0.0.1" && a[1]!="111.222.111.222" ... 50 addresses... && a[1]!="211.112.211.112"){c[a[1]]++}} END{for(ip in c){if(c[ip]>max){print ip}}}' | while read ip; do /sbin/iptables -m comment --comment "SCAN BLOCK" -I INPUT 1 -s $ip -j DROP; done

我怎么能缩短它从文件中读取IP地址,或从命令上方的数组列表中读取IP地址,或类似的东西,因为我现在有近100个IP地址,而且都是在一个大命令行中一个挨着另一个。
基本上,如何使命令像这样:

/bin/netstat -an | /usr/bin/awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="read from file"){c[a[1]]++}} END{for(ip in c){if(c[ip]>max){print ip}}}' | while read ip; do /sbin/iptables -m comment --comment "SCAN BLOCK" -I INPUT 1 -s $ip -j DROP; done
p3rjfoxz

p3rjfoxz1#

将IP列表放入文件中,例如:

$ cat iplist.txt
0.0.0.0
127.0.0.1
111.222.111.222
... snip ...
211.112.211.112

一般方法是让awk处理2个具有不同逻辑的输入文件,例如:

/bin/netstat -an | 
/usr/bin/awk -vmax=100 '

# process 1st file (iplist.txt): 

FNR==NR { iplist[$1]                 # FNR==NR is only true for the 1st file; for follow-on files FNR resets to 1 but NR keeps increasing
          next                       # skip to next input record; keeps from running follow-on code against 1st file contents
        }   

# process 2nd file (stdin):

/tcp/   { split($5,a,":")
          if (a[1] > 0 && !(a[1] in iplist))
             c[a[1]]++
        }
END     { for (ip in c) 
              if (c[ip]>max)
                 print ip
        }
' iplist.txt -                      # 2nd file actually says to read from stdin (ie, output from netstat call)

**注意:**OP会将此输出通过管道传送到同一个while/iptables循环,例如:

/bin/netstat -an | 
/usr/bin/awk -vmax=100 '
FNR==NR { iplist[$1] 
... snip ...
                 print ip
        }
' iplist.txt - |  while read ip; do /sbin/iptables ...;done

# or collapsed to one line (though harder to read and/or troubleshoot):

netstat -an | awk -vmax=100 'FNR==NR{iplist[$1];next} /tcp/{split($5,a,":"); if (a[1] > 0 && !(a[1] in iplist)) c[a[1]]++} END{for (ip in c) if (c[ip]>max) print ip}' iplist.txt - | while read ip; do /sbin/iptables ...;done
qcbq4gxm

qcbq4gxm2#

如果你不关心输出顺序,为什么不像其他人建议的那样,把第一个iplist.txt读入一个数组,然后只要它正好比vmax阈值多1就输出,例如:
第一个

ps:jot -w '%d 1.0.0.1' 105同样适用于line 1,但第1行是什么并不重要,因为它表示通过管道传入的任何内容

相关问题