我需要通过SSH启动远程Python脚本。远程计算机上的Python脚本需要执行一些文件操作,为模拟启动可执行文件(从几个小时到几天),收集结果并写入文件。
我使用Net-SSH exec!
从Ruby启动脚本。我使用渠道来捕获STDERR
和STDOUT
。
脚本运行正常,但现在我想从本地Ruby脚本中分离远程机器上运行的脚本。然后,我将直接在远程机器上检查模拟的状态。
我尝试使用nohup
运行脚本。
Net::SSH.exec!("nohup python script.py args > out.log 2> err.log < /dev/null &")
脚本已分离,我立即恢复控制,但远程计算机上的脚本被杀死,我无法在后台找到该进程。
理想情况下,我会直接从Ruby启动模拟可执行文件,但我必须使用Python,因为我需要一些Ruby中没有的库。
上述方法是否正确?我可以将nohup
与Net-SSH一起使用吗?
有更好的方法吗?
编辑:
def self.ssh_exec!(ssh, cmd, log = nil)
ssh.open_channel do |ch|
ch.request_pty do |chan,success|
end
ch.exec(cmd) do |chan, success|
raise "could not execute command" unless success
# "on_data" is called when the process writes something to stdout
chan.on_data do |c, data|
log ? (log << data) : (puts data)
end
# "on_extended_data" is called when the process writes something to stderr
chan.on_extended_data do |c, type, data|
log ? (log.error data) : (puts data)
end
chan.on_close do
puts 'Done'
end
end
end
end
然后我打电话给
Net::SSH.start(aws_ip, user, options = aws_options) do |ssh|
script = File.join(path, 'pyfoam_scripts', 'run_case.py')
cmd = "source...; python #{script} #{dst_case}"
RG::Utils.ssh_exec!(ssh, cmd, @logger)
ssh.loop
end
其中
:options => {:keys => path_to_key, 'key.pem'),
:keepalive => true,
:timeout => 3000,
:compression => true,
:compression_level => 6},
答案 0 :(得分:0)
经过一些测试后,感谢评论,我意识到我的代码中有三个错误:
channels
。 Channels
用于与远程计算机建立通信,捕获输出,使用回调。在这种情况下,我不需要任何这个。Net::SSH.exec!
等待命令完成。我需要发射并忘记。 (愚蠢的错误)ssh.loop
不需要。见1. 修正上述错误后,它就像魅力一样。