【问题标题】:Shell script command help to shorten?Shell脚本命令有助于缩短?
【发布时间】:2022-10-17 05:44:17
【问题描述】:

我有一个这样的命令:

/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

【问题讨论】:

  • while read line; do <your stuff> ; done < ip_list.txt 或类似的东西。

标签: shell awk ssh netstat


【解决方案1】:

将 ips 列表放在一个文件中,例如:

$ 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

【讨论】:

  • 你能告诉我把剩下的命令放在哪里吗:|同时读取ip;做 /sbin/iptables -m 评论 --comment "扫描块" -I INPUT 1 -s $ip -j DROP;完毕 ?对不起,但我不是专家......但......对于这种“复杂”的脚本:)
  • @Hrvoje 添加了有关完整命令系列的更多详细信息
【解决方案2】:

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

# imagine the <( echo ... ) is the iplist.txt being read in

jot -b '1.0.0.1' 105 | gcat -n | 

mawk 'FNR==NR ? __[$(_<_)] : $NF in __  && 
                         __[ $NF ]++==+_' _='100' <( echo '1.0.0.1' ) -
101 1.0.0.1

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

【讨论】:

  • gcat 很奇怪,-n 选项是非 POSIX 扩展,但 Awk 非常了解行号,这是您已经在使用的功能。
  • 还需要安装记事本在超过 30 个节点上,并且每个新节点都会产生......
  • @Hrvoje:不,这只是为了说明通过管道输入的任何内容……..如果您愿意,只要它以文本形式通过管道,您也可以让microsoft word生成该输入-因为OP没有提供有意义的测试集我必须想出一个
  • @tripleee:只是让一个外部独立实体确认行号而已……。当bsd-catgnu-cat 都支持此功能时,cat -n 不是posix 有什么关系? posix 是跨 unix 变体的标准化工作中发生过的最糟糕的事情之一,即使到今天,它仍然在迎合所有变体中的最低分母,从而阻止了每一个转折点的进展。 POSIX 排除 -n "cuz it's already offered by utility pr" 的理由比我想象的还要荒谬。
  • gcat 很奇怪,因为几乎没有人会拥有该名称的命令。我猜你的意思是 GNU cat,可能在带有 Homebrew 的 Mac 上,但很多用户不会。我仍然不明白这是如何“确认”行号的;你不信任 awk 的NR 吗?
猜你喜欢
  • 1970-01-01
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 2020-11-30
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多