Hífens em valores variáveis (em bash) [closed]

1

Estou escrevendo um script simples para iptables para restringir o acesso usando endereços MAC. Primeiro, verifico se um endereço foi passado para o script:

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

Depois, passo a variável MAC_STRING para iptables :

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

Eu poderia (é claro) ter a coisa toda, mas essa solução parece mais limpa. Se o usuário especificar um endereço MAC se for passado para iptables , caso contrário, apenas passamos uma string vazia.

No entanto, quando executo este script, recebo um erro de iptables :

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

O hífen / traço / menos antes que o m de MAC_STRING tenha desaparecido. Mas se eu, em vez disso, repetir o comando pretendido, tudo parece certo:

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

Eu tentei isso com outros comandos também, mas com o mesmo resultado; se eu tiver um valor de variável começando com um hífen, ele será devorado quando passado como um parâmetro para um programa.

    
por user1143242 14.04.2015 / 15:09

1 resposta

0

Ok, finalmente descobri graças ao @Gilles que me apontou na direção certa.

O snippet iptables / mac está dentro de uma função. No meu script, eu faço iterações em um determinado conjunto de arquivos e os analiso, e invoco a função iptables (para cada arquivo).

Como acontece, estou alterando o IFS na parte superior do script (para simplificar a análise do arquivo) e deixe que ele seja alterado para o restante do script. Mas se eu começar salvando o antigo valor de IFS e então configurá-lo de volta para este (valor antigo) antes de cada invocação, tudo funciona como esperado!

Portanto, este não funciona:

#!/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

Mas isso funciona perfeitamente:

#!/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

Eu poderia ter perdido alguma coisa durante copiar / colar aqui, mas espero que o essencial esteja lá.

Obrigado pela sua ajuda!

// Anders

    
por 15.04.2015 / 08:17

Tags