By default, cp
tests if its last argument is an existing directory. If this happens, cp
creates a link inside that directory, with the base name of the source. That is, given the command
cp foo/bar wibble
if wibble
is an existing directory then cp
copies the source to wibble/bar
. If wibble
does not exist then cp
links the source to wibble
.
If you want to be sure that the copy is always wibble
, then you can specify the --no-target-directory
(alias -T
) option. That way, if cp
succeeds, you can be sure that the copy is called wibble
. If wibble
already existed as a directory, then cp
will fail.
In tabular form:
The target is … Without -T With -T
existing directory copy in the directory error
existing file (not dir) overwrite overwrite
does not exist create create
The only difference is that with -T
, in case the target is an existing directory, the command returns an error. This is useful when you expect the directory not to exist: you get an error message instead of something unpredicted happening.
The same applies to mv
and ln
. If the target is an existing directory, with -T
, they signal an error rather than silently doing something different.
With cp
, there's a different case. If you do a recursive copy and the source is a directory, then cp -T
copies the content of the source into the destination, rather than copying the source itself. That is, given
$ tree source destination
source
└── foo
destination
└── bar
then
$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'
whereas
% cp -rvT source destination
`source/foo' -> `destination/foo'