Как создать функционирующий индикатор выполнения в Ruby?

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

У меня есть простой скрипт, который имеет только apt-get update . Когда я запускаю его, я хочу, чтобы он показывал индикатор выполнения, а не показывал все, что показывает обновление, когда вы запускаете его в обычном режиме.

Этот код создает индикатор выполнения, но как мне его реализовать, чтобы он показывал индикатор выполнения, а не все строки, которые он обычно показывает?

 require 'progress_bar'
bar = ProgressBar.new

100.times do
  sleep 0.1
  bar.increment!
end
  

Комментарии:

1. Вы должны иметь возможность получить разумную оценку количества циклов, которые потребуются для выполнения чего-либо, или количество блоков данных будет перемещено, иначе вы не сможете создать полезный индикатор выполнения. apt-get не скажет вам, сколько вещей он должен сделать, потому что он не будет знать, пока не запустится update . Вы могли бы запустить его дважды, чтобы получить информацию с первого запуска, но это заняло бы в два раза больше времени. Поищите в Интернете, как написать индикаторы выполнения, и вы узнаете гораздо больше, например askubuntu.com/q/445245 .

Ответ №1:

Основываясь на комментарии Tin Man: вам нужно иметь доступ к процессу, чтобы знать, сколько раз что-то произойдет. Я не знаю о процессе apt-get, но, похоже, это будет невозможно.

Я могу привести вам пример кода, который я использую для загрузки файлов, но это нелегко объяснить.

То, что нужно сделать методу, это похоронить в File.open блоке, записывая полученные входные данные в файл, остальное используется для передачи информации в progressbar.

В основном вам нужны две вещи:

  1. длина (из скольких шагов состоит ваше действие)
  2. блок выполнения, который определяет, когда выполняется шаг (часть работы), и, следовательно, отображается индикатор выполнения.

Оба реализованы в виде лямбд:

 require 'ruby-progressbar'

def download url, file, folder
  pbar = nil
  open(url, "rb",
    :content_length_proc => lambda {|t|
     if t amp;amp; 0 < t
       pbar = ProgressBar.create(title: file, total:t, progress_mark:'█'.encode('utf-8')) 
     end
    },
    :progress_proc => lambda {|s|
     pbar.progress = s if pbar
    }) do |page|
    File.open("#{folder}/#{file}", "wb") do |f|
      while chunk = page.read(1024)
        f.write(chunk)
      end
    end
  end
end
  

Здесь показан пример того, что показано, заголовок панели — это загружаемое имя файла, за которым следуют маркеры.
Всего отображается 80 символов, поэтому результат аккуратно выравнивается справа в вашей консоли. В этой настройке количество необходимых маркеров рассчитывается в зависимости от content_length и результирующего пространства на экране.

 23b31538241754716ea6db15a634e9b2.jpg: |████████████████████████████████████████|
  

Комментарии:

1. Это работает, когда вы можете попасть внутрь цикла завершения и / или знать, сколько раз что-то должно произойти, но OP должен знать для apt-get , что не позволит этому произойти.

2. спасибо, железный дровосек, у меня нет опыта работы с apt-get, поэтому, похоже, он не сможет делать то, что он просит, я адаптирую свой ответ, но оставлю его на месте для других целей.