Eu tenho um script mais ou menos assim:
for chain in http https ssh
do
iptables -nvxL $chain | tail -1 | awk '{print $2}'
done
Mas o que eu realmente quero fazer é capturar a saída do iptables
comando para cada iteração em uma variável diferente, cujo nome deve ser igual ao valor atual de chain
.
Portanto, para a primeira iteração do loop (onde $chain
é http
), quero que isso aconteça:
http=$(iptables -nvxL http | tail -1 | awk '{print $2}')
Então, para o próximo, eu quero isso:
https=$(iptables -nvxL https | tail -1 | awk '{print $2}')
Espero que você tenha a ideia, não tenho certeza de como fazer isso.
No seu caso, eu usaria um array associativo para isso:
Você pode acessar a saída desreferenciando, como em
ou
A resposta da matriz associativa é quase certamente como você deseja fazer isso.
No entanto, se você quiser literalmente variáveis nomeadas
http
,https
essh
(que você referenciaria com$http
,$https
e $ssh
), poderá usarprintf -v
para atribuir a saída do comando a uma variável cujo nome está contido em$chain
:Observe também que, de acordo com esta resposta , você pode usar
typeset
oudeclare
para obter a mesma coisa:Nenhum
eval
s foi prejudicado na elaboração desta resposta. Além disso, se você deseja imprimir os valores das variáveis de um loop como na resposta de @ penguin359, pode usar a indireção da variável bash para desreferenciar os nomes das variáveis - novamente, nãoeval
é necessário:Atualização: esqueci de citar o embutido
$2
no exemplo. Agora deve funcionar conforme solicitado pelo OP. Além disso, o ponto por trás dessa resposta e o uso deeval
é fornecer um exemplo portátil usando a sintaxe padrão do shell Bourne em várias implementações diferentes. Eu testei todo o código a seguir em bash, dash e zsh. Dash é um teste melhor de portabilidade, pois usa uma sintaxe do shell Bourne muito mais limitada e mais fiel. Também é o shell padrão no Debian/Ubuntu para/bin/sh
. Otypeset
eprintf -v
não existe no Dash. Eu achoeval
feio, mas foi o primeiro mecanismo no shell Bourne e é o melhor método para a verdadeira portabilidade.Embora eu ache que matrizes associativas são o caminho a percorrer, quero fornecer uma resposta exata para sua pergunta original e uma que seja portátil para outros shells Bourne além do Bash. Aqui seria como os nomes de variáveis dinâmicas seriam feitos tradicionalmente:
O
eval
operador no shell Bourne é usado para substituir variáveis em um comando e, em seguida, executá-lo novamente (reavaliá-lo) como um comando após a conclusão. Após a primeira substituição desse comando, a variável $chain e o primeiro conjunto de citações são concluídos, ficando assim:Que então avalia como uma atribuição de variável para uma expansão de comando de
iptables
. Como o comando interno usava aspas simples, não pude usá-las para citar aeval
instrução, daí o uso de"\"
e\""
citá-la para eval e passar as aspas duplas e simples conforme necessário no comando resultante. As aspas duplas em torno da expansão do comando podem não ser necessárias, mas encontrei problemas com alguns shells se o comando se expandir em várias palavras. Para despejar o conteúdo deles, faça algo semelhante:O primeiro cifrão é cotado e aprovado. Isso resulta na execução dos três comandos a seguir após o desenrolar do loop: