in reply to How to split output using Expect.pm

merlyn is too quick to jump to a conclusion here. <G>

It seems that Expect combines the STDERR and STDOUT of the program together. By adding the parameter '2>errfile.tmp', kudra and I determined that the STDERR from the program will go to the 'errfile.tmp' file, and STDOUT will go where expected.

The output in 'errfile.tmp' can now be processed as desired. This works quite well for her application, although it would be cooler if the output could be tied straight into a scalar, rather than having to open the file for processing.

Note that 'errfile.tmp' is not an ideal name, as it's not process specific, nor garanteed. We're aware that there are some suggestions for creating unique filenames, but that wasn't the point of this node.

Perl Cookbook, section 16.7, talks about redirecting I/O.

Revised code:
my $object = Expect->spawn("program 2>errfile.tmp"); # 1 my $error = ($object->expect(30, 'password:'))[1]; # 2 die "$error\n" if ($error); # 3 print $object "incorrectpassword\r"; # 4 $object->soft_close(); # 5

--Chris

e-mail jcwren

Replies are listed 'Best First'.
RE: (jcwren) RE: How to split output using Expect.pm
by tye (Sage) on Aug 17, 2000 at 08:10 UTC

    That is what pipes are for!

    Create a pipe, prevent it from being closed on exec, get the FD of it, then use 2>&$FD on the command line and you can read from the pipe to read the command's STDERR.

    Something like this; not just untested, I've never done anything like this before (: ...

    { local($^F)= 0x8000; pipe( READERR, WRITEERR ) or die "pipe: $!"; } my $fd= fileno(WRITEERR); Expect->new( "command 2>&$fd" ); close(WRITEERR);

    I'd probably do this using fcntl() instead of $^F so that I could have READERR closed on exec while WRITEERR stays open.

    To interleave the reading from the pipe with the use of Expect, it would probably be best to extend the expect() function to allow an extra file handle to be passed to the select() and return with a special code when that file handle gets some data. And if you're going to extend the expect() function, you could also extend the spawn() function so that it has an option to dup WRITEERR (instead of the new STDOUT) to STDERR.

    <RANT> Why the h*** does Expect do a exec join(' ',@_) instead of just exec @_? Why get passed the arguments pre-parsed if you're just going to smash them all together and force the shell to reinterpret them! If I wanted to have the shell mess up my command line, I'd pass it in as a single string, the way Larry intended!</RANT>

            - tye (but my friends call me "Tye")