Subject: Re: bug#14023: dirname/basename unexpected results when run by xargs -I

From: Bob Proulx <[email-masked]>
Date: Thu, 21 Mar 2013 19:05:49 -0600

Juho-Pekka Kuitunen wrote:
> Reproduce example;
> $ echo "testdir/testfile" | xargs -I '{}' echo '{}', dir: $(echo dirname '{}') = $(dirname '{}')

Thank you for the report and the very nice test case.  It made
debugging this problem so very much simpler.

> Expected output;
> testdir/testfile, dir: dirname testdir/testfile = testdir
>
> Actual output;
> testdir/testfile, dir: dirname testdir/testfile = .

Ah...  But you have missed a critical point!  :-)  The $(...) is
expanded by the current shell and not by the xargs.  Use echo to see
what you are asking.

  $ echo xargs -I '{}' echo '{}', dir: $(echo dirname '{}') = $(dirname '{}')
  xargs -I {} echo {}, dir: dirname {} = .

> This behavior seems to be limited to the xargs -I replace-str usage
> pattern, any other way I can think of running dirname works fine.

The problem is the $(...) which is running the dirname during the
earlier shell command line parsing pass and passing the result off to
the xargs command.

> Basename has similarly wonky behavior, it prints the full string
> instead of doing any stripping.

Also using $(...)?  :-)

> Not sure if there's a bug involved (or if it's on the findutils or
> coreutils side). Could also just be something silly I'm overlooking.
> I've tested this with findutils 4.4.2 and coreutils 8.5 & 8.13 with
> identical results.

So...  Not a bug.  Agreed?  (I am having a good chuckle.  I hope you
will too.)  We will close the bug then.

Bob