ruby ssh:交互式命令"su":成功登录后还有多远? [英] ruby ssh: interactive command "su": How further after successfull logged in?
问题描述
我想在SSH会话中的远程计算机上工作:
I want work on a remote machine within a SSH session:
- 在远程服务器上登录
- su
- 做我的工作
使用我的脚本,可以执行第1步和第2步.在执行su命令时,我可以发送密码,并得到期望的答案(
With my script a can do step 1 and 2 works. While executing the su command, I can send the password, and got the answer I'm expecting (
on_data: data = gis@v04ree:~>
got gis@v04ree:~>
但是,我该怎么办?我坐在自己的频道上,没有任何反应. 如何让频道了解命令已完成,并且希望在远程计算机上工作呢?
But then, what should I do? I'm sitting on my channel, nothing happens. How can I make the channel understand that the command has finished and that I want to make my wor on the remote machine?
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
正在创建子外壳,而net-ssh
正在控制最外层外壳.就像运行... emacs
或net-ssh
中的内容一样,您不能指望net-ssh
能够知道如何控制该内壳.
The problem is that su
is creating a subshell, and net-ssh
is controlling the outermost shell. Its just like running... emacs
or something from net-ssh
, you can't expect net-ssh
to be able to know how to control that inner shell.
因此,您需要做的是检测到su
成功后,必须像刚刚键入数据一样发送数据,然后才能读取标准输出.不幸的是,由于stdout
和stderr
在子外壳中,因此无法将其分开,但是仍然可以得到输出.
So what you have to do is when you detect su
was successful, you have to send the data as if you were just typing it in, and then you can read the stdout. Unfortunately, you can't separate the stdout
from the stderr
since its in a subshell, but you can still get the output.
成功完成su
之后,不要使用ch.exec
,而是使用ch.send_data "command\n"
并读取输出.不要忘记以ch.send_data "exit\n"
结尾的所有内容. (请注意,\n
必须遵循每个命令,才能在控制台中模拟Enter键)
Instead of using ch.exec
after su
ing successfully, use ch.send_data "command\n"
and read the output. Don't forgot to end everything with a ch.send_data "exit\n"
. (Note that \n
has to follow every command to simulate an enter keypress in the console)
这篇关于ruby ssh:交互式命令"su":成功登录后还有多远?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!