Я знаком с этим синтаксисом:
cmd1 << EOF | cmd2
text
EOF
но только что обнаружил, что bash позволяет мне написать:
cmd1 << EOF |
text
EOF
cmd2
(heredoc используется как вход для cmd2). Это похоже на очень странный синтаксис. Он переносится?
Я знаком с этим синтаксисом:
cmd1 << EOF | cmd2
text
EOF
но только что обнаружил, что bash позволяет мне написать:
cmd1 << EOF |
text
EOF
cmd2
(heredoc используется как вход для cmd2). Это похоже на очень странный синтаксис. Он переносится?
Да, стандарт POSIX позволяет это. Согласно версии 2008:
Настоящий документ должен рассматриваться как одно слово, которое начинается после следующий
<newline>
и продолжается до тех пор, пока не будет строка, содержащая только разделитель и<newline>
, без знаков<blank>
между ними. Затем начинается следующий документ, если он есть.
И включает в себя этот пример нескольких "здесь-документов" в одной строке:
cat <<eof1; cat <<eof2
Hi,
eof1
Helene.
eof2
Таким образом, нет проблем с перенаправлением или трубами. Ваш пример похож на что-то вроде этого:
cat file |
cmd
И грамматика оболочки (далее на связанной странице) содержит следующие определения:
pipe_sequence : command
| pipe_sequence '|' linebreak command
newline_list : NEWLINE
| newline_list NEWLINE
;
linebreak : newline_list
| /* empty */
Таким образом, символу трубы может следовать конец строки и по-прежнему считать частью конвейера.
Да, это в грамматике оболочки POSIX. Вы также можете иметь более одного здесь-документа для одной и той же команды (в некоторых других примерах используются две cat
invocations, но это также работает):
cat <<EOF1 <<EOF2
first here-doc
EOF1
second here-doc
EOF2
Это надуманное (с использованием 2 здесь-docs для stdin), но если вы думаете о предоставлении ввода для разных дескрипторов файлов, это сразу имеет смысл.
Также существует возможность полностью отказаться от cat
. Почему бы не сделать доступный здесь-документ доступным для cmd
:
cmd << EOF
input
here
EOF
Хмм, я полагаю, да, согласно тесту в bash в режиме POSIX:
$ bash --posix
$ cat <<EOF |
> ahoj
> nazdar
> EOF
> sed 's/a/b/'
bhoj
nbzdar