Выйти из функции bash, а не из терминала

Выйти из функции bash, а не из терминала

У меня есть скрипт 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

TL;DR

Используйте returnвместо exitИ запустите свой скрипт с помощью source your-script.shaka.. your-script.sh

Полная информация

При запуске скрипта с exitоператором в нем вам придется запустить его как дочерний элемент текущего дочернего элемента.

Если вы запустите его внутри текущей оболочки, запущенной в ходе сеанса терминала (использование . ./<scriptname>any exitзакроет основную оболочку, запущенную в ходе сеанса терминала).

Если бы вы запустили свой скрипт как bash ./<scriptname>(или любую другую оболочку вместоБаш), то exitостановилась бы ваша дочерняя оболочка, а не та, которая используется вашим терминалом.

Если ваш скрипт имеет права на исполнение, его непосредственное выполнение без указания имени оболочки приведет к его выполнению и в дочерней оболочке.

Использование returnвместо exitпозволит вам по-прежнему запускать ваш скрипт, используя . ./<script name>без закрытия текущей оболочки. Но вам нужно использовать returnтолько для выхода из функции или исходного скрипта (скрипт, запущенный с использованием синтаксиса . ./<scriptname>).

решение2

Вместо использования exit 1попробуйте использовать return 1.

решение3

Единственный способ, которым данный скрипт может завершить сеанс оболочки (и, следовательно, терминал), — это получить скрипт (чтобы установить функцию installZookв текущем сеансе оболочки), а затем запустить функцию в оболочке.

Если то, что вы показываете, является лишь частью более крупного скрипта, содержащего вызов функции installZook, то функция все равно может вызвать завершение работы терминала, только если скриптполучено, но не путем запуска в качестве обычного скрипта оболочки.

exitзавершает текущую сессию оболочки. Когда функция выполняется, exitона завершает оболочку, которая ее вызвала.

returnвозвращается из функции (или исходного файла скрипта). Если бы функция вместо exitиспользовала return, она бы вернула управление вызывающей среде (вероятно, интерактивной оболочке, из которой вы вызвали функцию) без выхода из нее.

Если вы вручную запуститеinstallZook функцию из оболочки, то все, что вам нужно сделать, это изменить на exit. returnЕсли в вашем скрипте есть другой фрагмент кода, который вызывает функцию (и который вы не показываете), то этот фрагмент кода нужнокроме тогореагировать на возвращаемый статус функции.

Например

installZook || return

Если бы это не было частью функции в скрипте и если бы вы получили скрипт в качестве источника, он бы вернул управление оболочке, если бы функция вернула ненулевой код выхода.

Связанный контент