2

SSH セッション内のリモート マシンで作業したい:

  1. リモートサーバーにログインする
  2. 私の作品を作る

私のスクリプトでは、ステップ 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
4

1 に答える 1

2

問題はsu、サブシェルを作成していnet-sshて、最も外側のシェルを制御していることです。実行中のようなものです...emacsまたは からの何か、その内部シェルを制御する方法を知ることができるとnet-sshは期待できません。net-ssh

したがって、検出suが成功した場合は、入力したかのようにデータを送信する必要があります。その後、stdout を読み取ることができます。stdout残念ながら、サブシェルにあるため、 を から分離することはできませんが、stderrそれでも出力を取得できます。

ch.execafter suing を正常に使用する代わりにch.send_data "command\n"、出力を使用して読み取ります。すべてを . で終わらせることを忘れないでくださいch.send_data "exit\n"\n(コンソールでEnterキーを押すことをシミュレートするには、すべてのコマンドに従う必要があることに注意してください)

于 2011-03-18T23:24:21.630 に答える