Display scp progress in zenity window

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-close

But 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 --progress

Original solution & more details from:

5

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like