Cómo ejecutar el primer proceso de una lista de procesos almacenados en un archivo y eliminar la primera línea como si el archivo era una cola y que se llama “pop”?

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

Pregunta

Cómo ejecutar el primer proceso de una lista de procesos almacenados en un archivo e inmediatamente eliminar la primera línea como si el archivo era una cola y me llama "pop"?

Me gustaría llamar a la primera orden que figuran en un archivo de texto simple con \ n como el separador de manera emergente como:


Figura 1:

cmdqueue.lst :

proc_C1
proc_C2
proc_C3
.
.

Figura 2:

Pop el primer comando a través de popcmd

proc_A | proc_B | popcmd cmdqueue.lst | proc_D

Figura 3:

cmdqueue.lst :

proc_C2
proc_C3
proc_C4
.
.
¿Fue útil?

Solución

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:]))

Ejemplo:

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

Otros consejos

Ooh, eso es un divertido de una sola línea.

De acuerdo, éste es el trato. Lo que queremos es un programa que, cuando se le llama, imprime la primera línea del fichero en la salida estándar, a continuación, eliminar esa línea del archivo. Suena como un trabajo para sed (1) .

Trate

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

Estoy seguro de que alguien que ya había tenido su café podría cambiar el programa sed para no necesitar la cabeza (1) llamada, pero que funciona, y muestra de usar un subnivel ( "( foo)" se ejecuta en un sub-proceso.)

Asumo que usted está constantemente realizando adiciones al archivo también, por lo que volver a escribir el archivo que pone en peligro de sobrescribir los datos. Para este tipo de tarea Creo que sería mejor usar archivos individuales para cada entrada de cola, usando fecha / hora para determinar el orden, y luego mientras procesa cada archivo se podría anexar los datos a un archivo de registro y luego eliminar el archivo de activación.

Realmente necesita más información con el fin de sugerir una buena solución. Es importante saber cómo el archivo está siendo actualizado. Es que una gran cantidad de procesos separados, sólo un proceso, etc.

Creo que tendría que volver a escribir el archivo - por ejemplo, ejecutar un comando para listar todas las líneas excepto la primera, que escribir en un archivo temporal y cambiarle el nombre a la original. Esto podría hacerse mediante cola o awk o perl en función de los comandos que tiene disponible.

Si desea tratar un archivo como una pila, a continuación, un mejor enfoque sería que la parte superior de la pila al final del archivo.

De este modo se puede fácilmente cortar el archivo en el inicio de la última línea (= emergente), y simplemente añadir al archivo a medida que empuja.

Puede utilizar un poco de escritura del golpe; El nombre de "popcmd":

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

editar usando sed para las dos líneas centrales, como Charlie Martin mostró, es mucho más elegante, por supuesto:

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

editar Se puede usar esta exactamente igual que en el código de ejemplo de uso:

proc_A | proc_B | popcmd cmdstack.lst | proc_D

No se puede escribir en el comienzo de un archivo, por lo que cortar la línea 1 sería mucho trabajo (reescribir el resto del archivo (que en realidad no es que mucho trabajo para el programador (es lo que todos los demás posterior respuesta ha escrito para ti :)))).

Me gustaría recomendar mantener todo el asunto en la memoria y el uso de una pila clásica en lugar de un archivo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top