2009-02-04 19 views
51

Ich versuche, den folgenden Befehl auszuführen:xargs nicht bash erkennen Aliase

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

wo „foobar“ ist ein Alias ​​oder eine Funktion in meinem .bashrc-Datei definiert (in meinem Fall ist es eine Funktion das dauert einen Parameter). Anscheinend erkennt Xargs diese nicht als Dinge, die es ausführen kann. Gibt es einen klugen Weg, um das zu beheben?

+1

Dies ist einer der Gründe, warum ich Skripte auf meinem ~/ist Ordner erstellen, statt Erstellen von Bash-Aliasen. Auf diese Weise kann ich meine Aliase aus beliebigen Shells verwenden: BASH, ZSH, IPYTHON oder FISH. – Yoo

+2

Hier ist eine ähnliche (wenn auch nicht identische) Frage: http: // stackoverflow.com/questions/979453/how-can-i-used-aliased-commands-with-xargs –

Antwort

34

Seit nur Ihre interaktive Shell kennt Aliasnamen, warum führen Sie nicht einfach den Aliasnamen ohne Auskreuzen durch xargs aus?

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

Wenn Sie sicher sind, dass Ihre Dateinamen haben keine Zeilenumbrüche in ihnen (ick, warum sollten sie?), Können Sie diese vereinfachen

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

oder auch nur find -iname '.#*' | ..., da die Standardverzeichnis ist . und die Standardaktion ist -print.

Eine weitere Alternative:

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

sagen, Bash, die Worte nur Split auf neue Zeilen (Standard: IFS=$' \t\n') sind. Sie sollten jedoch damit vorsichtig sein; Einige Skripte kommen mit einem geänderten $IFS nicht gut zurecht.

+1

Diese Antwort beantwortet, WARUM wir keine xargs verwenden können und WIE wir xargs mit dem Alias ​​verwenden könnten. –

+0

Diese Antwort gibt uns * Alternativen * zur Verwendung von Xargs. Für eine Antwort, die * mit xargs * funktioniert, siehe @ camhs Antwort in der verwandten Frage: http://stackoverflow.com/questions/979453/how-can-i-use-aliased-commands-with-xargs (was Nathan Fellman verlinkt nach oben) –

1

Normalerweise verwende ich wie diese finden:

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

'{}' wird mit dem Dateinamen ersetzt werden, und \; ist notwendig, um die Ausführungskette zu beenden. Wenn Sie jedoch, dass nicht mit Ihrer Funktion nicht funktioniert, müssen Sie es durch bash auszuführen:

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

Suche druckt jede Datei auf einer Linie, sed Präfixe nur dies mit Ihrem Befehl, und dann eine Pipe an bash zur Ausführung. Überspringen Sie zuerst die | bash, um zu sehen, was passieren wird.

+0

Wenn Sie eine neue GNU-Suche verwenden, verwenden Sie stattdessen '-exec cmd' {} '+ ': Dies verhält sich eher wie Xargs indem es Argumente in einem Lauf zusammenfasst, anstatt einen neuen cmd für jede gefundene Datei auszuführen. – ephemient

+0

Ich denke eher, wenn seine Funktion in der Lage wäre, mehrere Parameter zu nehmen, würde er nicht die -L 1 Optionen zu xargs liefern ... – Alnitak

+0

Oh, das ist was -L tut? Ich habe nicht nachgesehen, und ich benutze -n für diesen Zweck. – ephemient

4

Das funktioniert nicht, weil xargs das Programm in der Lage sein erwartet als Parameter gegeben exec.

Da foobar in Ihrem Fall nur ein bash Alias ​​oder Funktion ist, gibt es kein Programm zum Ausführen.

Obwohl es für jede Datei durch find zurück Start bash beinhaltet, können Sie einen kleinen Shell-Skript schreiben, also:

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

und dann den Namen dieses Skripts übergeben als Parameter an xargs

+0

Wo soll ich dieses Skript platzieren, damit * it * von 'xargs' erkannt wird? –

+0

@NickVolynkin, wo immer Sie wollen, solange es entweder in '$ PATH' ist oder den Speicherort direkt an' xargs' gibt. – Alnitak

+0

ok, danke für die Erklärung. –

8

Mit Bash Sie auch die Anzahl der args angeben kann (oder Funktion) wie so zu Ihrem Alias ​​übergeben wird:

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