Bash - Parâmetros Referência passando (tipo de)

1

Então,

Eu descobri até agora como utilizar o comando "local -n", o que efetivamente me permite "referenciar" uma variável de uma função para outra.

isso é bastante útil ao analisar parâmetros $ [#] que podem estar em qualquer ordem.

se% 1 é sempre a mesma coisa, isso não é um problema, mas (por exemplo):

git checkout -b --track MyBranch

é o mesmo que

git checkout --track -b MyBranch

no entanto, no conceito de uma função hipotética 'git' checkout, -b, --track e MyBranch são simples% 1,% 2,% 3 e% 4, o que significa que a função precisa ser inteligente o suficiente para interpretar qual é qual.

Ao resolver este enigma, e para expandir meu conhecimento de script, comecei a trabalhar com o comando local -n e criei uma função como esta:

parseParam %1 -d opt -c opt "%" name
parseParam %2 -d opt -c opt "%" name
parseParam %3 -d opt -c opt "%" name

"parseParam" simplesmente avalia o primeiro parâmetro (o passado% [#]) e compara aos parâmetros 2,4,6 (% é o moniker para apenas uma string no - ou / prefix), e em uma correspondência usa o parâmetro local -n nos parâmetros 3, 5 e 7 para atribuição. A função de chamada pode acessar $ opt ou $ name sem preocupação com o parâmetro $ [#] de origem.

Isso funciona. No entanto, como você pode ver a falha iminente na convenção de chamada acima, se ambos -d e -c forem fornecidos a função de chamada, depois de executar o "parseParam" o último parâmetro fornecido será atribuído a "opt".

Eu tentei duas soluções, uma funcionou, uma no entanto (a mais limpa) não.

parseParam $1 "%" name -c opt -d opt -s opt -m msg
if [[ $? -ge 2 ]] && [[ $? -le 4 ]]; then
    parseParam $2 "%" name -m msg
else parseParam $2 "%" name -c opt -d opt -s opt -m msg
fi;
if [[ $? -ge 2 ]] && [[ $? -le 4 ]]; then
    parseParam $3 "%" name -m msg
else parseParam $3 "%" name -c opt -d opt -s opt -m msg 
fi;

Essa versão funcional é ótima para um problema de parâmetro único. Esse fluxo diz que -c, -d ou -s podem ser usados como parâmetros, mas apenas um é aceito. mas se eu tivesse um "nome" e um parâmetro "target", esse fluxo ficaria insanamente complexo e efetivamente derrotaria o propósito do parseParam. Então eu tentei um tato diferente:

parm="\"%\" name -c opt -d opt -s opt -m msg"

parseParam $1 $parm
cleanParam $? parm $parm 

então parseParm executaria o mesmo, mas a lista de parâmetros seria fornecida pela variável $ parm. CleanParam, como você poderia esperar, removeria o parâmetro optiosn da variável $ parm com base na qual foi preenchida (como retornado pela função parseParam).

No entanto, embora parseParam tenha interpretado 11 parâmetros e reconhecido individualmente cada um deles, o comando local -n falhou em transcender o limite da função ao executar parseParam dessa maneira. Então, dentro de parseParam $ opt retornaria -d, mas uma vez de volta na função de chamada $ opt ainda estaria vazia. se eu passar os parâmetros individualmente, funciona, mas se eu passá-los como uma única string, eles não funcionam.

Então, depois de todo esse preâmbulo, minha pergunta é:

Existe uma maneira de passar uma lista de uma função para outra:

parseParam $! $listOfParameters $listOfVariableNames

Para que parseParam, ao processar os nomes das variáveis, pode atribuir um valor a esse nome (como o local -n) que será acessível a partir da função de chamada.

Obrigado Jaeden "Sifo Dyas" al'Raec Ruiner

Função atual defs para referência:

#======================================
# ParseParam function
#======================================

parseParam()
{
    p=$1;
    shift;
    l=$#;
    # echo "Param Count : $l, $p"
    if [ $((l%2)) -eq 0 ]; then
        paramType $p $1 $3 $5 $7 $9
        idx=$?
        if [[ $idx -gt 0 ]]; then
            shift $(( ($idx - 1) * 2 ))
            # echo "Index: $idx - $1 = $2"
            local -n var="$2"
            if [[ ${p:2:1} = "=" ]]; then var=${p:3}; 
            elif [[ $p == /* ]] || [[ $p == -* ]]; then var=${p:1:1};
            else var=$p;
            fi;
            # echo "Var = $var, $opt"
            return $idx;
        fi;
    fi;
    return 0;
}

#======================================
# ParamType function
#======================================

paramType() 
{
    ret=0;
    p=$1; 
    shift;
    while [ "${1+defined}" ]; do
        let ret+=1
        l=${#1}
        if ([[ $p == /* ]] || [[ $p == -* ]]) && ([[ $1 == /* ]] || [[ $1 == -* ]]) && [[ ${p:1:1} = ${1:1:1} ]]; then 
            return $ret
        elif [[ $p != /* ]] && [[ $p != -* ]] && [[ $1 = "%" ]]; 
            then return $ret;
        fi;
        shift
    done
    return 0;
}
    
por JaedenRuiner 11.12.2015 / 17:06

0 respostas

Tags