如何通过ssh在shell命令中显示进度条

Ste*_*fan 3 ruby ssh command-line

我有一个脚本应该在我的本地机器上模仿ffmpeg,通过将命令发送到远程机器,在那里运行然后返回结果.(参见前面的堆栈溢出问题.)

#!/usr/bin/env ruby

require 'rubygems'
require 'net/ssh'
require 'net/sftp'
require 'highline/import'


file = ARGV[ ARGV.index( '-i' ) + 1] if ARGV.include?( '-i' )  
puts 'No input file specified' unless file;

host = "10.0.0.10"
user = "user"
prod = "new-#{file}"               # product filename (call it <file>-new)
rpath = "/home/#{user}/.rffmpeg"   # remote computer operating directory
rfile = "#{rpath}/#{file}"         # remote filename
rprod = "#{rpath}/#{prod}"         # remote product
cmd = "ffmpeg -i #{rfile} #{rprod}"# remote command, constructed

pass = ask("Password: ") { |q| q.echo = false }  # password from stdin

Net::SSH.start(host, user ) do |ssh|
        ssh.sftp.connect do |sftp|

                # upload local 'file' to remote 'rfile'
                sftp.upload!(file, rfile)

                # run remote command 'cmd' to produce 'rprod'
                ssh.exec!(cmd)

                # download remote 'rprod' to local 'prod'
                sftp.download!(rprod, prod)
        end
end
Run Code Online (Sandbox Code Playgroud)

现在我的问题是

ssh.exec!(cmd)
Run Code Online (Sandbox Code Playgroud)

我想实时向本地用户显示cmd的输出.但是做到了

puts ssh.exec!(cmd)
Run Code Online (Sandbox Code Playgroud)

命令运行完毕后,我只得到结果输出.我如何更改代码才能使其工作?

小智 7

在问题的显示方面,您可以使用"\ r"字符串char在Ruby中生成更新进度条.这会将您备份到当前行的开头,允许您重新编写它.例如:

1.upto(100) { |i| sleep 0.05; print "\rPercent Complete #{i}%"}
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想在屏幕上显示进度条,则可以执行与此类似的操作:

1.upto(50) { sleep 0.05; print "|"}
Run Code Online (Sandbox Code Playgroud)

此外,与stdout相关,除了前一个示例(STDOUT.flush)的刷新输出之外,您还可以要求Ruby自动将写入与IO缓冲区(在本例中为STDOUT)同步设备写入(基本上关闭内部缓冲):

STDOUT.sync = true
Run Code Online (Sandbox Code Playgroud)

此外,我发现有时刷新对我不起作用,我使用"IO.fsync"代替.对我而言,这主要与文件系统工作有关,但值得了解.