I'm writing a simple script for iptables to restrict access using MAC addresses.First, I check if an address has been passed to the script:ALLOWED_MAC=$5MAC_STRING=if [ -n $ALLOWED_MAC ] ; then    MAC_STRING=-m mac --mac-source ${ALLOWED_MAC}fiThen I pass the MAC_STRINGvariable to iptables:iptables -A INPUT -p $PROTOCOL --dport $PORT $MAC_STRING -m state --state NEW,ESTABLISHED -j ACCEPTI could (of course) have if/else'ed the whole thing but this solution look cleaner. If the user specifies an MAC address if gets passed on to iptables, otherwise we just pass an empty string.However, when I run this script I get an error from iptables:iptables v1.4.9.1: Invalid match name  mac --mac-source 00:11:22:33:44:55 (28 chars max)The hyphen/dash/minus before the m from MAC_STRING has disappeared. But if I instead echo the intended command everything look right:iptables -A INPUT -p tcp --sport 80  -m mac --mac-source 00:11:22:33:44:55 -m state --state ESTABLISHED -j ACCEPTI've tried this with other commands as well but with the same result; if I have a variable value starting with a hypen it gets gobbled when passed as a parameter to a program.
Hyphens in variable values (in bash)
bash
Ok, so I finally figured it out thanks to @Gilles who pointed me in the right direction.The iptables/mac snippet is inside a function. In my script I iterate over a given set of files and parse them, and then invoke the iptables function (for each file).As it turns out I'm changing the IFSat the top of the script (to simplify the file parsing) and let it be changed for the rest of the script.But if I start by saving the old IFS value and then set it back to this (old value) before each invocation everything works as expected!So, this doesn't work:#!/bin/bashfunction allow(){    [variable defs]     if [ -n $ALLOWED_MAC ] ; then        MAC_STRING=-m mac --mac-source $ALLOWED_MAC    fi    iptables -A INPUT -p $PROTOCOL --dport $PORT $MAC_STRING -m state --state NEW,ESTABLISHED -j ACCEPT}#Set the Internal Field Separator to the token used in the files.IFS=;[variable defs]#Iterate over all the port files.for file in $FILESdo#Read the first (and only) line from the current file and split the tokens into an array.LINE=$(cat $file)set -- $LINE declare -a Tokens=($*) [parse tokens]#Call 'allow' for each port definition.allow $PROTOCOL $PORT $DIRECTION $ALLOWED_MACdoneBut this works perfectly:#!/bin/bashfunction allow(){    [variable defs]    if [ -n $ALLOWED_MAC ] ; then        MAC_STRING=-m mac --mac-source $ALLOWED_MAC    fi    iptables -A INPUT -p $PROTOCOL --dport $PORT $MAC_STRING -m state --state NEW,ESTABLISHED -j ACCEPT}#Save the original IFSOLD_IFS=$IFS[variable defs]#Iterate over all the port files.for file in $FILESdo#Set the Internal Field Separator to the token used in the files.IFS=;#Read the first (and only) line from the current file and split the tokens into an array.LINE=$(cat $file)set -- $LINE declare -a Tokens=($*) [parse tokens]#Reset IFS before invoking the function.IFS=$OLD_IFS#Call 'allow' for each port definition.allow $PROTOCOL $PORT $DIRECTION $ALLOWED_MACdoneI might have missed something during copy/paste into here but I'm hoping that the essentials are there.Thanks for your help!//Anders