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 echoco 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 evaljest zbyt ciężkie i zhackowane.
Właściwym sposobem na to jest włączenie funkcji najwyższego poziomu w funkcję i użycie localreguł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_valwskazuje 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_valjako locali 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.
returnw twoim przypadku jest zasadniczo taki sam, jak zexit codejakiego zakresu0 - 255. Użyjechozgodnie z sugestią @septi. Kody wyjścia można przechwytywać za pomocą$?.