Telnet - how to loop through commands listed in a file

Let me first explain what I’m trying to do. I have written a very
simplistic ruby telnet script. It logs in and can send one command I
give from the command line.

What I need, or want, to do is have a file which contains multiple
commands I would like to have executed on the switch I am connecting to
via telnet.

The script and a sample of the file are attached.

I currently have not removed the command line argument for passing in
the telnet command but it is not used so using a -c “nothing” gets me
past that. If and when I can get the source file working I will change
that for naming the file.

I get a failure in the for loop "C:Ruby Scripts/Telnet.rb:54:in
<main>': undefined methodeach’ for #String:0x2949e58
(NoMethodError)

If I enter a telnet.cmd line for each command it works but then it
limits the flexibility of being able to have multiple files with
different commands.

Thank you for any assistance. It would be greatly appreciated.

Hi, I believe you have an error in your for loop. why don’t you try this
for example:
net = Net::Telnet::new(“Host” => “#{$host}”, “TIMEOUT” => 10, “Prompt”
=>
/[$%#>] \z/
telnet.login(“admin”, “password”) { |c| print c }
File.open (“CMDs.txt”).each
{ | line |
telnet.cmd (line.gsub(“"”,“”)) { …}
}

I hope you get the idea.
And if you can use ssh to manage your network switch.
28-02-2013 22:26, “Bob F.” [email protected] napisa(a):

I looked at my for loop and saw that I didn’t even use the correct
variable in the loop… I change it but received the same error.

I tried the mentioned:
File.open (“CMDs.txt”).each
{ | line |
telnet.cmd (line.gsub(""","")) { …}
}
But that failed with the following:
C:/Ruby Scripts/TelnetCMDs.rb:56: syntax error, unexpected tLPAREN_ARG,
expecting $end
telnet.cmd (line.gsub(""","")) { |c| print c }

“{ | line |” must be on the same line as “.each”

On Thu, Feb 28, 2013 at 4:55 PM, Bob F. [email protected] wrote:

expecting $end
telnet.cmd (line.gsub(“"”,“”)) { |c| print c }

File.open(…) passes a file handle to the block. If you want to spin
through each line in a loop, try:

File.readlines(“CMDs.txt”).each do |line|
telnet.cmd(line.gsub(“"”, “”)) { … }
end

To stay with .open:

File.open(“CMDs.txt”) do |cmds|
telnet.cmd(cmds.gets.gsub(“"”, “”)) { … |
end

This is all working now.

======================= snippet =======================
telnet = Net::Telnet::new(“Host” => “#{$host}”,
“TIMEOUT” => 10,
“Prompt” => /[$%#>] \z/)
telnet.login(“admin”, “password”) { |c| print c }

File.readlines("#{$file_arg}").each do |line|
telnet.cmd(line.gsub(""", “”)) { |c| print c }
end

telnet.close

======================= snippet end =======================

What I’d like to do now is have the ability to do a nested loop where
the script acts on multiple file.

I tried many things but the answer eludes me. Here is one attempt:

======================= trial nested loop =======================
filenames = “#{$file_arg}”
filenames.each do |filename|
File.readlines(“filename”).each do |line|
telnet.cmd(line.gsub(""", “”)) { |c| print c }
end
end
======================= end trial nested loop =======================

The output is:

Ruby Scripts/TelnetCmds.rb:55:in <main>': undefined methodeach’ for
“C:\Scripts\VLAN_ES7000.txt”:String (NoMethodError)

Feeling stupid as this should be an easy thing to do. But again, the
answer is eluding me.

Am 05.03.2013 18:55, schrieb Bob F.:

end
end
======================= end trial nested loop =======================

The output is:

Ruby Scripts/TelnetCmds.rb:55:in <main>': undefined methodeach’ for
“C:\Scripts\VLAN_ES7000.txt”:String (NoMethodError)

The problem should be pretty clear from the error message.
You are trying to call #each for a string, but you actually
want an array of filenames, like this:

filenames = [‘file1’, ‘file2’, ‘file3’]
filenames.each do |filename|
puts filename # whatever
end

Hmmm, The files are entered from the command line using a getopt (e.g -f
“file1 file2 file3”).

I’ll look into this some more. Thank you.

unknown wrote in post #1100227:

Am 05.03.2013 19:07, schrieb Bob F.:

Hmmm, The files are entered from the command line using a getopt (e.g -f
“file1 file2 file3”).

I’ll look into this some more. Thank you.

“file1 file2 file3”.split

I invoke this script from the commandline like such

ruby TelnetCmds.rb -h 192.168.1.10 -f “C:{PATH_TO_FILE}\File1
C:{PATH_TO_FILE}|File2”

I’ve been trying to convert that string to an array but I get the same
error.

filenames = “#{$file_arg}.split(” “)”

Am 05.03.2013 19:07, schrieb Bob F.:

Hmmm, The files are entered from the command line using a getopt (e.g -f
“file1 file2 file3”).

I’ll look into this some more. Thank you.

“file1 file2 file3”.split

Bob F. wrote in post #1100248:

unknown wrote in post #1100227:

Am 05.03.2013 19:07, schrieb Bob F.:

Hmmm, The files are entered from the command line using a getopt (e.g -f
“file1 file2 file3”).

I’ll look into this some more. Thank you.

“file1 file2 file3”.split

I invoke this script from the commandline like such

ruby TelnetCmds.rb -h 192.168.1.10 -f “C:{PATH_TO_FILE}\File1
C:{PATH_TO_FILE}|File2”

I’ve been trying to convert that string to an array but I get the same
error.

filenames = “#{$file_arg}.split(” “)”

I got it finally:

filenames = “#{$file_arg}”.split(/ /)

Thank you for all the help!!!

Am 05.03.2013 21:40, schrieb Bob F.:

unknown wrote in post #1100227:

Am 05.03.2013 19:07, schrieb Bob F.:

Hmmm, The files are entered from the command line using a getopt (e.g -f
“file1 file2 file3”).

I’ll look into this some more. Thank you.

“file1 file2 file3”.split

Note that split is not part of the string,
but a method sent to the string!

I invoke this script from the commandline like such

ruby TelnetCmds.rb -h 192.168.1.10 -f “C:{PATH_TO_FILE}\File1
C:{PATH_TO_FILE}|File2”

I’ve been trying to convert that string to an array but I get the same
error.

filenames = “#{$file_arg}.split(” “)”

Do you use irb to actually see what your code is doing?
You really should:

2.0.0-p0 :001 > file_arg = “file1 file2 file3”
=> “file1 file2 file3”
2.0.0-p0 :002 > “#{file_arg}.split(” “)”
=> “file1 file2 file3.split()”

On Tue, Mar 5, 2013 at 4:25 PM, Bob F. [email protected] wrote:

I got it finally:

filenames = “#{$file_arg}”.split(/ /)

Thank you for all the help!!!


Posted via http://www.ruby-forum.com/.

Just thinking:

“#{$file_arg}” should be the same as $file_arg, no? You’re getting
strings from the command line parser, so the interpolation is
unnecessary. This should suffice:

filenames = $file_arg.split(/ /)

assuming you’re guaranteed one space between files. If it could be
more than one, you’ll want something like:

filenames = $file_arg.split(/ +/)

at the least. That’s generally considered bad form (not sure whether
the space and/or plus was deliberate), though, so better would be:

filenames = $file_arg.split(/[ ]+/)

Secondly, in Ruby, a $var is a global. You may not want that (true
global variables should be rarer than hen’s teeth).

I’ve now run into a little conundrum. There is one command that can
take up to 15 seconds to complete so I attempted to put in a simple “if”

========== snippet ==========
if #{line} == ‘w s’
puts “The commands is: #{line}\nWe should be sleeping for 15
seconds\n”
telnet.cmd(line.gsub(""", “”)) { |c| print c }
sleep 15
else
telnet.cmd(line.gsub(""", “”)) { |c| print c }
end

========== end snippet ==========

The “puts” prints for every single line. The sleep is never
encountered. I had placed an exit right under the “puts”. The “else”
line is the one being executed.

I assumed the “puts” the telnet.cmd and then the sleep would only happen
if #{line} equaled “w s”.

Once again I ask you out there what am I doing wrong?

Am 08.03.2013 17:54, schrieb Bob F.:

I’ve now run into a little conundrum. There is one command that can
take up to 15 seconds to complete so I attempted to put in a simple “if”

========== snippet ==========
if #{line} == ‘w s’

You want: if line == ‘w s’

#{line} only makes sense in a double quoted string,
without quotes you are starting a comment here!

I think you should read up on some basic Ruby syntax,
try e.g. Learn to Program, by Chris Pine.

Generally, placing puts statements like ‘puts your_var.inspect’
or ‘p your_var’ just before “critical” places in your code could
help you understand what’s going wrong.

And you should develop a habit of testing (simplified) code
snippets with irb.

Am 08.03.2013 20:14, schrieb Bob F.:

#{line} only makes sense in a double quoted string,
snippets with irb.

Yes I see I’ve forgotten the quotes. I had inadvertently stripped them
off trying different things.

you should not use them here, just do

if line == ‘w s’
puts ‘yes’
else
puts ‘no’
end

If that does not solve your problem, place

p line

just before your if expression in order to see what ‘line’
actually contains. There could be a newline character at the end,
if so, you can use ‘chomp’ (line.chomp) to get rid of it.

(“w b\n” and “w b” are different.)

I’ve read and googled and I know I’m horrible at Ruby. I only posted
here as a last resort.

Nothing I have attempted has worked. I know I’m missing something very
simple and hoped someone here might have been able to point me in the
correct direction.

Please forgive my ignorance and please forgive my asking for help on the
forum. It’ll not happen again.

No problem at all. Just ask.

unknown wrote in post #1100737:

Am 08.03.2013 17:54, schrieb Bob F.:

I’ve now run into a little conundrum. There is one command that can
take up to 15 seconds to complete so I attempted to put in a simple “if”

========== snippet ==========
if #{line} == ‘w s’

You want: if line == ‘w s’

#{line} only makes sense in a double quoted string,
without quotes you are starting a comment here!

I think you should read up on some basic Ruby syntax,
try e.g. Learn to Program, by Chris Pine.

Generally, placing puts statements like ‘puts your_var.inspect’
or ‘p your_var’ just before “critical” places in your code could
help you understand what’s going wrong.

And you should develop a habit of testing (simplified) code
snippets with irb.

Yes I see I’ve forgotten the quotes. I had inadvertently stripped them
off trying different things.

I’ve read and googled and I know I’m horrible at Ruby. I only posted
here as a last resort.

Nothing I have attempted has worked. I know I’m missing something very
simple and hoped someone here might have been able to point me in the
correct direction.

Please forgive my ignorance and please forgive my asking for help on the
forum. It’ll not happen again.