Huckle Huckle - 1 month ago 6
Bash Question

Why is stdin closed when using a heredoc as input to shell

I'm a bit confused by this

$ bash <<EOF
read -p 'This will not work' input
EOF


because

$ cat script
read -p 'This will work fine' input
$ bash script
This will work fine


What's the difference? It appears to be a standard behavior because
ash
behaves exactly the same way.




Based on the answers provided so far, I suspected (and then confirmed) that the following works. I think this is actually what I wanted to do all along, but the
<()
syntax is always one that I forget exists.

$ bash <( cat <<EOF
read -p 'This works' input
EOF
)

Answer

As read is a bash builtin, it inherits stdin from bash as is mentioned above. In the first case bash has a here document as stdin (or more professionally, File Descriptor 0) and there's nothing available for read to read.
read only reads from stdin (fd0) while in the second case, bash opens another file descriptor rather than stdin to read scripts from script, which does NOT conflict with stdin passed to read, so that read can work as intended.

You can try this to test out.
$ bash EOF ls -l /proc/$$/fd EOF
and
$ cat script.sh ls -l /proc/$$/fd $ bash script.sh
The difference is apparent if you compare the outputs from samples bove.

Comments