# Accept sh heredocs to Ruby script

**URL:** <https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738>\
**Category:** Ruby\
**Created:** [July 8, 2009, 3:04pm UTC](https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738 "2009-07-08T15:04:03Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [July 8, 2009, 3:04pm UTC](https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738/1 "2009-07-08T15:04:03Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [July 8, 2009, 3:10pm UTC](https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738/2 "2009-07-08T15:10:09Z")

</div>

Hm, apparently not even git will accept a heredoc:

$ git commit -m \<\<donenow

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

---

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [July 8, 2009, 4:21pm UTC](https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738/3 "2009-07-08T16:21:05Z")

</div>

On 2009-07-08, Oliver S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

---

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [July 8, 2009, 4:29pm UTC](https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738/4 "2009-07-08T16:29:53Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [July 8, 2009, 5:54pm UTC](https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738/5 "2009-07-08T17:54:39Z")

</div>

OK thanks. Mystery solved. 🙂

---

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [July 8, 2009, 5:35pm UTC](https://www.ruby-forum.com/t/accept-sh-heredocs-to-ruby-script/171738/6 "2009-07-08T17:35:55Z")

</div>

> 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
