Como juntar elementos de um array em POSIX delimitado por um espaço?

1

O seguinte funciona em um script Bash:

PACKAGES=(
    'curl'
    'git'
    'htop'
    'mc'
    'tree'
    'vim'
)

apt --yes install ${PACKAGES[@]}

Mas como posso fazer o mesmo no POSIX para poder usá-lo em um script #!/bin/sh ?

    
por Ricardo Amaral 19.04.2018 / 18:44

2 respostas

7

Em um shell POSIX sh , você tem exatamente uma matriz: $@ (a matriz de parâmetros posicionais, ou seja, $1 , $2 , ...). Você define seus valores com set :

set -- curl git htop mc tree vim

ou a partir da linha de comando:

./myscript.sh curl git htop mc tree vim

Então,

apt --yes install "$@"

Citando a expansão de $@ , a matriz é expandida para seus elementos citados . Ou seja, se a matriz $@ contiver a word e another word , "$@" será expandido para essas sequências duas . Não citar $@ fará com que ela se expanda para as quatro strings a , word , another e word . O comportamento não cotado depende do conteúdo de $IFS .

Observe que em bash também, você gostaria de citar duas vezes a expansão ${PACKAGES[@]} :

apt --yes install "${PACKAGES[@]}"

Relacionados: Matrizes no Unix Bourne Shell

Você não realmente "une os elementos com espaços" aqui. Sim, se você echo os valores você terá espaços entre eles, mas é a diferença entre

set -- a b c d
printf '>%s<\n' "$@"

que produz

>a<
>b<
>c<
>d<

(quatro argumentos separados, que é o que você quer)

e

printf '>%s<' "$*"

que produz

>a b c d<

(um único argumento com os elementos unidos por espaços (o primeiro caractere de $IFS ), que não é o que você realmente quer usar com o comando apt install )

    
por 19.04.2018 / 18:56
0

Como você tem nomes de pacotes, você pode armazená-los em uma variável de string simples, se quiser usar um shell padrão. Pelo menos de acordo com os manuais Debian , os nomes dos pacotes só podem contém os caracteres -+.:~a-z0-9A-Z , nenhum dos quais é um caractere glob ou espaço em branco.

Então, isso deve estar ok:

#!/bin/sh
packages="curl git htop ..."
IFS=" "                           # make sure there's nothing weird here
apt --yes install $packages       # no quotes!

Se você é paranóico, adicione set -f ao início para desativar o globbing do nome do arquivo. Isso deixaria apenas espaços como um problema, mas não acho que nenhum sistema sensato permitiria espaços em branco em nomes de pacotes.

    
por 19.04.2018 / 19:14