[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#16889: erratic behavior of cp command i.e while copying files (using
From: |
Bob Proulx |
Subject: |
bug#16889: erratic behavior of cp command i.e while copying files (using *) from one directory to another directory |
Date: |
Wed, 26 Feb 2014 12:53:07 -0700 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Anil Kumar wrote:
> I have observed, one erratic behavior of cp command i.e while copying
> files (using *) from one directory to another directory if
> we miss destination directory then cp command copies content of 1st
> file into 2nd file of same source directory instead of giving any
> error.
Others have already replied about this topic. But I wanted to mention
the GNU extension -t, --target-directory=DIRECTORY option. The
documentation says:
...
cp [OPTION]... -t DIRECTORY SOURCE...
* If the --target-directory (-t) option is given, or failing
that if the last file is a directory and the
--no-target-directory (-T) option is not given, cp copies
each SOURCE file to the specified directory, using the SOURCEs
names.
-t DIRECTORY
--target-directory=DIRECTORY
Specify the destination DIRECTORY. *Note Target directory::.
Using it can sometimes be useful at times to make commands simpler and
more clear about what is wanted. This also allows the target
directory to be specified with the command and an unknown number of
files to follow on the command line. This is most useful when using
commands such as 'find' and others. The documentation goes into some
detail about using it that way.
I will include the entire "Target directory" section at the bottom for
further reference.
Bob
2.8 Target directory
====================
The `cp', `install', `ln', and `mv' commands normally treat the last
operand specially when it is a directory or a symbolic link to a
directory. For example, `cp source dest' is equivalent to `cp source
dest/source' if `dest' is a directory. Sometimes this behavior is not
exactly what is wanted, so these commands support the following options
to allow more fine-grained control:
`-T'
`--no-target-directory'
Do not treat the last operand specially when it is a directory or a
symbolic link to a directory. This can help avoid race conditions
in programs that operate in a shared area. For example, when the
command `mv /tmp/source /tmp/dest' succeeds, there is no guarantee
that `/tmp/source' was renamed to `/tmp/dest': it could have been
renamed to `/tmp/dest/source' instead, if some other process
created `/tmp/dest' as a directory. However, if `mv -T
/tmp/source /tmp/dest' succeeds, there is no question that
`/tmp/source' was renamed to `/tmp/dest'.
In the opposite situation, where you want the last operand to be
treated as a directory and want a diagnostic otherwise, you can use
the `--target-directory' (`-t') option.
`-t DIRECTORY'
`--target-directory=DIRECTORY'
Use DIRECTORY as the directory component of each destination file
name.
The interface for most programs is that after processing options
and a finite (possibly zero) number of fixed-position arguments,
the remaining argument list is either expected to be empty, or is
a list of items (usually files) that will all be handled
identically. The `xargs' program is designed to work well with
this convention.
The commands in the `mv'-family are unusual in that they take a
variable number of arguments with a special case at the _end_
(namely, the target directory). This makes it nontrivial to
perform some operations, e.g., "move all files from here to
../d/", because `mv * ../d/' might exhaust the argument space, and
`ls | xargs ...' doesn't have a clean way to specify an extra
final argument for each invocation of the subject command. (It
can be done by going through a shell command, but that requires
more human labor and brain power than it should.)
The `--target-directory' (`-t') option allows the `cp', `install',
`ln', and `mv' programs to be used conveniently with `xargs'. For
example, you can move the files from the current directory to a
sibling directory, `d' like this:
ls | xargs mv -t ../d --
However, this doesn't move files whose names begin with `.'. If
you use the GNU `find' program, you can move those files too, with
this command:
find . -mindepth 1 -maxdepth 1 \
| xargs mv -t ../d
But both of the above approaches fail if there are no files in the
current directory, or if any file has a name containing a blank or
some other special characters. The following example removes
those limitations and requires both GNU `find' and GNU `xargs':
find . -mindepth 1 -maxdepth 1 -print0 \
| xargs --null --no-run-if-empty \
mv -t ../d
The `--target-directory' (`-t') and `--no-target-directory' (`-T')
options cannot be combined.