Two great uses for the cp command: Bash shortcuts

Here's how to streamline the backup and synchronize functions of the cp command.
256 readers like this.
Why the operating system matters even more in 2017

Internet Archive Book Images. Modified by Opensource.com. CC BY-SA 4.0

Last July, I wrote about two great uses for the cp command: making a backup of a file, and synchronizing a secondary copy of a folder.

Having discovered these great utilities, I find that they are more verbose than necessary, so I created shortcuts to them in my Bash shell startup script. I thought I’d share these shortcuts in case they are useful to others or could offer inspiration to Bash users who haven’t quite taken on aliases or shell functions.

Updating a second copy of a folder – Bash alias

The general pattern for updating a second copy of a folder with cp is:

cp -r -u -v SOURCE-FOLDER DESTINATION-DIRECTORY

where the -r stands for “recursively descend through the folder visiting all files”, -u stands for “update the target” and -v stands for “verbose mode”, SOURCE-FOLDER is the name of the folder that contains the most up-to-date information, and DESTINATION-DIRECTORY is the directory containing copy of the SOURCE-FOLDER that must be synchronized.

I can easily remember the -r option because I use it often when copying folders around. I can probably, with some more effort, remember -v, and with even more effort, -u (is it “update” or “synchronize” or…).

Or I can just use the alias capability in Bash to convert the cp command and options to something more memorable, like this:

alias sync='cp -r -u -v'

If I save this in my .bash_aliases file in my home directory and then start a new terminal session, I can use the alias, for example:

sync Pictures /media/me/4388-E5FE

to synchronize my Pictures folder in my home directory with the version of the same in my USB drive.

Not sure if you already have a sync alias defined? You can list all your currently defined aliases by typing the word alias at the command prompt in your terminal window.

Like this so much you just want to start using it right away? Open a terminal window and type:

echo "alias sync='cp -r -u -v'" >> ~/.bash_aliases

Then start up a new terminal window and type the word alias at the command prompt. You should see something like this:

me@mymachine~$ alias

alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

alias egrep='egrep --color=auto'

alias fgrep='fgrep --color=auto'

alias grep='grep --color=auto'

alias gvm='sdk'

alias l='ls -CF'

alias la='ls -A'

alias ll='ls -alF'

alias ls='ls --color=auto'

alias sync='cp -r -u -v'

me@mymachine:~$

There you can see the sync alias defined.

Making versioned backups – Bash function

The general pattern for making a backup of a file with cp is:

cp --force --backup=numbered WORKING-FILE BACKED-UP-FILE

where the -- force stands for “make the copy no matter what”, the -- backup=numbered stands for “use a number to indicate the generation of backup”, WORKING-FILE is the current file we wish to preserve, and BACKED-UP-FILE is the same name as the WORKING-FILE and will have the generation information appended.

Besides remembering the options to the cp command, we also need to remember to repeat the WORKING-FILE name a second time. But why repeat ourselves when a Bash function can take care of that overhead for us, like this:

Again, you can save this to your .bash_aliases file in your home directory.

function backup {

    if [ $# -ne 1 ]; then

        echo "Usage: $0 filename"

    elif [ -f $1 ] ; then

        echo "cp --force --backup=numbered $1 $1"

        cp --force --backup=numbered $1 $1

    else

        echo "$0: $1 is not a file"

    fi

}

I called this function “backup” because I don’t have any other commands called “backup” on my system, but you can choose whatever name suits.

The first if statement checks to make sure that only one argument is provided to the function, otherwise printing the correct usage with the echo command.

The elif statement checks to make sure the argument provided is a file, and if so, it (verbosely) uses the second echo to print the cp command to be used and then executes it.

If the single argument is not a file, the third echo prints an error message to that effect.

In my home directory, if I execute the backup command so defined on the file checkCounts.sql, I see that backup creates a file called checkCounts.sql.~1~. If I execute it once more, I see a new file checkCounts.sql.~2~.

Success! As planned, I can go on editing checkCounts.sql, but if I take a snapshot of it every so often with backup, I can return to the most recent snapshot should I run into trouble.

At some point, it’s better to start using git for version control, but backup as defined above is a nice cheap tool when you need to create snapshots but you’re not ready for git.

Conclusion

In my last article, I promised you that repetitive tasks can often be easily streamlined through the use of shell scripts, shell functions, and shell aliases.

Here I’ve shown concrete examples of the use of shell aliases and shell functions to streamline the synchronize and backup functionality of the cp command. If you’d like to learn more about this, check out the two articles cited above: How to save keystrokes at the command line with alias and Shell scripting: An introduction to the shift method and custom functions, written by my colleagues Greg and Seth, respectively.

Tags
Chris Hermansen portrait Temuco Chile
Seldom without a computer of some sort since graduating from the University of British Columbia in 1978, I have been a full-time Linux user since 2005, a full-time Solaris and SunOS user from 1986 through 2005, and UNIX System V user before that.

8 Comments

I think that "sync" is not a good name for alias - sync (/bin/sync) is a program to synchronize data on disk with memory.

Thanks for the coment, Artur, good point! I had called this a number of other things along the way. Probably should change this too.

In reply to by Artur (not verified)

I think you should also consider using 'cp -av'. This preserves things like timestamps, which I often use when looking for some file I made some time ago, and when it was made helps me find it. 'cp -ruv' will make a copy with a brand-new timestamp.

Thanks for this writeup! I had no idea that 'cp' was capable of this. GUIs often keep me a bit removed from the terminal. Also, I find it easier to simply work with a graphical file manager.

These examples (among a few others I've collected since transitioning to Linux) are great reasons to open up the terminal!

I'm curious about Greg Pittman's contribution, re: timestamps. He seems to make a good point and if so... perhaps an article edit to address this(?).

Thanks for your comment, john379. Always nice to hear when people find something useful.

I like Greg's idea. Next time I revisit this article I will definitely add it!

In reply to by john379 (not verified)

Thanks for your comment, tatethurston.

I love that use of the braces! I gotta say I spent many years using the c-shell in SunOS and Solaris and that one never occurred to me.

In reply to by tatethurston (not verified)

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.