Ruby,通过SSH逐个运行linux命令并记录所有内容
我想用Ruby witch net::ssh编写代码,在远程linux机器上逐个运行命令并记录所有内容(在linux机器上称为command、stdout和stderr) 所以我写函数: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
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中检查它,但是谢谢您的时间。也许将来会有人用它。