0

Are two here-documents allowed to be used on one line, like in the example below? I was not able to find the documentation and cannot make the example work as expected - seeing output of both echo commands.

$ ssh myhost <<HERE_DOCUMENT_1 <<HERE_DOCUMENT_2
> echo test1
> HERE_DOCUMENT_1
> echo test2
> HERE_DOCUMENT_2
Pseudo-terminal will not be allocated because stdin is not a terminal.
test2

I am trying to get both echo commands to output, so that I can try the solution described here: https://unix.stackexchange.com/questions/4770/quoting-in-ssh-host-foo-and-ssh-host-sudo-su-user-c-foo-type-constructs/102840#102840

So far I see that I'm not getting an error by using two here-documents on the same line, but it is not clear if this is supported.

dabest1
  • 252
  • 1
  • 2
  • 9

1 Answers1

3

It's possible to use multiple here-documents. What you can't do is redirect multiple things to stdin. Try this simpler command for example:

cat </etc/passwd </etc/hostname

It doesn't read both files. What happens is first the shell opens /etc/passwd and puts it on fd 0, replacing the previous fd 0, then it opens /etc/hostname and puts that on fd 0, replacing the /etc/passwd file descriptor without ever having a chance to read it.

The last redirection wins.

Your command would probably work as you intended it if you ran it with zsh, which allows multiple redirections to a single file descriptor when the MULTIOS option is set (it's on by default when not emulating another shell).

In the example you gave, there's really no point to 2 here-documents on stdin. If you want them to be concatenated into a single input, just go ahead and do that right there in the script. All you need to do is remove the first here-document delimiter and the matching redirection. I imagine you must have a more complicated use case in mind for a real application.

For the record, here's an example of multiple here-documents in a single command:

cat /dev/fd/3 /dev/fd/0 <<STDIN_END 3<<OTHER_END
this is first
STDIN_END
this is second
OTHER_END

It will print the second thing first because I put /dev/fd/3 first in cat's arguments, the reverse of the order in which the here-document redirections appear. (If the OTHER_END came before the STDIN_END, it wouldn't be recognized as a here-document terminator because that here-document hasn't started yet.)

I suspect that the answer you linked to in the other question was posted by a zsh user who didn't realize that it didn't work in other shells. I've left a comment there about it.