Можно ли использовать несколько документов здесь в Bash?

14

Можно ли использовать несколько here-документов для ввода команды в bash?

$ cat <<<foo <<<bar
bar
$ cat <<EOF1 <<EOF2
> foo
> EOF1
> bar
> EOF2
bar

Очевидно, что в обоих случаях второй here-документ используется как stdin и заменяет первую ссылку. Является ли решение использовать echos вместо?

$ cat <(echo -n foo) <(echo bar)
foobar

Кроме того, по какой-то причине использование комбинации не работает для меня. С чего бы это?

$ cat <<<foo <(echo bar)
bar
$ cat <(echo -n foo) <<<bar
foo
Sparhawk
источник
Есть ли причина того, что вы хотите использовать два документа здесь, а не объединять их в один?
бобы
1
@ Beans Я действительно столкнулся с этим при тестировании pasteс фиктивными входами. Я полагаю, я могу придумать несколько других сценариев. Если бы у меня был сценарий с предварительно обработанным текстом в нескольких переменных, я мог бы захотеть сделать что-то для обоих с помощью команды, которая, например, принимает только файлы diff.
Sparhawk
Другой вариант использования (я нашел это , используя здесь-документы , чтобы создать сценарий оболочки): вы хотите несколько строк с подстановкой переменных , а затем некоторые строки без: cat <<EOF1 <<"EOF2".
Тоби Спейт

Ответы:

18

Ты можешь сделать:

cat /dev/fd/3 3<< E1 /dev/fd/4 4<< E2
foo
E1
bar
E2

Может быть только один стандартный ввод, так как существует только один дескриптор файла 0.

cat << EOF
eof
EOF

это сокращение от:

cat /dev/fd/0 0<< EOF
eof
EOF

И:

cat <<< foo

является:

cat /dev/fd/0 0<<< foo

Вы должны решить, что открыть по дескриптору файла 0.

cat <(echo foo)

Является:

cat /dev/fd/123

Где 123дескриптор файла для канала, и параллельно bash запускается echo fooв другом процессе с stdout, перенаправленным на другой конец канала.

Как только вы передадите имя файла cat, catбольше не читайте из стандартного ввода. Вам нужно:

cat <(echo foo) /dev/fd/0 << EOF
bar
EOF

Или:

cat <(echo foo) - << EOF
bar
EOF

( -это сказать, catчтобы читать из стандартного ввода).

Стефан Шазелас
источник
1
cat <<EOFне совсем то же самое cat /dev/fd/0...: в последнем случае catвидит имя файла и открывает.
Микел
@Mikel, я имел в виду, что это функционально эквивалентно . Если не передан какой-либо аргумент, catсчитывается из его fd0, как если бы передан аргумент -или /dev/fd/0(хотя в Linux (и только в Linux)) открытие /dev/fd/0не совсем похоже на дублирование дескриптора файла 0).
Стефан Шазелас
Я был очень удивлен /dev/fd/3 3<< E1конструкцией, и мне интересно, что именно это за элементы в / dev / fd /. Хотя они каким-то волшебным образом выглядят после того, как процесс открывает файл где-то в файловой системе, за исключением 1 и 2, которые существуют по умолчанию для каждого процесса. Но в вашем примере вы используете файловые дескрипторы 3 и 4, которые не связаны ни с каким реальным файлом, кроме перенаправления ввода. Я не могу понять это в моей ментальной модели файловых дескрипторов. Что если процесс захочет открыть другой файл, узнает ли он, что должен использовать fd 5? Должны ли fds быть 3, 4, 5 .. или может быть что угодно?
calavera.info
@ calavera.info, похоже, вы хотите создать дополнительный вопрос.
Стефан Шазелас