BASH script to add GUI to cp

21 07 2011

Hi folks!

Got an interesting BASH script for you this time. I regularly use a BASH script to clone a HDD using cp, and other than perhaps using “-v”, I couldn’t think of a way to give it a GUI. A little research and thought into it came up with the following result:

echo "Copying $SRC to $TGT"
[[ -w /tmp/fifo ]] && rm /tmp/fifo
mkfifo /tmp/fifo
exec 5<>/tmp/fifo
(cat <&5 | dialog --guage "Copying OS and data files from source to target HDD" 7 30) &
TOTAL=$(df | grep $SRC | awk '{print $3}' | tr '\n' '+' | sed 's/.$/\n/' | bc)
while true; do
    COPIED=$(df | grep $TGT | awk '{print $3}' | tr '\n' '+' | sed 's/.$/\n/' | bc)
    echo 100*$COPIED/$TOTAL | bc >&5
    if [ ! "$(ps aux | awk '{print $2}' | grep $CPPID)" ]; then
    sleep 10

Apologies for the truly horrible formatting. WordPress’s code tags aren’t the best! Now I’ll do my best to explain each stage…

First up, the script sets variables for the locations to copy from and to. These must be mounted volumes in this example, as we use `df` to detect them. This wouldn’t be too difficult to convert to use some other method of working out the size, such as `du`, if you aren’t using a mounted volume.

We then create a pipe called fifo in /tmp. This is how we will feed data to `dialog`.

Now we connect file descriptor 5 to the pipe, to facilitate the connection to our ncurses dialog, then pipe FD 5 into the `dialog` program, yet again forked into the background.

Next, we find the total size of the source partition, and set it to the variable $TOTAL.

Here we set the copy process off, and fork it into the background, so the script will jump through to the next section, which regularly updates our instance of `dialog`.

Here’s the interesting bit… We run a while true loop, which every 10 seconds, checks the cumulative size of the target partition ($COPIED), and compares it to $TOTAL by converting it to a percentage, using bc. This number is then fed into the pipe, which we have connected to dialog. Each loop, we also check to see if the copy process is still running, and if not, we break out of the loop.

To clean up, we close the file descriptor (5<&-), and use `reset`, as dialog has a nasty habit of breaking the terminal, and `clear` doesn't fix it.

As always, if you have any questions, tips, improvements or corrections, just direct them straight to the comments!



How NOT to write a BASH script.

24 01 2011

Hey all!

Found another link for you guys to peruse at your leisure. I have found BASH scripting to be pretty much the most useful thing to know when administering Linux systems. Debugging a script which won’t play fair can be really time-consuming, and these tricks might just save you a heck of a lot of time!

Anyway. Here’s the link.