退出bash功能,而不是终端


12

我有一个bash脚本,如下所示,它可以安装zookeeper,但前提是尚未安装。

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

在标记为的行上<<<< here,如果已经安装了zookeeper,我想要退出它下面的脚本。但是using会exit退出终端本身。


1
您如何启动此脚本?
Benoit 2014年

2
使用return 1代替exit 1
polym

Answers:


21

TL; DR

使用return而不是exitAND 来与您的脚本一起运行source your-script.sh. your-script.sh

详细资料

如果启动其中包含exit语句的脚本,则必须作为当前子级的子级启动它。

如果您在终端会话开始的当前shell中启动它(使用. ./<scriptname>any exit会关闭主shell,那么它将在您的终端会话中启动)。

如果您像这样启动了脚本bash ./<scriptname>(或其他任何外壳程序而不是bash),那么exit该脚本将停止子外壳程序,而不是由终端使用。

如果您的脚本具有可执行权限,那么直接执行而不给出外壳程序名称也将在子外壳程序中执行该脚本。

使用return,而不是exit将允许您使用后仍然启动脚本. ./<script name>,而不关闭当前shell。但是您只需要使用return退出函数或源脚本(使用. ./<scriptname>语法运行脚本)即可退出。


return不会停止脚本文件
Nam G VU

@NamGVU返回而不是退出是正确的做法。假设他们提供了文件,然后调用了该函数(在获取给定文件时将调用函数中的exit/ ),那么如果使用了该函数,shell会话将终止(与终端一起)。使用,它将控制权返回给调用shell。请注意,如果您想从源脚本中返回(这无关紧要),也是终止shell会话的正确方法。returnexitreturnreturnexit
库萨兰达

这取决于您如何首先运行脚本
Nam G VU

@NamGVU文件中没有对该函数的调用。仅采购或运行文件不会调用该函数。说明该函数如何以任何其他方式终止Shell会话和终端,而不是通过首先获取文件然后在终端中调用它来终止。
Kusalananda

谢谢分享。我认为那时我们离主题不远了。
Nam G VU

1

给定脚本能够终止Shell会话(并因此终止终端)的唯一方法是通过采购脚本(installZook在当前Shell会话中安装函数),然后在Shell中运行该函数。

如果所显示的只是包含调用该installZook函数的较大脚本的一部分,则该函数仍然只能在脚本源化的情况下使终端终止,而不能通过作为普通shell脚本运行而终止。

exit终止当前的shell会话。函数执行时,exit它将终止调用它的外壳。

return从函数(或源脚本文件)返回。如果函数,而不是exit,使用return,能不退出其控制返回给调用环境(可能是交互的shell你叫从功能)。

如果您installZook从外壳程序手动运行该函数,则只需将更exit改为即可return。如果在你的脚本另一段代码调用该函数(和你没有显示),那么这段代码需要额外反应函数的返回状态。

例如

installZook || return

如果这是脚本中没有函数的一部分,并且您是脚本的源代码,则在函数返回非零退出代码的情况下,它将把控制权返回给Shell。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.