How to SSH interactive Session

Good day everyone

I need to execute command on linux machine this command is interactive
command.
Interactive command means require input like [yes , no] or password
twice

my real case is.
I create a script execute commands and get the outputs successfully.
but some servers has Loging password expired so I need to interact with
server to send the current password + the new password(twice)


ssh [email protected]
[email protected]’s password:
You are required to change your password immediately (password aged)
Last login: Sun Aug 7 13:15:40 2011 from 10.0.0.28
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user userName.
Changing password for userName
(current) UNIX password:
New UNIX password:
Retype new UNIX password:

Notice:

  • I’ve no problem in executing command in normal case
  • please, I have to avoid workarounds like (echo “pass” | ssh -S) to
    make me pass any other interactive situations.
  • I’m using ‘net/ssh’ libs
  • The Script is Attached
    http://king-sabri.net/files/LinuxHWScanner.rb

so please advice
Appreciate your help in advance

I’d suggest using Net::SSH::Telnet. This is a wrapper around Net::SSH
which gives an API very similar to Net::Telnet - this in turn lets you
send commands and match on the responses with regexps to decide what to
do next.

It also means you can write code which works with both telnet and ssh.

Thanks Brian,
“Net::SSH::Telnet” is has an advantage which it’s keeping the session
open until finish all commands not like “Net::SSH” which is create a
session for each command/communication.

However, it doenst solve my issue


require ‘net/ssh/telnet’

host = “127.0.0.1”
user = ‘userName’ # username
pass = “password” # password

s = Net::SSH::Telnet.new(“Host” => host, “Username” => user, “Password”
=> pass)

puts s.cmd(“pwd”)
puts s.cmd “sudo passwd userName”

that’s my code :frowning:

On Wed, Oct 26, 2011 at 2:35 PM, KING SABRI [email protected]
wrote:

host = “127.0.0.1”

that’s my code :frowning:

Not sure whether that works but you could use “expect” to match and
react on what the remote side says.

require ‘expect’

example with file

File.open “x” do |io|

io.expect /^prompt/ do |line|
puts “Got #{line}”
io.puts “exit”
end
end

Kind regards

robert

@robert_k78 : Thanks dear

after your advice, I looked at it, I found it a Linux command, so if I
depend on it then I cant use my script on windows.

Thanks robert for your effort

any advises ? if there is a class can open PTY , it’ll solve my issue ?

On Thu, Oct 27, 2011 at 12:47 PM, KING SABRI [email protected]
wrote:

@robert_k78 : Thanks dear

after your advice, I looked at it, I found it a Linux command, so if I
depend on it then I cant use my script on windows.

???

I was talking about a part of Ruby standard library.

12:51:06 ~$ irb19 -r expect
Ruby version 1.9.2
irb(main):001:0> File.open(‘x’,‘w’){|io| io.puts ‘foo’}
=> nil
irb(main):002:0> File.read ‘x’
=> “foo\n”
irb(main):003:0> File.open(‘x’, ‘r’){|io| io.expect(/^foo/){|l| p l}}
[“foo”]
=> nil
irb(main):004:0> File.open(‘x’, ‘r’){|io| io.expect(/^bar/){|l| p l}}
nil
=> nil
irb(main):005:0>

Cheers

robert

Dear Robert

I give it a simple try…

require ‘net/ssh’
require ‘expect’

host = “127.0.0.1”
user = ‘Username’ # username
pass = “123123” # password

Net::SSH.start(host, user, :password=> pass) do |ssh|

puts ssh.exec!(“pwd”)

puts ssh.exec!(“sudo passwd Username”)
ssh.expect(/^Changing/m) do |newpass|
puts newpass
end
ssh.loop
end

but it seems the connection it self doesn’t accept the return output
from this command

I mean , if the case is , I got the message then the expect can get
work, but in my case nothing returns

KING SABRI wrote in post #1028587:

However, it doenst solve my issue


require ‘net/ssh/telnet’

host = “127.0.0.1”
user = ‘userName’ # username
pass = “password” # password

s = Net::SSH::Telnet.new(“Host” => host, “Username” => user, “Password”
=> pass)

puts s.cmd(“pwd”)
puts s.cmd “sudo passwd userName”

that’s my code :frowning:

Yes, well you have to explicitly expect the two different outcomes and
deal with them. Net::Telnet has built-in expect-like functionality.

s.cmd is basically a shortcut for “send this, then expect a prompt”. So
you need to use s.puts, expect with a regexp which matches either a
normal prompt or the password expiry, and if you get a password expiry
then deal with it appropriately.

Guys , I got the solution

kindly find the link
Here to Enter new password for expired password

Here to reset the password remotely

thanks for @candlerb , @robert_k78
and the big thanks for forker from stackflow