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
}

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.

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
}

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.