Jak wyjść z funkcji w bash

101

Jak wyjść z funkcji, jeśli warunek jest prawdziwy bez zabijania całego skryptu, po prostu wróć do stanu sprzed wywołania funkcji.

Przykład

# Start script
Do scripty stuff here
Ok now lets call FUNCT
FUNCT
Here is A to come back to

function FUNCT {
  if [ blah is false ]; then
    exit the function and go up to A
  else
    keep running the function
  fi
}
Atomiklan
źródło

Odpowiedzi:

139

Posługiwać się:

return [n]

Z help return

return : return [n]

Return from a shell function.

Causes a function or sourced script to exit with the return value
specified by N.  If N is omitted, the return status is that of the
last command executed within the function or script.

Exit Status:
Returns N, or failure if the shell is not executing a function or script.
mohit
źródło
20
Zwróć uwagę, że jeśli set -eustawiłeś u góry skryptu i swoją return 1lub jakąkolwiek inną liczbę oprócz 0, cały skrypt zostanie zamknięty.
Yevgeniy Brikman
1
@YevgeniyBrikman, które jest prawdziwe tylko wtedy, gdy błąd w funkcji jest nieoczekiwany. Jeśli funkcja jest wywoływana przy użyciu np. ||Wtedy możliwe jest zwrócenie niezerowego kodu i kontynuowanie wykonywania skryptu.
Dan Passaro,
1
@DanPassaro Tak, zdecydowanie są możliwe rozwiązania, ale chciałem tylko zaznaczyć, że należy zachować szczególną ostrożność set -ei zwracać wartości niezerowe, ponieważ w przeszłości mnie to zaskoczyło.
Yevgeniy Brikman
21

Użyj returnoperatora:

function FUNCT {
  if [ blah is false ]; then
    return 1 # or return 0, or even you can omit the argument.
  else
    keep running the function
  fi
}
Nemanja Boric
źródło
2

Jeśli chcesz powrócić z funkcji zewnętrznej z błędem bez exitingerencji, możesz użyć tej sztuczki:

do-something-complex() {
  # Using `return` here would only return from `fail`, not from `do-something-complex`.
  # Using `exit` would close the entire shell.
  # So we (ab)use a different feature. :)
  fail() { : "${__fail_fast:?$1}"; }

  nested-func() {
      try-this || fail "This didn't work"
      try-that || fail "That didn't work"
  }
  nested-func
}

Wypróbuj to:

$ do-something-complex
try-this: command not found
bash: __fail_fast: This didn't work

Ma to tę dodatkową zaletę / wadę, że opcjonalnie można wyłączyć tę funkcję: __fail_fast=x do-something-complex.

Zauważ, że powoduje to, że najbardziej zewnętrzna funkcja zwraca 1.

Elliot Cameron
źródło
Czy mógłbyś wyjaśnić więcej na temat funkcji wewnętrznej fail, co tu robi okrężnica?
brook hong
:Jest wbudowany operatora bash, który jest „nie-op”. Ocenia wyrażenie, ale nic z nim nie robi. Używam go do zamiany zmiennej, która zakończy się niepowodzeniem, jeśli zmienna nie jest zdefiniowana, co oczywiście nie jest.
Elliot Cameron
Dzięki. Czy mogę zamienić wyrażenie na inne wyrażenie, aby sprawdzić parametr wejściowy do-something-complex? <code> checkPara () {if [$ 1 -lt $ 2]; następnie echo 3 $; fi; } zrób coś złożonego () {checkPara $ # 1 "Jakaś wiadomość ostrzegająca użytkownika, jak używać tej funkcji." echo "tak"} </code> do-something-complexPokazałbym użytkownikowi jakąś wiadomość i wróciłbym natychmiast, jeśli do funkcji nie został podany żaden parametr.
brook hong
Tak, możesz zrobić coś takiego, w którym checkParaużyłbyś mojej failfunkcji do wyjścia z całego stosu funkcji.
Elliot Cameron
Wygląda na to, że nie działa. (PS: codeblok nie działa w komentarzach do przepełnienia stosu). Biegnie dalej checkPara.
brook hong