Cómo salir de una función en bash

101

¿Cómo saldría de una función si una condición es verdadera sin matar todo el script? Simplemente vuelva a antes de llamar a la función.

Ejemplo

# 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
fuente

Respuestas:

139

Utilizar:

return [n]

Desde help return

retorno : retorno [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
fuente
20
Tenga en cuenta que si ha set -eestablecido en la parte superior de su secuencia de comandos y su return 1o cualquier otro número además de 0, se cerrará la secuencia de comandos completa.
Yevgeniy Brikman
1
@YevgeniyBrikman eso solo es cierto si el error en la función es inesperado. Si se llama a la función usando, por ejemplo, ||entonces es posible devolver un código distinto de cero y que el script continúe ejecutándose.
Dan Passaro
1
@DanPassaro Sí, definitivamente hay soluciones posibles, pero solo quería señalar que se debe tener un cuidado adicional set -ey devolver valores distintos de cero, ya que eso me tomó por sorpresa en el pasado.
Yevgeniy Brikman
21

returnOperador de uso :

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
fuente
2

Si desea regresar de una función externa con un error sin exiting, puede usar este truco:

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
}

Probándolo:

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

Esto tiene la ventaja / desventaja añadida de que, opcionalmente, puede desactivar esta característica: __fail_fast=x do-something-complex.

Tenga en cuenta que esto hace que la función más externa devuelva 1.

Elliot Cameron
fuente
¿Podría explicarnos más sobre la función interna fail, qué hace el colon aquí?
brook hong
El :es un operador de bash incorporado que es "no operativo". Evalúa la expresión pero no hace nada con ella. Lo estoy usando para hacer una sustitución de variables que fallará si la variable no está definida, lo que obviamente no lo está.
Elliot Cameron
Gracias. ¿Puedo reemplazar la expresión por alguna otra expresión para verificar el parámetro de entrada do-something-complex? <code> checkPara () {if [$ 1 -lt $ 2]; luego echo $ 3; fi; } do-something-complex () {checkPara $ # 1 "Algún mensaje aquí para advertir al usuario cómo usar la función". echo "yes"} </code> Le do-something-complexmostraría al usuario algún mensaje y regresaría inmediatamente si no hay ningún parámetro alimentado a la función.
Brook Hong
Sí, podría hacer algo así donde checkParausaría mi failfunción para salir de toda la pila de funciones.
Elliot Cameron
Parece que no funciona. (PD: el codebloque no funciona en el comentario sobre stackoverflow). Sigue corriendo después checkPara.
brook hong