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
wibble is an existing directory then
cp copies the source to
wibble does not exist then
cp links the source to
If you want to be sure that the copy is always
wibble, then you can specify the
-T) option. That way, if
cp succeeds, you can be sure that the copy is called
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
ln. If the target is an existing directory, with
-T, they signal an error rather than silently doing something different.
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
$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'
% cp -rvT source destination
`source/foo' -> `destination/foo'