Ich möchte use find
für einige Dateinamen aufrufen.
find $(do_something to find filenames) -print0 | xargs -r0 ls -ld
Dies bricht ab, wenn $(do_something to find filenames)
nichts zurückgegeben wird: Der Find-Befehl beginnt mit der rekursiven Suche.
Gibt es eine Möglichkeit, find anzuweisen, nichts zu tun, wenn es keinen expliziten Dateinamen/Verzeichnisnamen als Argument erhält?
Antwort1
Mit zsh
würde ich Folgendes tun:
files=($(do_something to find filenames))
(($#files)) && find $files ...
Mit tcsh
:
set files=(`do_something to find filenames`)
if ($#files) find $files:q ...
Mit bash
oder ,mksh
ksh93
set -f; files=($(do_something to find filenames))
((${#files[@]})) && find "${files[@]}" ...
POSIX:
set -f; set -- $(do_something to find filenames)
[ "$#" -gt 0 ] && find "$@" ...
(in Bash und anderen POSIX-Shells $(...)
werden Splits ( $IFS
standardmäßig bei Leerzeichen, Tabulator und Zeilenumbruch) durchgeführt, aber es wird auch Globbing auf die resultierenden Wörter angewendet, was Sie hier wahrscheinlich nicht wollen, daher das set -f
. Andere Shells ((t)csh, zsh, fish, rc, es...) haben dieses Problem nicht).
Antwort2
Wie wäre es damit:
paths=$(do_something to find filenames)
if [ "$paths" ]; then
find "$paths" ...
fi
Dies funktioniert unabhängig von der find
Implementierung.
Beachten Sie, dass find "$paths"
mehr als ein Pfadname Probleme verursacht. Wenn die Pfadnamen keine Leerzeichen enthalten, können Sie Folgendes verwenden: find $paths
, andernfalls ist diese Funktion eine funktionierende Alternative:
dofind() {
set -f
set -- $(do_something to find filenames)
if [ $# -gt 0 ]; then
find "$@" ...
fi
set +f
}
Es deaktiviert das Dateiglobbing und verwendet es dann, set --
um den Shell-Argumentvektor festzulegen. Dies funktioniert mit jeder POSIX-Shell.
Antwort3
Sie können find
zum Starten ein zusätzliches, nicht vorhandenes Verzeichnis angeben:
find " " $(do_something to find filenames) -print0 | xargs -r0 ls -ld
Um das zu bereinigen, löschen Sie find
die Fehlerausgabe:
find " " $(do_something to find filenames) -print0 2>/dev/null | xargs -r0 ls -ld
(dann merkt man es aber nicht, wenn wieder ein Fehler auftritt...).
Wenn do_something to find filenames
Dateinamen ausgegeben werden, find
wird dies bemängelt " "
, aber der Rest der Befehlszeile wird trotzdem verarbeitet. Wenn keine Dateinamen ausgegeben werden, find
wird dies erneut bemängelt, " "
aber der Standardwert wird nicht hinzugefügt .
.
Antwort4
In zsh
(und den meisten nicht von Bourne abgeleiteten Shells) gilt: Wenn ein (oderalleabhängig von der Schale)Globusnicht erweitert wird, wird der Befehl abgebrochen.
$(do_something to find filenames)
ist kein Glob, aber Sie können es zu einem machen, indem Sie in Folgendes einen Glob-Qualifizierer anhängen zsh
:
find $(do_something to find filenames)(#q) -print0...
Oben (#q)
wird das (ein leerer Glob-Qualifizierer, der also sonst nichts bewirkt) an das letzte Wort angehängt, das sich aus der Aufteilung der Ausgabe von ergibt do_something to find filenames
, sodass der Befehl abgebrochen wird, wenn dieser Befehl keine (oder eine leere) Ausgabe erzeugt, aber auch, wenn dieses letzte Wort (und nur dieses letzte Wort) nicht in einen vorhandenen Pfad aufgelöst wird. Sie können es auf jedes Wort anwenden lassen, das sich aus dieser Aufteilung ergibt (sodass der Befehl abgebrochen wird, wenn eines dieser Wörter nicht in eine vorhandene Datei aufgelöst wird), und zwar mit:
find ${^$(do_something to find filenames)}(#q) -print0...