How to know if data is piped into my script

M

Mahesh Asolkar

I have the following script:

-----
#!/usr/bin/perl

use strict;
use warnings;

my %hist = ();
my @hist;

$hist{(split /\s+/)[3]}++
foreach (`$ENV{'SHELL'} -c history`);

print map {"$hist{$_} : $_\n"}
sort {$hist{$b} <=> $hist{$a}}
keys %hist;
-----

I want to change it such that it uses '`$ENV{'SHELL'} -c history`'
only if nothing is piped into the script. If I call the script like:

% myscript.pl

It should use '`$ENV{'SHELL'} -c history`'. However if it is called
like:

% history | myscript.pl

It should use the piped in data instead.

What would be the best approach?

Thanks,
Mahesh
 
X

xhoster

Mahesh Asolkar said:
I have the following script:

-----
#!/usr/bin/perl

use strict;
use warnings;

my %hist = ();
my @hist;

$hist{(split /\s+/)[3]}++
foreach (`$ENV{'SHELL'} -c history`);

print map {"$hist{$_} : $_\n"}
sort {$hist{$b} <=> $hist{$a}}
keys %hist;
-----

Assuming it is safe to load all input into memory at once:

my @x=<>;
foreach (@x? @x : `$ENV{'SHELL'} -c history`) {

This will do what <> does, not just pipes. If you want only STDIN, and
only when STDIN is hooked up to a pipe, then maybe:

foreach (-p STDIN ? <STDIN> : `$ENV{'SHELL'} -c history`) {


Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
M

Mahesh Asolkar

unless (-t) {
    # STDIN is not opend to a tty but a file or pipe

}

Thanks Frank and Xho. -t and -p do exactly what I was looking for.

Xho, I had tried the first way you suggested too. It works in the case
of 'history | myscript.pl', but it blocks 'myscript.pl' waiting for <>
to return.

Here's the script with the changes (I picked -p):

---------
#!/usr/bin/perl

use strict;
use warnings;

my %hist = ();
my @hist;

$hist{(split /\s+/)[3]}++
foreach ((-p STDIN) ? <STDIN> : `$ENV{'SHELL'} -c history`);

print map {"$hist{$_} : $_\n"}
sort {$hist{$b} <=> $hist{$a}}
keys %hist;
 
N

nntpman68

Hi Makesh,


Small clarification.

-p checks whether input is a pipe
and "-p STDIN" would capture the case:

program | perlscript.pl


whereas -t CHECKS WHETHER input is a terminal.
so "unless -t STDIN" would also capture

perlscript.pl < filename


bye

N


Mahesh said:
unless (-t) {
# STDIN is not opend to a tty but a file or pipe

}

Thanks Frank and Xho. -t and -p do exactly what I was looking for.

Xho, I had tried the first way you suggested too. It works in the case
of 'history | myscript.pl', but it blocks 'myscript.pl' waiting for <>
to return.

Here's the script with the changes (I picked -p):

---------
#!/usr/bin/perl

use strict;
use warnings;

my %hist = ();
my @hist;

$hist{(split /\s+/)[3]}++
foreach ((-p STDIN) ? <STDIN> : `$ENV{'SHELL'} -c history`);

print map {"$hist{$_} : $_\n"}
sort {$hist{$b} <=> $hist{$a}}
keys %hist;
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top