Funkcja jest zdefiniowana jako:
do_something () {
do it
}
Mogłem zrozumieć jego nazwę „do_something” i nawias klamrowy do enkapsulacji kodu akcji, ale nie jestem w stanie zrozumieć, jaki jest cel tego ()
tutaj, ponieważ w skryptach Bash nie ma nazwanych parametrów. Zdefiniowanie go jako może być łatwiejsze i prostsze
do_something {
do it
}
Co nie jest sprzeczne z jego bieżącą składnią, a jeszcze bardziej deklaruje, że nie ma nazwanych parametrów. Jaki jest pożytek z ()
tego miejsca?
Odpowiedzi:
Bez tego
()
składnia byłaby naprawdę niejednoznaczna.Musi istnieć pewna jednoznaczna składnia do zdefiniowania funkcji i bez zasadniczej zmiany innej składni powłoki, nie może być tak:
Powiedziałeś, że to „nie ma nic wspólnego z obecną składnią”, ale tak się dzieje! Zauważ, że podczas próby uruchomienia pierwszego wiersza tego nie pojawia się żaden błąd składniowy . Wystąpił błąd, ale nie jest to błąd dotyczący składni. Drugi wiersz, z
}
, jest błędem składniowym, ale pierwszy wiersz nie. Zamiast tegodo_something {
próbuje uruchomić wywołaną komendędo_something
i przekazać{
jako argument do tej komendy:Jeśli istnieje już wywołane polecenie
do_something
, uruchamiasz je. Jeśli istnieje już wywołana funkcjado_something
, wywołujesz ją . Ogólnie ważne jest, aby składnia była jednoznaczna, ale ważne jest również, aby możliwe było ponowne zdefiniowanie funkcji bez przypadkowego jej wywołania. Zdefiniowanie i wywołanie funkcji nie powinno wyglądać tak samo.Jak leczy się skorupa
{
i(
.Jak
type {
powiedzą,{
jest słowem kluczowym powłoki. To sprawia, że tak[[
. Jeśli zostanie użyty w sytuacji, w której inaczej byłby poleceniem,{
niesie specjalną semantykę. W szczególności wykonuje grupowanie poleceń. W innych sytuacjach można go jednak użyć bez ukrycia, aby{
opisać dosłowny charakter. Obejmuje to sytuację przekazania go jako drugie lub kolejne słowo polecenia.Oczywiście Bash mógł zostać zaprojektowany tak, aby traktować go
{
inaczej niż obecnie. Jednak jego składnia nie byłaby wówczas kompatybilna z powłoką POSIX, a Bash tak naprawdę nie byłby powłoką w stylu Bourne'a i nie byłby w stanie uruchomić wielu skryptów powłoki.Natomiast
(
metaznak powłoki. To jest zawsze traktowane szczególnie jeśli okaże się w poleceniu i nie jest podawana (z'
'
,"
"
lub\
). Nie ma zatem dwuznaczności w składni:To nie mogło znaczyć nic innego. Gdyby Bash nie miał funkcji, byłby to błąd składniowy, z tego samego powodu
echo foo(bar)
to błąd składniowy.Jeśli naprawdę nie podoba ci się
()
notacja, możesz użyć słowa kluczowegofunction
i pominąć je, jak wspomina sudodus . Zauważ, że nie jest to część składni definiowania funkcji w większości innych powłok w stylu Bourne'a - i w niektórych jest obsługiwana, ale funkcje zdefiniowane w ten sposób mają inną semantykę - i dlatego skrypt, który jej używa, nie będzie przenośny. (Powodem, dla którego ta składnia może być jednoznaczna, jest to, żefunction
samo w Bash jest słowem kluczowym, które oznacza, że cokolwiek następuje po nim, jest początkiem definicji funkcji.)Na koniec zauważ, że chociaż większość definicji funkcji używa
{
w praktyce, każde polecenie złożone jest dozwolone. Jeśli miałeś funkcję, której ciało zawsze chciałeś uruchamiać w podpowłoce, możesz użyć(
)
zamiast niej{
}
.źródło
()
Token jest powiedzieć interpreter powłoki, które są deklarowania funkcji.Alternatywą
bash
jestfunction
lub jako jedno-liniowy możesz przetestować
źródło
function
kluczowe to ksh-ism sprzed POSIX, który bash obsługuje dla kompatybilności wstecznej; jednak bash źle to obsługuje (nie czyni zmiennych zmiennymi lokalnymi domyślnymi, jak stary ksh w funkcjach zadeklarowanych w tej formie). W związku z tym nie jest idealny dla nowego kodu. Zobacz wiki.bash-hackers.org/scripting/obsoletetypeset
bez-g
w funkcji zawsze deklaruje zmienną lokalną. Czyfunction
zmienne zasięgu słowa kluczowego, bash i ksh są takie same , czyż nie?Jak bardzo jeden z was ma styl prawdziwej klamry !
Zastanów się nad innymi, doskonale dobranymi stylami usztywnień:
W jaki sposób powłoka może stwierdzić, że są to definicje funkcji, a nie tylko polecenie
foo
poprzedzone listami poleceń? We wszystkich tych przypadkach konieczny jest dodatkowy czynnik jednoznaczny, taki jak()
lubfunction
słowo kluczowe.źródło
()
lub coś w tym rodzaju.