Manchmal stößt man auf Linux Verzeichnisse, die so viele Dateien enthalten, dass man sie nicht mehr löschen kann. |
Zum Beispiel:
$ rm * bash: /bin/rm: Argument list too long $ |
Dies ist ein Fall für den xargs
-Befehl. Mit diesem wenig bekannten Linux-Kommando kann man Befehle für beliebig viele Parameter aufrufen. Der auszuführende Befehl wird - ggf. mit weiteren Parametern - seinerseits dem xargs
-Befehl als Parameter übergeben. Alle zusätzlichen Parameter, wie z.B. ein paar hunderttausend zu löschende Dateinamen, liest xargs
dann von stdin ein. Der Befehl wird dann nur mit sovielen Parametern aufgerufen, wie unter Linux zulässig ist. Falls in der Kommandozeile auch weitere Parameter angegeben wurden, dann werden diese Parameter ebenfalls verwendet, die zusätzlichen Parameter von stdin kommen immer danach.
Konkret sieht das so aus:
$ find . | xargs rm |
Der find .
Befehl listet alle Dateien im aktuellen Verzeichnis. Durch das Pipe-Symbol wird das Listing dem xargs
-Kommando übergeben, welches dann seinerseits das rm
-Kommando ggf. mehrfach aufruft.
Etwas schwieriger ist das Kopieren von sehr vielen Dateien in ein Ziel-Directory. Wenn man find . | xargs cp (Ziel)
eingibt, funktioniert es nicht wie erhofft, da ja die Parameter für die zu kopierenden Dateien angehängt werden, d.h. das Ziel-Verzeichnis ist der erste Parameter und nicht der letzte.
Glücklicherweise gibt es für die cp
- oder mv
-Befehle den Parameter -t
oder --target-directory=
. Die korrekte Syntax sieht also so aus:
$ find . | xargs cp --target-directory=/home/mydata |
Richtig interessant wird es, wenn man Dateien kopieren will, die Leerzeichen oder andere spezielle Zeichen enthalten. Leerzeichen werden von xargs
nämlich als Trennzeichen aufgefasst:
$ ls -la total 8 drwxr-xr-x 2 u00 u00 4096 Feb 27 18:39 . drwxr-xr-x 12 u00 u00 4096 Feb 27 18:38 .. -rw-r--r-- 1 u00 u00 0 Feb 27 18:39 Datei eins -rw-r--r-- 1 u00 u00 0 Feb 27 18:39 Datei zwei $ find . -type f | xargs ls -l ls: ./Datei: No such file or directory ls: eins: No such file or directory ls: ./Datei: No such file or directory ls: zwei: No such file or directory |
Um dies zu umgehen, kann man xargs
veranlassen, das NUL-Zeichen (hexadezimal 0x00) als Trennzeichen zu verwenden. Natürlich muss das Programm, welches die Parameterliste generiert, ebenfalls das NUL-Zeichen verwenden.
Bei find
sieht das dann so aus:
$ find . -print0 -type f | xargs -0 ls -l -rw-r--r-- 1 u00 u00 0 Feb 27 18:39 ./Datei eins -rw-r--r-- 1 u00 u00 0 Feb 27 18:39 ./Datei zwei |
Falls das Tool keine Option -0
hat, muss man on-the-fly die NUL-Zeichen einbauen. Man ersetzt z.B. die Line Feeds mit Hilfe eines regulären Ausdrucks, am besten mit Perl:
$ find . -type f | perl -pe 's,\n,\0,' | xargs -0 ls -l -rw-r--r-- 1 u00 u00 0 Feb 27 18:39 ./Datei eins -rw-r--r-- 1 u00 u00 0 Feb 27 18:39 ./Datei zwei |
Unbedingt das Label kb-how-to-article aus dem nachfolgenden Macro löschen.
|