Problem z innymi odpowiedziami polega na tym, że albo używają globalnej, którą można zastąpić, gdy kilka funkcji znajduje się w łańcuchu połączeń, lub echo
co oznacza, że twoja funkcja nie może wyprowadzić informacji diagnostycznych (zapomnisz, że funkcja to robi i „wynik”, tj. Return wartość, będzie zawierać więcej informacji, niż oczekuje Twój rozmówca, co prowadzi do dziwnego błędu) lub eval
jest zbyt ciężkie i zhackowane.
Właściwym sposobem na to jest włączenie funkcji najwyższego poziomu w funkcję i użycie local
reguły dynamicznego określania zakresu przez bash. Przykład:
func1()
{
ret_val=hi
}
func2()
{
ret_val=bye
}
func3()
{
local ret_val=nothing
echo $ret_val
func1
echo $ret_val
func2
echo $ret_val
}
func3
To wychodzi
nothing
hi
bye
Dynamiczny zakres oznacza, że ret_val
wskazuje inny obiekt w zależności od dzwoniącego! Różni się to od zakresu leksykalnego, którego używa większość języków programowania. Jest to właściwie udokumentowana funkcja , po prostu łatwa do pominięcia i niezbyt dobrze wyjaśniona, oto jej dokumentacja (nacisk jest mój):
Zmienne lokalne dla funkcji mogą być deklarowane za pomocą wbudowanego lokalnego. Te zmienne są widoczne tylko dla funkcji i wywoływanych przez nią poleceń .
Dla kogoś z tłem C / C ++ / Python / Java / C # / javascript jest to prawdopodobnie największa przeszkoda: funkcje w bash nie są funkcjami, są poleceniami i zachowują się w ten sposób: mogą wysyłać dane do stdout
/ stderr
, mogą wpuszczać / out, mogą zwrócić kod wyjścia. Zasadniczo nie ma różnicy między zdefiniowaniem polecenia w skrypcie a utworzeniem pliku wykonywalnego, który można wywoływać z wiersza poleceń.
Zamiast pisać taki skrypt:
top-level code
bunch of functions
more top-level code
napisz to w ten sposób:
# define your main, containing all top-level code
main()
bunch of functions
# call main
main
gdzie main()
deklaruje ret_val
jako local
i wszystkie inne funkcje zwracają wartości przez ret_val
.
Zobacz także następujące pytanie dotyczące systemów Unix i Linux: Zakres zmiennych lokalnych w funkcjach powłoki .
Inną, być może nawet lepsze rozwiązanie w zależności od sytuacji, jest jednym wysłane przez ya.teck który korzysta local -n
.
return
w twoim przypadku jest zasadniczo taki sam, jak zexit code
jakiego zakresu0 - 255
. Użyjecho
zgodnie z sugestią @septi. Kody wyjścia można przechwytywać za pomocą$?
.