Ich kann bash
Funktionen definieren , indem ich das function
Schlüsselwort verwende oder weglasse . Gibt es da einen Unterschied?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Beide Aufrufe funktionieren foo
und sind bar
erfolgreich und ich sehe keinen Unterschied. Ich frage mich also, ob es nur darum geht, die Lesbarkeit zu verbessern, oder ob mir etwas fehlt ...
Übrigens schlägt dies in anderen Shells wie dash
( /bin/sh
wird in debian dash
/ ubuntu symbolisiert ) bei der Verwendung des function
Schlüsselworts fehl .
function baz { echo "baz"; }
. Siehe Bashism in GreyCats Wiki.Antworten:
Es gibt keinen Unterschied zwischen AFAIK und der Tatsache, dass die zweite Version portabler ist.
quelle
tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - "
ohne ihn vorher zu warnen, ob die Version von tar on desthost das "/" entfernt, was dazu führen könnte) Katastrophen in einigen Fällen ...). Zum Beispiel: Wenn Sie a verwendenfunction tar { #a safe tar with safety checks ... }
und essh
ignorieren, ...sh
sie dasfunction
Schlüsselwort erkennen - und im Allgemeinen gemeinsame, aber nicht standardmäßige Funktionen, die Shells mögenksh
undbash
anbieten - auf neueren Produktionssystemen häufig auch dann nicht funktionieren , wenn sie auf älteren Releases von funktionieren das gleiche Betriebssystem.bash
bietet immer nochsh
Unterstützung für viele GNU / Linux-Systeme, aber einige beliebte Distributionen haben aufsh
Symlink zudash
(der Debian Almquist SHell) umgestellt, um die Leistung zu verbessern. Dies beinhaltet Debian und Ubuntu .Das
function
Schlüsselwort wurde in ksh eingeführt . Die traditionelle Bourne-Shell hatte nur diefoo ()
Syntax, und POSIX standardisiert nur diefoo ()
Syntax.In ATT ksh (aber nicht in pdksh) gibt es einige Unterschiede zwischen Funktionen, die durch
function
die Bourne / POSIX-Syntax definiert sind, und Funktionen, die mit der Bourne / POSIX-Syntax definiert sind. In Funktionen, die durch definiert sindfunction
,typeset
deklariert das Schlüsselwort eine lokale Variable: Sobald die Funktion beendet ist, wird der Wert der Variablen auf den Wert vor dem Aufrufen der Funktion zurückgesetzt. Bei der klassischen Syntax haben Variablen einen globalen Gültigkeitsbereich, unabhängig davon, ob Sie sie verwendentypeset
oder nicht.Ein weiterer Unterschied in ksh besteht darin, dass mit dem
function
Schlüsselwort definierte Funktionen einen eigenen Trap-Kontext haben. Außerhalb der Funktion definierte Traps werden beim Ausführen der Funktion ignoriert, und schwerwiegende Fehler innerhalb der Funktion verlassen nur die Funktion und nicht das gesamte Skript. Ist auch$0
der Funktionsname in einer Funktion, die durch definiert ist,function
aber der Skriptname in einer Funktion, die mit definiert ist()
.Pdksh emuliert ATT ksh nicht.
typeset
Erstellt in pdksh unabhängig von der Funktion Variablen mit lokalem Gültigkeitsbereich und es gibt keine lokalen Traps (obwohl die Verwendungfunction
einige geringfügige Unterschiede hervorruft - Einzelheiten finden Sie auf der Manpage).Bash und zsh haben das
function
Schlüsselwort für die Kompatibilität mit ksh eingeführt. Allerdings sind in diesen Shellsfunction foo { … }
undfoo () { … }
streng identisch, ebenso wie die Bash- und Zsh-Erweiterungfunction foo () { … }
. Dastypeset
Schlüsselwort deklariert immer lokale Variablen (außer-g
natürlich) und Traps sind nicht lokal (Sie können lokale Traps in zsh erhalten, indem Sie dielocal_traps
Option setzen).quelle
foo() command
Die Bourne-Syntax wurde später aus Kompatibilitätsgründen zur Korn-Shell hinzugefügt.function { ... }; f;
auslässtf
nach demfunction
Stichwort?ist die Bourne-Syntax, die von jeder Bourne-ähnlichen Shell unterstützt wird, aber
bash
auch vonyash
neueren Versionenposh
(die nur zusammengesetzte Befehle unterstützen). (Die Bourne-Shell- und AT & T-Implementierungen von werdenksh
nur unterstützt,foo() any-command > redirections
wennany-command
es sich um einen zusammengesetzten Befehl handelt.)(Beispiele der Verbindung Befehle:
{ cmd; }
,for i do echo "$i"; done
,(cmd)
... die am häufigsten verwendet wird{ ...; }
)ist die POSIX-Syntax, die von jeder Bourne-ähnlichen Shell unterstützt wird und die Sie normalerweise verwenden möchten.
ist die Korn-Shell-Syntax, die der Bourne-Syntax vorausgeht. Verwenden Sie diese Option nur, wenn Sie speziell für die AT & T-Implementierung der Korn-Shell schreiben und die spezifische Behandlung benötigen, die sie dort erhält. Das Syntax ist nicht POSIX, sondern wird unterstützt durch
bash
,yash
undzsh
für die Kompatibilität mit dem Korn - Shell obwohl diese Schalen (und diepdksh
-basierten Varianten des Korn - Shell) nicht behandeln es anders von der Standard - Syntax.ist die Syntax ohne Shell und sollte nicht verwendet werden . Es geschieht nur durch Zufall unterstützt werden
bash
,yash
,zsh
und diepdksh
Basis - Varianten des Korn - Shell. Übrigens ist es auch dieawk
Funktionssyntax.Wenn wir die esoterische Liste weiter durchgehen,
(wie
function foo() (subshell)
oderfunction foo() for i do; ... done
) ist noch schlimmer. Es wird unterstützt durchbash
,yash
undzsh
, aber nicht ksh, auch diepdksh
-basierten Varianten.Während:
wird nur unterstützt von
zsh
.quelle
function
Schlüsselwort als auch die Klammern enthält, ist in Bash dokumentiert. Das Handbuch von Bash 4.2 und höher besagt, dass Funktionen durch die Syntaxname () compound-command [ redirections ]
oder deklariert werdenfunction name [()] compound-command [ redirections ]
. In Bash 4.1.11 bis mindestens 3.0-Beta war dies nur die einzelne Zeile,[ function ] name () compound-command [redirection]
die fälschlicherweise nicht die Syntax abdeckt, die dasfunction
Schlüsselwort enthält, aber keine Klammern, sondern die Syntax, die sowohl dasfunction
Schlüsselwort als auch die Klammern enthält.bash
erkennt (und immer erkennt), so dass es Skripte interpretieren kann, die für die Korn-Shell geschrieben wurden. Es unterstützt auch, aber es gibt keinen guten Grund, diesen zu verwenden.function foo {
foo() {
function foo () {
function f() {
. In Bezug auf die Lesbarkeit wird es nämlich von jedem, der Englisch kann, und von jedem, der C kann, als Funktion gegenüber nur einer dieser Mengen erkannt.You should never combine the keyword function with the parentheses () when defining a function.
Semantisch sind diese beiden Formen in Bash äquivalent.
Von der Manpage:
EDIT: Ich habe gerade bemerkt, dass diese Frage markiert ist
posix
. In POSIXsh
wird dasfunction
Schlüsselwort nicht verwendet (obwohl es reserviert ist).quelle
Einige andere haben inzwischen richtig geantwortet, aber hier ist meine kurze Zusammenfassung:
Die zweite Version ist portabel und funktioniert wahrscheinlich mit vielen Standard-Shells (insbesondere POSIX).
Die erste Version funktioniert nur mit Bash. Sie können jedoch die Klammern nach dem Funktionsnamen weglassen.
Andernfalls stellen sie identische Entitäten dar, nachdem die Bash sie interpretiert hat.
quelle
()
undfunction
einfügen, verhält sich die Shell so, als ob Sie esfoo(){ ...; }
trotzdem getan hätten , außer natürlich für eine Shell, in der es sich um eine ungültige Syntax handelt. und so solltest du tun,function foo { ...; }
wenn du musst, oderfoo(){ ...; }
anders.