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

How would I go about modifying the output of a program I've called with back ticks..

For example, I am calling telnet from my script, but the boss doesn't want users to see the ip that telnet is calling (It displays Trying 192.168.1.101... when you run telnet).

I would use Net::Telnet if there wasn't a need to have control of the terminal, but anyways.

I've searched all over, all I can find is how to capture STDOUT from telnet, save it to a file, variable, etc... However, I see nothing on how I could modify STDOUT, and print it back to the terminal, and move on happily. I've tried a few different things, but I think I'm confused, can this be done? I know I can modify STDOUT when saved in an @array using s/// to remove the ip, but I just can't seem to send it back to the Terminal smoothly without loosing control of telnet. Maybe stop the flush out the output via the shell(stty)??

Make any sense?

Thanks in advance!

Replies are listed 'Best First'.
Re: Modifying STDOUT and keeping control
by Aristotle (Chancellor) on Oct 14, 2002 at 20:48 UTC
    From the code you posted, it looks like what you really need is IPC::Open2.
    use IPC::Open2; my($rdh, $wrh); my $pid = open2($rdh, $wrh, "telnet", "192.168.1.1");
    Now you can print $wrh "some command"; and read back results with $var = <$rdh>; etc. Make sure to read Suffering from Buffering before you embark on that route.

    Makeshifts last the longest.

      Tell me, what am I doing wring here...
      open(PIPE, "telnet 192.168.1.1 |") or die $!; while (<PIPE>) { $bah = $_; $bah =~ s/192.168.1.1//; print $bah; } close(PIPE); bash~$ perl test.pl Trying ... Connected to . Escape character is '^]'.
      Locks up before it gets to the login prompt....
      use IPC::Open2; print open2(\*IN, \*OUT, "telnet 10.65.2.252"); print OUT "Trying\n"; while (<IN>) { $_ =~ s/10.65.2.252//; print; } close IN; close OUT; bash~$ perl test1.pl 26210Trying ... Connected to . Escape character is '^]'.
      Does the same thing in the same place, with the exception of printing the pid.

      Am I misunderstanding what can and can't be done here?

      All I need to do is just strip off that ip address, or the whole "trying" message, during execution.( these snips do that, but hang up in the same place ).

        What you are likely running into is that telnet is an interactive application. The buffering that Perl does to read input by lines destroys the interactivity. When the user hits the first key of their username, they expect to see it echoed immediately. But Perl is still sitting there waiting for the end of the line. Luckily, you only need to process the header. Once you finish reading the header, you can stop reading line by line. Either enter a loop that reads and writes a single character. Or find some way to reconnect the telnet stdout to the Perl stdout.

        I'm not sure what you mean by hanging. Do you mean it's not terminating? If so, do you know where it's stuck? Most likely, since the remote host hasn't closed the connection and therefor telnet is still running and hasn't closed the IN handle, while(<IN>) is blocked waiting for data. I also don't see any attempt at actually sending a command to the remote host. Is the user supposed to type that in? You'd have to do that yourself in that case. Are you printing a command but nothing happens? In that case you probably haven't read Suffering from Buffering.

        Also, it seems you haven't quote understood what the file handles do - or is Trying a command on the remote machine? That is the only reason you should be printing it to OUT, but it doesn't seem likely to me.

        Makeshifts last the longest.

Re: Modifying STDOUT and keeping control
by fruiture (Curate) on Oct 14, 2002 at 19:19 UTC

    Some relevant code might be helpful, i can't see what you're actually doing.

    ... program I've called with back ticks ...

    Well the `backticks` return the ouput of the program, you can modify this output and then print it to STDOUT. Where's the problem?

    Did you consider using open() to fork off telnet and process its output line by line and just in time? What do you mean with "loosing control of telnet"?

    --
    http://fruiture.de
      I have an script that works as an interactive menu, some of the choices require the script to telnet to a remote host for the user to login to and complete a task, when they are done, it takes them back to the menu. What I'm trying to do is prevent the user from seeing this:
      Trying 192.168.1.1... Connected to 192.168.1.1. Escape character is '^]'.
      Or at least the ip address, when the script calls 'telnet 192.168.1.1'.

      Does this make more sense?

        I think I would still use Net::Telnet, and build an interactive shell into your script that passes on the user entered data on via Net::Telnet to the remote shell. See PPM on ActivePerl and CPAN (the module) for examples of what I'm thinking of. Also check out the module Term::ReadLine, which modern versions of CPAN.pm use, to write the command line interface for this side.

        Oh, look, no code. But you didn't provide any code either, so I won't feel bad about it. :-)

        Does this make more sense?

        No, i still can't find any code in your post. What do you mean with "call" when you say "the script calls 'telnet ...'"?

        Maybe you want to have a look at Expect, but I'm still just guessing.

        --
        http://fruiture.de
Re: Modifying STDOUT and keeping control
by Tardis (Pilgrim) on Oct 15, 2002 at 11:39 UTC
    Sometimes the simple tricks are the best:

    machine:~ > telnet hostname 25
    Trying 192.168.0.1...
    Connected to hostname.
    Escape character is '^]'.
    220 hostname.domain ESMTP Postfix
    QUIT
    221 Bye
    Connection closed by foreign host.
    
    compare to:
    machine:~ > telnet hostname 25 | tail +4
    220 hostname.domain ESMTP Postfix
    QUIT
    Connection closed by foreign host.
    221 Bye
    
    I'm not sure you won't still have line vs character mode issues, but it might help.