Ïðèãëàøàåì ïîñåòèòü
Ãóìèëåâ (gumilev.lit-info.ru)

Q&A

Previous Table of Contents Next

Q&A

Q1:

How do I open a pipe both to and from a command? For example, open(P, "| cmd |") doesn't seem to work.

A1:

This task can actually be quite complicated because reading and writing from the same process can cause deadlock. At this point, your program is expecting cmd to print something and is waiting for data with <P>. Meanwhile, because of some snafu, cmd is actually waiting for your program to print something with print P "...". In fact, if you have warnings enabled, Perl will inform you with this message: Can't do bidirectional pipe.

If you're prepared for this kind of problem, the IPC::Open2 module will allow you to open a bidirectional pipe. Modules will be discussed in Hour 14, "Using Modules."

Q2:

The code $a=system("cmd") didn't capture the output of cmd in $a as I expected. Why not?

A2:

You're confusing system with backticks (``). The system function doesn't capture cmd's output. What you probably wanted was $a=`cmd`.

Q3:

When I run external programs under Unix with backticks (``), the error messages are not captured. Why not?

A3:

Because all Unix programs—including Perl—have two output file descriptors: STDOUT and STDERR. The STDOUT file descriptor is for normal program output. The STDERR file descriptor is reserved for error messages. Backticks—and open with pipes—capture only STDOUT. The short answer is to use the shell to redirect STDOUT into STDERR and then run your command as follows:


$a=`cmd 2>&1`;   # run "cmd", capturing output and errors


The Perl FAQ has a lengthy explanation of this and many other techniques for capturing a command's errors. Type perldoc perlfaq8 for the appropriate section of the FAQ.

    Previous Table of Contents Next