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

Good morning,
I am still suffering with problems with the Net::Telnet module. Basically, I need to telnet into a machine, read in the contents of the .vacation.msg file, and, without changing the actual .vacation.msg file, return to the perl script the vacation message with all occurances of '$SUBJECT' replaced with 'SUBJECT'. The relavant code is as follows:
#!/usr/bin/perl my $SED = "/bin/sed"; my $username = "user1"; my $password = "password"; my $host = "localhost"; &start_login; sub start_login { my $telnet = new Net::Telnet( -host => $hostname, -telnetmode => ''); telnet_login($username,$password,$host,\$telnet); ### This is the the problem area ### @vacation_str=$telnet->cmd("$SED s/\$SUBJECT/SUBJECT/g /home/$usern +ame/.vacation.msg"); ### telnet_close(\$telnet); } sub telnet_login { use Net::Telnet; my ($username, $password, $host, $telnet) = @_; my $error_msg = "Incorrect username or password, please try again" +; my $error_type = "ERROR"; $$telnet = new Net::Telnet ('Timeout'=>'7', 'Prompt'=> '/.*([\$#\%>~]|\\\[\\e\[0m\ +\\] \[0m)\s?/' ); $$telnet->open(Host=>$host); $$telnet->login($username,$password); }
I applogize for posting a similar post previously. Two people responded with some very good ideas that I am stil working with. Yet, I am still unable to make headway. The above code does not return to the variable @vacation_str what I expect. If I simply run the above 'sed' command in bash, it returns exactly what I am looking for (a vacation message string with all of the '$'s stripped from it). However, Using the Net::Telnet 'cmd' method to send the above command 'sed s/\$SUBJECT/SUBJECT/g /home/$username/.vacation.msg', only the first line of the vacation message shows up. Dispite all the approaches I have tried, I have not found one that returns the full contents of the .vacation.msg file when the file contains a $. My best guess is that I am not escaping something in the 'sed' commnad correctly, though I have tried fruitlessly to modify the expression so that it will work. If anyone has any ideas or resources, I would be very open to what you have to say. Thanks for your time,
Joe

Replies are listed 'Best First'.
Re: Net::Telnet, cmd, and sed
by belden (Friar) on Jun 27, 2003 at 21:04 UTC
    ### This is the the problem area ### @vacation_str=$telnet->cmd("$SED s/\$SUBJECT/SUBJECT/g /home/$usern +ame/.vacation.msg"); ###

    I'd guess that the problem is that you need to add an extra pair of \ to your sed command in order to escape SUBJECT properly:

    ### This is the the problem area ### @vacation_str=$telnet->cmd("$SED s/\\\$SUBJECT/SUBJECT/g /home/$use +rname/.vacation.msg"); ###

    As is, "\$SUBJECT" will send "$SUBJECT" to the shell that you're talking to; that shell will try to expand $SUBJECT. Since this is actually text within the file you're munging, you need to make the shell see \$SUBJECT. (I'm guessing here but this seems about right.)

    Another way of doing it would be to cut sed out of the loop altogether:

    @vacation = map { s/\$SUBJECT/SUBJECT/g } $telnet->cmd("cat ~$username/.vacation.msg");

    If that doesn't fix it, then the problem might not be the shell interpreting SUBJECT - perhaps the .vacation.msg file you're looking at has a sequence of characters in it that match your Net::Telnet object's prompt() string. You may need to try briefly undefining prompt() within your object, do your cat/sed/whatever, then re-define prompt().

    Gosh, I'm just full of ideas. In some places, your code refers to $$telnet, and in others, it refers to $telnet. This might be causing your cmd() some grief. Try tossing a 'use strict; use warnings;' at the top of your code to see what complains :)

    When automating Net::Telnet connections to other machines, I've found that I can get away with a very limited range of commands at the remote machine, particularly for file manipulations such as the one you're doing. /bin/echo and /bin/ls can be used to check whether files and directories exist; /bin/cat returns file contents to your program, so you can do whatever complex greps and seds on them using Perl's regexes.

    Good luck on your project, sounds like a fun one.

    blyman
    setenv EXINIT 'set noai ts=2'
      Wow! Thanks for all the ideas. Hopefully this will help me make some progress. I appreciate the help, especially when I am stuck at a stumbling block such as this. Can't wait to try some of this stuff out....