Wenn ich ein Verzeichnis habe, das einige Dateien enthält, deren Namen Leerzeichen enthalten, z
$ ls -1 dir1
file 1
file 2
file 3
Ich kann sie alle erfolgreich in ein anderes Verzeichnis kopieren:
$ find dir1 -mindepth 1 -exec cp -t dir2 {} +
Die Ausgabe von find dir1 -mindepth 1
enthält jedoch nicht maskierte Leerzeichen:
$ find dir1 mindepth 1
dir1/file 1
dir1/file 3
dir1/file 3
Wenn ich print0
anstelle von verwende print
, enthält die Ausgabe immer noch nicht maskierte Leerzeichen:
$ find dir1 mindepth 1 -print0
dir1/file 1dir1/file 2dir1/file 3
Um diese Dateien manuell mit zu kopieren cp
, müsste ich die Leerzeichen maskieren. aber es scheint, dass dies unnötig ist, wenn cp
die Argumente von kommen find
, egal ob ich +
oder \;
am Ende des Befehls.
Was ist der Grund dafür?
find..exec
Die Frage besteht aus zwei Teilen:
find
es, Programme mit aufzurufen,-exec
ohne auf Probleme mit Leerzeichen in Dateinamen zu stoßen, und-print0
Option?Zum einen
find
handelt es sich um einen Systemaufruf, der tatsächlich zu einer Gruppe verwandter Aufrufe gehört, die als "exec" bezeichnet werden . Es übergibt den Dateinamen als Argument direkt an diesen Aufruf, der dann direkt (nach dem Erstellen eines neuen Prozesses) übergeben wird, ohne Informationen über den Dateinamen zu verlieren.Die POSIX -
find
Funktion+
wird wie folgt erläutert, in der Begründung :Das "vor allem eine
-print0
primäre" bezieht sich auf GNUfind
undxargs
die das Problem auf eine andere Weise lösen. Es wird auch von FreeBSDfind
und unterstütztxargs
. Wenn Sie dem Aufruf eine-0
Option hinzugefügt haben (siehe Handbuchseite ),xargs
akzeptiert dieses Programm Zeilen, die mit "Null-Byte" -Zeichen abgeschlossen sind. Im Gegenzugxargs
ruft exec -Funktionen zu tun , seine Arbeit. Der Hauptunterschied zwischen dem-print0
und-0
Merkmal gegenüber dem+
Feature besteht darin, dass das erstere die Dateinamen über eine Pipe übergibt, während das letztere dies nicht tut. Entwickler finden für fast alle Funktionen Verwendung. Die Rohre sind keine Ausnahme.Zurück zum Beispiel von OP, das eine
-t
Option verwendet, umcp
: das in POSIX cp nicht gefunden wird . Es handelt sich vielmehr um eine Erweiterung (auch bekannt als "Nicht-Standard-Feature"), die von GNU cp bereitgestellt wird . Die-0
Erweiterung vonxargs
würde dieses Beispiel nicht verbessern, aber es gibt andere Fälle, in denen es effektiv genutzt werden kann - bedenken Sie, dass es die portable Alternative gibt+
, die GNUfind
akzeptiert.quelle
( Dies sollte ein Kommentar sein, aber er ist zu groß. )
Für diejenigen, die Dinge ausprobieren möchten:
Erstellen Sie ein Skript, das die übergebenen Positionsparameter auflistet, und rufen Sie es auf
list_positional_parameters.sh
.Führen Sie
find
es in einem Verzeichnis $ dir aus:Wie erwartet gibt es in allen Aufrufen nur einen einzigen Parameter, den Dateinamen, unabhängig davon, ob der Name Leerzeichen enthält oder nicht.
quelle
printf
gerneprintf '"%s"\n' "$@"
alle angegebenen Positionsargumente zur visuellen Kontrolle ausdrucken.