xargs n'utilise pas mon alias «ls»

8

Sur AIX (mais cela se produit également sur HP-UX), j'ai des GNU ls sur mon chemin et il est également alias comme ls.

Lorsque j'utilise xargs, il utilise à la lsplace l' Unix standard au lieu de l'alias.

Par exemple ( flocateest une fonction qui trouve le chemin exact du sujet de recherche):

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*

Pourquoi xargs n'utilise-t-il pas l' lsalias?

elbarna
la source
1
Que signifie exactement "J'ai des GNU sur mon chemin"? Le répertoire contenant l' lsexécutable GNU se trouve-t-il dans votre $PATHvariable d'environnement et précède-t-il (probablement /bin) le répertoire contenant la lscommande non GNU ? Veuillez mettre à jour votre question pour nous montrer la valeur réelle de votre $PATH. xargsexécutera la première ls commande qu'il trouve dans un répertoire de votre $PATH; il ne connaît pas les alias.
Keith Thompson

Réponses:

9

La commande xargsne peut exécuter que des commandes, pas des alias. Cependant, GNU Parallel est capable d'exécuter des fonctions:

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).

Je recommanderais donc soit:

  • Donner à xargs le chemin complet de la version de ls que vous souhaitez utiliser (ou un nom non ambigu, peut-être en glsfonction de la façon dont il a été installé sur votre système) ou, si votre shell le permet,

  • Définition en lstant que fonction ( function ls { gls "$@"; }; export -f lsen bash) et utilisation de GNU parallel au lieu de xargs ( parallel -j1si vous souhaitez utiliser un seul CPU).

dhag
la source
l'exportation de fonctions ne fonctionne qu'avec le bashshell. Vous pouvez également utiliser xargsavec les fonctions exportées: ls() { gls "$@"; }; export -f ls; ... | xargs bash -c '"$0" "$@"' ls
Stéphane Chazelas
Oh, bonne astuce, cela pourrait être utile si l'on est obligé d'utiliser xargs.
2015
Vous pouvez utiliser env_parallelsi vous souhaitez utiliser des alias ou ne souhaitez pas exporter la fonction. Les alias sont pris en charge dans: ash, bash, csh, dash, fish, ksh, mksh, pdksh, tcsh, zsh. Les fonctions sont prises en charge dans: bash, fish, ksh, mksh, pdksh, sh, zsh. Ils fonctionnent même si vous exécutez des commandes sur des serveurs distants. gnu.org/software/parallel/env_parallel.html
Ole Tange
3

La substitution d'alias est effectuée par le shell. Si le shell essaie d'appeler la commande fooet qu'il y a un alias foo=bar, c'est le shell qui remplace le foopar barici.

Le shell ne fait cela que pour les commandes. (Sinon, les arguments qui se trouvent être identiques à une commande aliasée seraient également remplacés.) Mais votre lsici n'est pas exécuté par le shell, mais un argument pour xargs. Par conséquent, le shell ne le remplace pas.

xargsS'exécute ensuite ls, mais il ne connaît pas les alias, il exécute donc le premier qu'il trouve dans le chemin.

Les alias sont internes au shell et il n'existe aucun moyen standardisé pour un programme de les lire.

marinus
la source
1
Notez que faire alias xargs='xargs 'indiquera au shell de développer les alias après xargs.
Stéphane Chazelas