APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed
RSS Feeds RSS Feeds











(OLDER) <- More Stuff -> (NEWER) (NEWEST)
Printer Friendly Version
->
-> Basic perl input/output




Perl Input


Perl has wonderful I/O capabilities. I'm only going to cover input here: reading from files or standard input. There are two ways to do that (actually a lot more than two, but this is supposed to be introductory material): you can open a specific file, or you can pass files on the command line and either open them individually or just ignore the whole thing and pretend everything is coming from STDIN.

Let's just take a look at some simple examples. Create files a, b and c with text you will recognize, and try this:


#!/usr/bin/perl
open(F,"a");
while (<F>) {
  print;
}
 

Run that and "a" will be displayed. That was easy enough. Now the command line way:

#!/usr/bin/perl
foreach (@ARGV) {
  open(F,$_);
  while (<F>) {
    print;
  }
}
 

If you called that t.pl, run ./t.pl a b c and you'll see each of your files go by. Notice that I didn't bother to close F. There are cases where being sloppy like that could get you in trouble, but in this simple situation, Perl happily closes the previous file for you when it sees you re-using F.

Now the magic angle bracket way:

#!/usr/bin/perl
while (<>) {
 print;
}
 

Try that both by itself (type lines to it), and as ./t.pl a b c, and finally as cat a b c | ./t.pl. You'll see that whatever you do, it reads the lines or the files. When you give it file names, they act like they came from STDIN. If you don't, it reads STDIN. If you want to read BOTH the files and STDIN, do ./t.pl a b c -.

If you want, you can do things when each file ends:

#!/usr/bin/perl
while (<>) {
 print;
 print "--- End of $ARGV ----\n" if eof;
}
 

And of course you can accumulate all the lines instead:

#!/usr/bin/perl
@lines=(<>) ;
.. do stuff
print @lines;
 

