Как выйти из bash linux

Обновлено: 02.07.2024

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

run.sh Предполагается, что мой сценарий будет выполнен напрямую из другого сценария.

РЕДАКТИРОВАТЬ: Чтобы быть более конкретным, есть два сценария run2.sh как

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

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

Я действительно, действительно, действительно должен спросить: почему вы используете выход в сценарии с источником? команда выхода не должна завершать сеанс терминала / вход в систему. если вы используете exit 0 для завершения сценария после успеха, при запуске сценария ex: ./test.sh вы должны увидеть выходные данные, но ваша консоль останется открытой. Вы можете использовать shell команду, которая фактически открывает терминал оболочки. Однако мой собственный опыт показывает, что этого не происходит exit . Выход обычно возвращает управление родительскому скрипту.

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

Вместо того, чтобы использовать exit , вы захотите использовать return .

Хотя это правильно, это не очень хороший ответ. Он игнорирует, что вызывающий скрипт может объявлять переменные или функции, к которым этот вызывающий скрипт должен иметь доступ. Лучше объяснить, как установить код возврата, а затем обработать его в runs.sh @ruakh, и лучше ответить на этот вопрос. Что если функция является вложенным вызовом? то есть a вызывает b, b вызывает c, c хочет немедленно выйти из a и b. Источник почти такой же, как копировать вставить. Лучше использовать sh <script> или, bash <script> если кто-то хочет запустить скрипт и завершить его в какой-то момент

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

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

return может использоваться ТОЛЬКО из функции. Если вы используете return и выполняете его как сценарий оболочки (например sh run.sh ), bash сообщит об ошибке - return: can only return 'из скрипта функции или источника' Я не согласен с тобой. Я просто хочу отметить, что return это не будет работать, если скрипт запускается как скрипт оболочки и не выполняется. (или source ). Кстати, где я могу найти документ о source -d ?

Вместо запуска скрипта с помощью . run2.sh , вы можете запустить его с помощью sh run2.sh или bash run2.sh

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

@ H0WARD Ты прав, я забыл удалить точки. Я отредактировал ответ сейчас.

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

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

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

На самом деле, я думаю, что вы можете быть смущены тем, как вы делаете run a script .

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

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

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

Во всяком случае, я согласен с Kaz это проблема дизайна.

Из текста неясно, что пытается сделать этот ответ, но он, конечно, не решает рассматриваемый вопрос.

Есть строка Шебанга, которая вызывает предполагаемый сценарий, например,

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

Таким образом, ответ был

  1. Убедитесь, что в скрипте есть шебанг, чтобы не было никаких сомнений относительно его предполагаемого обработчика.
  2. chmod .sh файл, чтобы он мог быть выполнен. (chmod +x file.sh)

Вызывать его напрямую без каких-либо sh или .

Надеюсь, что это помогает кому-то с похожим вопросом или проблемой.

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

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

Вам не нужен полный путь к сценарию, если . myscript.sh работает. Самое большее, вам может понадобиться ./myscript.sh .

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

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

Следующий пример может быть запущен напрямую как foo.sh или из источника . foo.sh / source foo.sh . В любом случае он будет держать сеанс открытым после «выхода». $@ Строка передаются так , что функция имеет доступ к аргументам внешнего скрипта.

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

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

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

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

изменить: Чтобы быть более конкретным, есть два скрипта run2.sh as

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

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

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

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

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

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

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

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

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

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

вы должны запустить это в подсхеме:

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

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

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

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

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

Если ваш эмулятор терминала нет -hold вы можете санировать исходный скрипт и удерживать терминал с помощью:

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

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

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

Как использовать коды завершения в Bash-скриптах главное изображение

Инструменты автоматизации и мониторинга удобны тем, что разработчик может взять готовые скрипты, при необходимости адаптировать и использовать в своём проекте. Можно заметить, что в некоторых скриптах используются коды завершения (exit codes), а в других нет. О коде завершения легко забыть, но это очень полезный инструмент. Особенно важно использовать его в скриптах командной строки.

Что такое коды завершения

В Linux и других Unix-подобных операционных системах программы во время завершения могут передавать значение родительскому процессу. Это значение называется кодом завершения или состоянием завершения. В POSIX по соглашению действует стандарт: программа передаёт 0 при успешном исполнении и 1 или большее число при неудачном исполнении.

Почему это важно? Если смотреть на коды завершения в контексте скриптов для командной строки, ответ очевиден. Любой полезный Bash-скрипт неизбежно будет использоваться в других скриптах или его обернут в однострочник Bash. Это особенно актуально при использовании инструментов автоматизации типа SaltStack или инструментов мониторинга типа Nagios. Эти программы исполняют скрипт и проверяют статус завершения, чтобы определить, было ли исполнение успешным.

