I would like to graphically display the scp transfer progress of several files from a remote server to the local machine.
I thought using Zenity for example. Browsing the net I found the command pv can be used to do so.
Something like that:
(
scp user@remote:/home/folder/* . | pv -n -b -s $totalSize
) | zenity --progress --title="Transfer window" --percentage=0 --auto-closeBut this doesn't work.
Using rsync could be an alternative.
Any idea?
Thanks.
2 Answers
Your problem lies in the fact that zenity expects numbers and comments, one by line. You're sending more with the "-b" flag. Try removing it and try again.
Zenity reads data from standard input line by line. If a line is prefixed with #, the text is updated with the text on that line. If a line contains only a number, the percentage is updated with that number.
See: Zenity documentation
Using SCP alone
Now, it seems like you want to have some sort of progession view. I'd try the verbose flag of scp which should do the trick:
scp -v user@remote:/home/folder/* .I'm not sure of what you're trying to accomplish there but you might want to include subfolders in your copy command and compression to cut down transfer times like so:
scp -vrC user@remote:/home/folder/* .Using Rsync
If I were you, I'd use rsync for that, which makes incremental copies and many more stuff like keeping permissions and times. Here's some commands I use all the time:
Incremental copy without removing local files
rsync -avz --progress user@remote:/home/folder/ ./Incremental copy making a mirror of both directories, deleting files not present on remote server
rsync -avz --delete --progress user@remote:/home/folder/ ./ Unfortunately, scp doesn't display progress if stdout is not a terminal.
You have 2 options:
Option 1 modify scp code to ignore the stdout not being a terminal. Download sources (from )
Comment the following code in scp.c:main()
if (!isatty(STDOUT_FILENO)) showprogress = 0;Option 2 Using a wrapper, fool scp to think that there is a terminal.
#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;
} Compile the wrapper and use it to scp
$ ./scpwrap /home/ubuntu/somefile :~ | zenity --progressOriginal solution & more details from:
5