Method 2 doesn't work — it produces an invalid iptables
invocation. Whatever you thought it might do, it only adds one iptables rule, and you can't match an arbitrary set of interfaces in a single rule. Method 1 is the normal way and pretty much the only way.
Not that efficiency of setting iptables rules is a concern. You'd have to work very hard to do something noticeably non-optimal. The concerns here are to get the rules right, possibly the efficiency of the rules themselves, and keep the script readable so that it's easy to maintain.
Writing $Ext_INTF
— a variable substitution outside double quotes — splits the value of the variable into whitespace-separated parts, and then expands each part as a wildcard pattern matching file names. Here the variable doesn't contain any wildcard character (\[*?
). Thus for i in $Ext_INTF; …
loops over the words in the value of the variable. In general you should only use variable substitutions inside double quotes, because $Ext_INTF
means “the value of Ext_INTF
” only inside double quotes, but here you want the splitting to happen, and the parts don't contain any shell wildcard characters.
Ext_INTF="eth0 usb0 tun0 tun1"
for i in $Ext_INTF; do
iptables -A FORWARD -i "$i" -j DROP
done
In bash and ksh, but not in plain sh, you can use an array instead of a string variable. (And in zsh you must use an array or explicitly request splitting with $=Ext_INTF
.) You have to type a few more characters, but this makes the intent clearer, and allows the elements to contain whitespace and wildcards if need be.
Ext_INTF=(eth0 usb0 tun0 tun1)
for i in "${Ext_INTF[@]}"; do
iptables -A FORWARD -i "$i" -j DROP
done
IPTABLES
doesn't contain any whitespace or wildcard characters and you aren't changing the value ofIFS
then writing$IPTABLES
without quotes is ok. However making such assumptions defeats the purpose of using a variable. What if you want to use a different version ofiptables
that's located in/opt/advanced networking/bin
? Either writeiptables
(there's very little reason to replaceiptables
by something else) or"$IPTABLES"
. – Gilles 'SO- stop being evil' May 16 '17 at 11:04