
Ich habe dieses Skript, das die Aussprache der Wörter herunterlädt, die Sie als Argument eingeben:
#!/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
wenn ich es mit diesem Befehl ausführe
./a.sh personality brave selfish
es sollte auf der Standardausgabe gedruckt werden
personality
brave
selfish
aber stattdessen druckt es
1
2
3
würden Sie mir helfen, dieses Problem zu lösen?
ps: Wenn ich das Skript ohne for-Schleife mit $1 schreibe, funktioniert es beispielsweise korrekt, aber ich möchte mehrere Dateien gleichzeitig herunterladen
Antwort1
In jeder Bourne-ähnlichen Shell ist es:
for arg
do printf 'Something with "%s"\n' "$arg"
done
Das heißt, dass standardmäßig for
eine Schleife für die Positionsparameter ( $1
, ...) ausgeführt wird (wenn Sie keinen Teil angeben).$2
in ...
Beachten Sie, dass dies portabler ist als:
for arg; do
printf 'Something with "%s"\n' "$arg"
done
Was bis zur Ausgabe 2016 des Standards weder POSIX noch Bourne war (funktioniert jedoch in den meisten anderen Bourne-ähnlichen Shells, bash
sogar im POSIX-Modus)
Oder als:
for arg in "$@"; do
printf 'Something with "%s"\n' "$arg"
done
Dies ist POSIX, funktioniert aber in der Bourne-Shell oder in ksh88 nicht richtig, wenn $IFS
das Leerzeichen nicht enthalten ist, oder bei einigen Versionen der Bourne-Shell, wenn kein Argument vorhanden ist, oder bei einigen Shells (einschließlich einiger Versionen von bash
), wenn kein Argument vorhanden ist und die -u
Option aktiviert ist.
Oder als
for arg do
printf 'Something with "%s"\n' "$arg"
done
Das ist POSIX und Bourne, funktioniert aber nicht in sehr alten, auf Ash basierenden Shells. Ich persönlich ignoriere das und verwende diese Syntax selbst, da ich sie für die lesbarste halte und nicht erwarte, dass der Code, den ich schreibe, jemals von einer so geheimnisvollen Shell interpretiert wird.
Mehr Infos unter:
- http://www.in-ulm.de/~mascheck/various/bourne_args/
- Was ist der Zweck des Schlüsselworts „do“ in Bash-For-Schleifen?
$i
Wenn Sie nun eine Schleife ausführen und auf die entsprechenden Elemente zugreifen möchten [1..$#]
, haben Sie folgende Möglichkeiten:
in jeder POSIX-Shell:
i=1
for arg do
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
oder:
i=1
while [ "$i" -le "$#" ]; do
eval "arg=\${$i}"
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
Oder mitbash
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${!i}"
done
${!i}
Dabei handelt es sich um eine indirekte Variablenerweiterung, d. h., sie wird auf den Inhalt des Parameters erweitert, dessen Name in der i
Variablen gespeichert ist, ähnlich dem Parametererweiterungsflag zsh
von :P
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${(P)i}"
done
Obwohl zsh
Sie in auch über das Array auf Positionsparameter zugreifen können $argv
(wie in csh
):
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: $argv[i]"
done
Antwort2
Ich würde verwenden shift
. Das [ -n "$1" ]
bedeutet, dass die Schleife fortgesetzt wird, solange arg-1 nicht leer ist.
#! /bin/bash
while [ -n "$1" ]; do
echo "$1"
wget "https://ssl.gstatic.com/dictionary/static/sounds/de/0/$1.mp3"
shift
done
Antwort3
Einfachster Weg
#!/bin/bash
for i
do
echo $i
done
und Renn
./a.sh personality brave selfish
und hier ist der Ausdruck auf der Standardausgabe
personality
brave
selfish