Что происходит, когда коды завершения не определены

В Linux любой код, запущенный в командной строке, имеет код завершения. Если код завершения не определён, Bash-скрипты используют код выхода последней запущенной команды. Чтобы лучше понять суть, обратите внимание на пример.

Этот скрипт запускает команды touch и echo . Если запустить этот скрипт без прав суперпользователя, команда touch не выполнится. В этот момент мы хотели бы получить информацию об ошибке с помощью соответствующего кода завершения. Чтобы проверить код выхода, достаточно ввести в командную строку специальную переменную $? . Она печатает код возврата последней запущенной команды.

Как видно, после запуска команды ./tmp.sh получаем код завершения 0 . Этот код говорит об успешном выполнении команды, хотя на самом деле команда не выполнилась. Скрипт из примера выше исполняет две команды: touch и echo . Поскольку код завершения не определён, получаем код выхода последней запущенной команды. Это команда echo , которая успешно выполнилась.

Если убрать из скрипта команду echo , можно получить код завершения команды touch .

Поскольку touch в данном случае — последняя запущенная команда, и она не выполнилась, получаем код возврата 1 .

Как использовать коды завершения в Bash-скриптах

Удаление из скрипта команды echo позволило нам получить код завершения. Что делать, если нужно сделать разные действия в случае успешного и неуспешного выполнения команды touch ? Речь идёт о печати stdout в случае успеха и stderr в случае неуспеха.

Проверяем коды завершения

Выше мы пользовались специальной переменной $? , чтобы получить код завершения скрипта. Также с помощью этой переменной можно проверить, выполнилась ли команда touch успешно.

После рефакторинга скрипта получаем такое поведение:

  • Если команда touch выполняется с кодом 0 , скрипт с помощью echo сообщает об успешно созданном файле.
  • Если команда touch выполняется с другим кодом, скрипт сообщает, что не смог создать файл.

Создаём собственный код завершения

Наш скрипт уже сообщает об ошибке, если команда touch выполняется с ошибкой. Но в случае успешного выполнения команды мы всё также получаем код 0 .

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

Как использовать коды завершения в командной строке

Скрипт уже умеет сообщать пользователям и программам об успешном или неуспешном выполнении. Теперь его можно использовать с другими инструментами администрирования или однострочниками командной строки.

В примере выше && используется для обозначения «и», а || для обозначения «или». В данном случае команда выполняет скрипт ./tmp.sh , а затем выполняет echo "bam" , если код завершения 0 . Если код завершения 1 , выполняется следующая команда в круглых скобках. Как видно, в скобках для группировки команд снова используются && и || .

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

Дополнительные коды завершения

Команда exit принимает числа от 0 до 255 . В большинстве случаев можно обойтись кодами 0 и 1 . Однако есть зарезервированные коды, которые обозначают конкретные ошибки. Список зарезервированных кодов можно посмотреть в документации.

Адаптированный перевод статьи Understanding Exit Codes and how to use them in bash scripts by Benjamin Cane. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.

Favorite

Добавить в избранное

Bash Heredoc

Ч асто при написании сценариев Bash вам необходимо завершить выполнение сценария, когда выполняется определенное условие, или предпринять действия, основанные на коде завершения команды.

В этой статье мы рассмотрим встроенную команду exit в Bash и статусы выхода выполненных команд.

Статус выхода

Каждая команда оболочки возвращает код завершения, когда она завершается, либо успешно, либо безуспешно.

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

Специальная переменная $? возвращает состояние выхода последней выполненной команды:

Команда date выполнена успешно, и код выхода равен нулю:

Если вы попытаетесь запустить команду ls с несуществующим каталогом, код выхода будет ненулевым:

При выполнении многокомпонентного конвейера состояние выхода конвейера соответствует статусу последней команды:

В приведенном выше примере echo $? будет напечатан код выхода команды tee.

Команда exit в Bash

Команда exit выходит из оболочки со статусом N. Он имеет следующий синтаксис:

Если N не указан, код состояния выхода соответствует коду последней выполненной команды.

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

Примеры

Статус выхода команд можно использовать в условных командах, таких как if. В следующем примере grepвыйдет с нуля (что означает true в сценариях оболочки), если «search-string» находится в filename:

При запуске списка команд, разделенных &&(and) или ||(or), состояние выхода команды определяет, будет ли выполнена следующая команда в списке. Здесь команда mkdir будет выполнена только если cd вернет ноль:

Читайте также: