fork download
  1. require "net/ssh"
  2.  
  3. Net::SSH.start("192.168.0.12", "testuser", {:password => "testpass"}) {|ssh|
  4. # ログイン時の Message of the day 消し
  5. ssh.exec! "ls"
  6.  
  7. # ステートマシンとして実装しなおしたほうがいい、今は実験中
  8. expected = false
  9. su_cmd_sended = false
  10. su_exited = false
  11. skip_head = false
  12. end_load = false
  13. stdout_data = ""
  14.  
  15. # channel = ssh.open_channel
  16. # channel.close
  17. #
  18. # って書式は例外飛ばされるのでブロック必須、中がすげぇカオスになりがち
  19. ssh.open_channel {|channel|
  20.  
  21. # (出力としては断片的な)パケットをもらったとき
  22. # ls -al /etc すると
  23. # "total 764" ってdataでこのイベントが走り
  24. # "drwxr-xr-x 83 root root 4096 Mar 24 16:00 ." ってdataが来るイベント発動 orz
  25. channel.on_data {|ch, data|
  26. if !expected
  27. if data =~ /assword:/
  28. channel.send_data "rootpass\n"
  29. channel.process
  30. expected = true
  31. end
  32. else
  33. # ターミナルでsu - した直後
  34. if !su_cmd_sended
  35. channel.send_data "stty -echo\n"
  36. channel.process
  37.  
  38. # コマンドの終了を判定するための文言を無理やり追加なう
  39. channel.send_data "PS1='__currently__auto__mode__'\n"
  40. channel.process
  41.  
  42. # したいことをおくろう
  43. channel.send_data "ls -al\n"
  44. channel.process
  45.  
  46. su_cmd_sended = true
  47. elsif !skip_head
  48. # PS1で設定した文言来るまではエコーバック、コマンド実行結果じゃない
  49. if data =~ /__currently__auto__mode__$/
  50. skip_head = true
  51. end
  52. elsif !end_load
  53. # PS1で設定したあの文言が来たら出力は終わったと思われ
  54. if data =~ /__currently__auto__mode__/
  55.  
  56. # rootからexit
  57. channel.send_data "exit\n"
  58. channel.process
  59.  
  60. # 一般ユーザーからexit (でリモート側がeof)、こっちからのchannel.eof!はNet::SSHにシカトされた
  61. channel.send_data "exit\n"
  62. channel.process
  63.  
  64. end_load = true
  65. else
  66. # まだPS1の文言は来てないから出力でそ、コマンド出力の一部分しか来ないねん
  67. stdout_data += data
  68. end
  69. end
  70. end
  71. }
  72.  
  73. # ptyがくっつきますた、on_dataコールバックの"data"に user@machine: ~$ とか拾うようになります
  74. channel.request_pty
  75. channel.send_channel_request "shell" do |ch, success|
  76. channel.send_data "su - \n"
  77. channel.process
  78. end
  79. }
  80.  
  81. ssh.loop
  82. print stdout_data.chomp
  83. # 問題: su - の後にぶっぱしたコマンドの戻り値が取れない
  84. }
  85.  
Runtime error #stdin #stdout #stderr 0s 28680KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
prog.rb:1:in `require': cannot load such file -- net/ssh (LoadError)
	from prog.rb:1:in `<main>'