Subject: Re: bug#6353: cp and mv with single wild card argument acts as if multiple arguments were entered.

From: Bob Proulx <[email-masked]>
Date: Fri, 4 Jun 2010 14:52:15 -0600

Darwin Gregory wrote:
> I did a quick search of the archive, and didn't find this one,

It gets discussed every so often.  Look for file glob or file
globbing.

> but there seems to be a potential logical failure in the cp and mv
> commands.  It may be specific to an implementation, but I feel it is
> a critical issue.

This applies to *all* command line use of shell wildcards.  It isn't
specific to GNU or GNU coreutils or any other particular command.
This is part of the fabric that underlays the entire operating system.

> If you execute "cp /path/*" the command expands the wildcard, and treats the
> last file as the destination directory.  If the last file in /path/ is not a
> directory the command fails, but not with the appropriate error.  However,
> if the last file in the directory (or other wildcard expansion) is a
> directory, it will copy all earlier files in the expansion to that
> directory.

The part that you are missing is that the shell expands '*' file glob
characters prior to passing the result as arguments to the command.
The command invoked does not receive the '*' itself (unless there were
no matches at all) and the command cannot tell the difference between
the user specifying files explicitly versus having had a file glob
expanded.

> The same happens for mv.  I did mv * in my home directory where the last
> entry was a workspace subdirectory.  It moved all of my files and
> directories to my workspace subdirectory.

Yes.  That is forty years of expected behavior.  Shell wildcards are
expanded by the shell before invoking the command.

> I feel this is an unacceptable outcome for a single argument that is a
> wildcard, since whether it works or not is based on the arbitrary presence
> or absence of a directory as the final element in the wildcard expansion.

This is a fundamental behavior of the shell.  The Unix philosophy is
to separate this behavior out into the shell so that it would be
applied uniformly to all commands.

Now you may say that this is unacceptable and be shocked by this but
if you think about the fact that this has been the standard behavior
for four decades then you must realize that there is some value and
benefit to this design or it would have been changed and replaced with
something different by now.

> It would be much better to fail with an error indicating  "missing
> destination file operand" as it does if the first argument does not
> contain a wildcard.

This is not possible in the Unix command line shell architecture.

> Also, if a wildcard expansion contains exactly 2 elements, the second is
> treated as a target whether or not it is a directory, causing a potential
> overlay of data.

That is correct.  Don't do that.

Note that you are always free to use a different shell that behaves
differently.  There isn't any requirement that you use bash, or
whatever shell you happen to be using at the moment.  It just turns
out that it is more useful than any of the alternatives.  It is so
much more useful that you may find it difficult to locate successful
alternatives that do not do file glob expansion.  And also you would
need to use a set of utilities that were designed to match the
behavior.

Bob