ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
16.4. Reading or Writing to Another ProgramProblemYou want to run another program and either read its output or supply the program with input. SolutionUse $pid = open(README, "program arguments |") or die "Couldn't fork: $!\n"; while (<README>) { # ... } close(README) or die "Couldn't close: $!\n"; To write to the program, put the pipe at the beginning: $pid = open(WRITEME, "| program arguments") or die "Couldn't fork: $!\n"; print WRITEME "data\n"; close(WRITEME) or die "Couldn't close: $!\n"; DiscussionIn the case of reading, this is similar to using backticks, except you have a process ID and a filehandle. As with the backticks, However, sometimes this isn't desirable. Piped Notice how we specifically call $pid = open(F, "sleep 100000|"); # child goes to sleep close(F); # and the parent goes to lala land To avoid this, you can save the PID returned by If you attempt to write to a process that has gone away, your process will receive a SIGPIPE. The default disposition for this signal is to kill your process, so the truly paranoid install a SIGPIPE handler just in case. If you want to run another program and be able to supply its STDIN yourself, a similar construct is used: $pid = open(WRITEME, "| program args"); print WRITEME "hello\n"; # program will get hello\n on STDIN close(WRITEME); # program will get EOF on STDIN The leading pipe symbol in the filename argument to You can also use this technique to change your program's normal output path. For example, to automatically run everything through a pager, use something like: $pager = $ENV{PAGER} || '/usr/bin/less'; # XXX: might not exist open(STDOUT, "| $pager"); Now, without changing the rest of your program, anything you print to standard output will go through the pager automatically. As with When using piped opens, always check return values of both By the time the child process tries to Check the return value from In the case of a pipe opened for writing, you should also install a SIGPIPE handler, since writing to a child that isn't there will trigger a SIGPIPE. See AlsoThe |