Accept sh heredocs to Ruby script

In sh, you can do this:

$ cat <<donenow

i
like
jam
donenow
i
like
jam
$

This suggests to me that cat should receive a temporary file as a result
of the heredoc that it can then display similar to the <() construct:

$ cat <(echo ‘pie’)
pie
$ echo <(echo ‘pie’)
/dev/fd/63

So I created a Ruby script called args_test.rb that looks like this:

#!/usr/bin/env ruby
p ARGV

Here it is run with a <() construct.

$ ./args_test.rb <(echo ‘pie’)
["/dev/fd/63"]

All good. But with heredoc you get this:

$ ./args_test.rb <<donenow

i
like
jam
donenow
[]

Can anyone explain this?
I tried this in Io with the same results.

Hm, apparently not even git will accept a heredoc:

$ git commit -m <<donenow

Commiting a file
donenow
error: switch `m’ requires a value

On 2009-07-08, Oliver S. [email protected] wrote:

$ ./args_test.rb <<donenow

i
like
jam
donenow
[]

Can anyone explain this?

The script args_test.rb sees no command line arguments because the shell
didn’t give it any. Instead,

This type of redirection instructs the shell to read input from the
current source until a line containing only WORD (with no trailing
blanks) is seen. All of the lines read up to that point are then
used
as the standard input for a command.

  • from the bash docs about here documents (not specific to bash though).
    The opinion on jam was still available to the script on its standard
    input, but nothing as an argument.

Oliver S. wrote:

$

This suggests to me that cat should receive a temporary file as a result
of the heredoc that it can then display similar to the <() construct:

What leads you to think that << creates a temp file? Maybe the shell is
just piping the heredoc contents to the ruby child process’s stdin?

OK thanks. Mystery solved. :slight_smile:

What leads you to think that << creates a temp file? Maybe the shell is
just piping the heredoc contents to the ruby child process’s stdin?

you’re right:

ruby -e"puts STDIN.gets" <<XYZ

bar
goo
XYZ
bar

Greetz