xargs ne reconnaît pas les alias bash
-
21-08-2019 - |
Question
Je suis en train d'exécuter la commande suivante:
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 qui prend un paramètre). Apparemment xargs ne reconnaît pas ces choses comme il peut courir. Est-il un moyen intelligent pour remédier à cette situation?
La solution
Depuis que votre shell interactif connaît des alias, pourquoi ne pas exécuter simplement l'alias sans bifurquer à travers xargs
?
find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done
Si vous êtes sûr que vos noms n'ont pas les nouvelles lignes dans les (beurk, pourquoi seraient-ils?), Vous pouvez simplifier à
find . -iname '.#*' -print | while read -r i; do foobar "$i"; done
ou même find -iname '.#*' | ...
, puisque le répertoire par défaut est l'action et .
par défaut est -print
.
Une autre solution:
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 devez être prudent avec cela, cependant; certains scripts ne pas bien faire face à un changement $IFS
.
Autres conseils
Utilisation Bash Vous pouvez également spécifier le nombre de args étant passé à 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 "$@"' arg0
Cela ne fonctionne pas parce que pour être attend xargs
pouvoir le exec
programme donnée comme paramètre.
Comme dans votre cas foobar
est juste un alias ou fonction il n'y bash
a pas d'exécuter le programme.
Bien qu'il implique à partir de chaque fichier find
retourné par <=>, vous pouvez écrire un petit script shell ainsi:
#!/bin/bash
. $(HOME)/.bashrc
func $*
, puis transmettre le nom de ce script comme paramètre à <=>
J'utilise généralement trouver comme ceci:
find . -iname '' -exec cmd '{}' \;
'{}' va se remplacé par le nom de fichier, et \; est nécessaire de mettre fin à 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 PRFIXES juste avec votre commande, puis conduite à bash pour l'exécution. Passer le |. Bash d'abord pour voir ce qui se passera
essayer
find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)