Como executar o primeiro processo a partir de uma lista de processos armazenados em um arquivo e apagar a primeira linha como se o arquivo foi uma fila e eu chamei de “pop”?

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

Pergunta

Como executar o primeiro processo a partir de uma lista de processos armazenados em um arquivo e excluir imediatamente a primeira linha como se o arquivo foi uma fila e eu chamei de "pop"?

Eu gostaria de chamar o primeiro comando listado em um arquivo de texto simples com \ n como separador em um pop-como a moda:


Figura 1:

cmdqueue.lst :

proc_C1
proc_C2
proc_C3
.
.

Figura 2:

Pop o primeiro comando via popcmd :

proc_A | proc_B | popcmd cmdqueue.lst | proc_D

Figura 3:

cmdqueue.lst :

proc_C2
proc_C3
proc_C4
.
.
Foi útil?

Solução

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

Exemplo:

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

Outras dicas

Ooh, isso é um one-liner divertido.

Ok, aqui está o negócio. O que você quer é um programa que, quando chamado, imprime a primeira linha do arquivo na saída padrão, em seguida, exclua essa linha do arquivo. Soa como um trabalho para sed (1) .

Tente

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

Eu tenho certeza que alguém que já tinha tido seu café poderia mudar o programa sed para não precisar cabeça (1) chamada, mas que funciona, e mostra usando um subnível ( "( foo)" é executado em um sub-processo).

Eu suponho que você está constantemente adicionando ao arquivo também, então reescrever o arquivo o coloca em perigo de substituição de dados. Para este tipo de tarefa que eu acho que seria melhor usar arquivos individuais para cada entrada fila, com data / hora para determinar a ordem, e depois como você processa cada arquivo que você poderia anexar os dados para um arquivo de log e, em seguida, apagar o arquivo gatilho.

Realmente precisar de mais informações, a fim de sugerir uma solução boa. É importante saber como o arquivo está sendo atualizado. É um monte de processos separados, apenas um processo, etc.

Eu acho que você teria que reescrever o arquivo - por exemplo, executar um comando para listar todas as linhas, mas a primeira, escrita que, para um arquivo temporário e renomeá-lo para o original. Isso poderia ser feito usando cauda ou awk ou perl dependendo dos comandos que você tem disponível.

Se você quiser tratar um arquivo como uma pilha, então uma abordagem melhor seria ter o topo da pilha no final do arquivo.

Assim, você pode facilmente cortar o arquivo no início da última linha (= pop), e simplesmente acréscimo para o arquivo como você empurrar.

Você pode usar um script bash pouco; nomeá-lo "popcmd":

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

edit: usando sed para o meio duas linhas, como Charlie Martin mostrou, é muito mais elegante, é claro:

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

edit: Você pode usar este exatamente como no seu exemplo código de uso:

proc_A | proc_B | popcmd cmdstack.lst | proc_D

Você não pode escrever para o início de um arquivo, assim que cortar a linha 1 seria um monte de trabalho (reescrever o resto do arquivo (que não é verdade que muito trabalho para o programador (que é o que todos os outros resposta post foi escrito para você :)))).

Eu recomendo manter a coisa toda na memória e usando uma pilha clássico em vez de um arquivo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top