Progress Bar

I have made a macro which copies a lot of data to another network drive.
This takes some time.

Since the copy action in KM does not have a progress bar, has anybody made anything like that?
Either in Applescript or via a shell script?

1 Like

If your macro uses a shell script to do your data transfer, you can use CocoaDialog to display nice progress-bars that are driven by the data output from your scripts:

http://mstratman.github.io/cocoadialog/

2 Likes

I also have the need for a progress bar. My needs are even simpler, oddly enough complicating the situation. I have a couple of macros that move a single file back and forth between an external disk and the local disk. The file is about 2 GB, so this one file takes a few minutes.

My guess is that there is no way to conveniently show percentage progress or the number of items copied (since it is 0 for a long time then the final 1). Maybe a being able to display an elapsed time would work. Is that something that is possible?

I never found a solution which was easy enough for me to implement unfortunately.

I like this problem. I want to think about it.

I am so darn close to a fabulous solution. So so close. Almost there.

The basis for my idea for a progress alert for copying files is that I recalled that when I'm in a Unix shell and I copy files in groups, I usually see the names of the files being printed as I'm waiting for the copy to complete. Knowing that feature exists, I figured there must be a way to exploit that to transfer that information back to KM. And there is a way to do that. I will explain.

Before I explain, I want to add that there are some utilities in some versions of Unix that provide even more information than just filenames. They provide things like percent complete information. But since that's not available in the standard macOS "cp" command, I made no attempt to obtain that information. If anyone can find a way to display progress in percentages in macOS while copying files, I'd be willing to tackle that too.

Another thing that hampered me is that the macOS version of Unix is not the same as the Linux version. There are some handy things in Linux like "unbuffer" which probably would have helped here. These utilities can probably be added to macOS but there's no way I'm going to make that part of my solution. I want my solution to be easy for everyone.

Lastly, how you display the progress is up to you. I used an action that puts the name of the file in HUUUGE letters on the screen. That may not be your preferred display method. In that case replace the option "Display Large Text" with "Display Text Briefly". Or change the Action to Speak Text. Whatever you want is possible.

You need to create a macro with one action. It's that simple:

And then you must modify the default trigger at the top which says "Or by script" and change that to "or by Shell Script." The first line of the text window that opens needs to be copied out of there. It will look something like this:

osascript -e 'tell application "Keyboard Maestro Engine" to do script "7BBDDDAF9-89E4-44D9-9D5E-62BDDDDD4D7C"'

Then all you have to do is issue your copy command, which I presume you will use an Execute Shell Script for, and the text you place into that action will be this:

script -q /dev/null cp -v ~/test/* ~/test/copy | xargs -I % osascript -e 'tell application "Keyboard Maestro Engine" to do script "7BDD4AF9-89E4-4D09-9DDE-6DDD4D74D7C" with parameter "%"'

Of course you will substitute your own paths for the ones I used, which were just test files. And you are likely to want to put KM variables in there.

As usual, there's a chance that one of the KM gods, or maybe The KM God himself, might find a way to improve or correct my idea above. I will accept corrections.

This principle may work for other things besides copying files.

2 Likes

@Sleepy, sorry for the long delay. I have been thinking about your solution and knew there had to be answer to the missing piece. I have a solution for getting the percent complete for a single file.

This script (below) is a POC and relies on the fact that sending a SIGINFO (29) to /bin/cp, it will print completion stats. The reason I am very specific about the location of of the cp command is that this does not work for Gnu Bash, only cp on the Mac. That messed with for a while, as I have the Gnu Utilities installed via brew

If you run the script, you can see output like this:

/tmp/bigfile1 -> /tmp/bigfile2  34%
/tmp/bigfile1 -> /tmp/bigfile2  50%
/tmp/bigfile1 -> /tmp/bigfile2  68%
/tmp/bigfile1 -> /tmp/bigfile2  84%

And here is the script:

# From the /bin/cp man page:
# If cp receives a SIGINFO (see the status argument for stty(1)) signal,
#     the current input and output file and the percentage complete will be
#     written to the standard output.

# Create a big file for testing
dd if=/dev/zero of=/tmp/bigfile1 bs=1M count=1000

/bin/cp /tmp/bigfile1 /tmp/bigfile2 &
sleep 0.5
PID=$!
while [[ -n $PID ]]; do # See https://stackoverflow.com/questions/3043978/how-to-check-if-a-process-id-pid-exists
    PID="$(ps -p $PID -o pid=)"
    sleep 0.75
    if [ -n "$(ps -p $PID -o pid=)" ]; then
        kill -29 $PID # | awk '{print $4}'  # This would work nicely, but does not grab output :-(
    else
        PID=""
    fi
done

Happy Fourth of July!

Hey Paul,

Your script is pretty slick. :smile:

I'm surprised to see the GNU version of CP not support percentage complete...

When I install GNU core utilities on my system I use the option that forces a ā€œgā€ prefix to use them.

So cp becomes gcp.

I prefer this, because it doesn't screw up any old scripts that rely on stock Unix commands.

-Chris

Glad you like it @ccstone! It took a bit of futzing to get it to work right, but anything that does not kill us...

You are correct about "gcp" being the underlying name. I asked brew to make symlinks so that cp points to scp. For the most part, GNU utilities are much better than the outdated OSX counterparts.

Hey Paul,

Agreed. Certainly much more modern.

Many Unix executables on Sierra go back to 2005...

-Chris

Dang, you're smarter than me.

But you did say "Happy 4th" while here in Canada it's the July 1 where we got our independence. We beat the US by three days, although they beat us by 91 years.