Ich habe ein Skript in einer Datei namens instance:
echo "hello world"
echo ${1}
Und wenn ich dieses Skript mit:
./instance solfish
Ich bekomme diese Ausgabe:
hello world
solfish
Aber wenn ich renne:
echo $#
Es sagt "0". Warum? Ich verstehe nicht was das $#
bedeutet.
Bitte erkläre es.
$#
? Was willst du erreichen Woher hast du diesen Befehl? Es ist überhaupt nicht relevant.echo $#
und es ist wieder da,0
was normal ist. Das hat Sie überrascht, aber Sie erklären nicht, was Sie erwartet haben oder warum Sie überrascht waren. Es würde uns also helfen, Ihnen eine bessere Antwort zu geben, wenn Sie erklären, was Sie erwartet haben. Was Sie dachten,echo $#
würde das tun. Wenn Sie lief./instance solfish
und./instance
enthieltecho $#
, würde das drucken1
und nicht0
.Antworten:
$#
ist eine spezielle Variable inbash
, die um die Anzahl der Argumente (Positionsparameter) erweitert wird, dh$1, $2 ...
an das betreffende Skript oder die Shell übergeben wird, wenn Argumente direkt an die Shell übergeben werden, zbash -c '...' ....
. B. in .Dies ist ähnlich wie
argc
in C.Vielleicht wird dadurch klar:
Beachten Sie, dass
bash -c
Argumente nach dem darauf folgenden Befehl ab 0 verwendet werden ($0
technisch gesehen ist dies nurbash
die Art und Weise, Sie festlegen zu lassen$0
, kein wirkliches Argument). Sie_
werden hier also nur als Platzhalter verwendet. Die tatsächlichen Argumente sindx
($1
),y
($2
) undz
($3
).Ebenso in Ihrem Skript (vorausgesetzt
script.sh
), wenn Sie haben:Wenn Sie dann tun:
das Skript gibt 2 aus; Gleichfalls,
gibt 1 aus.
quelle
bash -c
unterscheidet sich das Verhalten bei der Verwendung von Shell-Skripten von dem bei der Ausführung eines ausführbaren Shell-Skripts, da im letzteren Fall das Argument mit dem Index 0 der Shell-Befehl ist, mit dem es aufgerufen wird. Aus diesem Grund besteht die Möglichkeit, diese Antwort zubash -c
korrigieren, darin, sie so zu ändern, dass sie Skripte als Dateien ausführt, anstatt sie zu verwenden , da der Fragesteller dies getan hat.$0
wäre das Skript selbst; Argumente wären$1, $2, $3...
.bash -c
Verhalten ist anders, da es für die nicht interaktive Verwendung gedacht ist und die Argumente, die dem Befehl folgen, beginnen würden.$0
Ich glaube, ich habe dies klar erwähnt.bash -c
, sollten Siebash
einen aussagekräftigen Namen als Füllzeichen für das 0. Argument übergeben.bash -c 'echo "$@"' foo bar
druckt nurbar
, weil"$@"
nicht enthalten$0
, wie immer.bash -c
macht "$ 0 nicht zu einem der Argumente", sondern ermöglicht es Ihnen lediglich, "$ 0" auf dieselbe Weise wie beim Ausführen eines Programms mit demexecve
Systemaufruf oder einer Shell-Methode zum Überschreiben des 0. Arguments festzulegen.$0
sollte niemals als "einer der Gründe" angesehen werden.echo $#
gibt die Anzahl der Positionsparameter Ihres Skripts aus.Sie haben keine und geben 0 aus.
echo $#
ist nützlich innerhalb des Skripts, nicht als separater Befehl.Wenn Sie ein Skript mit einigen Parametern wie ausführen
Das
echo $#
im Skript platzierte wird 2 ausgeben.quelle
echo $#
zu Ihrem Skript hinzufügen und dann erneut ausführen./instance solfish
, sollten Sie eine zusätzliche Ausgabezeile mit erhalten,1
da Sie 1 Parameter angegeben haben$#
wird normalerweise in Bash-Skripten verwendet, um sicherzustellen, dass ein Parameter übergeben wird. Im Allgemeinen suchen Sie am Anfang Ihres Skripts nach einem Parameter.Zum Beispiel ist hier ein Ausschnitt eines Skripts, an dem ich heute gearbeitet habe:
Um
$#
Berichte zusammenzufassen , geben Sie die Anzahl der an ein Skript übergebenen Parameter an. In Ihrem Fall haben Sie keine Parameter übergeben und das gemeldete Ergebnis ist0
.Andere
#
Verwendungen in BashDas
#
wird häufig in Bash verwendet, um die Anzahl der Vorkommen oder die Länge einer Variablen zu zählen.So ermitteln Sie die Länge einer Zeichenfolge:
kehrt zurück:
11
So ermitteln Sie die Anzahl der Array-Elemente:
kehrt zurück:
3
So ermitteln Sie die Länge des ersten Array-Elements:
Gibt Folgendes zurück:
1
(Die Länge vonA
, 0 ist das erste Element, da Arrays auf Null basierende Indizes / Indizes verwenden.)quelle
$# -ne 1
? Warum nicht$# -le 0
oder gleichwertig?$#
ist die Anzahl der Argumente, aber denken Sie daran, dass es in einer Funktion anders sein wird.$#
ist die Anzahl der Positionsparameter, die an das Skript, die Shell oder die Shell-Funktion übergeben werden . Dies liegt daran, dass während der Ausführung einer Shell-Funktion die Positionsparameter vorübergehend durch die Argumente der Funktion ersetzt werden . Auf diese Weise können Funktionen ihre eigenen Positionsparameter akzeptieren und verwenden.Dieses Skript wird immer gedruckt
3
, unabhängig davon, wie viele Argumente an das Skript selbst übergeben wurden, da"$#"
in der Funktionf
die Anzahl der an die Funktion übergebenen Argumente erweitert wird:Dies ist wichtig, da Code wie dieser möglicherweise nicht wie erwartet funktioniert, wenn Sie nicht mit der Funktionsweise von Positionsparametern in Shell-Funktionen vertraut sind:
In
check_args
, wird$#
auf die Anzahl der Argumente erweitert, die an die Funktion selbst übergeben werden. In diesem Skript ist dies immer 0.Wenn Sie eine solche Funktionalität in einer Shell-Funktion wünschen, müssen Sie stattdessen Folgendes schreiben:
Dies funktioniert, weil
$#
es außerhalb der Funktion erweitert und als einer seiner Positionsparameter an die Funktion übergeben wird. Wird in der Funktion$1
zum ersten Positionsparameter erweitert, der an die Shell-Funktion und nicht an das Skript übergeben wurde, zu dem sie gehört.So wie
$#
die speziellen Parameter$1
,$2
usw., sowie$@
und$*
auch an die an eine Funktion übergebenen Argumente beziehen sich , wenn sie in der Funktion erweitert werden. Es$0
ändert sich jedoch nichts an dem Namen der Funktion, weshalb ich sie immer noch verwenden konnte, um eine Qualitätsfehlermeldung zu erzeugen.Wenn Sie eine Funktion in einer anderen definieren, arbeiten Sie auf ähnliche Weise mit den Positionsparametern, die an die innerste Funktion übergeben werden, in der die Erweiterung ausgeführt wird:
Ich habe dieses Skript aufgerufen
nested
und (nach dem Ausführenchmod +x nested
) ausgeführt:Ja, ich weiß. "1 Argumente" ist ein Pluralisierungsfehler.
Die Positionsparameter können auch geändert werden.
Wenn Sie ein Skript schreiben, sind die Positionsparameter außerhalb einer Funktion die Befehlszeilenargumente, die an das Skript übergeben werden, sofern Sie sie nicht geändert haben .
Eine gebräuchliche Möglichkeit, sie zu ändern, ist die
shift
Verwendung des eingebauten Parameters, der jeden Positionsparameter um eins nach links verschiebt, den ersten um eins senkt und um eins verringert$#
:Sie können auch mit dem
set
eingebauten geändert werden :quelle