Salga de la función bash, no de la terminal

12

Tengo un script bash como el siguiente que instala zookeeper pero solo si aún no está instalado.

##zookeper
installZook(){

        ZOOK_VERSION="3.4.5"
        ZOOK_TOOL="zookeeper-${ZOOK_VERSION}"
        ZOOK_DOWNLOAD_URL="http://www.us.apache.org/dist/zookeeper/${ZOOK_TOOL}/${ZOOK_TOOL}.tar.gz"

        if [ -e $DEFAULT_INSTALLATION_DEST/${ZOOK_TOOL} ]; then
                echo "${ZOOK_TOOL} alreay installed";
                exit 1;      # <<<< here
        elif [ ! -e $DEFAULT_SOURCE_ROOT/${ZOOK_TOOL}.tar.gz ]; then
                wgetIt $ZOOK_DOWNLOAD_URL
        else
                echo "[info] : $DEFAULT_SOURCE_ROOT/$ZOOK_TOOL already exists"
        fi

        sudo mkdir -p /var/lib/zookeeper
        sudo mkdir -p /var/log/zookeeper

        tarIt "$DEFAULT_SOURCE_ROOT/$ZOOK_TOOL.tar.gz"
        sudo chmod 777 -R $DEFAULT_INSTALLATION_DEST/$ZOOK_TOOL
        cp $DEFAULT_INSTALLATION_DEST/$ZOOK_TOOL/conf/zoo_sample.cfg $DEFAULT_INSTALLATION_DEST/$ZOOK_TOOL/conf/zoo.cfg
cat >> ~/.bash_profile <<'EOF'

  ###############################
  ########### ZOOK ###############
  ###############################
  ZOOK_HOME=/usr/local/zookeper-3.4.5
  export ZOOK_HOME
  export PATH=$PATH:$ZOOK_HOME/bin

EOF
}

En la línea marcada <<<< here, si zookeeper ya está instalado, lo que quiero es salir del script debajo de él. Pero el uso exitsale del terminal en sí.

prayagupd
fuente
1
¿Cómo lanzas este script?
Benoit
2
usar en return 1lugar deexit 1
polym

Respuestas:

21

TL; DR

Use en returnlugar de exitY ejecute su script con source your-script.shaka.. your-script.sh

Todos los detalles

Si inicia un script con una exitdeclaración, debe iniciarlo como un elemento secundario de su elemento actual.

Si lo inicia dentro del shell actual de iniciado con su sesión de terminal (el uso de . ./<scriptname>cualquiera exitcerrará el shell principal, el que comenzó a lo largo de su sesión de terminal.

Si hubiera lanzado su script como bash ./<scriptname>(o cualquier otro shell en lugar de bash ), entonces exithabría detenido su shell hijo y no el utilizado por su terminal.

Si su script tiene permisos ejecutables, ejecutarlo directamente sin dar el nombre del shell también lo ejecutará en un shell hijo.

El uso en returnlugar de exitle permitirá seguir ejecutando su script . ./<script name>sin cerrar el shell actual. Pero debe usar returnpara salir solo de una función o un script de origen (el script se ejecutó utilizando la . ./<scriptname>sintaxis).

Benoit
fuente
returnNO detendrá el archivo de script
Nam G VU
@NamGVU Devolver en lugar de salir es lo correcto. Suponiendo que obtienen el archivo y luego llaman a la función ( no se llamará a exit/ returnen la función mientras se obtiene el archivo dado), la sesión de shell finalizará (junto con el terminal) si se utiliza la función . Con , manejaría el control de regreso al shell de llamada. Tenga en cuenta que si desea regresar de un script de origen (del que no se trata), es la forma correcta de hacerlo también, ya que terminaría la sesión de shell. exitreturnreturnexit
Kusalananda
Depende de cómo ejecutas el script en primer lugar
Nam G VU
@NamGVU No hay llamada a la función en el archivo. Simplemente obtener o ejecutar el archivo no llamaría a la función. Explique cómo la función termina la sesión de shell y el terminal de cualquier otra forma que no sea primero buscando el archivo y luego llamándolo en el terminal.
Kusalananda
Gracias por compartir. Creo que no vamos muy lejos del tema entonces.
Nam G VU
1

La única forma en que el script dado puede terminar la sesión de shell (y, por lo tanto, el terminal) es obteniendo el script (para instalar la installZookfunción en la sesión de shell actual) y luego ejecutando la función en el shell.

Si lo que está mostrando es solo una parte de un script más grande que contiene una llamada a la installZookfunción, entonces la función solo puede hacer que el terminal termine si el script se obtiene , pero no a través de la ejecución como un script de shell ordinario.

exittermina la sesión de shell actual. Cuando la función se ejecuta exit, termina el shell que la llamó.

returnregresa de una función (o un archivo de script de origen). Si la función, en lugar de exitusarse return, devolvería el control al entorno de llamada (probablemente el shell interactivo desde el que llamó a la función) sin salir de ella.

Si ejecuta manualmente la installZookfunción desde el shell, todo lo que debe hacer es cambiar la función exita return. Si hay otra pieza de código en su script que llama a la función (y que no está mostrando), entonces esa pieza de código debe reaccionar adicionalmente al estado de retorno de la función.

Por ejemplo

installZook || return

Si esto no forma parte de ninguna función en el script, y si obtuvo el script, devolvería el control al shell si la función devolviera un código de salida distinto de cero.

Kusalananda
fuente
0

En lugar de usar exit 1intente usar return 1.

ryekayo
fuente
1
returnregresará de la InstallZook()función, no saldrá del script.
Barmar
@Barmar Ver comentario arriba .
Kusalananda