在Bash中读取ini配置文件为何与直接定义变量结果不同?
问题解决:Bash读取INI配置后IP变量异常及多IP放行实现
问题场景
有一个smb.ini配置文件,内容如下:
USERNAME=bridge01.test PASSWORD="8934v98nt3jiogt" SHARE="//test.one.test.nl/Data/" DOMAIN=ONE USERDNS=one.test.nl INTERFACE=eth0 IPALLOWED="172.1.50.95" DNSSERVERS=172.2.1.21,172.17.1.11,10.2.1.10 HOSTNAME=bridge01.test
通过Bash脚本的source命令读取该文件后,执行iptables规则添加时出现异常,错误输出:
Adding firewall rules ' not found.8.7 (nf_tables): host/network `172.1.50.95 Try `iptables -h' or 'iptables --help' for more information. 172.1.50.95 ' not found.8.7 (nf_tables): host/network `172.1.50.9
脚本代码如下:
config_file="smb.ini" source "$config_file" # Loop through the IP addresses and allow traffic from them for IPS in $IPALLOWED do echo $IPS # Allow traffic from the current IP address on TCP ports 137, 139, and 445 iptables -I INPUT -s "$IPS" -p tcp -m multiport --dports 137,139,445 -m state --state NEW -j ACCEPT echo "Allowed traffic from $IPS" iptables-restore < /etc/iptables iptables-save done
同时需要实现多IP批量放行的功能。
问题原因
- 变量引号残留:
smb.ini中IPALLOWED="172.1.50.95"的双引号会被source当作变量值的一部分,导致$IPALLOWED实际值为"172.1.50.95",iptables无法识别带引号的IP。 - 隐藏换行符/回车符:如果
smb.ini是Windows格式创建的,会包含\r回车符,导致IP字符串末尾有隐藏字符,触发iptables识别错误。 - 多IP处理逻辑错误:原脚本按空格分割
$IPALLOWED,但配置文件中多IP用逗号分隔(参考DNSSERVERS格式),无法正确拆分多个IP。
解决方案
1. 修正INI配置文件格式
- 去掉
IPALLOWED的双引号,若需要配置多个IP,用逗号分隔:IPALLOWED=172.1.50.95,192.168.1.100,10.0.0.5 - 若文件是Windows格式,执行
dos2unix smb.ini转换为Unix换行格式,清除隐藏的\r字符。
2. 修改脚本的IP处理逻辑
调整脚本,正确拆分逗号分隔的IP列表,同时优化iptables规则保存逻辑:
config_file="smb.ini" # 先转换文件格式(避免Windows换行问题,无则忽略错误) dos2unix "$config_file" 2>/dev/null source "$config_file" # 将逗号分隔的IP字符串转为数组 IFS=',' read -ra IP_LIST <<< "$IPALLOWED" # 循环处理每个IP for IPS in "${IP_LIST[@]}" do # 去除IP前后可能的空格 IPS=$(echo "$IPS" | xargs) echo "Processing IP: $IPS" # 添加iptables规则 iptables -I INPUT -s "$IPS" -p tcp -m multiport --dports 137,139,445 -m state --state NEW -j ACCEPT echo "Allowed traffic from $IPS" done # 统一保存规则到配置文件,避免循环内重复操作 iptables-save > /etc/iptables
关键优化点
- 用
IFS=',' read -ra将逗号分隔的IP转为数组,确保每个IP被正确拆分。 - 用
xargs去除IP前后的空格,兼容配置中可能出现的空格(如IPALLOWED=172.1.50.95, 192.168.1.100)。 - 将
iptables-save移到循环外,减少不必要的磁盘操作,提升效率。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

