xargs nicht erkennt, bash-Aliase
-
21-08-2019 - |
Frage
Ich versuche, den folgenden Befehl ausführen:
find . -iname '.#*' -print0 | xargs -0 -L 1 foobar
wo "foobar" ist ein alias oder eine Funktion definiert, die in meinem .bashrc-Datei (in meinem Fall ist es eine Funktion, die einen parameter).Offenbar xargs nicht erkennen, wie die Dinge ablaufen können.Ist es ein kluger Weg, dies zu beheben?
Lösung
Da nur Sie Ihre interaktive shell kennt auch Aliase, warum nicht starten Sie einfach den alias ohne Gabelung durch xargs
?
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?), Sie vereinfachen diesen zu
find . -iname '.#*' -print | while read -r i; do foobar "$i"; done
oder auch nur find -iname '.#*' | ...
, da das Standard-Verzeichnis ist .
und die Standard-Aktion -print
.
Eine weitere alternative:
IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done
erzählen Bash, die Worte sind nur auf Spalten mit Zeilenumbruch (Standardeinstellung: IFS=$' \t\n'
).Sie sollten vorsichtig sein mit diesem, aber;einige Scripte nicht gut bewältigen, eine veränderte $IFS
.
Andere Tipps
Mit Bash können Sie auch geben Sie die Anzahl der Argumente übergeben, um Ihre alias - (oder-Funktion) wie so:
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
Dies funktioniert nicht, da xargs
erwartet werden in der Lage zu exec
die Programm gegeben als parameter.
Da foobar
in Ihrem Fall ist nur ein bash
alias oder eine Funktion, es gibt kein Programm zum ausführen.
Obwohl es umfasst ab bash
für jede Datei zurückgegeben find
, Sie könnte schreiben Sie ein kleines shell-Skript so:
#!/bin/bash
. $(HOME)/.bashrc
func $*
und dann übergeben Sie den Namen des Skripts als parameter zu xargs
Normalerweise verwende ich finden, wie diese:
find . -iname '' -exec cmd '{}' \;
'{}' wird ersetzt mit dem Dateinamen "und"\";ist notwendig, um zu beenden die Ausführung Kette.Aber wenn das nicht funktioniert, mit Ihrer Funktion, die Sie möglicherweise benötigen, um es durch bash:
find .. |sed -e "s/.*/cmd '&'/"|bash
Finden druckt jede Datei auf einer Linie, sed nur Präfixe dies mit dem Befehl, und leiten es an der bash ausgeführt werden.Überspringen Sie das |bash zuerst, um zu sehen, was passieren wird.
versuchen Sie es
find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)