seanborland has asked for the wisdom of the Perl Monks concerning the following question:

I am the beginner of Expect.I want to store the output of the process in my own array when use Expect. e.g. if I send a command to a ftp process, and I want to store it's return value into my array, such as @filelist. How can I? If I use expect(), the result is just printed on the STDOUT. Thanks a lot.
  • Comment on How to store the output of the process in my own array?

Replies are listed 'Best First'.
Re: How to store the output of the process in my own array?
by matija (Priest) on Mar 01, 2004 at 08:20 UTC
    The log_file routine accepts a filehandle, but it can also take a coderef.

    So you could do

    #!/usr/bin/perl -w use Expect; my @mylog; sub reporter { # print "PASSED:<",join("><",@_).">\n"; push(@mylog,@_); } $object=Expect->spawn("some command I need"); $object->log_file(\&reporter);
    (Yes, I tested this)
      thank you very much. All the output can be store in the array but I still meet a small problem. I input ls command, and then print @mylog, but it doesn't contain the result of ls. When I input quit command to quit ftp, and then print @mylog, I get the ls result and quit result together. How can I solve this problem? Thanks a log. By the way, I use to meet this problem when I use C++ and C# to write the same program. In C++ and C#, anonymous pipe is used to implement it and I use multi-thread to solve the problem.
        I still meet a small problem. I input ls command, and then print @mylog, but it doesn't contain the result of ls.
        The reason for the difference, is because ls detects whether it's connected to a pipe or to a TTY, and behaves differently for both cases. You have to fool it into believing it's connected to a terminal. The common way to do that, is to connect it to a pseudo-terminal.

        To this end, you can use the module IO::Pty. And judging by the documentation, Expect (which I've never ever used in my life, sorry) ought to have support for it built-in.

        Happy hunting.

        Well, from my experimenting with Expect it looks like the subroutine for logging the output is called when $object->expect is called, or even when $object->expect finds a match. Probably also when it's buffer becomes full, but you realy don't want to count on that.

        My suggestion is to put in some $object->expect calls that match on whatever prompt you are getting in your input stream.

Re: How to store the output of the process in my own array?
by tinita (Parson) on Mar 01, 2004 at 08:06 UTC
    a quick search through the docs would suggest doing
    $exp->log_stdout(0); my $output = $exp->before();
    but that's just a guess which works with a simple command; have a further look at the documentation, i don't have experience with Expect.pm
Re: How to store the output of the process in my own array?
by grinder (Bishop) on Mar 01, 2004 at 09:02 UTC
    if I send a command to a ftp process, and I want to store it's (sic) return value

    Are you just doing FTP? Do you need to use Expect, or is there some reason why you can't/don't want to use Net::FTP? The code will be much simpler:

    my $ftp = Net::FTP->new('foo.example.com') or die "can't connect: $@"; $ftp->login( 'leet', 'seKreT' ) or die 'can't login: ' . $ftp->message; $ftp->cwd("/pub/foo/bar") or die 'cannot set cwd' . $ftp->message; my @files = $ftp->dir(); $ftp->quit;
      I just take ftp for example. However, thank you very much to tell me how to use Net::FTP :)