The f*
expression is also known as a shell glob, and is supposed to be interpreted by the shell. You can try it out independently e.g. by running echo f*
.
When you run ls -la f*
from the shell, the shell interprets it according to your directory contents, and calls ls
with the expanded version, like: ls -la file1 file2 file3
. You can get some commands confused about this if it matches no file and the command expects one.
But when you pass that argument to ls
through xargs
, the shell doesn't get a chance to expand it, and ls
feels like it's invoked exactly as ls -la f*
. It recognizes -la
as options, and f*
as a filename to list. That file happens not to exist, so it fails with the error message you see.
You could get it to fail on a more usual filename:
$ ls non_existing_file
ls: cannot access non_existing_file: No such file or directory.
Or you could get it to succeed by actually having a file of that name:
$ touch 'f*'
$ xargs ls -la <<< 'f*'
-rw-rw-r-- 1 jb jb 0 2013-11-13 23:08 f*
$ rm 'f*'
Notice how I had to use single quotes so that the shell would not interpret f*
as a glob when creating and deleting it.
Unfortuately, you can't get it to expand it when it gets passed directly from xargs
to ls
, since there's no shell there.