Now we're going to get much trickier. We're not going to read unless there is something ready to read. This can be useful if you need to do other things while waiting for input, or if you don't want lack of input to hold you up forever. The code will use Perl's "select" command, which just passes to the system level select() call. Perl's "select" is one of those overloaded functions that does very different things depending on how many arguments you give it, so don't get confused here. This is the usage that tells us whether or not filehandles are ready for io. We also use the "fileno" command to get the actual file number of STDIN. The "vec" is used to turn "$rin" into a bit structure that is what the system level select() is looking for; if STDIN is file number 0 as it would be if not redirected, then the first bit of $rin get sets to 1 before we call the Perl select (you don't have to understand that to use it). The structure gets changed by select(), so we protect it with the "$rout=$rin"; $rout will get changed, not $rin. It all sounds very complicated, but it really isn't bad in usage:

#!/usr/bin/perl
$rin="";
vec($rin,fileno(STDIN),1)=1;
while (1) {
sleep 2;
$nfound=select($rout=$rin,"","",1);
print "$nfound $what\n";
$what="";
$what=<>if ($nfound) ;
}
 

(I'm making this code artificially simple. This works, but isn't the way you would probably do it in reality.)

Try that first with just ./t.pl. You'll see it print 0 every two seconds. If you type something, it only gets read when you press enter (buffered input). Use CTRL-C or your INTR character to quit this.

0 
0 
0 
hello
1 
0 hello

0 
0 
 

Now try it like this: ./t.pl a. My "a" contains "This is A":

0 
0 
0 
hello
1 
1 This is A

1 
0 hello

0 
 

Nothing happened until we gave it a line on STDIN. Then, and only then, did Perl rearrange things so that the file "a" came through STDIN before our line. That makes sense, because until you try to read STDIN, Perl has no idea what your intentions toward the files on the command line are. You might want to process them specifically as we did in the second little script.

Single character input is a little trickier, because you first need to convince your OS that it should be feeding you that way. Exactly how you do that depends on the heritage of your system; it's going to be a "stty" command of some sort. This works on my Mac OS X box:

#!/usr/bin/perl
system "stty cbreak < /dev/tty > /dev/tty 2>&1";
while (($key=getc) ) {
  print "$key\n";
  last if $key eq "q";
};
system "stty -cbreak < /dev/tty > /dev/tty 2>&1";
 

The angle brackets have one more trick up their sleeves:

foreach (<[a-c]*;>) {
  open(F,$_);
  while (<F>) {
    print;
  }
}
 

That opens every file that begins with "a", "b' or "c". Use any wild card characters you need just like you would at the command line.

This should give you some feel for the flexibility of Perl input.




If this page was useful to you, please help others find it:  





10 comments




More Articles by - Find me on Google+



Click here to add your comments
- no registration needed!







Tue Jun 29 20:10:00 2010: 8759   Anonymous

gravatar


Does the following look OK?

#! perl
print "content-type: text/html\n\n";
my$STDIN=<STDIN>;

When called in a browser from MS's IIS6, the page hangs and does a continuous load.



Tue Jun 29 20:21:46 2010: 8760   TonyLawrence

gravatar


Of course it does. Where is STDIN? There isn't any for the browser.



Thu Jul 1 00:34:29 2010: 8765   anonymous

gravatar


Re: Of course it does. Where is STDIN? There isn't any for the browser.

Why should calling
#!perl
my$stdin=<STDIN>;
(from a server using windows 2003, IIS 6, and perl 5.008008),
cause the page to hang and do a continuous load,
when the page is called in a browser.

my$stdin is not being printed (e.g. print $stdin;).

If <STDIN> is undefined, then I believe $stdin=<STDIN> would be also be undefined, and calling the page would just display a blank page.

To expand my examples,
I am getting the same problem after I send something to $stdin...

#! perl
my$stdin=<STDIN>;
print $stdin;

... from an html page using <form src="my_stdin.pl" method="post"><input type="text" name="TEXT"><input type="submit"></form>.

The page just hangs and does a continuous load.

I'm believing it is the configuration of the IIS 6 server.

What is your opinion about this ?

- Look For God.








Thu Jul 1 09:42:40 2010: 8767   TonyLawrence

gravatar


You can look look for gods all you want, but you are simply wasting your time.

You are also wasting your time with this stupidity. See http://www.infoqu.com/dev/perl-programming/cannot-read-stdin-from-html-form-76763-1/



Fri Nov 5 03:14:08 2010: 9098   anonymous

gravatar


why didn't run
my $in="";
foraeach ( @choose )
{
$in =<>;
# but - on this time -> $in is empty!?
if ( $in eq "yes")
{
#do somthings!!!
#
}






Fri Nov 5 09:57:02 2010: 9100   TonyLawrence

gravatar


$n must be stripped of its line ending - chomp $n.

Or (better)

if ($n =~ /^yes/i);

to accept either upper or lower case.








Fri Nov 5 15:15:53 2010: 9101   anonymous

gravatar


Sry, but..
foreach (@choose)
{
$in =<>; # -> e.g. yes
# $in is empty
print $in; # stdout print nothing
}







Fri Nov 5 19:46:30 2010: 9102   TonyLawrence

gravatar


Perhaps you need to explain what you think you are trying to do. Your code loops through @choose, but does nothing with it. You then read $in for stdin.

So??







Fri Apr 8 05:43:02 2011: 9436   anonymous

gravatar


How to read the information from the Asterisk CLI mode using STDIN in the perl scripting






Fri Apr 8 11:39:05 2011: 9437   TonyLawrence

gravatar


"How to read the information from the Asterisk CLI mode using STDIN in the perl scripting "

Look at http://aplawrence.com/BGarlock/logger.html by Bruce Garlock

Don't miss responses! Subscribe to Comments by RSS or by Email

Click here to add your comments


If you want a picture to show with your comment, go get a Gravatar

Kerio Samepage


Have you tried Searching this site?

Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.

Publishing your articles here

Jump to Comments



Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.

I am a Kerio reseller. Articles here related to Kerio products reflect my honest opinion, but I do have an obvious interest in selling those products also.

Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.

We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.

pavatar.jpg

This post tagged:

       - Code
       - Perl
       - Popular
       - Programming



















My Troubleshooting E-Book will show you how to solve tough problems on Linux and Unix systems!


book graphic unix and linux troubleshooting guide



Buy Kerio from a dealer
who knows tech:
I sell and support

Kerio Connect Mail server, Control, Workspace and Operator licenses and subscription renewals



Click and enter your name and phone number to call me about Kerio® products right now (Flash required)