Любой способ выйти из 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
У меня была та же проблема, и из приведенных выше ответов и из того, что я понял, в конечном итоге у меня сработало
- Иметь строку 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.