我有一個如下的 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
長話短說
使用akareturn
代替exit
AND 運行腳本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。