我想在 SSH 会话中的远程计算机上工作:
- 登录远程服务器
- su
- 做我的工作
使用我的脚本 a 可以完成步骤 1 和 2 的工作。在执行 su 命令时,我可以发送密码,并得到了我期望的答案(
on_data: data = gis@v04ree:~>
got gis@v04ree:~>
但接下来我该怎么办呢?我坐在我的频道上,什么也没发生。
如何让通道了解命令已完成并且我想在远程计算机上完成工作?
require 'net/ssh'
require 'net/sftp'
class Connection
def connect
host = 'host'
user = 'user'
#1. Login
Net::SSH.start(host, user) do |ssh|
puts ssh.exec!("whoami")
#2. su
begin
puts(su(ssh, "otherUser", "otherPwd"))
rescue Exception => e
puts e
end
#3. work
puts "logged in as " << ssh.exec!("whoami")
ssh.close
end
end
def su(ssh, user, pwd)
channel = ssh.open_channel do |ch|
channel.request_pty do |ch, success|
raise "Could not obtain pty (i.e. an interactive ssh session)" if !success
end
command = "su - #{user}\n"
puts "command = #{command}"
channel.exec command do |ch, success|
raise "could not execute command" unless success
# "on_data" is called when the process writes something to stdout
ch.on_data do |c, data|
puts "on_data: data = "+data
if data == "Password: "
puts "Password request"
channel.send_data "#{pwd}\n"
end
if data == "gis@v04ree:~> "
#logged in as gis
puts "got gis@v04ree:~>"
#and now? What's next?
#channel.eof! # <-doesn't work
ch.exec "ls" do |ch, success| #<- doesn't work either: success is false
unless success
puts "alas! the command could not be invoked!"
end
end
end
end
#wouldn't be called
ch.on_extended_data do |c, type, data|
puts "on_extended_data: data = #{data}"
end
end #end su - gis
#which statement
ssh.loop
#channel.wait
end
end
end #class end
Connection.new.connect
问题是su
正在创建一个子shell,并且net-ssh
控制着最外层的外壳。就像跑步一样...emacs
或来自net-ssh
,你不能期望net-ssh
能够知道如何控制那个内壳。
所以你要做的就是当你检测到su
成功后,您必须像刚刚输入数据一样发送数据,然后才能读取标准输出。不幸的是,你无法将它们分开stdout
来自stderr
因为它在子 shell 中,但您仍然可以获得输出。
而不是使用ch.exec
after su
成功,使用ch.send_data "command\n"
并读取输出。不要忘记用一个结束一切ch.send_data "exit\n"
。 (注意\n
必须遵循每个命令来模拟控制台中的输入按键)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)