开发者

How can I pass a filehandle to Perl Expect's log_file function?

I feel stupid for asking this, but I've tried a couple things and I'm not sure where to go with it.

From the Expect.pm documentation:

$object->log_file("filename" | $filehandle | \&coderef | undef)

Log session to a file. All characters send to or received from the spawned process are written to the file.

I'd like to pass the $filehandle to log_file. However, when I tried this:

open (LOG, ">>" .$opt{l});
my $sess = Expect->spawn("telnet $ip");
$sess->log_file(LOG)

I get a file named 'LOG' in the directory that I'm running the script out of. After some investigation, I tried this:

open (LOG, ">>" .$opt{l});
my $sess = Expect->spawn("telnet $ip");
my $fh = *LOG;
$sess->开发者_JAVA技巧log_file($fh)

Now, I get a file named *main::LOG in the directory. I do have another file as well, named whatever I specified on the -l option, but it only contains the lines that I send to print LOG.

I'm not sure if the filehandling functionality is hosed in the function, or if I'm doing something wrong.


If you have a bareword filehandle named LOG, you can pass it to a function by saying \*LOG (you can read more about this in perldoc perldata), but don't do that. Bareword filehandles are a very old style and should no longer be used. Try using a lexical filehandle and the three argument version of open:

open my $log, ">>", $opt{l}
    or die "could not open $opt{l}: $!";

you can use $log anywhere you used LOG in the past.

You should also be using the strict and warnings pragmas.


Try using a lexical filehandle (and the three-argument open, and die) to begin with:

open my $logfh, ">>", $opt{l} or die "Could not open log file $opt{l}: $!\n";
$sess->log_file( $logfh );

LOG is incredibly generic and could be getting trumped (or doing the trumping) of another filehandle somewhere in your code. Using a lexical filehandle helps to prevent confusion. And you should always check the return status of open() (or use autodie) in case you can't actually open the file.


It might be a better idea to return a filehandle using log_file by passing it the filename instead.


From the Expect documentation:

$object->log_file("filename" | $filehandle | \&coderef | undef)

Log session to a file. All characters send to or received from the spawned process are written to the file. Normally appends to the logfile, but you can pass an additional mode of "w" to truncate the file upon open():

$object->log_file("filename", "w");

Returns the logfilehandle.

So you should be able to achieve the same functionality using the following:

my $sess = Expect->spawn("telnet $ip");
$sess->log_file($opt{l});               # Or my $fh = $sess->log_file...
                                        # if that filehandle is needed

Now all your session activity will be logged to the file. Append mode is the default.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