8

On AIX (but this happens on HP-UX as well), I have GNU ls in my path and it is also aliased as ls.

But when i use xargs, it uses the standard Unix ls instead of the alias.

For example (flocate is a function which finds the exact path of the search subject):

flocate mirrorvg | xargs ls -lh
ls: illegal option -- h
usage: ls [-1ACFHLNRSabcdefgiklmnopqrstuxEUX] [File...]

ls -lh /usr/sbin/mirrorvg
-r-xr-x--- 1 root system 37K apr  3  2014 /usr/sbin/mirrorvg*

Why doesn't xargs use the ls alias?

  • 1
    What exactly does "I have GNU ls in my path" mean? Is the directory containing the GNU ls executable in your $PATH environment variable, and does it precede the directory (probably /bin) containing the non-GNU ls command? Please update your question to show us the actual value of your $PATH. xargs will execute the first ls command that it finds in a directory in your $PATH; it doesn't know about aliases. – Keith Thompson Apr 29 '15 at 18:34
9

The command xargs is only able to run commands, not aliases. GNU parallel, however, is able to run functions:

The command must be an executable, a script, a composed
command, or a function. If it is a function you need to export
-f the function first. An alias will, however, not work (see
why http://www.perlmonks.org/index.pl?node_id=484296).

So I would recommend either:

  • Giving xargs the full path to the version of ls you want to use (or an unambiguous name, perhaps gls depending on how it was installed on your system) or, if your shell allows it,

  • Defining ls as a function (function ls { gls "$@"; }; export -f ls in bash) and using GNU parallel instead of xargs (parallel -j1 if you would like to use a single CPU).

  • exporting functions only works with the bash shell. You can use xargs with exported functions as well: ls() { gls "$@"; }; export -f ls; ... | xargs bash -c '"$0" "$@"' ls – Stéphane Chazelas Apr 29 '15 at 19:50
  • Oh, nice trick, it could be useful if one is forced to use xargs. – dhag Apr 29 '15 at 19:55
3

The alias substitution is done by the shell. If the shell tries to call command foo, and there is an alias foo=bar, it's the shell that substitutes the foo by bar here.

The shell only does this for commands. (Otherwise, arguments that happen to be the same as an aliased command would be replaced too.) But your ls here is not run by the shell, but an argument to xargs. Therefore, the shell does not replace it.

Then xargs executes ls, but it does not know about the aliases, so it just runs the first one it finds in the path.

The aliases are internal to the shell and there is no standardized way for a program to read them out.

  • 1
    Note that doing alias xargs='xargs ' will tell the shell to expand aliases after xargs. – Stéphane Chazelas Apr 29 '15 at 19:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.