2016-08-08 28 views
1

Ich versuche, eine Reihe von Prozessen dynamisch auf einer festen Anzahl von Prozessoren auszuführen. Ich möchte die Ausgabe für jeden Prozess in eine eindeutige Datei drucken, aber es gibt ein Problem mit Xargs, die den In-Place-Dateinamen nicht verwenden, um eine separate Datei für jeden Prozess zu erstellen.Senden der Befehlsausgabe an eine eindeutige Datei mit Xargs in Bash

Der Bash-Skript ruft eine Csh Skript und ist unter:

$ cat temp | xargs -P 8 % csh '%'.csh >& '%'.log 

Wo Temp eine Textdatei von csh Befehlsnamen ist.

Mein Problem ist, dass xargs %.log wörtlich nimmt und ständig die Datei überschreibt, während die Prozesse darauf schreiben, anstatt separate .log Dateien wie gewünscht zu haben.

Ich betreiben dieses Skript als $ bash run.bash &

Antwort

0

Im Allgemeinen string Ersatz mit in dem Code zu ersetzen, ist eine schlechte Idee - in Ihrem Fall, wenn Sie ein Skript mit einem bösartigen Namen haben, kann dieser Name verwendet wird führe beliebige Befehle aus. (Sicher, Sie führen das Skript aus, aber dasselbe gilt auch in Situationen, in denen Sie sich ausschließlich mit Daten und Dateinamen von Ausgaben beschäftigt haben - also sollten Sie sich den robusten Ansatz am besten aneignen).

Führen Sie die Namen als an das Skript Parameter, anstatt sie in das Skript ersetzt wird (wie xargs würde, wenn Sie durch das Hinzufügen -I oder -J Parameter seine Verwendung festgelegt werden tun:

# best-practice approach: run a completely fixed shell script, passing arguments on 
# its command line. 
xargs -P 8 -n 1 \ 
    sh -c 'for x; do csh "${x}.csh" >"${x}.log" 2>&1; done' _ 

Sie Beachten Sie, dass eine sh -c Instanz aufgerufen wird: Dies wird benötigt, weil xargs selbst keine Shell-Operationen wie Umleitungen versteht, wenn Sie möchten, dass eine Umleitung ausgeführt wird, benötigen Sie eine Shell, um das zu tun.


Nun lassen Sie uns ein wenig mehr gehen in warum verhielt sich Ihren ursprünglichen Code, wie es tat:

xargs -P 8 % csh '%'.csh >& '%'.log 

... erste führt die Umleitung auf %.log, dann den Befehl läuft

xargs -P 8 % csh '%'.csh 

Es gibt keine Möglichkeit für xargs, die %.log zu ersetzen Zeichenfolge, da diese Umleitung von der umschließenden Shell vor der xargs Befehl ausgeführt wurde überhaupt ausgeführt wurde.

+0

Danke für die ausführliche Antwort. –

+0

@WillPhilpott, wenn dies Ihre Frage vollständig beantwortet, sollten Sie das Kontrollkästchen neben der Antwort aktivieren, um diese Frage zu markieren. –

0

Benutzung von GNU Parallel es wie folgt aussieht:

cat temp | parallel -P 8 'csh {}.csh >& {}.log' 

Wenn Sie 8 Kerne haben, können Sie auch tun:

cat temp | parallel 'csh {}.csh >& {}.log' 

GNU Parallel Zitate {}, so dass schädliche Eingang wird nicht ausgeführt .