Вы были очень близки! Вот исправленная версия того, что вы пытались:
bzr commit -m "merged upstream version ${REV_UPSTREAM}" || exit 0
Это теперь делает то, что вы просили, но не идеально. Я вернусь к этому позже.
Обратите внимание на крошечное важное изменение в вашей версии - мы сейчас явно заявляем, что должны выйти с кодом 0 (успех), если команда bzr не делает этого. В вашей версии exit (без аргумента) прервет ваш скрипт, но вернет код завершения последней выполненной команды - в этом случае bzr commit.
Подробнее о выходе
Как мы узнаем об этом поведении выхода? Команда exit
является встроенной в оболочку - для поиска документации по ней мы используем команду справки:
help exit
Что на моей машине говорит мне:
exit: exit [n]
Exit the shell.
Exits the shell with a status of N. If N is omitted, the exit status
is that of the last command executed.
Вот достойное руководство по кодам выхода и выхода в оболочке bash
Hudson и коды выхода
Хадсон следует этому общему правилу интерпретации кода выхода 0 как успеха, а любого другого кода как сбоя. Он будет помечать вашу сборку как неудачную, если выполняемый скрипт сборки завершит работу с ненулевым кодом.
Почему ваш скрипт останавливается после коммита bzr
Если, как вы говорите, у вас есть следующее, и ваш скрипт останавливается после коммита bzr ...
bzr commit -m "merged upstream version ${REV_UPSTREAM}"
./run_tests.sh
... Я подозреваю, что в вашем скрипте есть инструкция типа set -e
или он вызывается с чем-то вроде bash -e build_script.sh
Любой из этих параметров заставляет оболочку немедленно выйти, если команда завершается с ненулевым статусом, и передавать тот же самый код завершения «сбой». (Есть тонкости - см. Сноску 1).
Отключение выхода при ошибке
Хотя такое поведение при выходе из ошибки чрезвычайно полезно, иногда мы хотели бы временно отключить его. Вы нашли один способ, в
bzr commit whatever || true
Мы также можем отключить проверку ошибок с помощью set + e.
Вот шаблон, который вы можете найти полезным. В нем мы будем:
- Отключить выход при ошибке (с
set +e
)
- запустить команду, которая может вызвать ошибку
bzr commit whatever
- захватить код выхода ($?) Для позже проверка
- Снова включить выход при ошибке (с
set -e
)
- Тестировать и действовать по коду выхода любых команд
Давайте реализуем это. Снова мы выйдем 0 (успех), если команда bzr не удалась.
set +e
bzr commit whatever
commit_status=$?
set -e
if [[ "$commit_status" != "0" ]]; then
echo "bzr commit finds nothing to do. Build will stop, with success"
exit 0
fi
echo "On we go with the rest of the build script..."
Обратите внимание, что мы заключаем в скобки как можно меньше с помощью set + e / set -e. Если в этом разделе в нашем скрипте есть опечатки, они не остановят скрипт, и будет хаос. Прочтите раздел «Как избежать set -e» в посте « Недостаточно известные функции оболочки POSIX » для получения дополнительных идей.
Что не так с foo || exit 0
?
Как я упоминал ранее, есть проблема с нашим первым предложенным решением. Мы сказали, что когда bzr commit
не равен нулю (т.е. он не фиксируется нормально), мы всегда останавливаемся и указываем success . Это произойдет, даже если bzr commit
не получится по какой-то другой причине (и с некоторым другим ненулевым кодом выхода): возможно, вы сделали опечатку в вызове команды, или bzr не может подключиться к репо.
По крайней мере, в некоторых из этих случаев вы, возможно, захотите пометить сборку как сбой, чтобы вы могли что-то с этим сделать.
На пути к лучшему решению
Мы хотим конкретно указать, какие ненулевые коды выхода мы ожидаем от bzr, и что мы будем делать с каждым.
Если вы оглянетесь назад на шаблон set + e / set -e, приведенный выше, не составит труда расширить приведенную выше условную логику (если) в нечто, что может иметь дело с рядом конкретных кодов выхода из bzr, и с универсальным кодом для непредвиденных кодов выхода, который (я полагаю) завершается неудачно при сборке и сообщает о нарушающем коде и команде.
Чтобы узнать коды выхода для любой команды, прочитайте документы или выполните команду, а затем введите echo $?
в качестве следующей команды . $? содержит код завершения предыдущей команды.
Сноска 1. В поведении выхода при ошибке, переключенном с помощью set -e, есть некоторые тонкости, с которыми вам нужно ознакомиться, касающиеся поведения, когда команды находятся в конвейерах, условных выражениях и других конструкциях.