Potrafię zdefiniować bash
funkcje za pomocą lub pominięcia function
słowa kluczowego. Czy jest jakaś różnica?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Oba wywołania funkcji foo
i bar
odnieść sukces i nie widzę żadnej różnicy. Zastanawiam się więc, czy chodzi tylko o poprawę czytelności, czy czegoś mi brakuje ...
BTW w innych powłokach, takich jak dash
( /bin/sh
jest dowiązaniem symbolicznym do dash
debian / ubuntu), nie działa przy użyciu function
słowa kluczowego.
function baz { echo "baz"; }
. Zobacz bashowymi w wiki GreyCat użytkownika.Odpowiedzi:
Nie ma różnicy AFAIK, poza tym, że druga wersja jest bardziej przenośna.
źródło
tar cf - /some/thing | ssh user@desthost "cd destinationdir && tar xf - "
bez uprzedniego ostrzeżenia najpierw sprawdził, czy wersja tar na desthostu pozbędzie się „/” może prowadzić do katastrofy w niektórych przypadkach ...). Na przykład: jeśli używasz afunction tar { #a safe tar with safety checks ... }
ish
ignoruje to, ...sh
rozpoznająfunction
słowo kluczowe - i, ogólnie rzecz biorąc, które przyjmują wspólne, ale niestandardowe funkcje, które powłoki lubiąksh
ibash
oferują - również często nie będą działać na nowszych systemach produkcyjnych, nawet jeśli działały na starszych wydaniach ten sam system operacyjny.bash
wciąż działash
na wielu systemach GNU / Linux, ale niektóre popularne dystrybucje przeszły na posiadaniesh
jako dowiązanie symboliczne dodash
(Debell Almquist SHell) w celu poprawy wydajności. Obejmuje to Debian i Ubuntu .function
Hasło zostało wprowadzone w ksh . Tradycyjna powłoka Bourne'a miała tylkofoo ()
składnię, a POSIX standaryzuje tylkofoo ()
składnię.W ATT ksh (ale nie pdksh) istnieje kilka różnic między funkcjami zdefiniowanymi przez
function
i funkcjami zdefiniowanymi za pomocą składni Bourne / POSIX. W funkcjach zdefiniowanych przezfunction
Thetypeset
kluczowe deklaruje zmienną lokalną: raz wyjść funkcyjnych, wartość zmiennej jest ustawiany na to, co było przed wejściem do funkcji. Przy klasycznej składni zmienne mają zasięg globalny, niezależnie od tego, czy korzystasz,typeset
czy nie.Inną różnicą w ksh jest to, że funkcje zdefiniowane za pomocą
function
słowa kluczowego mają własny kontekst pułapki. Pułapki zdefiniowane poza funkcją są ignorowane podczas wykonywania funkcji, a krytyczne błędy wewnątrz funkcji wychodzą tylko z funkcji, a nie z całego skryptu. Ponadto,$0
nazwa funkcji w funkcji jest zdefiniowana przez,function
ale nazwa skryptu w funkcji zdefiniowanej przez()
.Pdksh nie emuluje ksh ATT. W pdksh
typeset
tworzy zmienne o zasięgu lokalnym, niezależnie od funkcji, i nie ma pułapek lokalnych (chociaż użyciefunction
powoduje niewielkie różnice - zobacz stronę manuala, aby uzyskać szczegółowe informacje).Bash i zsh wprowadzili
function
słowo kluczowe dla zgodności z ksh. Jednak w tych pociskówfunction foo { … }
ifoo () { … }
są absolutnie identyczne, jak to bash i zsh rozszerzeniefunction foo () { … }
. Słowotypeset
kluczowe zawsze deklaruje zmienne lokalne (z wyjątkiem-g
oczywiście), a pułapki nie są lokalne (można uzyskać pułapki lokalne w zsh, ustawiająclocal_traps
opcję).źródło
foo() command
składnię, a składnia Bourne została później dodana do powłoki Korn w celu zachowania zgodności.function { ... }; f;
pomijaf
pofunction
hasła?to składnia Bourne'a obsługiwana przez dowolną powłokę podobną do Bourne'a
bash
,yash
a także najnowsze wersjeposh
(które obsługują tylko polecenia złożone). (implementacje powłoki Bourne'a i AT&Tksh
nie obsługują,foo() any-command > redirections
chyba żeany-command
jest to polecenie złożone).(Przykłady związku Polecenia:
{ cmd; }
,for i do echo "$i"; done
,(cmd)
... najczęściej są stosowane w{ ...; }
)to składnia POSIX obsługiwana przez dowolną powłokę podobną do Bourne'a i ta, której ogólnie chcesz używać.
to składnia powłoki Korna, która poprzedza składnię Bourne'a. Używaj go tylko wtedy, gdy piszesz specjalnie dla implementacji AT&T powłoki Korn i potrzebujesz specjalnego traktowania, które tam otrzyma. Że składnia POSIX nie jest, ale jest wspierany przez
bash
,yash
izsh
dla kompatybilności z powłoki Korna chociaż te muszle (orazpdksh
opartych warianty Korn shell) nie traktować go różni od standardowej składni.jest składnią braku powłoki i nie należy jej używać . To tylko dzieje się przez przypadek wspierane przez
bash
,yash
,zsh
apdksh
wariantach opartych na powłoce Korna. Nawiasem mówiąc, jest to równieżawk
składnia funkcji.Jeśli będziemy nadal schodzić po liście ezoterycznej,
(jak
function foo() (subshell)
lubfunction foo() for i do; ... done
) jest jeszcze gorszy. Jest obsługiwany przezbash
,yash
izsh
, ale nie ksh, nawetpdksh
oparte na wariantach.Podczas:
jest obsługiwany tylko przez
zsh
.źródło
function
słowo kluczowe, jak i nawiasy, jest udokumentowana w języku Bash. Podręcznik Bash 4.2 i późniejszych mówi, że funkcje są deklarowane przez składnięname () compound-command [ redirections ]
lubfunction name [()] compound-command [ redirections ]
. W wersji Bash 4.1.11 do co najmniej 3.0-beta była to tylko pojedyncza linia,[ function ] name () compound-command [redirection]
która błędnie nie obejmuje składni zawierającejfunction
słowo kluczowe, ale nie zawiera nawiasów, ale nadal obejmuje składnię zawierającą zarównofunction
słowo kluczowe, jak i nawiasy.bash
rozpoznajefunction foo {
opróczfoo() {
kompatybilności z powłoką Korna (i zawsze ma), dzięki czemu może interpretować skrypty napisane dla powłoki Korna. Obsługujefunction foo () {
również, ale nie ma dobrego powodu, aby z niego korzystać.function f() {
. Mianowicie, pod względem czytelności, będzie rozpoznawany jako funkcja przez każdego, kto zna angielski i każdego, kto zna C, w porównaniu z tylko jednym z tych zestawów.You should never combine the keyword function with the parentheses () when defining a function.
Semantycznie te dwie formy są równoważne w Bash.
Ze strony podręcznika:
EDYCJA: Właśnie zauważyłem, że to pytanie jest oznaczone
posix
. W POSIXsh
Thefunction
słowo kluczowe nie jest używana (choć jest on zarezerwowany).źródło
Do tej pory kilka innych osób odpowiedziało poprawnie, ale oto moje zwięzłe streszczenie:
Druga wersja jest przenośna i prawdopodobnie będzie działać z wieloma standardowymi powłokami (szczególnie POSIX).
Pierwsza wersja będzie działać tylko z bash, ale możesz pominąć nawiasy następujące po nazwie funkcji.
W przeciwnym razie reprezentują identyczne byty po ich interpretacji przez bash.
źródło
()
ifunction
kluczowe powłoka zachowuje się tak, jakby po prostu niefoo(){ ...; }
tak, z wyjątkiem, oczywiście, do muszli, w której jest nieprawidłowa składnia. i dlatego powinieneś to zrobić,function foo { ...; }
jeśli musisz lubfoo(){ ...; }
inaczej.