Are there any disadvantages of setting `noclobber`?
The reason noclobber
is not set by default is tradition. As a matter of user interface design, it's a good idea to make “create this new file” the easy action and to put an extra hurdle the more dangerous action “either create a new file or overwrite an existing file”. Thus noclobber
is a good idea (>
to create a new file, >|
to potentially overwrite an existing file) and it would likely have been the default if the shell had been designed a few decades later.
I strongly recommend to use the following in your interactive shell startup file (.bashrc
or .zshrc
):
set -o noclobber
alias cp='cp -i'
alias mv='mv -i'
In each case (redirection, copying, moving), the goal is to add an extra hurdle when the operation may have the side effect of erasing some existing data, even though erasing existing data is not the primary goal of the operation. I don't put rm -i
in this list because erasing data is the primary goal of rm
.
Do note that noclobber
and -i
are safety nets. If they trigger, you've done something wrong. So don't use them as an excuse to not check what you're overwriting! The point is that you should have checked that the output file doesn't exist. If you're told file exists: foo
or overwrite 'foo'?
, it means you made a mistake and you should feel bad and be more careful. In particular, don't get into the habit of saying y
if prompted to overwrite (arguably, the aliases should be alias cp='yes n | cp -i' mv='yes n | mv -i'
, but pressing Ctrl+C makes the output look better): if you did mean to overwrite, cancel the command, move or remove the output file, and run the command again.
It's also important not to get into the habit of triggering those safeties because if you do, one day you'll be on a machine which doesn't have your configuration, and you'll lose data because the protections you were counting on aren't there.
noclobber
will only be set for interactive shells, since .bashrc
or .zshrc
is only read by interactive shells. Of course you shouldn't change shell options in a way that would affect scripts, since it could break those scripts.
Setting the noclobber
shell option in ~/.bashrc
(for bash
) or ~/.zshrc
(or more precisely $ZDOTDIR/.zshrc
, for zsh
) will make it active in interactive shell sessions.
Non-interactive shells (scripts) do not read these files.
Shell options are not normally inherited from parent shells.
This means that you should be able to set the option in those files without modifying the behaviour in existing scripts, unless scripts explicitly sources those files.
The only downside of doing this that I can see is that you will repeatedly forget that you have set the option, at least in the beginning. Later, as with all these kind of things, you will start to habitually use >|
, even in cases where you actually might not want to clobber the file (just like people with aliases for rm
, cp
and mv
with the -i
option always set, eventually start to always use -f
on the command line).
The downside is that, if you become used to having noclobber
active, you will one day use a system where it it not active and you will blithely execute a potentially-dangerous command, expecting the noclobber
to save you... and it won't. And then you'll have to hope that there's a recent-enough backup to recover the data you destroyed because you assumed you would be asked for confirmation first.