X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlfaq8.pod;h=feb10f39473325df739b983637300de08fb8a81f;hb=d672126634c5e568812ed35d4c8ea53a9a55ee4c;hp=cc2f072219f120ce613fb08a530019389361f6a9;hpb=0bc0ad857ef0ded50c72fba42503c958a1579a5a;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlfaq8.pod b/pod/perlfaq8.pod index cc2f072..feb10f3 100644 --- a/pod/perlfaq8.pod +++ b/pod/perlfaq8.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq8 - System Interaction ($Revision: 1.6 $, $Date: 2002/01/28 04:17:27 $) +perlfaq8 - System Interaction ($Revision: 1.8 $, $Date: 2002/05/16 12:41:42 $) =head1 DESCRIPTION @@ -680,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`; @@ -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