Я хотел бы графически отобразить ход передачи scp нескольких файлов с удаленного сервера на локальный компьютер.

Я думал, используя Zenity, например. Просматривая сеть, я обнаружил, что для этого можно использовать команду pv.

Что-то вроде того:

(
scp user@remote:/home/folder/* . | pv -n -b -s $totalSize
) | zenity --progress --title="Transfer window" --percentage=0 --auto-close

Но это не работает.

Использование rsync может быть альтернативой.

Любая идея?

Благодарю.

2 ответа2

0

Ваша проблема заключается в том, что zenity ожидает цифры и комментарии, один за другим. Вы отправляете больше с флагом "-b". Попробуйте удалить его и попробуйте снова.

Zenity читает данные из стандартного ввода построчно. Если перед строкой стоит префикс #, текст обновляется текстом этой строки. Если строка содержит только число, процент обновляется с этим числом.

Смотрите: документация Zenity

Используя только SCP

Похоже, вы хотите иметь представление о прогрессии. Я бы попробовал многословный флаг scp, который должен помочь:

scp -v user@remote:/home/folder/* .

Я не уверен в том, чего вы пытаетесь достичь, но вы можете включить подпапки в команду копирования и сжатия, чтобы сократить время передачи следующим образом:

scp -vrC user@remote:/home/folder/* .

Использование Rsync

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

Инкрементная копия без удаления локальных файлов

rsync -avz --progress user@remote:/home/folder/ ./

Инкрементная копия создает зеркало обеих каталогов, удаляя файлы, отсутствующие на удаленном сервере

rsync -avz --delete --progress user@remote:/home/folder/ ./
-1

К сожалению, scp не отображает прогресс, если stdout не является терминалом.

У вас есть 2 варианта:

Вариант 1 изменить код scp, чтобы игнорировать стандартный вывод, не являющийся терминалом. Скачать исходники (с http://www.openssh.com/)

Прокомментируйте следующий код в scp.c:main()

if (!isatty(STDOUT_FILENO))
    showprogress = 0;

Вариант 2 Используя обертку, обманите scp, чтобы подумать, что есть терминал.

#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>

main(int argc, char **argv) {
 int fd;
 pid_t pid;
 char c,c1,c2;

 if (argc != 3) {
  printf("usage: [[user@]host1:]file1 [[user@]host2:]file2\n\nThis is a program that wraps scp and prints out the numeric progress on separate lines.\n");
  fflush(stdout);
  _exit(1);
 }

 pid = forkpty (&fd, NULL, NULL, NULL);
 if (pid == 0) {
  execlp ("scp", "scp", argv[1], argv[2], (char *) NULL);
  _exit (1);
 } else if (pid == -1) {
  return 1;
 } else {
  FILE *F;

  F = fdopen (fd, "r");

  //reading character by character isn't horribly efficient...
  while((c = fgetc(F)) != -1) {
   if (c == '%') {
    if (c1 == ' ')
     printf("%c\n", c2);  //one digit progess
    else if (c1 == '0' && c2 == '0')
     printf("100\n"); //done
    else
     printf("%c%c\n", c1,c2); //two digit progress
   }
   fflush(stdout);
   c1 = c2;
   c2 = c;                   
  }

 fflush (F);
 wait (0);
 }
 return 0;
} 

Скомпилируйте оболочку и используйте ее для scp

 $ ./scpwrap /home/ubuntu/somefile user@example.com:~ | zenity --progress

Оригинальное решение и более подробную информацию можно получить по адресу : http://blog.clay.shep.me/2009/06/showing-scp-progress-using-zenity.html.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .