BASH / DASH: Qual é a melhor maneira de transmitir matriz para funcionar?

1

Eu tenho esse array:

PARAMETERS_OF_COMPONENTS[1]="component1"
PARAMETERS_OF_COMPONENTS[2]="component21 component22 component23"
PARAMETERS_OF_COMPONENTS[3]="component3"
PARAMETERS_OF_COMPONENTS[4]="component41 component42 component43"

Eu quero passar esse array para esta função:

foo()
{
    local param1="$1"
    local param2="$2"
    local array_param="$3"
    . . .

    echo "${PARAMETERS_OF_COMPONENTS[@]}"
}

Quando eu passo um array dessa maneira:

foo "$param1" "$param2" "${PARAMETER_OF_COMPONENTS[@]}"

então a função apenas imprime:

component1

Além disso, experimentei vários outros métodos para transmitir a matriz, mas ainda não encontrei a solução correta.

Como posso transmitir corretamente a matriz para funcionar? Além disso, a solução deve ser compatível com o Dash (pelo menos sem bashisms).

UPD @Kusalananda me explicou que Dash não suporta matrizes. Obrigado por esclarecer.

Vou perguntar outro. Como posso passar muitos parâmetros para funcionar sem passá-lo diretamente na maneira $1 , $2 ... e não envolvem variáveis globais? Eu tenho várias idéias, mas gostaria de ouvir suas abordagens?

Minha tarefa é mover a função de um arquivo para outro, mas essa função usa variáveis globais. Eu não quero usar variáveis globais. Então, como fazer isso da maneira mais correta?

    
por Yurij Goncharuk 21.05.2018 / 15:39

1 resposta

3

Em um shell sh que não suporta arrays e a palavra-chave local , você ainda pode usar $@ como uma matriz na função. Você pode escolher os dois primeiros argumentos com shift 2 e depois usar $@ , que agora contém todos os argumentos restantes.

foo () {
    arg1=$1
    arg2=$2

    shift 2  # shift $3 into $1, $4 into $2 etc.

    for n in "$@"; do    # or just: for n do
        printf 'Other argument: %s\n' "$n"
        # other code acting on "$n"
    done
}

foo "arg1" "arg2" "arg3" "arg4"

Coloque o corpo da função em ( ... ) em vez de { ... } para tornar todas as variáveis locais, se a função não precisar modificar variáveis globais e você não quiser poluir o espaço de nomes da variável com variáveis desnecessárias. / p>

Usando seus dados originais com foo declarado como acima:

set -- "component1" \
       "component21 component22 component23" \
       "component3" \
       "component41 component42 component43"

foo "$param1" "$param2" "$@"

Em um shell que suporta arrays e local , você faria exatamente a mesma coisa (mas a função pode querer usar variáveis declaradas como local ), e a chamada pode ser

foo "arg1" "arg2" "${myarray[@]}"

Para passar várias matrizes em bash , eu usaria uma referência de nome na função (requer bash release 4.3 ou posterior):

foo () {
   local arg1=$1
   local arg2=$2
   local -n arr1=$3
   local -n arr2=$4

   for n in "${arr2[@]}"; do ...; done
}

foo "arg1" "arg2" myarray1 myarray2

Note que você não pode passar uma variável array para a função que tem o mesmo nome da variável de referência do nome correspondente na função (eu considero isso um bug, ela funciona em ksh93 ).

    
por 21.05.2018 / 16:23