ruby ssh:交互式命令"su":成功登录后还有多远? [英] ruby ssh: interactive command "su": How further after successfull logged in?

查看:137
本文介绍了ruby ssh:交互式命令"su":成功登录后还有多远?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在SSH会话中的远程计算机上工作:

I want work on a remote machine within a SSH session:

  1. 在远程服务器上登录
  2. su
  3. 做我的工作

使用我的脚本,可以执行第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正在控制最外层外壳.就像运行... emacsnet-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成功后,必须像刚刚键入数据一样发送数据,然后才能读取标准输出.不幸的是,由于stdoutstderr在子外壳中,因此无法将其分开,但是仍然可以得到输出.

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 suing 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