Итак, у меня есть небольшой скрипт для запуска некоторых тестов.
javac *.java && java -ea Test
rm -f *.class
Теперь проблема в том, что когда я запускаю скрипт ./test
, он вернет код успешного завершения, даже если тест не пройден из-за rm -f *.class
успеха.
Единственный способ заставить меня делать то, что я хочу, кажется мне уродливым:
javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
if [ "$test_exit_code" != 0 ] ; then false; fi
Но это похоже на обычную проблему - выполнить задачу, очистить, а затем вернуть код завершения исходной задачи.
Какой самый идиоматичный способ сделать это (в bash или просто в оболочках в целом)?
bash
shell
exit-status
math4tots
источник
источник
eval
всегда любимый фанатом.Я бы пошел с:
Зачем прыгать, когда
exit
есть в наличии?Вы можете использовать
trap
:Например:
источник
exit ${last_error_code:=0}
.Насколько я знаю, самое близкое, что есть у bash к
try...finally
блоку из более C-подобного языка программирования (что вы, вероятно, хотели бы получить, если бы он был доступен), - этоtrap
конструкция, которая работает следующим образом:Это выполнит "rm -f * .class", когда ваш скрипт завершится. Если у вас есть что-то более сложное, вы можете поместить это в функцию:
Если вы так склонны, вы можете превратить это в довольно общую идиому, которая работает примерно как
try...catch...finally
блок в C. Что-то вроде этого:Обратите внимание, что скобки разделяют подоболочку; при такой конструкции в случае сбоя команды завершается только подоболочка, а не весь скрипт. Помните, что подоболочки являются в некотором смысле вычислительно дорогими, поэтому не используйте их слишком много (сотни). В зависимости от вашего сценария вы можете добиться того же эффекта более эффективно с помощью функций оболочки и
trap ... RETURN
, но это ваше дело исследовать.источник