使用awk调用system函数生成ufw规则时遇换行及内容丢失问题求助
修复awk脚本生成UFW规则的换行与丢行问题
问题根源
规则换行、第4条内容丢失,大概率是以下原因导致:
- 目标IP文件
susp.txt采用Windows换行格式(每行结尾带\r回车符),输出时触发换行 - 频繁调用
system(grep...)存在shell解析风险,且多次文件IO可能导致丢行 - 未对IP内容做清洗,特殊字符干扰规则生成
修复方案:预加载黑名单+直接写入文件
使用以下awk脚本,一次性加载黑名单IP到内存,清洗IP内容后直接写入规则文件,避免shell调用的问题:
#!/usr/bin/awk -f BEGIN { # 定义文件路径 banned_path = "/usr/local/test/banned.txt" output_path = "/usr/local/test/script.sh" # 预加载黑名单IP到数组,避免重复调用grep while ((getline ip < banned_path) > 0) { banned[ip] = 1 } close(banned_path) } # 匹配合法IPv4地址行(假设每行一个IP) /^([0-9]{1,3}\.){3}[0-9]{1,3}$/ { ip = $0 # 移除Windows换行符\r,避免规则换行 gsub(/\r/, "", ip) # 检查IP不在黑名单中则生成规则 if (!banned[ip]) { rule = "/sbin/ufw deny from " ip " to any" # 直接用awk内置print追加到文件,无shell转义风险 print rule >> output_path } } END { close(output_path) }
使用步骤
- 将上述脚本保存为
filter_ips.awk - 赋予执行权限:
chmod +x filter_ips.awk - 运行脚本处理目标文件:
./filter_ips.awk /usr/local/test/susp.txt
替代单行命令
如果不想保存脚本,可直接执行以下单行命令:
awk 'BEGIN{while((getline ip < "/usr/local/test/banned.txt")>0) banned[ip]=1; close("/usr/local/test/banned.txt")} /^([0-9]{1,3}\.){3}[0-9]{1,3}$/{gsub(/\r/,"",$0); if(!banned[$0]) print "/sbin/ufw deny from " $0 " to any" >> "/usr/local/test/script.sh"} END{close("/usr/local/test/script.sh")}' /usr/local/test/susp.txt
关键优化点
- 预加载黑名单:一次性读取
banned.txt到数组,避免多次调用grep,提升效率且消除shell解析风险 - IP清洗:用
gsub(/\r/, "", ip)移除Windows换行符,确保规则单行显示 - 直接写入文件:使用awk内置的
print >>操作,替代system(echo...),避免shell特殊字符干扰
内容的提问来源于stack exchange,提问作者Conspiracy
相关产品推荐
相关产品推荐

