There are multiple ways to do this. The simplest is probably this:
cat <<EOF | sh
touch somefile
echo foo > somefile
EOF
Another, which is nicer syntax in my opinion:
(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh
This works as well, but without the subshell:
{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh
More variations:
cat <<EOF |
touch somefile
echo foo > somefile
EOF
sh
Or:
{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF
By the way, I expect the use of cat
in your question is a placeholder for something else. If not, take it out, like this:
sh <<EOF
touch somefile
echo foo > somefile
EOF
Which could be simplified to this:
sh -c 'touch somefile; echo foo > somefile'
or:
sh -c 'touch somefile
echo foo > somefile'
Redirecting output instead of piping
sh >out <<EOF
touch somefile
echo foo > somefile
EOF
Using cat
to get the equivalent of echo test > out
:
cat >out <<EOF
test
EOF
Multiple Here Documents
( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2
This produces the output:
hi
---
there
Here's what's going on:
- The shell sees the
( ... )
and runs the enclosed commands in a subshell.
- The cat and echo are simple enough. The
cat <&3
says to run cat with file descriptor (fd) 0 (stdin) redirected from fd 3; in other words, cat out the input from fd 3.
- Before the
(...)
is started, the shell sees the two here document redirects and substitutes fd 0 (<<EOF
) and fd 3 (3<<EOF2
) with the read-side of pipes
- Once the initial command is started, the shell reads its stdin until EOF is reached and sends that to the write-side of the first pipe
- Next, it does the same with EOF2 and the write-side of the second pipe
Best Answer
You're redirecting
tee
's input, notbash
's. Use:A few more examples to illustrate how it works:
Redirecting compound commands:
Or:
You can reuse the same ending token:
As to why the first
history
command is run in that newbash
in:That is because
bash
stdin is still the terminal, but its stdout is a dead pipe (at the other end of the pipe,tee
has redirected its stdin from that delete temp file, so the reading end of that pipe is closed).bash
doesn't write its prompt or the echo of what you type on its stdout (the dead pipe), but to the terminal, so thatbash
will let you enterhistory
at a first prompt.However, that
history
(which is a builtin, so executed by thebash
process, not a child), will write its output to that dead pipe. When doing so, thebash
process will receive a SIGPIPE signal (since there's no reader) and die.The next prompt will be issued by the calling shell.