2009-02-04 7 views
51

Je suis en train d'exécuter la commande suivante:xargs ne reconnaît pas des alias bash

find . -iname '.#*' -print0 | xargs -0 -L 1 foobar 

où « foobar » est un alias ou une fonction définie dans mon .bashrc (dans mon cas, il est une fonction cela prend un paramètre). Apparemment, xargs ne les reconnaît pas comme des choses qu'il peut faire fonctionner. Y a-t-il une manière intelligente de remédier à cela?

+1

C'est l'une des raisons pour lesquelles je crée des scripts sur mon dossier ~/bin au lieu de créer des alias de bash. De cette façon, je peux utiliser mes alias de n'importe quel shell: BASH, ZSH, IPYTHON ou FISH. – Yoo

+2

Voici une question similaire (mais pas identique): http: // stackoverflow.com/questions/979453/how-can-i-utiliser-aliased-commands-with-xargs –

Répondre

34

Depuis seul votre shell interactif connaît les alias, pourquoi ne pas simplement exécuter l'alias sans forcer à travers xargs?

find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done 

Si vous êtes sûr que vos noms de fichiers ne sont pas dans les nouvelles lignes (beurk, pourquoi seraient-ils?), Vous pouvez simplifier à

find . -iname '.#*' -print | while read -r i; do foobar "$i"; done 

ou même find -iname '.#*' | ..., depuis le Le répertoire par défaut est . et l'action par défaut est -print.

Une alternative plus:

IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done 

dire Bash que les mots ne sont divisés sur les nouvelles lignes (par défaut: IFS=$' \t\n'). Vous devriez être prudent avec cela, cependant; certains scripts ne se débrouillent pas bien avec un $IFS modifié.

+1

Cette réponse répond POURQUOI nous ne pouvons pas utiliser xargs et COMMENT nous pourrions utiliser xargs avec l'alias. –

+0

Cette réponse nous donne * des alternatives * à l'utilisation de xargs. Pour une réponse qui fonctionne * en utilisant xargs *, voir la réponse de @ camh dans la question connexe: http://stackoverflow.com/questions/979453/how-can-i-use-aliased-commands-with-xargs (que Nathan Fellman lié à au-dessus) –

1

J'utilise généralement trouver comme ceci:

find . -iname '' -exec cmd '{}' \; 

'{}' va se remplacé par le nom de fichier, et \; est nécessaire pour terminer la chaîne d'exécution. Cependant, si cela ne fonctionne pas avec votre fonction, vous devrez peut-être exécuter par bash:

find .. |sed -e "s/.*/cmd '&'/"|bash 

Trouver imprime chaque fichier sur une ligne, sed préfixes juste avec votre commande, puis conduite à bash pour l'exécution. Passer le | bash d'abord pour voir ce qui va arriver.

+0

Si vous utilisez une recherche GNU newish, utilisez '-exec cmd '{}' +' à la place: cela agit plus comme xargs en ce qu'il va regrouper les arguments en une seule fois au lieu d'exécuter un nouveau cmd pour chaque fichier trouvé. – ephemient

+0

Je pense plutôt que si sa fonction était capable de prendre plusieurs paramètres, il ne fournirait pas les options -L 1 à xargs ... – Alnitak

+0

Oh, c'est ce que -L fait? Je n'ai pas cherché, et j'utilise -n dans ce but. – ephemient

4

Cela ne fonctionne pas parce que xargs attend de pouvoir exec le programme donné comme paramètre.

Depuis foobar dans votre cas est juste un bash alias ou fonction il n'y a pas de programme à exécuter.

Bien qu'il implique à partir bash pour chaque fichier retourné par find, vous pouvez écrire un petit script shell ainsi:

#!/bin/bash 
. $(HOME)/.bashrc 
func $* 

puis passer le nom de ce script comme paramètre à xargs

+0

Où dois-je placer ce script pour que * it * soit reconnu par 'xargs'? –

+0

@NickVolynkin où vous voulez, tant qu'il est dans '$ PATH' ou donne directement son emplacement à' xargs'. – Alnitak

+0

ok, merci pour l'explication. –

8

En utilisant Bash Vous pouvez également spécifier le nombre de args étant passés à votre alias (ou fonction) comme ceci:

alias myFuncOrAlias='echo' # alias defined in your ~/.bashrc, ~/.profile, ... 
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0 
echo arg1 arg2 | xargs bash -cil 'myFuncOrAlias "[email protected]"' arg0 
Questions connexes