Можно ли показать вывод rsync на одной строке?

У меня есть сценарий bash, который rsyncing большой каталог и функция -progress отлично, но возможно ли показать весь этот вывод в одной строке? то есть. как передача файлов, просто плюйте на него –progress output на ту же строку, что и последняя, ​​чтобы я мог следить за прогрессом без прокрутки экрана?

2 Solutions collect form web for “Можно ли показать вывод rsync на одной строке?”

Сценарий обертки

Вот проект сценария оболочки, написанный на Perl, который будет эмулировать PTY (поэтому rsync должен вести себя точно так же, как в терминале), и анализирует вывод, чтобы он мог поддерживать двухстрочный показ файла и статус передачи. Это выглядит так:

src/test.c 142 100% 0.19kB/s 0:00:00 (xfr#28, to-chk=0/30) 

Первая строка (filename, src/test.c ) изменится в зависимости от текущего имени файла, полученного rsync . Вторая строка будет изменяться всякий раз, когда rsync выводит обновленную строку состояния.

NB: я выбрал 2-строчный дисплей (еще один, который все еще не будет прокручиваться!) Вместо 1-строчного дисплея, по крайней мере в моем типичном использовании, я получаю длинный путь / имена файлов, которые были бы слишком широкими, если в сочетании со строкой состояния. Однако, как вы увидите ниже, было бы легко изменить, чтобы объединить файл / путь и статус в одну строку.

Когда rsync завершает работу, сценарий выходит с тем же кодом выхода (так что вы все еще можете ловить ошибки и т. Д.),

обоснование

Основываясь на обсуждениях с OP, встроенные параметры rsync были неадекватными, их версия rsync старше, и их потребности уникальны. Таким образом, я чувствовал, что пользовательский скрипт является единственным способом достижения своей цели.

Другие варианты состоят в том, чтобы использовать любую из многих существующих утилит оболочки rsync «backup» уже там, хотя я не знаю никого, поддерживающего аналогичный вывод.

Исходный код

  #!/usr/bin/env perl # Custom progress wrapper for rsync use 5.012; use strict; use warnings; use autodie; use IPC::Run qw/run start pump finish harness/; my $RSYNC=`which rsync`; # Try to get rsync location from PATH chomp $RSYNC; my ($in,$out); # Input and output buffers my $h = harness [ $RSYNC, @ARGV ], '<pty<', \$in, '>pty>', \$out; local $| = 1; # Autoflush output print "\n\n\e[2A\e[s"; # Make room and save cursor position my ($file, $status) = ('',''); # Will hold filename and status lines while ($h->pump) { parse() } parse(); # Don't miss leftover output $h->finish; exit $h->result; # Pass through the exit code from rsync # Parse and display file/status lines from rsync output sub parse { for (split /[\n\r]+/, $out) { $file = $_ if /^\S/; $status = $_ if /^\s/; print "\e[u\e[0J$file\n$status\n"; } $out = ''; # Clear output for next pump } 

Предпосылки

Для сценария требуются два нестандартных модуля: IPC::Run и IO::Pty . Оба они могут быть установлены с помощью cpan , который поставляется с Perl. Многие, включая меня, предпочитают cpanm , которые могут быть установлены со следующим однострочным:

 curl -L https://cpanmin.us | perl - App::cpanminus 

Затем вы запускаете:

 cpanm IPC::Run IO::Pty 

Поддерживаемые типы терминалов

Это будет работать практически на любом современном терминале, поскольку он использует простые движения курсора ANSI и коды очистки, чтобы постоянно переписывать нижние несколько строк экрана.

Применение

То же самое, что и rsync . Обратите внимание, что вам нужно указать --progress самостоятельно, но вы можете легко редактировать некоторые аргументы по умолчанию, изменив строку $h = harness ... :

  my $h = harness [ $RSYNC, '--progress', @ARGV ], '<pty<', \$in, '>pty>', \$out; 

двоичное местоположение rsync

Сценарий пытается автоматически определить местоположение двоичного rsync , с которым будет работать почти во всех средах. Вы также можете отредактировать my $RSYNC='...' чтобы указать произвольное местоположение, если это необходимо или требуется (важно: в этом случае изменить обратные метки (`) на одинарные кавычки (').)

Устранение неполадок / расширение

Ошибка вывода не обрабатывается специально, но может быть, с некоторыми незначительными изменениями в скрипте.

В то время как разумно надежный, это, очевидно, «быстрое» усилие, которое не может учитывать все возможные выходы из невероятно сложной утилиты rsync . Возможно, вам придется немного адаптировать его в соответствии с вашими потребностями, что, мы надеемся, достаточно просто: весь выход входит в переменную $out , которую вы можете обрабатывать в соответствии с вашими потребностями.

Преобразование в 1-строчный дисплей вместо 2-строчного дисплея

Как упоминалось выше, я выбрал двухстрочный дисплей без прокрутки, чтобы лучше использовать длинные пути. Однако преобразование вывода в однострочный дисплей тривиально. Просто измените строку print ... в parse() на что-то вроде этого:

  printf "\e[u\e[0J%-30.30s %s\n", $file, $status; 

или, чтобы вообще отказаться от кодов движения ANSI:

  printf "\r%-30.30s %-40.40s", $file, $status; STDOUT->flush; # $| = 1 won't help you here 

Тогда вы увидите что-то вроде этого:

 src/test.c 142 100% 0.19kB/s 0:00:00 (xfr#28, to-chk=0/30) 

Вы можете заметить, что %-30.30s является довольно произвольной шириной printf , и вы будете правы. Вы можете использовать что-то вроде ответа от этого вопроса, чтобы получить ширину терминала, чтобы вы могли соответственно увеличивать / уменьшать этот размер.

У меня есть общий сценарий bash oneline в который я oneline материал, который я хочу прокрутить в одну строку:

 #!/bin/bash cr=`tput cr;tput el` if [ -z "$COLUMNS" ] then COLUMNS=80 fi while read line do echo -n "$cr${line:0:$COLUMNS}" done echo 

Команда tput должна получить коды для возврата каретки и очистить до конца строки, поэтому короткие строки не оставляют нежелательные сообщения из предыдущих длинных строк на экране. Обратите внимание: если ваша команда выводит на stderr, вам нужно будет перенаправить ее на stdout перед каналом. например mycommand 2>&1 | oneline mycommand 2>&1 | oneline .

  • Как проверить, является ли процесс демоном или нет?
  • получение владельца папки с командой if
  • Как я могу использовать shebang для разграничения версий python
  • Как разбить массив в наборе из пяти файлов и загрузить их параллельно?
  • Как добиться переносимости с помощью sed -i (редактирование на месте)?
  • Массивы в Unix Bourne Shell
  • Где найти ссылку на форматирование printf?
  • Файлы инициализации Shell
  • Могу ли я подключиться к команде cd?
  • Список файлов другого формата при поиске определенного шаблона имени
  • Git alias multi-commands с; а также &&
  • Linux и Unix - лучшая ОС в мире.