Bash 用于读取文件的Shell脚本

Bash 用于读取文件的Shell脚本,bash,shell,sh,iptables,Bash,Shell,Sh,Iptables,我编写了一个shell脚本来读取由IP地址组成的文件,然后在iptables的帮助下阻止它们。它工作得很好,但是当我第二次运行脚本时,它会再次写入规则(重复)。我希望它检查IP是否已经被阻止,然后忽略它,否则阻止。以下是脚本: #!/bin/bash ipadds="/home/asad/Downloads/blacklist" dropit=$(grep -Ev "^#" $ipadds) for i in $dropit; do iptables -A INPUT -s $i -j DRO

我编写了一个shell脚本来读取由IP地址组成的文件,然后在iptables的帮助下阻止它们。它工作得很好,但是当我第二次运行脚本时,它会再次写入规则(重复)。我希望它检查IP是否已经被阻止,然后忽略它,否则阻止。以下是脚本:

#!/bin/bash
ipadds="/home/asad/Downloads/blacklist"
dropit=$(grep -Ev "^#" $ipadds)
for i in $dropit; do
 iptables -A INPUT -s $i -j DROP
 iptables -A FORWARD -s $i -j DROP
done
首次运行脚本后的输出:

root@ubuntu:/home/asad/Downloads# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
root@ubuntu:/home/asad/Downloads# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
第二次运行脚本后的输出:

root@ubuntu:/home/asad/Downloads# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
root@ubuntu:/home/asad/Downloads# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
DROP       all  --  192.168.248.2        anywhere
DROP       all  --  192.168.232.20       anywhere
DROP       all  --  192.168.232.5        anywhere
DROP       all  --  192.168.232.190      anywhere
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
如何避免这种重复?需要帮忙吗

#!/bin/bash
ipadds=/home/asad/Downloads/blacklist
grep -v "^#" $ipadds | while read i; do
 if ! iptables -nL INPUT | grep -Fq "$i" ; then
   iptables -A INPUT -s "$i" -j DROP
   iptables -A FORWARD -s "$i" -j DROP
 fi
done
或者(也许这对你没什么影响)

#/bin/bash
ipadds=/home/asad/Downloads/blacklist
当我读书时;做
如果!iptables-nL输入| grep-Fq“$i”;然后
iptables-A输入-s“$i”-j拖放
iptables-A FORWARD-s“$i”-j DROP
fi
完成<您可以试试

#!/bin/bash

ipadds="/home/asad/Downloads/blacklist"

while IFS='' read -r 
do 
    # check if the rule already exists - if not add it - and 
    # silently ignore warnings for rules that dont exist
    if ! iptables -C INPUT -s "$REPLY" -j DROP 2> /dev/null
    then 
        iptables -A INPUT -s "$REPLY" -j DROP
    fi

    if ! iptables -C FORWARD -s "$REPLY" -j DROP 2> /dev/null
    then 
        iptables -A FORWARD -s "$REPLY" -j DROP
    fi
# Please note proper syntax for process substitution
done < <(grep -Ev "^#" $ipadds)
#/bin/bash
ipadds=“/home/asad/Downloads/blacklist”
而IFS=''读-r
做
#检查规则是否已存在(如果不存在,请添加它),然后
#默认忽略不存在的规则的警告
如果!iptables-C输入-s“$REPLY”-j DROP 2>/dev/null
然后
iptables-A输入-s“$REPLY”-j删除
fi
如果!iptables-C FORWARD-s“$REPLY”-j DROP 2>/dev/null
然后
iptables-转发-s“$REPLY”-j丢弃
fi
#请注意进程替换的正确语法

已完成<不要使用<代码>进行<代码>循环命令输出,使用<代码>进行进程替换,而<代码>@gniourf\u gniourf:意识到这并不能解决问题。您预期的代码不能以这种方式工作。您应该需要一个数组来存储命令输出。您当前的语法允许shell进行分词处理,将单个空格分隔的行处理为多个entries坦率地说,我强烈建议使用一个已经可以为您实现这一点的框架,例如,而不是自己重新设计轮子。我绝对同意@charlesduff。我也想到了。我的观点很好!如果您在
$i
周围添加双引号将更好,因为
“$i”
更重要roubust@Inian
$i
是合法的,当且仅当它包含有效的IP地址,即点和数字(在ipV4环境中),并且将其置于引号中只会保留非法字符。为了增加健壮性,应该相应地对其进行解析,这将是低效的。我想不出有哪种情况,
$ip
会失败,
“$ip”
会成功。引用并没有坏处。特别是当
IFS
包含句点或数字时。真的,不要做假设。只需引用每一个扩展。不过,一个更大的问题是,句点将被解释为“匹配任何单个字符”。另一个问题是正则表达式没有被锚定。仍然缺少引号,仍然没有被锚定。@Dario:没有,那是因为您没有全局分配
IFS
。在您的代码段中,
IFS
只是一个要读取的环境变量,因此它的值被还原,然后执行
echo$i
。试试这个:
i=“1.2.3.4”IFS=。;echo$i
。惊喜。回答很好(我编辑了它,因为它缺少必要的
@Inian,它可以工作,但得到了很多警告:“iptables v1.6.0:主机/网络未找到”。无论如何,感谢您的关注。