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.
8 Comments