X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlfaq8.pod;h=feb10f39473325df739b983637300de08fb8a81f;hb=b03ad8f690c4dcc613a1ec77d747e2d429945b16;hp=c093b77cc7750174cd12ec4afe1eccdaf7d6a521;hpb=a93751fa40b15f424f91bba70d1533c6b4024e42;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlfaq8.pod b/pod/perlfaq8.pod index c093b77..feb10f3 100644 --- a/pod/perlfaq8.pod +++ b/pod/perlfaq8.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq8 - System Interaction ($Revision: 1.2 $, $Date: 2001/10/16 13:27:22 $) +perlfaq8 - System Interaction ($Revision: 1.8 $, $Date: 2002/05/16 12:41:42 $) =head1 DESCRIPTION @@ -634,9 +634,10 @@ STDOUT). Note that you I use Bourne shell (sh(1)) redirection syntax in backticks, not csh(1)! Details on why Perl's system() and backtick -and pipe opens all use the Bourne shell are in -http://www.cpan.org/doc/FMTEYEWTK/versus/csh.whynot . -To capture a command's STDERR and STDOUT together: +and pipe opens all use the Bourne shell are in the +F article in the "Far More Than You Ever Wanted To +Know" collection in http://www.cpan.org/olddoc/FMTEYEWTK.tgz . To +capture a command's STDERR and STDOUT together: $output = `cmd 2>&1`; # either with backticks $pid = open(PH, "cmd 2>&1 |"); # or with an open pipe @@ -679,50 +680,38 @@ there, and the old standard error shows up on the old standard out. =head2 Why doesn't open() return an error when a pipe open fails? -Because the pipe open takes place in two steps: first Perl calls -fork() to start a new process, then this new process calls exec() to -run the program you really wanted to open. The first step reports -success or failure to your process, so open() can only tell you -whether the fork() succeeded or not. +If the second argument to a piped C 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 L<"How can I capture STDERR from an +external command?"> elsewhere in this document, or use the +L module. -To find out if the exec() step succeeded, you have to catch SIGCHLD -and wait() to get the exit status. You should also catch SIGPIPE if -you're writing to the child--you may not have found out the exec() -failed by the time you write. This is documented in L. - -In some cases, even this won't work. 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. Now when you call wait(), you only learn whether or not the -I could be successfully started...it's best to avoid shell -metacharacters. - -On systems that follow the spawn() paradigm, open() I do what -you expect--unless perl uses a shell to start your command. In this -case the fork()/exec() description still applies. +If there are no shell metacharacters in the argument of C, Perl +runs the command directly, without using the shell, and can correctly +report whether the command started. =head2 What's wrong with using backticks in a void context? Strictly speaking, nothing. Stylistically speaking, it's not a good -way to write maintainable code because backticks have a (potentially -humongous) return value, and you're ignoring it. It's may also not be very -efficient, because you have to read in all the lines of output, allocate -memory for them, and then throw it away. Too often people are lulled -to writing: +way to write maintainable code. Perl has several operators for +running external commands. Backticks are one; they collect the output +from the command for use in your program. The C function is +another; it doesn't do this. - `cp file file.bak`; - -And now they think "Hey, I'll just always use backticks to run programs." -Bad idea: backticks are for capturing a program's output; the system() -function is for running programs. +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? Consider this line: `cat /etc/termcap`; -You haven't assigned the output anywhere, so it just wastes memory -(for a little while). You forgot to check C<$?> to see whether -the program even ran correctly, too. Even if you wrote +You forgot to check C<$?> to see whether the program even ran +correctly. Even if you wrote print `cat /etc/termcap`; @@ -954,8 +943,7 @@ in L. There are a number of excellent interfaces to SQL databases. See the DBD::* modules available from http://www.cpan.org/modules/DBD . -A lot of information on this can be found at -http://www.symbolstone.org/technology/perl/DBI/ +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? @@ -980,9 +968,17 @@ sysopen(): =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 @@ -1088,7 +1084,7 @@ but other times it is not. Modern programs C instead. =head1 AUTHOR AND COPYRIGHT -Copyright (c) 1997-1999 Tom Christiansen and Nathan Torkington. +Copyright (c) 1997-2002 Tom Christiansen and Nathan Torkington. All rights reserved. This documentation is free; you can redistribute it and/or modify it