我有一个如下的 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,我想要的是退出它下面的脚本。但使用exit
会退出终端本身。
答案1
长话短说
使用return
而不是exit
并使用 aka 运行你的脚本source your-script.sh
。. your-script.sh
详细信息
如果启动其中包含语句的脚本exit
,则必须将其作为当前子项的子项启动。
如果您在随终端会话启动的当前 shell 中启动它(使用. ./<scriptname>
任何命令exit
都会关闭主 shell,即随终端会话启动的 shell)。
如果您启动了脚本bash ./<scriptname>
(或任何其他 shell 而不是巴什),那么exit
就会停止你的子 shell,而不是你的终端使用的 shell。
如果您的脚本具有可执行权限,则直接执行它而不给出 shell 名称也会在子 shell 中执行它。
使用return
而不是exit
允许您仍然启动脚本. ./<script name>
而不关闭当前 shell。但是您需要使用return
仅退出函数或源脚本(使用语法运行的脚本. ./<scriptname>
)。
答案2
而不是使用exit 1
尝试使用return 1
。
答案3
给定脚本能够终止 shell 会话(以及终端)的唯一方法是获取脚本(installZook
在当前 shell 会话中安装该函数),然后在 shell 中运行该函数。
如果您显示的只是包含函数调用的较大脚本的一部分installZook
,则该函数仍然只能导致终端终止(如果脚本是)来源,但不是通过作为普通 shell 脚本运行。
exit
终止当前 shell 会话。当函数执行时,exit
它会终止调用它的 shell。
return
从函数(或源脚本文件)返回。如果该函数而不是exit
使用return
,它将把控制权返回给调用环境(可能是您调用该函数的交互式 shell),而不退出它。
如果您从 shell 手动运行该installZook
函数,那么您需要做的就是将 更改exit
为return
.如果您的脚本中有另一段代码调用该函数(并且您没有显示),那么该代码需要此外对函数的返回状态做出反应。
例如
installZook || return
如果这是脚本中无函数的一部分,并且您获取了该脚本,则如果该函数返回非零退出代码,它将把控制权返回给 shell。