разница между "exec" и "exit" в bash - PullRequest
4 голосов
/ 16 января 2012

Я видел, как "exit" и "exec" использовались в скрипте bash, чтобы остановить выполнение скрипта, если произошла ошибка.Например:

if [ ! -f file ]; then
echo "no file"
exit 1
fi

и:

if [ ! -f file ]; then
exec echo "no file"
fi

Какова лучшая практика здесь и почему?Также приветствуются более широкие обсуждения / объяснения относительно "exec" и "exit":)

Ответы [ 3 ]

14 голосов
/ 16 января 2012

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

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

Ваш первый пример - почти, но не совсем, правильный способ остановить скрипт, если произошла ошибка. Следует читать

if [ ! -f file ]; then
    echo "no file" >&2
    exit 1
fi

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *..

Ваш второй пример - неправильно . В дополнение к сообщению об ошибке, помещающемуся в неправильное место, exec echo остановит скрипт (потому что /bin/echo выполнит свою работу и затем завершится), но вернет код выхода 0 родительскому процессу. Код выхода 0 означает успех . Программы, работающие в среде Unix, всегда должны возвращать ненулевой код завершения, если они потерпели неудачу.

Правильное использование exec в сценариях оболочки, которые выполняют некоторую настройку, а затем вызывают долгоживущую программу, написанную на другом языке, и после этого не нужно ничего делать, поэтому нет смысла сохранять процесс оболочки висит вокруг. Например:

#! /bin/sh
PATH=/special/directory/for/foo:$PATH
export PATH
exec foo
3 голосов
/ 16 января 2012

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

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

Я бы определенно рекомендовал первый вариант.Сохраняет запуск внешней команды /bin/echo и правильно указывает ошибку с кодом выхода.

0 голосов
/ 16 января 2012

Правильный способ указать на ошибку - скрипт вернет ненулевой код, например 1. В вашем случае лучше всего использовать «выход 1».

Использование "exec" просто выполнит код после него. Возможно, примеры, которые вы видели, используют «#! / Bin / bash -e» или «set -e», а затем «exec» для вызова кода, который завершается ошибкой, в результате чего сам «exec» возвращает ненулевой код и "-e" означает, что если какая-либо команда возвращает ненулевой код или возвращает значение false, немедленно выйдите из сценария.

...