Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby,通过SSH逐个运行linux命令并记录所有内容_Ruby_Ssh_Command_Logging_Sequential - Fatal编程技术网

Ruby,通过SSH逐个运行linux命令并记录所有内容

Ruby,通过SSH逐个运行linux命令并记录所有内容,ruby,ssh,command,logging,sequential,Ruby,Ssh,Command,Logging,Sequential,我想用Ruby witch net::ssh编写代码,在远程linux机器上逐个运行命令并记录所有内容(在linux机器上称为command、stdout和stderr) 所以我写函数: def rs(ssh,cmds) cmds.each do |cmd| log.debug "[SSH>] #{cmd}" ssh.exec!(cmd) do |ch, stream, data| log.debug "[SSH:#{stream

我想用Ruby witch net::ssh编写代码,在远程linux机器上逐个运行命令并记录所有内容(在linux机器上称为command、stdout和stderr)

所以我写函数:

  def rs(ssh,cmds)
    cmds.each do |cmd|
      log.debug "[SSH>] #{cmd}"
      ssh.exec!(cmd) do |ch, stream, data|    
        log.debug "[SSH:#{stream}>] #{data}"            
      end  
    end
  end
例如,如果我想在远程linux上创建新文件夹和文件:“./verylongdirname/anotherlongdirname/a.txt”,并在该目录中列出文件,然后在其中找到firefox(这有点愚蠢:p),所以我调用上面的过程如下:

Net::SSH.start(host, user, :password => pass) do |ssh|  

  cmds=["mkdir verylongdirname", \                                 #1
        "cd verylongdirname; mkdir anotherlongdirname, \           #2
        "cd verylongdirname/anotherlongdirname; touch a.txt", \    #3
        "cd verylongdirname/anotherlongdirname; ls -la", \         #4
        "cd verylongdirname/anotherlongdirname; find ./ firefox"   #5 that command send error to stderr.
        ]

  rs(ssh,cmds)   # HERE we call our function

  ssh.loop
end
  cmds=["mkdir verylongdirname", \     #1
        "cd verylongdirname", \        
        "mkdir anotherlongdirname", \  #2
        "cd anotherlongdirname", \
        "touch a.txt", \               #3
        "ls -la", \                    #4
        "find ./ firefox"]             #5
在运行上述代码之后,我将在第1、2、3、4、5行中获得有关执行命令的完整日志信息。问题是,在linux上,cmds数组的execude命令之间的状态并没有保存(所以在运行正确的命令之前,我必须重复“cd”语句)。我对此并不满意

我的目的是创建这样的cmds表:

Net::SSH.start(host, user, :password => pass) do |ssh|  

  cmds=["mkdir verylongdirname", \                                 #1
        "cd verylongdirname; mkdir anotherlongdirname, \           #2
        "cd verylongdirname/anotherlongdirname; touch a.txt", \    #3
        "cd verylongdirname/anotherlongdirname; ls -la", \         #4
        "cd verylongdirname/anotherlongdirname; find ./ firefox"   #5 that command send error to stderr.
        ]

  rs(ssh,cmds)   # HERE we call our function

  ssh.loop
end
  cmds=["mkdir verylongdirname", \     #1
        "cd verylongdirname", \        
        "mkdir anotherlongdirname", \  #2
        "cd anotherlongdirname", \
        "touch a.txt", \               #3
        "ls -la", \                    #4
        "find ./ firefox"]             #5

如您所见,在linux机器上,运行每个命令之间的状态是save(在运行正确的命令之前,我们不需要重复适当的“cd”语句)。如何更改“rs(ssh,cmds)”过程以像以前一样执行此操作并记录所有内容(comand,stdout,stdin)?

或许可以尝试使用ssh通道来打开远程shell。当连接保持打开时,应保持命令之间的状态:

这里还有一篇文章是关于用一点不同的方法做一些类似的事情:

编辑1

嗯。我明白你在说什么<代码>同步shell已从Net::SSH 2.0中删除。但是我发现了这个,看起来它和
SyncShell
做的差不多:

例如:

s = Net::SSH.start(host, user)
t = Net::SSH::Telnet.new("Session" => s, "Prompt" => %r{^myprompt :})
puts t.cmd("cd /tmp")  
puts t.cmd("ls")       # <- Lists contents of /tmp
s=Net::SSH.start(主机、用户)
t=Net::SSH::Telnet.new(“会话”=>s,“提示”=>%r{^myprompt:})
放置t.cmd(“cd/tmp”)

放置t.cmd(“ls”)#您可以改用管道:

require "open3"

SERVER = "..."
BASH_PATH = "/bin/bash"

BASH_REMOTE = lambda do |command|
  Open3.popen3("ssh #{SERVER} #{BASH_PATH}") do |stdin, stdout, stderr|
    stdin.puts command
    stdin.close_write
    puts "STDOUT:", stdout.read
    puts "STDERR:", stderr.read
  end
end

BASH_REMOTE["ls /"]
BASH_REMOTE["ls /no_such_file"]

好的,最后在@Casper的帮助下,我得到了这个过程(可能有人使用它):


谢谢,再见。

这是关于Net的包装器/ssh这是文章

来源


要记录所有命令,只需覆盖Box.bash方法并在其中添加日志记录

1。我们看到:`shell=session.shell.sync`Thad web是从2006年开始的。现在,ruby shell.sync无法工作。Shell可能是从developnet::ssh中删除的(我不知道为什么)。有一些可供选择的包netsshshell,但使用起来还很年轻(那里没有实现多少功能)。我以前读过。当我尝试使用带有on_数据(用于stdout)、on_扩展_数据(用于stderr)和send_数据(用于循环中逐个发送命令)功能的通道时——但我无法强制顺序日志(记录顺序命令1、stdout1、STDER1、command2、stdout2、STDER2、command3、stdout3、sterr3…)。原因是在send_data中,所有命令都是在第一个命令在远程机器上执行之前发送的(因此在日志中我们看到:command1、command2、command3、…、stdout1、stderr1、stdout2、stderr2、stdout3、stderr3…)。好的,非常感谢,这是我不想做的顺便说一句:我的linux提示符是“/[$%#>]\z/n”-它是net/ssh/telnet包的默认值-因此我不需要使用“提示符”选项。感谢该解决方案在Windows中不起作用-因此它不可移植。我没有在linux中检查它,但是谢谢您的时间。也许将来会有人用它。