ruby ssh:交互式命令“su”:成功登录后又如何?

时间:2010-06-17 12:40:54

标签: ruby ssh interactive

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

  1. 登录远程服务器
  2. su
  3. 让我的工作
  4. 使用我的脚本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
    

1 个答案:

答案 0 :(得分:2)

问题是su正在创建一个子shell,而net-ssh正在控制最外层的shell。就像运行emacs或来自net-ssh的某些内容一样,您不能指望net-ssh能够知道如何控制内壳。

所以你需要做的就是当你发现su成功时,你必须发送数据就好像你只是输入它一样,然后你就可以阅读标准输出了。遗憾的是,您不能将stdoutstderr分开,因为它位于子shell中,但您仍然可以获得输出。

在成功ch.exec之后,不使用su,而是使用ch.send_data "command\n"并阅读输出。不要忘记用ch.send_data "exit\n"结束所有事情。 (请注意,\n必须遵循每个命令来模拟控制台中的回车键