J'ai ce script qui a conçu pour télécharger la prononciation des mots que vous lui donnez comme argument:
#!/bin/bash
m=$#
for ((i=1;i<=m;i++));do
echo $i
#wget https://ssl.gstatic.com/dictionary/static/sounds/de/0/"$i".mp3
done
si je l'exécute par cette commande
./a.sh personality brave selfish
il devrait imprimer sur la sortie standard
personality
brave
selfish
mais à la place, il imprime
1
2
3
pourriez-vous m'aider à résoudre ce problème?
p.s: Si j'écris le script sans boucle avec $ 1 par exemple, cela fonctionnera correctement mais je veux télécharger plusieurs fichiers en même temps
Dans tout Shell Bourne-like, c'est:
for arg
do printf 'Something with "%s"\n' "$arg"
done
Autrement dit, for
fait une boucle sur les paramètres positionnels ($1
, $2
...) par défaut (si vous ne donnez pas de partie in ...
).
Notez que c'est plus portable que:
for arg; do
printf 'Something with "%s"\n' "$arg"
done
Ce qui n'était pas POSIX avant l'édition 2016 de la norme ni Bourne (bien que fonctionne dans la plupart des autres shells de type Bourne, y compris bash
même en mode POSIX)
Ou que:
for arg in "$@"; do
printf 'Something with "%s"\n' "$arg"
done
Qui est POSIX mais ne fonctionne pas correctement dans le Bourne Shell ou ksh88 lorsque $IFS
Ne contient pas le caractère espace, ou avec certaines versions du Bourne Shell quand il n'y a pas d'argument, ou avec certains shells (y compris certains versions de bash
) lorsqu'il n'y a pas d'argument et que l'option -u
est activée.
Ou que
for arg do
printf 'Something with "%s"\n' "$arg"
done
qui est POSIX et Bourne mais ne fonctionne pas dans les très vieilles coquilles à base de cendres. Personnellement, j'ignore cela et j'utilise cette syntaxe moi-même car je trouve que c'est la plus lisible et je ne m'attends pas à ce que le code que j'écris finisse par être interprété par un shell aussi arcanique.
Plus d'infos sur:
Maintenant, si vous voulez que $i
Passe en boucle sur [1..$#]
Et accède aux éléments correspondants, vous pouvez faire:
dans n'importe quel shell POSIX:
i=1
for arg do
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
ou:
i=1
while [ "$i" -le "$#" ]; do
eval "arg=\${$i}"
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
Ou avec bash
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${!i}"
done
${!i}
Étant une extension de variable indirecte, qui est développée au contenu du paramètre dont le nom est stocké dans la variable i
, similaire au paramètre zsh
de P
drapeau d'expansion:
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${(P)i}"
done
Bien que dans zsh
, vous pouvez également accéder aux paramètres de position via le tableau $argv
(Comme dans csh
):
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: $argv[i]"
done
J'utiliserais shift
. Celui-là [ -n "$1" ]
signifie que arg-1 n'est pas vide, continuez à boucler.
#! /bin/bash
while [ -n "$1" ]; do
echo "$1"
wget "https://ssl.gstatic.com/dictionary/static/sounds/de/0/$1.mp3"
shift
done
Manière la plus simple
#!/bin/bash
for i
do
echo $i
done
et courir
./a.sh personality brave selfish
et voici l'impression sur la stdout
personality
brave
selfish