Perl Cd Bookshelf [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Perl Cd Bookshelf [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید

16.1. Gathering Output from a Program


16.1.1. Problem




You want to run a program and collect
its output into a variable.

16.1.2. Solution


Either use backticks:

$output = `program args`;   
# collect output into one multiline string
@output = `program args`;
# collect output into array, one line per element

or use Recipe 16.4:

open(my $fh, "-|", "program", @args)
or die "Can't run program: $!\n";
while (<$fh>) {
$output .= $_;
}
close $fh;

16.1.3. Discussion


The backticks are a convenient way to run other programs and gather
their output. The backticks do not return until the called program
exits. Perl goes to some trouble behind the scenes to collect the
output, so it is inefficient to use the backticks and ignore their
return value:

`fsck -y /dev/rsd1a`;   
# BAD AND SCARY

The backtick operator calls the shell to run the command. This makes
it unsafe when used in a program with special privileges, but lets
you use shell wildcards in the command:

@files = `ls -1 /music/*.mp3`;

If you want to read the output of a wildcarded command line as it's
generated (and don't mind the potential security problems), use this
form of open:

open(README, "ls -l /music/*.mp3 |") or die "Can't run program: $!\n";
while(<README>) {
# the latest line is in $_
}
close(README);

In versions of Perl before 5.8, this two-argument form of
open was the only one available to you. In those
versions of Perl, you wrote the solution as:

open(FH, "program @args |")
or die "Can't run program: $!\n";

Here's a low-level workaround, using pipe (to
create two connected filehandles), fork (to split
off a new process), and exec (to replace the new
process with the program to read from):

use POSIX qw(:sys_wait_h);
my ($readme, $writeme);
pipe $readme, $writeme;
if ($pid = fork) {
# parent
$SIG{CHLD} = sub { 1 while ( waitpid(-1, WNOHANG)) > 0 };
close $writeme;
} else {
die "cannot fork: $!" unless defined $pid;
# child
open(STDOUT, ">&=", $writeme)
or die "Couldn't redirect STDOUT: $!";
close $readme;
exec($program, $arg1, $arg2)
or die "Couldn't run $program : $!\n";
}
while (<$readme>) {
$string .= $_;
# or push(@strings, $_);
}
close($readme);

There's no reason to prefer this over the open
"-|
" code in the Solution, except that the low-level
workaround lets you change signal disposition before you launch the
new program. For example, you could disable the INT signal in the
child so that only the parent process receives it.

16.1.4. See Also


The section on The section on "Talking to Yourself" in Chapter 16 of
Programming Perl or
perlsec(1); Recipe 16.2;
Recipe 16.4; Recipe 16.10; Recipe 16.19; Recipe 19.5

/ 875