Использование & & после heredoc в bash
у меня есть скрипт bash, команды которого я связываю вместе с помощью &&
, так как я хочу, чтобы скрипт останавливался, если отдельные шаги терпят неудачу.
один из шагов создает файл конфигурации на основе heredoc:
some_command &&
some_command &&
some_command &&
some_command &&
some_command &&
some_command &&
cat > ./my-conf.yml <<-EOF
host: myhost.example.com
... blah blah ...
EOF
... lots more commands ...
как я могу включить эту команду в &&
цепи? Я попробовал:
- помещения
&&
сразу после EOF. Не работает, поскольку EOF должен быть на линии сам по себе. - помещения
&&
в строке сам после EOF. Не работает, потому что баш думает, что я пытаюсь использовать&&
как команду. - помещения
&&
до>
редиректор. Не сработало, так как перенаправители логически являются частью команды&&
- ed.
пояснение:
есть много (многострочных) команд, следующих за командой, которая генерирует конфигурационный файл из heredoc, поэтому в идеале я ищу решение, которое позволяет мне чтобы разместить следующие команды после heredoc, который является естественным потоком сценария. То есть я бы предпочел не иметь встроенных команд 20+ на одной строке.
2 ответов
цепочки команд в одной строке
вы можете поставить пульт управления &&
сразу после EOF
слово документ и вы можете связать более одной команды:
cat > file <<-EOF && echo -n "hello " && echo world
он будет ждать вашего здесь-документа, а затем напечатает Привет, мир.
пример
$ cat > file <<-EOF && echo -n "hello " && echo world
> a
> b
> EOF
hello world
$ cat file
a
b
цепочки команд после помощи heredoc разделитель
теперь, если вы хотите разместить следующие команды после помощи heredoc вы можете группа это в фигурных скобках и продолжить сцепление команды следующим образом:
echo -n "hello " && { cat > file <<-EOF
a
b
EOF
} && echo world
пример
$ echo -n "hello " && { cat > file <<-EOF
> a
> b
> EOF
> } && echo world
hello world
$ cat file
a
b
используя встроенный набор
если вы собираетесь использовать set [-+]e
вместо прикован команды С &&
, вы должны заметить, что вокруг кусок кода с set -e
и set +e
не является прямой альтернативой, и вы должны заботиться, как объясняется ниже:
окружающие зависимые команды с set [-+]e
echo first_command
false # it doesnt stop the execution of the script
# surrounded commands
set -e
echo successful_command_a
false # here stops the execution of the script
echo successful_command_b
set +e
# this command is never reached
echo last_command
как вы можете видеть, если вам нужно продолжать выполнять команды после в окружении команды, это решение не работает.
Объединения Команд спасения
вместо этого вы можете сгруппировать окруженные команды для того, чтобы создать подоболочку следующим образом:
echo first_command
false # it doesnt stop the execution of the script
# surrounded commands executed in a subshell
(
set -e
echo successful_command_a
false # here stops the execution of the group
echo successful_command_b
set +e # actually, this is not needed here
)
# the script is alive here
false # it doesnt stop the execution of the script
echo last_command
Итак, если вам нужно выполнить что-то еще после ваших цепных команд, и вы хотите использовать the set
builtin, рассмотрим примеры выше.
также обратите внимание на следующее о подоболочек:
подстановка команд, команды, сгруппированные в круглые скобки, и асинхронные команды вызываются в среде subshell, которая является дубликатом оболочки среда, за исключением того, что ловушки, пойманные оболочкой, сбрасываются до значений, унаследованных оболочкой от ее родителя при вызове. Встроенные команды, вызываемые как часть конвейера, также выполняются в среде подрешетки. Изменения, внесенные в среду subshell, не могут повлиять на среду выполнения оболочки.
Если вы используете оператор && только для остановки по команде, которая не выполняется и не продолжается, вы можете окружить кусок кода set-e и закрыть set +e. таким образом, вы можете удалить&&, и ваш код, скорее всего, будет выглядеть чище.