What is the added value of the -T option in GNU cp and mv?

Your . trick can only be used when you're copying a directory, not a file. The -T option works with both directories and files. If you do:

cp srcfile destfile

and there's already a directory named destfile it will copy to destfile/srcfile, which may not be intended. So you use

cp -T srcfile destfile

and you correctly get the error:

cp: cannot overwrite directory `destfile' with non-directory

If you tried using the . method, the copy would never work:

cp: cannot stat `srcfile/.`: Not a directory

The problem with cp/mv/ln as they were originally designed is that they're two commands in one (copy to and copy into).

cp A B

is either copy A to B or copy A into B (copy A to B/A) depending on whether B exists and is a directory or not (and more variations if B is a symlink to a directory).

That's bad because it's ambiguous. So the GNU implementations have added options to work around that.

cp -T A B

copies A to B regardless. If B exists and is a directory, that will fail (unless you pass -r). In any case, you will not end-up with a A file inside B when you intended A to be copied to B.

And:

cp -t B A

is the copy into.


The -T can provide a failure if a directory incorrectly exists for what should be a destination file:

$ mkdir mustbeafile
$ touch afile
$ cp -T afile mustbeafile
cp: cannot overwrite directory `mustbeafile' with non-directory
$ echo $?
1
$ cp afile mustbeafile
$ 

That is, instead of success-on-unexpected-copy-to-a-subdir, a warning and not-good exit status happens, which could then cause a script to abort, and human inspect why there's a directory where there shouldn't be one.

Tags:

Cp

Coreutils