Passando vários conjuntos de argumentos para um comando

1

instances contém várias strings separadas por espaços em branco, assim como snapshots . Eu quero executar o comando abaixo, com cada par instantâneo de instância.

ec2-attach-volume --instance $instances --device /dev/sdf $snapshots

Por exemplo, se instances contiver A B C e snapshots contiver 1 2 3 , quero que o comando seja chamado assim:

ec2-attach-volume -C cert.pem -K pk.pem --instance A --device /dev/sdf 1
ec2-attach-volume -C cert.pem -K pk.pem --instance B --device /dev/sdf 2
ec2-attach-volume -C cert.pem -K pk.pem --instance C --device /dev/sdf 3

Eu posso fazer um ou outro com xargs -n 1 , mas como faço os dois?

    
por Max 25.10.2012 / 19:47

3 respostas

0

Usando o shell bash , um método possível é:

instances=( 'cat instances' )
snapshots=( 'cat snapshots' )

for i in ${!instances[@]}; do
    ec2-attach-volume -C cert.pem -K pk.pem \
        --instance ${instances[i]} --snapshot ${snapshots[i]}
done

Aqui ${!instances[@]} se expande para todos os índices da matriz instances (0, 1, 2 e assim por diante). Você pode examinar o conteúdo da matriz fazendo declare -p instances snapshots após as duas primeiras linhas.

    
por 25.10.2012 / 20:11
1

Para fazer isso em paralelo, você pode usar o GNU Parallel:

parallel --xapply ec2-attach-volume --instance {1} --device /dev/sdf {2} ::: 'cat instances' ::: 'cat snapshots'

Assista aos vídeos de introdução para saber mais: link

    
por 03.01.2013 / 01:12
0

Veja uma abordagem que inclui o tratamento de erros (algumas):

xargs –n 1 < instances > instances.1_per_line    # “xargs –n 1” is equivalent to
xargs –n 1 < snapshots > snapshots.1_per_line    # “xargs –n 1 echo”.
if [ $(wc –l < instances.1_per_line)  !=  $(wc –l < snapshots.1_per_line) ]
then
        echo "Different numbers of strings." >&2
else
        paste instances.1_per_line snapshots.1_per_line | while read inst snap
        do
                ec2-attach-volume -C cert.pem -K pk.pem --instance "$inst" \
                                --device /dev/sdf "$snap"
        done
fi
rm instances.1_per_line snapshots.1_per_line

Isso pode funcionar melhor do que resposta do grawity para arquivos grandes, como não precisa ler os arquivos na memória. E isso pode funcionar melhor em versões mais antigas de bash . (Se $(command) não funcionar, tente 'command' .) Por outro lado, minha resposta irá falhar se alguma das strings nos arquivos contiver caracteres de aspas.

    
por 25.10.2012 / 22:31