Provided by:
manpages-zh_1.5.2-1_all 
NAME
perlfaq8 - (2003/01/26 17:44:04 )
DESCRIPTION
Perl FAQ (IPC) ()
perl FAQ (perlvms,perlplan9...) perl
exec() ?
system()
Keyboard
Term::Cap
Term::ReadKey CPAN
Term::ReadLine::Gnu CPAN
Term::ReadLine::Perl CPAN
Term::Screen CPAN
Screen
Term::Cap
Curses CPAN
Term::ANSIColor CPAN
Mouse
Tk CPAN
Some of these specific cases are shown below.
How do I print something out in color?
In general, you don't, because you don't know whether the recipient has
a color-aware display device. If you know that they have an ANSI
terminal that understands color, you can use the Term::ANSIColor module
from CPAN:
use Term::ANSIColor;
print color("red"), "Stop!\n", color("reset");
print color("green"), "Go!\n", color("reset");
Or like this:
use Term::ANSIColor qw(:constants);
print RED, "Stop!\n", RESET;
print GREEN, "Go!\n", RESET;
How do I read just one key without waiting for a return key?
Controlling input buffering is a remarkably system-dependent matter.
On many systems, you can just use the stty command as shown in "getc"
in perlfunc, but as you see, that's already getting you into
portability snags.
open(TTY, "+</dev/tty") or die "no tty: $!";
system "stty cbreak </dev/tty >/dev/tty 2>&1";
$key = getc(TTY); # perhaps this works
# OR ELSE
sysread(TTY, $key, 1); # probably this does
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
The Term::ReadKey module from CPAN offers an easy-to-use interface that
should be more efficient than shelling out to stty for each key. It
even includes limited support for Windows.
use Term::ReadKey;
ReadMode('cbreak');
$key = ReadKey(0);
ReadMode('normal');
However, using the code requires that you have a working C compiler and
can use it to build and install a CPAN module. Here's a solution using
the standard POSIX module, which is already on your systems (assuming
your system supports POSIX).
use HotKey;
$key = readkey();
And here's the HotKey module, which hides the somewhat mystifying calls
to manipulate the POSIX termios structures.
# HotKey.pm
package HotKey;
@ISA = qw(Exporter);
@EXPORT = qw(cbreak cooked readkey);
use strict;
use POSIX qw(:termios_h);
my ($term, $oterm, $echo, $noecho, $fd_stdin);
$fd_stdin = fileno(STDIN);
$term = POSIX::Termios->new();
$term->getattr($fd_stdin);
$oterm = $term->getlflag();
$echo = ECHO | ECHOK | ICANON;
$noecho = $oterm & ~$echo;
sub cbreak {
$term->setlflag($noecho); # ok, so i don't want echo either
$term->setcc(VTIME, 1);
$term->setattr($fd_stdin, TCSANOW);
}
sub cooked {
$term->setlflag($oterm);
$term->setcc(VTIME, 0);
$term->setattr($fd_stdin, TCSANOW);
}
sub readkey {
my $key = '';
cbreak();
sysread(STDIN, $key, 1);
cooked();
return $key;
}
END { cooked() }
1;
How do I check whether input is ready on the keyboard?
The easiest way to do this is to read a key in nonblocking mode with
the Term::ReadKey module from CPAN, passing it an argument of -1 to
indicate not to block:
use Term::ReadKey;
ReadMode('cbreak');
if (defined ($char = ReadKey(-1)) ) {
# input was waiting and it was $char
} else {
# no input was waiting
}
ReadMode('normal'); # restore normal tty settings
How do I clear the screen?
If you only have do so infrequently, use "system":
system("clear");
If you have to do this a lot, save the clear string so you can print it
100 times without calling a program 100 times:
$clear_string = `clear`;
print $clear_string;
If you're planning on doing other screen manipulations, like cursor
positions, etc, you might wish to use Term::Cap module:
use Term::Cap;
$terminal = Term::Cap->Tgetent( {OSPEED => 9600} );
$clear_string = $terminal->Tputs('cl');
How do I get the screen size?
If you have Term::ReadKey module installed from CPAN, you can use it to
fetch the width and height in characters and in pixels:
use Term::ReadKey;
($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
This is more portable than the raw "ioctl", but not as illustrative:
require 'sys/ioctl.ph';
die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
open(TTY, "+</dev/tty") or die "No tty: $!";
unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
}
($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
print "(row,col) = ($row,$col)";
print " (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
print "\n";
( WWW )
perlfunc "crypt" "no echo" ioctl() POSIX POSIX stty
CPAN Term::ReadKey
use Term::ReadKey;
ReadMode('noecho');
$password = ReadLine(0);
Unix /dev ;
lockfiles
open mode
perlfunc open sysopen() Fcntl perl
"O_RDWR|O_NDELAY|O_NOCTTY" perlfunc sysopen
end of line
"\r" "\n" perl "\r" "\n" Unix ASCII "\015" "\012" ("\015")
("0x0D") ("\cM")
print DEV "atv1\012"; # wrong, for some devices
print DEV "atv1\015"; # right, for some devices
"\n" UnixDOS/Win Macintosh "\015\012" socket (autoflushing)
flushing output
print() select() $| perlvar "$|" perlfunc "select" perlfaq5,
``How do I flush/unbuffer an output filehandle? Why must I do
this?''):
$oldh = select(DEV);
$| = 1;
select($oldh);
select((select(DEV), $| = 1)[0]);
Or if you don't mind pulling in a few thousand lines of code just
because you're afraid of a little $| variable:
use IO::Handle;
DEV->autoflush(1);
As mentioned in the previous item, this still doesn't work when
using socket I/O between Unix and Macintosh. You'll need to hard
code your line terminators, in that case.
non-blocking input
read() sysread() alarm 4 select() perlfunc select
While trying to read from his caller-id box, the notorious Jamie
Zawinski <jwz@netscape.com>, after much gnashing of teeth and fighting
with sysread, sysopen, POSIX's tcgetattr business, and various other
functions that go bump in the night, finally came up with this:
sub open_modem {
use IPC::Open2;
my $stty = `/bin/stty -g`;
open2( \*MODEM_IN, \*MODEM_OUT, "cu -l$modem_device -s2400 2>&1");
# starting cu hoses /dev/tty's stty settings, even when it has
# been opened on a pipe...
system("/bin/stty $stty");
$_ = <MODEM_IN>;
chomp;
if ( !m/^Connected/ ) {
print STDERR "$0: cu printed `$_' instead of `Connected'\n";
}
}
Unix - Unix Crack
passwd(1)
Several modules can start other processes that do not block your Perl
program. You can use IPC::Open3, Parallel::Jobs, IPC::Run, and some of
the POE modules. See CPAN for more details.
system("cmd &")
fork perlfunc fork perlipc Unix
STDIN, STDOUT, and STDERR are shared
STDINSTDOUT STDERR (pipe) open
SIGCHLD SIGPIPE SIGCHLD SIGPIPE SIGPIPE system("cmd&")
$SIG{CHLD} = sub { wait };
$SIG{CHLD} = 'IGNORE';
You can also use a double fork. You immediately wait() for your
first child, and the init daemon will wait() for your grandchild
once it exits.
unless ($pid = fork) {
unless (fork) {
exec "what you really wanna do";
die "exec failed!";
}
exit 0;
}
waitpid($pid,0);
Signals system("prog &")
/
``'' Signals
C [re-entrant] print() stdio (dump core) syswrite() print()
malloc()
$Interrupted = 0; #
$SIG{INT} = sub {
$Interrupted++;
syswrite(STDERR, "ouch\n", 5);
}
< FH>read()connect() wait() Signals flock()
Unix shadow
perl perlfunc getpw*() passwd(5) pwd_mkdb(8) pwd_mkdb(5)
date(1) UnixMS-DOSWindows NT VMS set time
$ENV{TZ} = "MST7MDT"; # unixish
$ENV{'SYS$TIMEZONE_DIFFERENTIAL'}="-5" # vms
system "trn comp.lang.perl.misc";
sleep() alarm() ?
sleep() select select() Time::HiRes BSD::Itimer ( CPAN Perl 5.8
Time::HiRes ).
Time::HiRes CPAN Perl 5.8
Perl syscall() gettimeofday(2)
require 'sys/syscall.ph';
$TIMEVAL_T = "LL";
$done = $start = pack($TIMEVAL_T, ());
syscall(&SYS_gettimeofday, $start, 0) != -1
or die "gettimeofday: $!";
##########################
# DO YOUR OPERATION HERE #
##########################
syscall( &SYS_gettimeofday, $done, 0) != -1
or die "gettimeofday: $!";
@start = unpack($TIMEVAL_T, $start);
@done = unpack($TIMEVAL_T, $done);
# fix microseconds
for ($done[1], $start[1]) { $_ /= 1_000_000 }
$delta_time = sprintf "%.4f", ($done[0] + $done[1] )
-
($start[0] + $start[1] );
atexit() setjmp()/longjmp()
Perl END atexit() (thread) END perlmod
For example, you can use this to make sure your filter program managed
to finish its output without filling up the disk:
END {
close(STDOUT) || die "stdout close failed: $!";
}
END END
use sigtrap qw(die normal-signals);
Perl eval() eval() setjmp die() longjmp Signals Camel flock()
exceptions.pl perl
atexit() rmexit() CPAN AtExit
sockets System V (Solaris)
Sys-V Solaris 2.X socket perl ``use Socket''
SunOS Solaris
Perl C
- C Perl [h2xs, xsubpp] syscall() syscall perlfunc
perl CPAN On Windows, try Win32::API. On Macs, try Mac::Carbon. If
no module has an interface to the C function, you can inline a bit of C
in your Perl source with Inline::C.
ioctl() syscall()
perl h2ph C cpp(1) &SYS_getitimer errno.h syscall.h socket.h
ioctl.h *.ph
1.
2. cd /usr/include
3. h2ph *.h */*.h
h2xs perl C Perl (extensions) h2xs perlxstut
h2xs perlxstut MakeMaker make perl make perl
setuid perl
setuid Perl perlsec
(pipe)
IPC::Open2 perl pipe() fork() exec() ( IPC::Open2 ) perlipc
"Bidirectional Communication with Another Process" "Bidirectional
Communication with Yourself"
You may also use the IPC::Open3 module (part of the standard perl
distribution), but be warned that it has a different order of arguments
from IPC::Open2 (see IPC::Open3).
system()
system() (``) system() 16 (``) STDOUT
$exit_status = system("mail-users");
$output_string = `ls`;
STDERR
system $cmd; # system()
$output = `$cmd`; # backticks (``)
open (PIPE, "cmd |"); # open()
system() STDOUT STDERR script STDOUT, STDERR open() STDOUT
IPC::Open3 . Benjamin Goldberg provides some sample code:
To capture a program's STDOUT, but discard its STDERR:
use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(NULL, ">", File::Spec->devnull);
my $pid = open3(gensym, \*PH, ">&NULL", "cmd");
while( <PH> ) { }
waitpid($pid, 0);
To capture a program's STDERR, but discard its STDOUT:
use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(NULL, ">", File::Spec->devnull);
my $pid = open3(gensym, ">&NULL", \*PH, "cmd");
while( <PH> ) { }
waitpid($pid, 0);
To capture a program's STDERR, and let its STDOUT go to our own STDERR:
use IPC::Open3;
use Symbol qw(gensym);
my $pid = open3(gensym, ">&STDERR", \*PH, "cmd");
while( <PH> ) { }
waitpid($pid, 0);
To read both a command's STDOUT and its STDERR separately, you can
redirect them to temp files, let the command run, then read the temp
files:
use IPC::Open3;
use Symbol qw(gensym);
use IO::File;
local *CATCHOUT = IO::File->new_tempfile;
local *CATCHERR = IO::File->new_tempfile;
my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "cmd");
waitpid($pid, 0);
seek $_, 0, 0 for \*CATCHOUT, \*CATCHERR;
while( <CATCHOUT> ) {}
while( <CATCHERR> ) {}
But there's no real need for *both* to be tempfiles... the following
should work just as well, without deadlocking:
use IPC::Open3;
use Symbol qw(gensym);
use IO::File;
local *CATCHERR = IO::File->new_tempfile;
my $pid = open3(gensym, \*CATCHOUT, ">&CATCHERR", "cmd");
while( <CATCHOUT> ) {}
waitpid($pid, 0);
seek CATCHERR, 0, 0;
while( <CATCHERR> ) {}
And it'll be faster, too, since we can begin processing the program's
stdout immediately, rather than waiting for the program to finish.
(file descriptor)
open(STDOUT, ">logfile");
system("ls");
Bourne shell
$output = `$cmd 2>some_file`;
open (PIPE, "cmd 2>some_file |");
STDERR STDOUT
$output = `$cmd 2>&1`;
open (PIPE, "cmd 2>&1 |");
STDERR STDOUT shell
open(STDERR, ">&STDOUT");
$alloutput = `cmd args`; # stderr still escapes
open() STDERR open() STDOUT STDOUT STDERR STDOUT
Bourne shell (sh(1)) csh(1) Perl system() Bourne shell"Far More
Than You Ever Wanted To Know"
http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz . STDERR STDOUT:
$output = `cmd 2>&1`; # either with backticks
$pid = open(PH, "cmd 2>&1 |"); # or with an open pipe
while (<PH>) { } # plus a read
To capture a command's STDOUT but discard its STDERR:
$output = `cmd 2>/dev/null`; # either with backticks
$pid = open(PH, "cmd 2>/dev/null |"); # or with an open pipe
while (<PH>) { } # plus a read
To capture a command's STDERR but discard its STDOUT:
$output = `cmd 2>&1 1>/dev/null`; # either with backticks
$pid = open(PH, "cmd 2>&1 1>/dev/null |"); # or with an open pipe
while (<PH>) { } # plus a read
To exchange a command's STDOUT and STDERR in order to capture the
STDERR but leave its STDOUT to come out our old STDERR:
$output = `cmd 3>&1 1>&2 2>&3 3>&-`; # either with backticks
$pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe
while (<PH>) { } # plus a read
To read both a command's STDOUT and its STDERR separately, it's easiest
and safest to redirect them separately to files, and then read from
those files when the program is done:
system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
Ordering is important in all these examples. That's because the shell
processes file descriptor redirections in strictly left to right order.
system("prog args 1>tmpfile 2>&1");
system("prog args 2>&1 1>tmpfile");
The first command sends both standard out and standard error to the
temporary file. The second command sends only the old standard output
there, and the old standard error shows up on the old standard out.
open()
If the second argument to a piped open() contains shell metacharacters,
perl fork()s, then exec()s a shell to decode the metacharacters and
eventually run the desired program. If the program couldn't be run,
it's the shell that gets the message, not Perl. All your Perl program
can find out is whether the shell itself could be successfully started.
You can still capture the shell's STDERR and check it for error
messages. See "How can I capture STDERR from an external command?"
elsewhere in this document, or use the IPC::Open3 module.
If there are no shell metacharacters in the argument of open(), Perl
runs the command directly, without using the shell, and can correctly
report whether the command started.
Perl "system"
Writing backticks in your program sends a clear message to the readers
of your code that you wanted to collect the output of the command. Why
send a clear message that isn't true?
`cat /etc/termcap`;
) $?
print `cat /etc/termcap`;
system("cat /etc/termcap") == 0
or die "cat program failed!";
system() shell (wildcard)
shell
@ok = `grep @opts '$search_string' @filenames`;
Perl 5.8.0 open() system() exec() shell
open( GREP, "-|", 'grep', @opts, $search_string, @filenames );
chomp(@ok = <GREP>);
close GREP;
my @ok = ();
if (open(GREP, "-|")) {
while (<GREP>) {
chomp;
push(@ok, $_);
}
close GREP;
} else {
exec 'grep', @opts, $search_string, @filenames;
}
system() exec() shell perlipc "Safe Pipe Opens"
Note that if you're use Microsoft, no solution to this vexing issue is
even possible. Even if Perl were to emulate fork(), you'd still be
stuck, because Microsoft does not have a argc/argv-style API.
EOFUnix ^DMS-DOS ^Z STDIN
stdio set error eof POSIX clearerr()
1
$where = tell(LOG);
seek(LOG, $where, 0);
2 seek()
3 seek()
4 stdio sysread
shell perl
Perl shell Perl shell->perl shell [pipeline datastream
paradigm]
perl telnet ftp
Net::FTPTCP::Client NET::Telnet CPAN
http://www.perl.com/CPAN/scripts/netstuff/telnet.emul.shar telnet
Net::Telnet
telnet telnet
use IO::Socket; # new in 5.004
$handle = IO::Socket::INET->new('www.perl.com:80')
|| die "can't connect to port 80 on www.perl.com: $!";
$handle->autoflush(1);
if (fork()) { # XXX: undef means failure
select($handle);
print while <STDIN>; # everything from stdin to socket
} else {
print while <$handle>; # everything from socket to stdout
}
close $handle;
exit;
Perl Expect
chat2.pl perl CPAN Expect CPAN IO::Pty IO::Stty.
perl
$0 perlvar sendmail (daemons)
$0 = "orcus [accepting connections]";
perl script {}
Unix
script shell shell shell eval() script comp.unix.questions
FAQ
kill TERM KILL
fork
tty Unix Unix Your_OS::Process
o /dev/tty TIOCNOTTY ioctl tty(4) POSIX::setsid()
o /
o STDINSTDOUT STDERR tty
o
fork && exit;
The Proc::Daemon module, available from CPAN, provides a function to
perform these actions for you.
"-t STDIN"N "-t STDOUT"
if (-t STDIN && -t STDOUT) {
print "Now what? ";
}
POSIX
use POSIX qw/getpgrp tcgetpgrp/;
open(TTY, "/dev/tty") or die $!;
$tpgrp = tcgetpgrp(fileno(*TTY));
$pgrp = getpgrp();
if ($tpgrp == $pgrp) {
print "foreground\n";
} else {
print "background\n";
}
Signals Camel alarm() CPAN Sys::AlarmCall
The alarm() function is not implemented on all versions of Windows.
Check the documentation for your specific version of Perl.
CPU ?
CPAN BSD::Resource
Unix
Signals reaper SIGCHLD wait() perlfaq8 "How do I start a process
in the background?" fork
SQL ?
The DBI module provides an abstract interface to most database servers
and types, including Oracle, DB2, Sybase, mysql, Postgresql, ODBC, and
flat files. The DBI module accesses each database type through a
database driver, or DBD. You can see a complete list of available
drivers on CPAN: http://www.cpan.org/modules/by-module/DBD/ . You can
read more about DBI on http://dbi.perl.org .
Other modules provide more specific access: Win32::ODBC, Alzabo, iodbc,
and others found on CPAN Search: http://search.cpan.org .
system() control-C ?
system() perlipc INT
$rc = system($cmd);
if ($rc & 127) { die "signal death" }
Unix Fcntl O_NDELAY O_NONBLOCK sysopen()
use Fcntl;
sysopen(FH, "/tmp/somefile", O_WRONLY|O_NDELAY|O_CREAT, 0644)
or die "can't open /tmp/somefile: $!":
How do I install a module from CPAN?
CPAN 5.004
$ perl -MCPAN -e shell
cpan shell -- CPAN exploration and modules installation (v1.59_54)
ReadLine support enabled
cpan> install Some::Module
CPAN CPAN
1
2
perl Makefile.PL
3
make
4
make test
5
make install
perl (make) make perl perl
ExtUtils::MakeMaker require use
require use
Perl offers several different ways to include code from one file into
another. Here are the deltas between the various inclusion constructs:
1) do $file is like eval `cat $file`, except the former
1.1: searches @INC and updates %INC.
1.2: bequeaths an *unrelated* lexical scope on the eval'ed code.
2) require $file is like do $file, except the former
2.1: checks for redundant loading, skipping already loaded files.
2.2: raises an exception on failure to find, compile, or execute $file.
3) require Module is like require "Module.pm", except the former
3.1: translates each "::" into your system's directory separator.
3.2: primes the parser to disambiguate class Module as an indirect object.
4) use Module is like require Module, except the former
4.1: loads the module at compile time, not run-time.
4.2: imports symbols and semantics from that package to the current one.
In general, you usually want "use" and a proper Perl module.
/
Makefiles PREFIX
perl Makefile.PL PREFIX=/mydir/perl LIB=/mydir/perl/lib
PERL5LIB perlrun
use lib '/mydir/perl/lib';
BEGIN {
unshift(@INC, '/mydir/perl/lib');
}
lib Perl lib
/
use FindBin;
use lib "$FindBin::Bin";
use your_own_modules;
include (@INC)
PERLLIB
PERL5LIB
perl -Idir
use lib
use lib "$ENV{HOME}/myown_perllib";
lib.pm 5.002 Perl
socket.ph
It's a perl4-style file defining values for system networking
constants. Sometimes it is built using h2ph when Perl is installed,
but other times it is not. Modern programs "use Socket;" instead.
AUTHOR AND COPYRIGHT
Copyright (c) 1997-2003 Tom Christiansen and Nathan Torkington. All
rights reserved.
This documentation is free; you can redistribute it and/or modify it
under the same terms as Perl itself.
Irrespective of its distribution, all code examples in this file are
hereby placed into the public domain. You are permitted and encouraged
to use this code in your own programs for fun or for profit as you see
fit. A simple comment in the code giving credit would be courteous but
is not required.