Monday, January 22, 2018

Two great uses for the cp command: Bash shortcuts

https://opensource.com/article/18/1/two-great-uses-cp-command-update

Here's how to streamline the backup and synchronize functions of the cp command.

Two great uses for the cp command: Bash shortcuts
Image by : 
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.

No comments:

Post a Comment