Monday, 3 September 2012

Preventing Accidental Overwriting Of Files In Bash Shell

How many times has this happened to you? It used to happen once in a while with me. A Linux user learns to use the redirection operators such as '>' and '>>' but accidental overwriting starts to become common in commands you use and shell scripts you write.

The accidental overwriting of files that happens unintentionally is known as clobbering and it commonly happens while using the '>' redirection operator.

samar@Techgaun:~$ mycmd > myfile

In the above example, the mycmd clobbers any existing data in the myfile file if that file exists already. Worse things may happen sometime. Imagine accidentally typing

samar@Techgaun:~$ mycmd > /etc/passwd

instead of possibly using other redirection operators (like >> or <). Thankfully, you could recover /etc/passwd from either /etc/passwd- or /var/backups/passwd.bak if you hadn't rm'd these files.

To prevent such accidental overwriting, we can set the noclobber environment variable. Below is a session of enabling this variable:

samar@Techgaun:~/Desktop/test$ echo "" > myfile
samar@Techgaun:~/Desktop/test$ echo "Overwriting" > myfile
samar@Techgaun:~/Desktop/test$ set -o noclobber
samar@Techgaun:~/Desktop/test$ echo "Retrying to overwrite" > myfile
-bash: myfile: cannot overwrite existing file

As seen above, you have to turn on the noclobber variable using the set -o noclobber command in your shell. However, you might want to intentionally overwrite contents of certain files even when the noclobber is turned on.

samar@Techgaun:~$ mycmd >| myfile

Notice the >| in place of your normal > redirection operator. Using this operator, you can however overwrite the existing files even if the noclobber is turned on.

If you want to turn off the noclobber variable, type the following:

samar@Techgaun:~$ set +o noclobber

You can also permanently turn on the noclobber by the following command:

samar@Techgaun:~$ echo "set -o noclobber" >> ~/.bashrc

Moreover, such accidental overwriting can be prevented by enabling the interactive mode which is available in most of the linux commands. For example, you can write the alias for many commands that are likely to cause accidental overwriting. See some examples of aliases below:

samar@Techgaun:~$ alias rm=rm -i
samar@Techgaun:~$ alias mv=mv -i

You could even keep these aliases in your ~/.bashrc file permanently. Enabling such interactive modes by default in the commands that are more likely to cause accidental overwriting can prevent clobbering in many cases.

I hope this proves useful to you :)