Estou um pouco preso. Minha tarefa é imprimir os argumentos no meu script em ordem inversa, exceto o terceiro e o quarto.
O que eu tenho é este código:
#!/bin/bash
i=$#
for arg in "$@"
do
case $i
in
3) ;;
4) ;;
*) eval echo "$i. Parameter: \$$i";;
esac
i=`expr $i - 1`
done
Como odeio eval (saudações ao PHP), estou procurando uma solução sem ela, mas não consigo encontrar uma.
Como posso definir a posição do argumento dinamicamente?
PS: Não, não é uma lição de casa, estou aprendendo a fazer um exame, então tento resolver os exames antigos.
fonte
arg
pois eles estão ordenados corretamente e não ao contrário. Para o uso deexpr
, estou limitado a usar apenas o padrão.#!/bin/bash
, você pode usar${!i}
e(())
. Se você deseja manter o sh padrão , eles não estão disponíveis, mas$((…))
estão.eval
não é a única maneira portátil como Ryan mostrou .Eu mantenho um script
reverse
no meu caminho que faz isso:Exemplo de uso:
Você também pode usar uma função em vez de um script dedicado.
fonte
$#
? Pode ser algo diferente de um número inteiro não negativo?local arg=$1
Este é um uso correto e não perigoso de eval. Você controla totalmente o conteúdo que está
eval
inserindo.Se isso ainda lhe causar sentimentos ruins, se você não se importa com portabilidade, pode usar a
${!i}
sintaxe indireta de Bash .fonte
${!i}
não faz parte da sintaxe padrão?Supondo que os parâmetros posicionais não contenham caracteres de nova linha:
Teste:
Saída de teste:
fonte
Com
zsh
:Oa
é um sinalizador de expansão de parâmetro para classificar os elementos da matriz após a expansão no sentido inverso índices da matriz .Para excluir 3 e 4:
fonte
Com basicamente qualquer shell:
E você não precisa usar sub-conchas. Por exemplo:
... imprime ...
E aqui está uma função de shell que pode definir um shell
alias
para você que imprimirá os argumentos para frente ou para trás:Ele não tenta armazenar os valores literais para nenhum argumento, mas coloca uma string como esta no
args
alias
:... e, portanto, armazena apenas referências aos parâmetros para trás e para frente. Ele armazenará até uma contagem, como dado como argumento. E assim o acima
alias
foi gerado como:printf
O comportamento do é afetado com base no valor de retorno do comando anterior - que é sempre:
o comando nulo e, portanto, geralmente verdadeiro.printf
pulará metade de seus argumentos sempre que imprimir - o que, por padrão, fará com que os argumentos sejam impressos do menor para o maior. No entanto, se você apenas fizer:... imprime-os ao contrário.
Como o alias não armazena nenhum valor literal, seu valor permanece estático enquanto os argumentos reais podem mudar, mas ainda fará referência a quantos forem. Por exemplo:
... que imprime ...
Mas a redefinição do alias pode ser feita como:
... e assim imprime ...
fonte
fonte
for ((i = $# - 1; i >= 0; i--))