Je suis un peu coincé. Ma tâche consiste à imprimer les arguments de mon script dans l'ordre inverse, à l'exception des troisième et quatrième.
Ce que j'ai c'est ce code:
#!/bin/bash
i=$#
for arg in "$@"
do
case $i
in
3) ;;
4) ;;
*) eval echo "$i. Parameter: \$$i";;
esac
i=`expr $i - 1`
done
Comme je déteste eval (salutations à PHP), je cherche une solution sans mais je ne trouve pas de solution.
Comment définir dynamiquement la position de l'argument?
PS: Non ce n'est pas un devoir, j'apprends le shell pour un examen donc j'essaie de résoudre les anciens examens.
la source
arg
car ils sont commandés correctement et non en sens inverse. À l'usage deexpr
, je suis limité à utiliser la norme uniquement.#!/bin/bash
, vous pouvez utiliser${!i}
et(())
. Si vous voulez vous en tenir à sh standard , ceux-ci ne sont pas disponibles, mais ils le$((…))
sont.eval
n'est pas le seul moyen portable comme Ryan l'a montré .Je garde un script
reverse
sur mon chemin qui fait ceci:Exemple d'utilisation:
Vous pouvez également utiliser une fonction au lieu d'un script dédié.
la source
$#
? Peut-il être autre chose qu'un entier non négatif?local arg=$1
Il s'agit d'une utilisation correcte et non dangereuse d'eval. Vous contrôlez entièrement le contenu que vous
eval
utilisez.Si cela vous donne toujours de mauvais sentiments, alors si vous ne vous souciez pas de la portabilité, vous pouvez utiliser la
${!i}
syntaxe d'indirection de Bash .la source
${!i}
ne fait donc pas partie de la syntaxe standard?En supposant que les paramètres positionnels ne contiennent pas de caractères de nouvelle ligne:
Tester:
Sortie de test:
la source
Avec
zsh
:Oa
est un indicateur d'extension de paramètre pour trier les éléments du tableau lors de l'expansion dans les indices de tableau inversés .Pour exclure 3 et 4:
la source
Avec pratiquement n'importe quel shell:
Et vous n'avez pas besoin d'utiliser de sous-coquilles. Par exemple:
... impressions ...
Et voici une fonction shell qui peut définir
alias
pour vous un shell qui affichera les arguments en avant ou en arrière:Il ne tente pas de stocker les valeurs littérales des arguments, mais il place plutôt une chaîne comme celle-ci dans
args
alias
:... et ne stocke donc que les références aux paramètres en avant et en arrière. Il stockera jusqu'à un décompte tel qu'il lui est donné comme argument. Et donc ce qui précède a
alias
été généré comme:printf
Le comportement de 'est affecté en fonction de la valeur de retour de la commande précédente - qui est toujours:
la commande null, et donc généralement true.printf
sautera la moitié de ses arguments à chaque impression - ce qui, par défaut, affichera les arguments du plus petit au plus grand. Cependant, si vous le faites simplement:... il les imprime à l'envers.
Étant donné que l'alias ne stocke aucune valeur littérale, sa valeur reste statique pendant que les arguments réels peuvent changer, mais il en référencera toujours autant qu'il le pourrait. Par exemple:
... qui imprime ...
Mais la réinitialisation de l'alias peut se faire comme:
... et donc ça imprime ...
la source
la source
for ((i = $# - 1; i >= 0; i--))