Вийдіть з функції 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, якщо зоопарк уже встановлений, я хочу вийти зі скрипту під ним. Але використання exitвиходів із самого терміналу.


1
Як запустити цей сценарій?
Бенуа

2
використовувати return 1замістьexit 1
polym

Відповіді:


21

TL; DR

Використовуйте returnзамість exitІ запускайте свій сценарій з source your-script.shака.. your-script.sh

Повна інформація

Якщо ви запускаєте скрипт із exitзаявою в ньому, ви повинні запустити його як дитина вашої поточної дитини.

Якщо ви запускаєте його всередині поточної оболонки, розпочатої з вашого термінального сеансу (використовуючи . ./<scriptname>будь-яку, exitбуде закрито основну оболонку, та, що розпочалася під час сеансу терміналу.

Якби ви запустили такий сценарій, як bash ./<scriptname>(або будь-яка інша оболонка замість bash ), ви exitзупинили б свою дочірню оболонку, а не ту, яку використовує ваш термінал.

Якщо ваш скрипт має виконавчі дозволи, його виконання безпосередньо без введення імені оболонки виконає і в дочірній оболонці.

Використання returnзамість exitдозволить все-таки запустити сценарій за допомогою, . ./<script name>не закриваючи поточну оболонку. Але вам потрібно скористатися лише returnдля виходу із функції або скрипту (скрипт виконується за допомогою . ./<scriptname>синтаксису).


returnНЕ зупинить файл сценарію
Nam G VU

@NamGVU Повернення, а не вихід - це правильна річ. Якщо припустити, що вони посилають файл і потім викликають функцію (функція exit/ returnу функцію не буде викликана під час отримання даного файлу), сеанс оболонки припиняється (разом із терміналом), якщо функція використовується exit. З return, він буде обробляти управління назад до оболонки виклику. Зауважте, що якщо ви хочете повернутися з джерела скрипту (про який мова не йде), returnце правильний спосіб зробити це також, як exitі припинить сеанс оболонки.
Kusalananda

Це залежить від того, як ви запускаєте сценарій на першому місці
Nam G VU

@NamGVU У файлі немає виклику функції. Просто пошук або запуск файла не викликав би функцію. Поясніть, як функція завершує сеанс оболонки та термінал будь-яким іншим способом, ніж спочатку знайти файл, а потім викликати його в терміналі.
Kusalananda

Дякую за обмін. Я думаю, що ми не надто далеко пішли від теми.
Нам Г ВУ

1

Єдиний спосіб, коли даний скрипт здатний припинити сеанс оболонки (і, отже, термінал), - це виправити скрипт (встановити installZookфункцію в поточному сеансі оболонки), а потім виконати функцію в оболонці.

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

exitзавершує поточний сеанс оболонки. Коли функція виконує, exitвона припиняє оболонку, яка її викликала.

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

Якщо ви вручну запускаєте installZookфункцію з оболонки, то все, що вам потрібно зробити, - це змінити exitна return. Якщо у вашому скрипті є ще один фрагмент коду, який викликає функцію (і який ви не показуєте), тоді цей фрагмент коду повинен додатково реагувати на стан повернення функції.

Наприклад

installZook || return

Якщо це було частиною жодної функції в скрипті, і якщо ви встановили скрипт, він поверне контроль до оболонки, якщо функція поверне ненульовий код виходу.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.