Warum gibt $ 1 in einer Funktion nicht das erste Argument des Skripts aus?

13

Warum wird in diesem einfachen Bash-Skript nicht echo $1gedruckt $1?

#!/bin/bash
# function.sh
print_something () {
echo $1
}
print_something

$ ./function.sh 123  -> why doesn't it print '123' as a result?
Pietro Letti
quelle
6
weil du beim Aufruf von print_something die $ 1 vergessen hast. Bitte versuchen Sie, Text in die Frage und nicht in den Titel aufzunehmen.
Rui F Ribeiro
Vielen Dank. Was sollte das Echo-Argument sein, wenn ich die folgenden Befehle in das Skript einfügen muss: print_something "$ 1"; print_something "$ 2"; und vielleicht noch mehr?
Pietro Letti
13
Als ich das in HNQ sah, dachte ich, Sie drucken Dollarnoten und hofften, eine saftige Geschichte darüber zu lesen, wie Ihr Drucker feststellt, dass Sie falsches Geld drucken.
Pipe
@pipe Mir ist das schon mal passiert, aus irgendeinem Grund wird es abgelehnt, irgendetwas zu drucken, nicht nur die mit den Anti-Druck-Verhinderungen.
Codingale

Antworten:

41

Positionsparameter beziehen sich auf die Argumente des Skripts in der Hauptebene des Skripts, aber auf Funktionsargumente im Funktionskörper. So

print_something Something

würde tatsächlich drucken Something.

Wenn Sie die Argumente des Skripts an eine Funktion übergeben möchten, müssen Sie dies explizit tun. Verwenden

print_something "$1"

das erste Argument übergeben, oder

print_something "$@"

um sie alle zu übergeben, obwohl die Funktion im Beispiel nur die erste verwendet.

komisch
quelle
1
Übergeben "$@"an print_something, wie es derzeit geschrieben wird, würde jedoch immer noch nur das erste der Argumente ausgeben.
Kusalananda
13
Aber der Punkt war , zu zeigen , wie man passieren alle Argumente, nehme ich an . Die Tatsache, dass die Funktion in ihrer jetzigen Form nur das erste ihrer Argumente verwendet, ist ein wenig irrelevant.
Weirdan
Nun, ich denke, es hat keinen Sinn, alle Argumente weiterzugeben, wenn nur das erste verwendet wird.
Kusalananda
14
@allo No. "$*"wäre eine einzelne Zeichenfolge (verbunden mit dem ersten Zeichen von $IFS), während "$@"eine Liste von einzeln zitierten Elementen wäre.
Kusalananda
5
@Kusalananda Wenn Sie jemandem mitteilen möchten, dass er die Befehlszeilenparameter an eine zu verwendende Funktion übergeben möchte "$@", auch wenn in diesem Fall nur ein solcher Parameter vorhanden ist, müssen Sie alle diese Fälle abdecken . Wenn das OP beschließt, einen zweiten Parameter hinzuzufügen, muss der Funktionsaufruf nicht geändert werden. Und jeder andere, der dies liest, lernt, wie man es richtig macht, um zu vermeiden, dass es auch später noch einmal gemacht werden muss.
Monty Harder
10

Dies liegt daran, dass eine aufgerufene Funktion unabhängig von der Menge der Eltern / Aufrufer eine eigene Menge von Positionsparametern erhält. Versuchen

print_something "$1"

(und echo "$1", oder noch besser printf '%s\n' "$1", denken Sie daran, Parametererweiterungen anzugeben, echodie nicht für beliebige Daten verwendet werden können).

RudiC
quelle
Sie müssen klarer werden, wovon Sie sprechen. Der Aufrufer unterscheidet sich im $1Allgemeinen von den Funktionen $1, obwohl sie die gleichen werden können, wenn sie wie oben vorgeschlagen verwendet werden. Wenn ich Sie richtig echoecho $1print_something $2$1
verstehe
6
Die Verwendung echo $1ist nur dann sinnvoll, wenn Sie $1als durch $ IFS begrenzte Liste der zu erweiternden Dateimuster behandelt werden möchten . echo "$1"wäre sinnvoller, würde aber nicht den inhalt $1für werte $1wie ausgeben -nene, -EE...
Stéphane Chazelas