Любой способ выйти из bash script, но не выйти из терминала

Когда я использую команду exit в оболочке script, script завершает работу терминала (подсказка). Есть ли способ прервать script, а затем остаться в терминале?

Ожидается, что мой script run.sh будет выполняться напрямую из источников или из другого script.

EDIT: Чтобы быть более конкретным, существует два сценария run2.sh как

...
. run.sh
echo "place A"
...

и run.sh как

...
exit
...

когда я запустил его на . run2.sh, и если он попал в exit в run.sh, я хочу, чтобы он остановился на терминале и остался там. Но используя exit, весь терминал закрывается.

PS: Я попытался использовать return, но echo код будет по-прежнему выполняться....

Ответ 1

"Проблема" на самом деле заключается в том, что вы работаете и не выполняете script. Когда вы отправляете файл, его содержимое будет выполняться в текущей оболочке, вместо того, чтобы размножать подоболочку. Таким образом, все, включая выход, повлияет на текущую оболочку.

Вместо использования exit вы захотите использовать return.

Ответ 2

Да; вы можете использовать return вместо exit. Его основная цель - вернуться из функции оболочки, но если вы используете ее в source -d script, она возвращает из этого script.

Как & sect; 4.1 "Встроенные оболочки Bourne" в справочном руководстве Bash:

     return [n]

Вызов функции оболочки для выхода с возвращаемым значением n. Если n не указывается, возвращаемым значением является статус выхода последняя команда, выполняемая в этой функции. Это также можно использовать для завершения выполнения выполняемого scriptс встроенным . (или source), возвращая либо n, либо статус выхода последней команды, выполненной в script, как выход статус script. Выполняется любая команда, связанная с ловушкой returnперед исполнением возобновляется после функции или script. Статус возврата не равен нулю, если return используется вне функции а не во время выполнения script на . или source.

Ответ 3

Вместо запуска кода с помощью . run2.sh вы можете запустить script с помощью sh run2.sh или bash run2.sh
Новый экземпляр будет открыт для запуска script, после чего он будет закрыт в конце script, оставив открытую оболочку. `

Ответ 4

Это похоже на то, что вы помещаете функцию запуска внутри script run2.sh. Вы используете код выхода внутри run, а источник - файл run2.sh в bash tty. Если дать функции запуска ее мощность, чтобы выйти из script и дать run2.sh его способность выйти из терминатора. Тогда из-за того, что функция запуска имеет силу для выхода из вашего темпера.

    #! /bin/sh
    # use . run2.sh

    run()
    {
        echo "this is run"
        #return 0
        exit 0
    }

    echo "this is begin"
    run
    echo "this is end"

В любом случае, я одобряю с Kaz проблема дизайна.

Ответ 5

Вы можете добавить дополнительную команду выхода после команды возврата, чтобы она работала как для выполнения сценария из командной строки, так и для получения из терминала.

Пример кода выхода в скрипте:

   if [ $# -lt 2 ]; then
     echo "Needs at least two arguments"
     return 1 2>/dev/null
     exit 1
   fi

Строка с командой exit не будет вызываться при вводе сценария после команды return.

Когда вы выполняете скрипт, команда return выдает ошибку. Итак, мы подавляем сообщение об ошибке, пересылая его в /dev/null.

Ответ 6

Я думаю, что это происходит, потому что вы запускаете его в режиме источника с точкой

. myscript.sh

Вы должны запустить это в подоболочке:

/full/path/to/script/myscript.sh

'source' http://ss64.com/bash/source.html

Ответ 7

Правильно, что сценарии, полученные от исполняемых или исполняемых, используют return vs. exit, чтобы тот же сеанс открывался, как отмечали другие.

Вот связанный совет, если вы когда-нибудь захотите script, который должен держать сеанс открытым, независимо от того, был ли он найден.

Следующий пример можно запустить прямо как foo.sh или получить как . foo.sh/source foo.sh. В любом случае он будет держать сессию открытой после "выхода". Строка [email protected] передается так, чтобы функция имела доступ к внешним аргументам script.

#!/bin/sh
foo(){
    read -p "Would you like to XYZ? (Y/N): " response;
    [ $response != 'y' ] && return 1;
    echo "XYZ complete (args [email protected]).";
    return 0;
    echo "This line will never execute.";
}
foo "[email protected]";

Результат терминала:

$foo.sh
$ Хотели бы вы XYZ? (Y/N): n
$. foo.sh
$ Хотели бы вы XYZ? (Y/N): n
$ |
(окно терминала остается открытым и принимает дополнительный вход)

Это может быть полезно для быстрого тестирования изменений script в одном терминале, сохраняя при этом код скрапа под основным exit/return во время работы. Это также может сделать код более переносимым в некотором смысле (если у вас есть множество скриптов, которые могут или не могут быть вызваны по-разному), хотя он гораздо менее неуклюж, чтобы использовать return и exit, где это необходимо.

Ответ 8

На самом деле я думаю, что вы можете быть смущены тем, как вы "запускаете скрипт".

Если вы используете sh для запуска скрипта, скажем, sh./run2.sh, даже если встроенный скрипт завершается с exit, окно вашего терминала все равно останется.

Однако, если вы используете . или source, ваше окно терминала также закроется и закроется, когда индекс закончится.

для более подробной информации, пожалуйста, обратитесь к разделу В чем разница между использованием sh и source?

Ответ 9

У меня была та же проблема, и из приведенных выше ответов и из того, что я понял, в конечном итоге у меня сработало

  1. Иметь строку shebang, которая вызывает намеченный сценарий, например, #!/bin/bash использует bash для выполнения сценария

У меня есть сценарии с обоими видами Шебанга. Из-за этого, используя sh или. был ненадежным, так как приводил к неправильному выполнению (например, когда сценарий вылетает не полностью)

Поэтому ответ был

    • убедитесь, что в скрипте есть шебанг, чтобы не было никаких сомнений относительно его предполагаемого обработчика
    • chmod.sh файл, чтобы он мог быть выполнен
    • вызывать его напрямую, без всяких sh или.

./myscript.sh

Надеюсь, что это помогает кому-то с аналогичными требованиями/обстоятельствами

Ответ 10

Если ваш эмулятор терминала не имеет -hold, вы можете дезинфицировать источник script и удерживать терминал с помощью

#!/bin/sh
sed "s/exit/return/g" script >/tmp/script
. /tmp/script
read

в противном случае вы можете использовать $TERM -hold -e script

Ответ 11

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

Ответ 12

Чтобы написать сценарий, который является пуленепробиваемым для запуска в качестве сценария оболочки или был получен как rc файл, сценарий может проверить и сравнить $0 и $BASH_SOURCE и определить, можно ли безопасно использовать exit.

Вот короткий фрагмент кода для этого

[ "X$(basename $0)" = "X$(basename $BASH_SOURCE)" ] && \
    echo "***** executing $name_src as a shell script *****" || \
    echo "..... sourcing $name_src ....."

Ответ 13

1) выход 0 выйдет из script, если он будет успешным.

2) выход 1 выйдет из script, если это сбой.

Вы можете попробовать эти два выше, основываясь на ur req.