变量值中的连字符(在 bash 中)

变量值中的连字符(在 bash 中)

我正在写一个简单的脚本iptables使用 MAC 地址限制访问。首先,我检查地址是否已传递给脚本:

ALLOWED_MAC=$5
MAC_STRING=""
if [ -n "$ALLOWED_MAC" ] ; then
    MAC_STRING="-m mac --mac-source ${ALLOWED_MAC}"
fi

然后我将MAC_STRING变量传递给iptables:

iptables -A INPUT -p $PROTOCOL --dport $PORT $MAC_STRING -m state --state NEW,ESTABLISHED -j ACCEPT

我(当然)可以对整个事情进行 if/else,但这个解决方案看起来更干净。如果用户指定 MAC 地址,则传递到iptables,否则我们只传递一个空字符串。

但是,当我运行此脚本时,我收到错误iptables:

iptables v1.4.9.1: Invalid match name " mac --mac-source 00:11:22:33:44:55" (28 chars max)

mfrom之前的连字符/破折号/减号MAC_STRING消失了。但如果我回显预期的命令,一切看起来都正确:

iptables -A INPUT -p tcp --sport 80  -m mac --mac-source 00:11:22:33:44:55 -m state --state ESTABLISHED -j ACCEPT

我也尝试过使用其他命令,但结果相同;如果我有一个以连字符开头的变量值,那么当它作为参数传递给程序时,它会被吞噬。

答案1

好的,感谢@Gilles,我终于弄清楚了,他为我指明了正确的方向。

iptables/mac 片段位于函数内部。在我的脚本中,我迭代一组给定的文件并解析它们,然后调用 iptables 函数(对于每个文件)。

事实证明,我正在更改IFS脚本顶部的(以简化文件解析)并让它针对脚本的其余部分进行更改。但是,如果我首先保存旧IFS值,然后在每次调用之前将其设置回此(旧值),则一切都会按预期工作!

所以这工作:

#!/bin/bash

function 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 $FILES
do

#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_MAC

done

但这很有效:

#!/bin/bash

function 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" IFS
OLD_IFS=$IFS

[variable defs]

#Iterate over all the port files.
for file in $FILES
do

#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_MAC

done

我可能在复制/粘贴到这里的过程中错过了一些东西,但我希望要点在那里。

感谢您的帮助!

//安德斯

相关内容