Como passar a matriz ao bash shell script?

3

Como faço para passar uma matriz como uma variável de um primeiro script de shell bash para um segundo script.

first.sh
#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
sh second.sh "$AR" # foo
sh second.sh "${AR[@]}" # foo
second.sh
#!/bin/bash
ARR=$1
echo ${ARR[@]}

Em ambos os casos, o resultado é foo . Mas o resultado que eu quero é foo bar baz bat .

O que estou fazendo de errado e como corrigi-lo?

    
por Mowzer 23.04.2016 / 09:35

3 respostas

4

AFAIK, você não pode. Você tem que serializar e desserializar, por exemplo através da matriz de argumentos:

primeiro

#!/bin/bash
ar=('foo' 'bar' 'baz' 'bat')
second "${ar[@]}" #this is equivalent to: second foo bar baz bat

segundo

#!/bin/bash
arr=( "$@" )
printf ' ->%s\n' "${arr[@]}"
<<PRINTS
   -> foo
   -> bar
   -> baz
   -> bat
PRINTS

Um pouco de conselho:

  • reservar todas as maiúsculas para export ed variáveis
  • a menos que você tenha uma boa razão específica para não fazê-lo "${someArray[@]}" deve sempre ser citado duas vezes; esta fórmula se comporta exatamente como 'array item 0' 'array item 1' 'aray item 2' 'etc.' (assumindo someArray=( 'array item 0' 'aray item 1' 'aray item 2' 'etc.' ) )
por 23.04.2016 / 09:41
1

A matriz AR é passada pelo primeiro argumento para second.sh .

first.sh

#!/bin/bash
AR=('foo' 'bar' 'a space' 'bat')
printf "AR array contains %d elements: " ${#AR[@]}
printf "%s " "${AR[@]}"
printf "\n"
./second.sh "$AR"
./second.sh "$(printf "(" ; printf "'%s' " "${AR[@]}" ; printf ")")"

Observe que sh não é mais usado para executar o script second.sh .

Esses printf encadeados são usados para forjar um único parâmetro que será seguro se alguns elementos da matriz contiverem caracteres de espaço.

second.sh

#!/bin/bash
declare -a ARR=$1
printf "ARR array contains %d elements: " ${#ARR[@]}
printf "%s " "${ARR[@]}"
printf "\n"

----

Para uma solução em que a matriz AR é passada usando qualquer número de argumentos para o script second.sh .

first.sh

#!/bin/bash
AR=('foo' 'bar' 'a space' 'bat')
printf "AR array contains %d elements: " ${#AR[@]}
printf "%s " "${AR[@]}"
printf "\n"
./second.sh "$AR"
./second.sh "${AR[@]}"

second.sh

#!/bin/bash
ARR=( "$@" )
printf "ARR array contains %d elements: " ${#ARR[@]}
printf "%s " "${ARR[@]}"
printf "\n"

----

O teste:

$ chmod +x *sh
$ ./first.sh
AR array contains 4 elements: foo bar a space bat
ARR array contains 1 elements: foo
ARR array contains 4 elements: foo bar a space bat
    
por 23.04.2016 / 15:08
0

primeiro

#!/bin/bash
ar=('foo' 'bar' 'baz' 'bat')
./second "${ar[@]}"

segundo

#!/bin/bash
read -a arr1 <<< "${BASH_ARGV[@]}"
echo "${arr1[@]}"

Isso deve ter sido suficiente, mas a ordem da matriz é revertida, então acrescentei:

for (( i=${#arr1[@]}-1,j=0 ; i>=0 ; i--,j++ ))
do
    arr2[j]="${arr1[i]}"
done
echo "${arr2[@]}"

read -a lê a entrada no array arr1, mas por algum motivo eu não consigo descobrir, o array está invertido, então eu inverto de volta para arr2.

    
por 23.04.2016 / 11:55