=head1 NAME
-perlfaq8 - System Interaction ($Revision: 1.7 $, $Date: 2002/04/18 14:23:15 $)
+perlfaq8 - System Interaction ($Revision: 1.14 $, $Date: 2002/11/10 17:35:47 $)
=head1 DESCRIPTION
=head2 How do I start a process in the background?
-You could use
+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.
+
+You could also use
system("cmd &")
=item Zombies
-You have to be prepared to "reap" the child process when it finishes
+You have to be prepared to "reap" the child process when it finishes.
$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);
+
See L<perlipc/"Signals"> for other examples of code to do this.
Zombies are not an issue with C<system("prog &")>.
script's STDOUT and STDERR, unless the system() command redirects them.
Backticks and open() read B<only> the STDOUT of your command.
+You can also use the open3() function from 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.
+
With any of these, you can change file descriptors before the call:
open(STDOUT, ">logfile");
backticks, not csh(1)! Details on why Perl's system() and backtick
and pipe opens all use the Bourne shell are in the
F<versus/csh.whynot> article in the "Far More Than You Ever Wanted To
-Know" collection in http://www.cpan.org/olddoc/FMTEYEWTK.tgz . To
+Know" collection in http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz . To
capture a command's STDERR and STDOUT together:
$output = `cmd 2>&1`; # either with backticks
=head2 Why doesn't open() return an error when a pipe open fails?
-If the second argument to a piped C<open> contains shell
+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
successfully started. You can still capture the shell's STDERR and
check it for error messages. See L<"How can I capture STDERR from an
external command?"> elsewhere in this document, or use the
-L<IPC::Open3> module.
+IPC::Open3 module.
-If there are no shell metacharacters in the argument of C<open>, Perl
+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.
=head2 How can I call backticks without shell processing?
-This is a bit tricky. Instead of writing
+This is a bit tricky. You can't simply write the command
+like this:
@ok = `grep @opts '$search_string' @filenames`;
-You have to do this:
+As of Perl 5.8.0, you can use open() with multiple arguments.
+Just like the list forms of system() and exec(), no shell
+escapes happen.
+
+ open( GREP, "-|", 'grep', @opts, $search_string, @filenames );
+ chomp(@ok = <GREP>);
+ close GREP;
+
+You can also:
my @ok = ();
if (open(GREP, "-|")) {
Just as with system(), no shell escapes happen when you exec() a list.
Further examples of this can be found in L<perlipc/"Safe Pipe Opens">.
-Note that if you're stuck on Microsoft, no solution to this vexing issue
+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 hosed, because Microsoft gives no argc/argv-style API. Their API
-always reparses from a single string, which is fundamentally wrong,
-but you're not likely to get the Gods of Redmond to acknowledge this
-and fix it for you.
+be stuck, because Microsoft does not have a argc/argv-style API.
=head2 Why can't my script read from STDIN after I gave it EOF (^D on Unix, ^Z on MS-DOS)?
``Signals'' in the Camel. You may instead use the more flexible
Sys::AlarmCall module available from CPAN.
+The alarm() function is not implemented on all versions of Windows.
+Check the documentation for your specific version of Perl.
+
=head2 How do I set CPU limits?
Use the BSD::Resource module from CPAN.
Use the reaper code from L<perlipc/"Signals"> to call wait() when a
SIGCHLD is received, or else use the double-fork technique described
-in L<perlfunc/fork>.
+in L<perlfaq8/"How do I start a process in the background?">.
=head2 How do I use an SQL database?
There are a number of excellent interfaces to SQL databases. See the
-DBD::* modules available from http://www.cpan.org/modules/DBD .
+DBD::* modules available from http://www.cpan.org/modules/by-module/DBD/ .
A lot of information on this can be found at http://dbi.perl.org/
=head2 How do I make a system() exit on control-C?
=head2 How do I install a module from CPAN?
The easiest way is to have a module also named CPAN do it for you.
-This module comes with perl version 5.004 and later. To manually install
-the CPAN module, or any well-behaved CPAN module for that matter, follow
-these steps:
+This module comes with perl version 5.004 and later.
+
+ $ perl -MCPAN -e shell
+
+ cpan shell -- CPAN exploration and modules installation (v1.59_54)
+ ReadLine support enabled
+
+ cpan> install Some::Module
+
+To manually install the CPAN module, or any well-behaved CPAN module
+for that matter, follow these steps:
=over 4