Wie der ersten Prozess aus einer Liste von Prozessen in einer Datei, und löschen Sie die erste Zeile, als ob die Datei war eine Warteschlange gespeichert laufen und ich rief „Pop“?

StackOverflow https://stackoverflow.com/questions/366533

Frage

Wie der ersten Prozess aus einer Liste von Prozessen in einer Datei gespeichert laufen und sofort die erste Zeile löschen, als ob die Datei eine Warteschlange war und ich rief „Pop“?

Ich mag den ersten Befehl in einer einfachen Textdatei mit \ n als Separator in einem Pop-artig aufgelistet nennen:


Abbildung 1:

cmdqueue.lst :

proc_C1
proc_C2
proc_C3
.
.

Abbildung 2:

Pop

den ersten Befehl über popcmd :

proc_A | proc_B | popcmd cmdqueue.lst | proc_D

Abbildung 3:

cmdqueue.lst :

proc_C2
proc_C3
proc_C4
.
.
War es hilfreich?

Lösung

pop-cmd.py:

#!/usr/bin/env python
import os, shlex, sys
from subprocess import call
filename = sys.argv[1]
lines = open(filename).readlines()
if lines:
    command = lines[0].rstrip()
    open(filename, "w").writelines(lines[1:])
    if command:
        sys.exit(call(shlex.split(command) + sys.argv[2:]))

Beispiel:

proc_A | proc_B | python pop-cmd.py cmdstack.lst | proc_D

Andere Tipps

Oh, das ist ein amüsanter Einzeiler.

Okay, hier ist der Deal. Was Sie wollen, ist ein Programm, das, wenn sie aufgerufen wird, druckt die erste Zeile der Datei auf stdout, dann diese Zeile aus der Datei löschen. Klingt wie ein Job für sed (1) .

Versuchen

proc_A | proc_B | `(head -1 cmdstack.lst; sed -i -e '1d' cmdstack.lst)` | proc_D

Ich bin sicher, dass jemand, der bereits hatte ihren Kaffee hatte, konnte das sed Programm ändert nicht den Kopf müssen (1) Anruf, aber das funktioniert, und protzt eine Subshell mit ( "( foo)“läuft in einem Teilprozess.)

Ich gehe davon aus, dass Sie ständig auch in die Datei anhängen, so die Datei Umschreiben bringt Sie in Gefahr Daten zu überschreiben. Für diese Art von Aufgabe ich glaube, Sie würden mit einzelnen Dateien für jeden Warteschlangeneintrag besser sein, mit Datum / Uhrzeit, um zu bestimmen, und dann, wie Sie jede Datei bearbeiten können Sie die Daten in eine Protokolldatei anhang und dann die Trigger-Datei löschen.

Wirklich mehr Informationen benötigen, um eine gute Lösung vorzuschlagen. Es ist wichtig zu wissen, wie die Datei aktualisiert wird immer. Ist es viele getrennte Prozesse, nur ein Prozess, etc.

Ich denke, man müsse die Datei neu zu schreiben - z.B. führen Sie einen Befehl alle Zeilen aufzulisten, aber die erste, schreiben, dass in eine temporäre Datei und benennen Sie sie in das Original. Das könnte mit Schwanz oder awk oder Perl getan werden, in Abhängigkeit von den Befehlen, die Sie zur Verfügung haben.

Wenn Sie eine Datei wie ein Stapel behandeln wollen, dann ein besserer Ansatz, um die Spitze des Stapels am Ende der Datei zu haben wäre.

So können Sie ganz einfach die Datei am Anfang der letzten Zeile (= pop), und einfach anhängen an die Datei abgeschnitten, wie Sie drücken.

Sie können ein wenig Bash-Skript verwenden; nennen Sie es "popcmd":

#!/bin/bash
cmd=`head -n 1 $1`
tail -n +2 $1 > ~tmp~
mv -f ~tmp~ $1
$cmd

edit: für die mittleren zwei Linien sed verwenden, wie Charlie Martin zeigte, ist viel eleganter, natürlich:

#!/bin/bash
cmd=`head -n 1 $1`
sed -i -e '1d' $1
$cmd

edit: können Sie diese verwenden, um genau wie in Ihrem Beispiel Verwendungscode:

proc_A | proc_B | popcmd cmdstack.lst | proc_D

Sie nicht an den Anfang einer Datei schreiben kann, so das Ausschneiden der Linie 1 würde den Rest der Datei eine Menge Arbeit (neu schreiben (was das eigentlich nicht viel Arbeit für den Programmierer ist (es ist, was alle anderen Antwort Beitrag wird für Sie geschrieben :)))).

Ich würde empfehlen, das Ganze im Speicher zu halten und einen klassischen Stapel anstatt eine Datei.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top