Обработка ошибок кода возврата Bash при использовании ввода heredoc - PullRequest
0 голосов
/ 15 октября 2019

Мотивация

Я нахожусь в ситуации, когда мне приходится запускать несколько команд bash одним вызовом bash без возможности написать полный файл сценария (сценарий использования: Передача нескольких команд контейнеру в Кубернетес ). общее решение состоит в том, чтобы объединять команды с ; или &&, например:

bash -c " \
echo \"Hello World\" ; \
ls -la ; \
run_some_command "

На практике написание таких сценариев bash оказывается подверженным ошибкам, потому что яЯ часто забываю точку с запятой, приводящую к незаметным ошибкам.

Вдохновленный этим вопросом , я экспериментировал с написанием сценариев в более стандартном стиле с использованием heredoc:

bash <<EOF
echo "Hello World"
ls -la
run_some_command
EOF

К сожалению, я заметил, что при обработке heredoc есть разница в обработке кода выхода. Например:

bash -c " \
run_non_existing_command ; \
echo $? "

выходов (обратите внимание, что $? правильно фиксирует код выхода):

bash: run_non_existing_command: command not found
127

, тогда как

bash <<EOF
run_non_existing_command
echo $?
EOF

выходов (обратите внимание, что $? не в состоянии захватить код завершения по сравнению со стандартным выполнением сценария):

bash: line 1: run_non_existing_command: command not found
0

Почему версия heredoc ведет себя по-другому? Можно ли написать скрипт в стиле heredoc и поддерживать нормальную обработку кода выхода?

1 Ответ

4 голосов
/ 15 октября 2019

Почему версия heredoc ведет себя по-разному?

Поскольку $? раскрывается перед запуском команды.

Следующее выведет 1, то есть выходстатус команды false:

false
bash <<EOF
run_non_existing_command
echo $?
EOF

В принципе это то же самое, что и следующее, что выдает 5:

variable=5
bash <<EOF
variable="This is ignored"
echo $variable
EOF

Можно ли написатьсценарий в стиле heredoc и поддержание нормальной обработки кода выхода?

Если вы хотите, чтобы $? раскрывался внутри подоболочки, то:

bash <<EOF
run_non_existing_command
echo \$?
EOF

или

bash <<'EOF'
run_non_existing_command
echo $?
EOF

Также обратите внимание, что:

bash -c \
run_non_existing_command ;
echo $? ;

просто равно:

bash -c run_non_existing_command
echo $?

echo $? не выполняется внутри bash -c.

...