... Manchmal stößt man auf Linux Verzeichnisse, die so viele Dateien enthalten, dass man sie nicht mehr löschen kann. Z.B.: {noformat} $ rm * bash: /bin/rm: Argument list too long $ {noformat} 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: {noformat} $ find . | xargs rm {noformat} 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. h2. Kopieren 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: {noformat} $ find . | xargs cp --target-directory=/home/mydata {noformat} h2. Kopieren von Dateien mit Leerzeichen 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: {noformat} $ 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 {noformat} 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: {noformat} $ 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 {noformat} 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: {noformat} $ 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 {noformat}
|