how to determine if pipe is given

A

ara.t.howard

note that none of these are documented. i think that's because it's
considered
'standard' bahaviour.

oh yeah - nearly forgot my favourite: curl. it's takes about six billion bits
of information optionally on stdin

harp:~ > PAGER=cat man curl|grep -B1 -A1 stdin
file name to read the data from, or - if you want curl to read
the data from stdin. The contents of the file must already be
url-encoded. Multiple files can also be specified. Posting data
--

To read the file's content from stdin insted of a file, use -
where the file name should've been. This goes for both @ and <
--
Specify the filename as '-' to make curl read the file from
stdin.

--

Use the file name "-" (a single dash) to use stdin instead of a
given file.
--
"string", to get read from a particular file you specify it
"@filename" and to tell curl to read the format from stdin you
write "@-".




harp:~ > echo http_code | curl --write-out - http://ruby-lang.org
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://www.ruby-lang.org/">here</a>.</p>
</body></html>


it's even documented - how un-unixish! ;-)

-a
 
G

gwtmp01

not if they work on unix! ;-)

Huh? That is like saying that grep at the end of a pipeline is expected
to be called as:

source | grep 'pattern' -

instead of simply

source | grep 'pattern'
#
# tarfile on stdout
#
harp:~ > tar -cf - directory > tarfile_on_stdout.tgz

Hmm. Tar is a bit of a special case, isn't it? It's default behavior
is to access devices in /dev. You don't need -f, if you are using the
default devices.
# echo foobar into a gzip of stdin, sending compressed output to
stdout, pipe
# that into another gzip which is decompressing stdin, dump that
output back
# out to stdout
#
harp:~ > echo foobar | gzip - -c | gzip -d - -c
foobar

But gzip works just fine without all those extra arguments:

echo foobar | gzip > foobar.gz
echo foobar | gzip | gzip -d -c
# use image magick's convert command to convert stdin -> stdout
#
harp :~ > convert - - < map.png > map2.png
harp :~ > file map2.png
map2.png: PNG image data, 713 x 569, 8-bit/color RGB, non-interlaced

Are you saying that

convert < map.png > map2.png

doesn't work?

If you look back at my posting I said that a program that *requires*
the use of '-'
would be unusual. I understand why some programs support the '-'
notation, which is
still a hack if you've got /dev/stdin or /dev/stdout available.

Maybe I totally missed the point but I thought the OP was making the
requirement that
his program would not bother to read from stdin *unless* it saw
something special on
the command line, which led to your suggestion of the '-'. My point
is that the OP's
requirement would be very unexpected for the usual Unix programmer.
 
A

ara.t.howard

Huh? That is like saying that grep at the end of a pipeline is expected
to be called as:

source | grep 'pattern' -

instead of simply

source | grep 'pattern'

you are right. i'm just saying it's but not uncommon to sentinal stdin via
'-'.
Hmm. Tar is a bit of a special case, isn't it? It's default behavior is to
access devices in /dev. You don't need -f, if you are using the default
devices.

for output yes. for input no.
But gzip works just fine without all those extra arguments:

echo foobar | gzip > foobar.gz
echo foobar | gzip | gzip -d -c

that is true. i'm merely pointing out the standardness of '-', not it's
required-ness...
Are you saying that

convert < map.png > map2.png

doesn't work?

yes.

harp:~ > file map.png
map.png: PNG image data, 640 x 480, 8-bit colormap, non-interlaced

harp:~ > convert < map.png > map2.png

harp:~ > file map2.png
map2.png: ASCII English text

note that the output file is the output of --help. note the last 5 lines ;-)

harp:~ > tail -5 map2.png
By default, the image format of `file' is determined by its magic number. To
specify a particular image format, precede the filename with an image format
name and a colon (i.e. ps:image) or specify the image type as the filename
suffix (i.e. image.ps). Specify 'file' as '-' for standard input or output.

If you look back at my posting I said that a program that *requires* the use
of '-' would be unusual. I understand why some programs support the '-'
notation, which is still a hack if you've got /dev/stdin or /dev/stdout
available.

i personally wouldn't quite call it a hack tough, curl, wget, tar, gzip, image
magic - these are all commands which will compile on many oses. some of them
even compile on windows! ;-)

i suppose it just depends on what kinds of command one is using and in what
kinds of environments with respect to whether one finds '-' odd or not. i run
many things under cron and in a clustered environment and have grown
accustomed to it. i admit it's not common for tty usage.
Maybe I totally missed the point but I thought the OP was making the
requirement that his program would not bother to read from stdin *unless* it
saw something special on the command line, which led to your suggestion of
the '-'. My point is that the OP's requirement would be very unexpected for
the usual Unix programmer.

sorry. you are right here of course. i'm going to bow out of this thread -
the last thing i'll say is that i've been bitten by automatic reading of stdin
and, even though many unix standards do it (cat, gzip, etc) i've noticed newer
and more complicated, eg. curl, programs seemed to have shyed away from it. i
have too, just because it's bitten me with hung programs in a clustered
environment (no tty).

anyhow - this horse is dead! ;-)

kind regards.

-a
 
R

Rick DeNatale

eeeks! that's is pure __evil__!

Yes I agree with this, but...
consider i have many, many programs which do things like

convert infile outfile
convert - outfile # infile on stdin
convert infile - # outfile on stdout
convert - - # infile on stdin, outfile on stdout
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.

mysql> 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)

mysql>


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

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

program </dev/null &
 
G

greg

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
input = STDIN.readlines
end

# do some stuff
# parse some options

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

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

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

puts input

Greg
 
G

greg

small typo there, this is better...

require 'thread'

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

# do some stuff
# parse some options

while t.alive?
old = input
puts "collecting input..." if old

puts "thread running for 1 second"
Kernel.sleep(1)

if old == input
if input
puts "done collecting input"
else
puts "no input found on STDIN"
end
Kernel.sleep(1)
t.kill
break
end
end

puts input
 
G

greg

should be
old = input ? input.dup : nil

However, a duration of time must be specified to wait for the pipe or
timeout. So I guess IO is pain :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,213
Messages
2,571,109
Members
47,702
Latest member
gancflex

Latest Threads

Top