# How to determine if pipe is given

**URL:** <https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397>\
**Category:** ruby-talk\
**Created:** [27 September 2006 16:52 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397 "2006-09-27T16:52:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@greg](https://rubytalk.org/u/greg)\
**Post date:** [27 September 2006 16:52 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/1 "2006-09-27T16:52:08Z")

</div>

To retrieve piped input to my program I can use something like  
ARGF.readlines

However, if there is no piped data, this will wait for input from the  
terminal- how can I avoid this?

Thanks,  
Greg Weber

---

<div class="post-metadata">

**Author:** ![Vincent\_Fourmond](https://avatars.discourse-cdn.com/v4/letter/v/cdc98d/32.png) [@Vincent\_Fourmond](https://rubytalk.org/u/Vincent_Fourmond)\
**Post date:** [27 September 2006 16:57 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/2 "2006-09-27T16:57:09Z")

</div>

greg wrote:

> To retrieve piped input to my program I can use something like  
> ARGF.readlines
> 
> However, if there is no piped data, this will wait for input from the  
> terminal- how can I avoid this?

&nbsp;&nbsp;You can check if $stdin is a terminal with

$stdin.tty?

&nbsp;&nbsp;Vince

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [27 September 2006 17:02 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/3 "2006-09-27T17:02:39Z")

</div>

you can do something like

&nbsp;&nbsp;&nbsp;stdin =  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if STDIN.tty?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;''  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDIN.read  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

but that is an extremely bad idea because running the program under cron, or  
even using something like

&nbsp;&nbsp;&nbsp;program &

will cause it to hang

the best/safest approach is to \_\_always\_\_ construct the command-line to give  
clear notice that stdin will be following. the most common way to do this is  
to pass '-' on the command line. for example

&nbsp;&nbsp;&nbsp;program -  
&nbsp;&nbsp;&nbsp;program --verbosity=4 -

etc. then, the code is simple and always correct:

&nbsp;&nbsp;&nbsp;# parse options first

&nbsp;&nbsp;&nbsp;stdin = ARGV.delete '-'

&nbsp;&nbsp;&nbsp;if stdin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = STDIN.read  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ...  
&nbsp;&nbsp;&nbsp;end

regards.

-a

> **···**
>
> On Thu, 28 Sep 2006, greg wrote:
> 
> > To retrieve piped input to my program I can use something like  
> > ARGF.readlines
> > 
> > However, if there is no piped data, this will wait for input from the  
> > terminal- how can I avoid this?
> 
> --  
> in order to be effective truth must penetrate like an arrow - and that is  
> likely to hurt. -- wei wu wei

---

<div class="post-metadata">

**Author:** ![greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@greg](https://rubytalk.org/u/greg)\
**Post date:** [27 September 2006 20:27 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/4 "2006-09-27T20:27:21Z")

</div>

thanks, a

This kind of sucks though.

apparently in perl, if there is a piped input, '-' will show up  
automatically in ARGV. I think I will propose this change to Ruby.

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [27 September 2006 20:42 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/5 "2006-09-27T20:42:48Z")

</div>

> thanks, a
> 
> This kind of sucks though.

why? is this hard?

&nbsp;&nbsp;&nbsp;stdin = ARGV.delete '-'

> apparently in perl, if there is a piped input, '-' will show up  
> automatically in ARGV. I think I will propose this change to Ruby.

eeeks! that's is pure \_\_evil\_\_!

consider i have many, many programs which do things like

&nbsp;&nbsp;&nbsp;convert infile outfile  
&nbsp;&nbsp;&nbsp;convert - outfile # infile on stdin  
&nbsp;&nbsp;&nbsp;convert infile - # outfile on stdout  
&nbsp;&nbsp;&nbsp;convert - - # infile on stdin, outfile on stdout  
&nbsp;&nbsp;&nbsp;convert --infiles=- # list of infiles on stdin, auto-name outfiles

this is standard unix practice (do a man on gzip, tar, etc). now, if ruby  
just started willy nilly adding a '-' to the command line this technique would  
not work because it's not just the existence of '-' but the \_\_position\_\_ of it  
which can have meaning.

auto-munging of ARGV is a bad idea imho.

regards.

-a

> **···**
>
> On Thu, 28 Sep 2006, greg wrote:  
> --  
> in order to be effective truth must penetrate like an arrow - and that is  
> likely to hurt. -- wei wu wei

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [27 September 2006 20:50 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/6 "2006-09-27T20:50:06Z")

</div>

Normally I would just nod my head in agreement with Ara, but not this time.

I just have to say yuck with regard to using '-' and the idea that command lines  
should have have an explicit syntax to indicate that the program should read from  
stdin.

If your program is prepared to deal with piped input, why are  
you concerned about input coming from the keyboard? If I found a program  
that worked as:

&nbsp;&nbsp;cat file | program

and as

&nbsp;&nbsp;program \< file

but did not work as just

&nbsp;&nbsp;program

I would be surprised, to say the least.

Usually the issue is the other way around where an interactive program (vim, for  
example) \*needs\* a tty device on stdin and may complain when STDIN.tty? fails, but  
I'm not sure I understand the need to complain about STDIN being tied to a tty device  
for a program that is just reading a stream of data.

The '-' hack just makes me shudder. Something like '/dev/stdin' would be marginally better  
if you really need something like that (although not as portable).

> **···**
>
> On Sep 27, 2006, at 4:27 PM, greg wrote:
> 
> > thanks, a
> > 
> > This kind of sucks though.
> > 
> > apparently in perl, if there is a piped input, '-' will show up  
> > automatically in ARGV. I think I will propose this change to Ruby.

---

<div class="post-metadata">

**Author:** ![Paul\_Lutus](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@Paul\_Lutus](https://rubytalk.org/u/Paul_Lutus)\
**Post date:** [27 September 2006 20:50 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/7 "2006-09-27T20:50:15Z")

</div>

greg wrote:

> thanks, a
> 
> This kind of sucks though.

Why? One performs a test to determine if there is a pipe. That seems  
reasonable.

> apparently in perl, if there is a piped input, '-' will show up  
> automatically in ARGV.

Have you done an experiment to see if this is true? In fact, the user of the  
script must provide this symbol as an argument if he wants the read a pipe,  
then the script must interpret the presence of this symbol as a signal to  
commence reading a pipe, by the way a very common \*nix convention. It's all  
very non-automatic.

> I think I will propose this change to Ruby.

No sense doing it in Ruby if it isn't done in Perl. It isn't done in Perl.

> **···**
>
> --  
> Paul Lutus  
> [http://www.arachnoid.com](http://www.arachnoid.com)

---

<div class="post-metadata">

**Author:** ![Paul\_Lutus](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@Paul\_Lutus](https://rubytalk.org/u/Paul_Lutus)\
**Post date:** [27 September 2006 20:55 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/8 "2006-09-27T20:55:26Z")

</div>

/ ...

> > apparently in perl, if there is a piped input, '-' will show up  
> > automatically in ARGV. I think I will propose this change to Ruby.
> 
> eeeks! that's is pure \_\_evil\_\_!

It also isn't true. IMHO Larry Wall wouldn't countenance such a thing.

> **···**
>
> ara.t.howard@noaa.gov wrote:
> 
> --  
> Paul Lutus  
> [http://www.arachnoid.com](http://www.arachnoid.com)

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [27 September 2006 20:56 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/9 "2006-09-27T20:56:25Z")

</div>

> consider i have many, many programs which do things like
> 
> &nbsp;&nbsp;convert infile outfile  
> &nbsp;&nbsp;convert - outfile # infile on stdin  
> &nbsp;&nbsp;convert infile - # outfile on stdout  
> &nbsp;&nbsp;convert - - # infile on stdin, outfile on stdout  
> &nbsp;&nbsp;convert --infiles=- # list of infiles on stdin, auto-name outfiles

While I understand the historical reason for such constructs, I much prefer:

&nbsp;&nbsp;&nbsp;convert infile outfile  
&nbsp;&nbsp;&nbsp;convert /dev/stdin outfile # infile on stdin  
&nbsp;&nbsp;&nbsp;convert infile /dev/stdout # outfile on stdout  
&nbsp;&nbsp;&nbsp;convert # infile on stdin, outfile on stdout

> &nbsp;&nbsp;convert --infiles=- # list of infiles on stdin, auto-name outfiles

Not sure about this last one. It certainly isn't all that common. You can get close  
to this via:

&nbsp;&nbsp;&nbsp;cat filenames | xargs convert

with maybe an option to convert to cause it to send output to auto-named outfiles:

&nbsp;&nbsp;&nbsp;cat filenames | xargs convert --inplace

I realize that some Unix systems don't support /dev/stdin, /dev/stdout, though...

Gary Wright

> **···**
>
> On Sep 27, 2006, at 4:42 PM, ara.t.howard@noaa.gov wrote:

---

<div class="post-metadata">

**Author:** ![greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@greg](https://rubytalk.org/u/greg)\
**Post date:** [27 September 2006 21:25 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/10 "2006-09-27T21:25:08Z")

</div>

sorry, misread some perl stuff.

How about a global flag or constant  
like $PIPE set to true if there is a pipe, and otherwise set to false?

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [27 September 2006 21:50 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/11 "2006-09-27T21:50:03Z")

</div>

it may well work, but hang forever in cron though:

this is as easy to do as

&nbsp;&nbsp;&nbsp;infile = get\_infile # oops, returned nil  
&nbsp;&nbsp;&nbsp;system "program #{ infile }" # hangs forever

that's also very problematic for prorgams which take two arguments:

&nbsp;&nbsp;&nbsp;cat infile | program - outfile  
&nbsp;&nbsp;&nbsp;cat infile | program - - | outfile\_filter \> outfile

note that you cannot simply say that the abscence of infile means stdin and  
similar for outfile because

&nbsp;&nbsp;&nbsp;program infile\_or\_outfile?

i'm sure one could skin this differently, i just have debugged many hung  
processes that make assumptions based on STDIN.tty?

kind regards.

-a

> **···**
>
> On Thu, 28 Sep 2006 gwtmp01@mac.com wrote:
> 
> > If your program is prepared to deal with piped input, why are you concerned  
> > about input coming from the keyboard? If I found a program that worked as:
> > 
> > &nbsp;&nbsp;cat file | program
> > 
> > and as
> > 
> > &nbsp;&nbsp;program \< file
> > 
> > but did not work as just
> > 
> > &nbsp;&nbsp;program
> 
> --  
> in order to be effective truth must penetrate like an arrow - and that is  
> likely to hurt. -- wei wu wei

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [28 September 2006 22:43 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/12 "2006-09-28T22:43:54Z")

</div>

> \> apparently in perl, if there is a piped input, '-' will show up  
> \> automatically in ARGV. I think I will propose this change to Ruby.
> 
> eeeks! that's is pure \_\_evil\_\_!

Yes I agree with this, but...

> consider i have many, many programs which do things like
> 
> &nbsp;&nbsp;&nbsp;convert infile outfile  
> &nbsp;&nbsp;&nbsp;convert - outfile # infile on stdin  
> &nbsp;&nbsp;&nbsp;convert infile - # outfile on stdout  
> &nbsp;&nbsp;&nbsp;convert - - # infile on stdin, outfile on stdout  
> &nbsp;&nbsp;&nbsp;convert --infiles=- # list of infiles on stdin, auto-name outfiles
> 
> this is standard unix practice (do a man on gzip, tar, etc).

Standard but by no means universal. For example the mysql command  
doesn't use or like it:

rick@frodo:/public/rubyscripts$ mysql -p -  
Enter password:  
ERROR 1049 (42000): Unknown database '-'

It either tries to use - as the database name or:

rick@frodo:/public/rubyscripts$ mysql -p depot\_development -  
mysql Ver 14.12 Distrib 5.0.22, for pc-linux-gnu (i486) using readline 5.1  
...  
Usage: mysql [OPTIONS] [database]

It tells me that I don't know the right syntax.

I don't think that it has been mentioned here that one reason for  
detecting what's connected to stdin/stdout is useful when a tool  
want's to have interactive and non-interactive modes:

Here's mysql in non-interactive mode:

rick@frodo:/public/rubyscripts$ echo "describe products;" | mysql -p  
depot\_development  
Enter password:  
Field Type Null Key Default Extra  
id int(11) NO PRI NULL auto\_increment  
title varchar(255) YES NULL  
description text YES NULL  
image\_url varchar(255) YES NULL  
price decimal(8,2) YES 0.00  
rick@frodo:/public/rubyscripts$

And here it is in interactive mode:  
rick@frodo:/public/rubyscripts$ mysql -p depot\_development  
Enter password:  
Reading table information for completion of table and column names  
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor. Commands end with ; or \g.  
Your MySQL connection id is 5691 to server version:  
5.0.22-Debian\_0ubuntu6.06-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

> **···**
>
> On 9/27/06, ara.t.howard@noaa.gov \<ara.t.howard@noaa.gov\> wrote:
> 
> > describe products;
> 
> +-------------+--------------+------+-----+---------+----------------+
> 
> > Field | Type | Null | Key | Default | Extra |
> 
> +-------------+--------------+------+-----+---------+----------------+
> 
> > id | int(11) | NO | PRI | NULL | auto\_increment |  
> > title | varchar(255) | YES | | NULL | |  
> > description | text | YES | | NULL | |  
> > image\_url | varchar(255) | YES | | NULL | |  
> > price | decimal(8,2) | YES | | 0.00 | |
> 
> +-------------+--------------+------+-----+---------+----------------+  
> 5 rows in set (0.01 sec)
> 
> Note that it not only puts out prompts but it changes the output to  
> be for human rather than computer consumption.
> 
> > auto-munging of ARGV is a bad idea imho.
> 
> I agree but for other reasons.
> 
> As for programs hanging if you do
> 
> &nbsp;&nbsp;&nbsp;program &
> 
> Well, that's really a user error, and maybe even not that, maybe I  
> want to suspend program and then use fg to resume it.
> 
> And - doesn't really help this. I think that it's better in most  
> cases to solve it the other way around with something like
> 
> &nbsp;&nbsp;&nbsp;program \</dev/null &
> 
> --  
> Rick DeNatale
> 
> My blog on Ruby  
> [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![Paul\_Lutus](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@Paul\_Lutus](https://rubytalk.org/u/Paul_Lutus)\
**Post date:** [27 September 2006 21:50 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/13 "2006-09-27T21:50:22Z")

</div>

greg wrote:

> sorry, misread some perl stuff.
> 
> How about a global flag or constant  
> like $PIPE set to true if there is a pipe, and otherwise set to false?

Are you asking whether this is true, or whether it would be a good idea? If  
the latter, I personally think stuff like this should be explicitly coded  
by the programmer. There are situations where detecting the  
presence/absence of a pipe may have side effects best avoided.

Of course, reasonable people may (will) differ.

> **···**
>
> --  
> Paul Lutus  
> [http://www.arachnoid.com](http://www.arachnoid.com)

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [27 September 2006 21:50 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/14 "2006-09-27T21:50:48Z")

</div>

thanks - that's good to know. larry++.

-a

> **···**
>
> On Thu, 28 Sep 2006, Paul Lutus wrote:
> 
> > ara.t.howard@noaa.gov wrote:
> > 
> > / ...
> > 
> > > > apparently in perl, if there is a piped input, '-' will show up  
> > > > automatically in ARGV. I think I will propose this change to Ruby.
> > > 
> > > eeeks! that's is pure \_\_evil\_\_!
> > 
> > It also isn't true. IMHO Larry Wall wouldn't countenance such a thing.
> 
> --  
> in order to be effective truth must penetrate like an arrow - and that is  
> likely to hurt. -- wei wu wei

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [27 September 2006 21:55 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/15 "2006-09-27T21:55:02Z")

</div>

> > consider i have many, many programs which do things like
> > 
> > &nbsp;&nbsp;convert infile outfile  
> > &nbsp;&nbsp;convert - outfile # infile on stdin  
> > &nbsp;&nbsp;convert infile - # outfile on stdout  
> > &nbsp;&nbsp;convert - - # infile on stdin, outfile on stdout  
> > &nbsp;&nbsp;convert --infiles=- # list of infiles on stdin, auto-name outfiles
> 
> While I understand the historical reason for such constructs, I much prefer:
> 
> convert infile outfile  
> convert /dev/stdin outfile # infile on stdin  
> convert infile /dev/stdout # outfile on stdout  
> convert # infile on stdin, outfile on stdout

agreed.

> > &nbsp;&nbsp;convert --infiles=- # list of infiles on stdin, auto-name outfiles
> 
> Not sure about this last one. It certainly isn't all that common. You can  
> get close to this via:

&nbsp;&nbsp;&nbsp;harp:~ \> printf "stdin\nstdout\nstderr\n" | grep -i -f- a.rb  
&nbsp;&nbsp;&nbsp;STDERR.puts "#{ msg } (#{ tid })"  
&nbsp;&nbsp;&nbsp;STDIN.gets

we have lots of code that does this because they take thousands of infiles,  
hdrfiles, etc...

cheers.

-a

> **···**
>
> On Thu, 28 Sep 2006 gwtmp01@mac.com wrote:
> 
> > On Sep 27, 2006, at 4:42 PM, ara.t.howard@noaa.gov wrote:
> 
> --  
> in order to be effective truth must penetrate like an arrow - and that is  
> likely to hurt. -- wei wu wei

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [27 September 2006 21:55 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/16 "2006-09-27T21:55:26Z")

</div>

STDIN.tty?

-a

> **···**
>
> On Thu, 28 Sep 2006, greg wrote:
> 
> > sorry, misread some perl stuff.
> > 
> > How about a global flag or constant  
> > like $PIPE set to true if there is a pipe, and otherwise set to false?
> 
> --  
> in order to be effective truth must penetrate like an arrow - and that is  
> likely to hurt. -- wei wu wei

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [28 September 2006 02:16 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/17 "2006-09-28T02:16:53Z")

</div>

> it may well work, but hang forever in cron though:

Hmm. Doesn't cron arrange for stdin and stdout to be /dev/null, in which case  
the read will simply return EOF, correct?

I just tried some experiments on Mac OS X and it seems that cron arranges for  
stdin to be an empty pipe for cron jobs.

In any case, clearly the program has been invoked incorrectly for that  
context (background cron job) and it pretty much doesn't matter what structure  
you choose for the command line arguments it is always possible to screw it  
up and provide the wrong arguments or plumb the wrong input or output sources.

> i'm sure one could skin this differently, i just have debugged many hung  
> processes that make assumptions based on STDIN.tty?

I'm not sure I understand. The OP was suggesting that the program was designed  
to read from a pipe, so it really shouldn't care if it was reading from a tty  
device, should it?

I think of this like duck typing in Ruby. As long as you can read lines  
from the file descriptor and your program is designed to read lines of text,  
should you really care if stdin is associated with a file, a pipe, a network  
connection, or a tty device? Why not just read and process the data?

Gary Wright

> **···**
>
> On Sep 27, 2006, at 5:50 PM, ara.t.howard@noaa.gov wrote:

---

<div class="post-metadata">

**Author:** ![greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@greg](https://rubytalk.org/u/greg)\
**Post date:** [29 September 2006 11:58 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/18 "2006-09-29T11:58:08Z")

</div>

Thanks for all the info guys. Here is what I came up with.  
This code seems invincible so far- it even works with &

require 'thread'

input = nil  
t = Thread.new() do  
&nbsp;&nbsp;&nbsp;input = STDIN.readlines  
end

# do some stuff  
# parse some options

while t.alive?  
&nbsp;&nbsp;&nbsp;old = input  
&nbsp;&nbsp;&nbsp;puts "thread running for 1 second"  
&nbsp;&nbsp;&nbsp;Kernel.sleep(1)

&nbsp;&nbsp;&nbsp;if old == input  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if input  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "done collecting input"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "no input found on STDIN"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kernel.sleep(1)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.kill  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break  
&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "done collecting input"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kernel.sleep(1)  
&nbsp;&nbsp;&nbsp;end  
end

puts input

Greg

---

<div class="post-metadata">

**Author:** ![greg](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@greg](https://rubytalk.org/u/greg)\
**Post date:** [27 September 2006 23:42 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/19 "2006-09-27T23:42:58Z")

</div>

Didn't you just say that this is a bad idea because of program & and  
other cases?

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [28 September 2006 02:55 UTC](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397/20 "2006-09-28T02:55:57Z")

</div>

> Hmm. Doesn't cron arrange for stdin and stdout to be /dev/null, in which  
> case the read will simply return EOF, correct?
> 
> I just tried some experiments on Mac OS X and it seems that cron arranges  
> for stdin to be an empty pipe for cron jobs.

hmmm. you are right. i had to look back at what had given me trouble before  
- the crux of it was basically this

&nbsp;&nbsp;&nbsp;input\_on\_stdin = not STDIN.tty?

&nbsp;&nbsp;&nbsp;infile =  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if input\_on\_stdin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDIN.read  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

so, basically assuming that the user gave input on stdin simply because STDIN  
was not a tty, which may or may not be true, as in the case where one is  
running under cron or a system call from a daemon, etc.

i guess my point is that

&nbsp;&nbsp;&nbsp;'stdin is not a tty'

and

&nbsp;&nbsp;&nbsp;'input was given on stdin'

are two orthogonal ideas which, when merged, have bitten me in the past. so  
that's why i've developed a preference for '-' to signal input on stdin - it's  
non-ambiguous.

> In any case, clearly the program has been invoked incorrectly for that  
> context (background cron job) and it pretty much doesn't matter what  
> structure you choose for the command line arguments it is always possible to  
> screw it up and provide the wrong arguments or plumb the wrong input or  
> output sources.

indeed.

> I'm not sure I understand. The OP was suggesting that the program was  
> designed to read from a pipe, so it really shouldn't care if it was reading  
> from a tty device, should it?

well - that is true. maybe i confused things by making it more general. the  
only reason i was making a fuss is that it's caused me problems - as i  
mentioned. probably the noise wasn't worth it.

> I think of this like duck typing in Ruby. As long as you can read lines  
> from the file descriptor and your program is designed to read lines of text,  
> should you really care if stdin is associated with a file, a pipe, a network  
> connection, or a tty device? Why not just read and process the data?

i think that you are quite right in this case.

cheers.

-a

> **···**
>
> On Thu, 28 Sep 2006 gwtmp01@mac.com wrote:  
> --  
> in order to be effective truth must penetrate like an arrow - and that is  
> likely to hurt. -- wei wu wei

[Next page](https://rubytalk.org/t/how-to-determine-if-pipe-is-given/31397.md?page=2)
