2008-12-14 18 views
3

Comment exécuter le premier processus à partir d'une liste de processus stockés dans un fichier et supprimer immédiatement la première ligne comme si le fichier était une file d'attente et j'ai appelé "pop"?Comment exécuter le premier processus à partir d'une liste de processus stockés dans un fichier et supprimer la première ligne comme si le fichier était une file d'attente et que j'ai appelé "pop"?

Je voudrais appeler la première commande répertoriée dans un simple fichier texte avec \ n comme séparateur de façon semblable à la pop:


Figure 1:

cmdqueue.lst : 

proc_C1 
proc_C2 
proc_C3 
. 
. 

Figure 2:

Pop la première commande via popcmd:

proc_A | proc_B | popcmd cmdqueue.lst | proc_D 

Figure 3:

cmdqueue.lst : 

proc_C2 
proc_C3 
proc_C4 
. 
. 
+0

Je suppose que c'est techniquement une ** queue ** car je doute que de nouvelles commandes soient ajoutées au début du fichier. Implémenter une pile dans un fichier aurait beaucoup plus de sens à la fin du fichier. – jmucchiello

+0

Vous avez raison. Merci pour la note. – secr

Répondre

4

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

Exemple:

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

Python est un peu exagéré pour cela. – Svante

+0

@Harleqin: Le script est multi-plateforme. Il n'a pas de dépendances autres que le python lui-même. Quelle alternative pourriez-vous suggérer? – jfs

+0

Cette chose-shlex est vraiment utile. – secr

1

Je pense que vous auriez besoin de réécrire le fichier - par exemple exécutez une commande pour lister toutes les lignes sauf la première, écrivez-la dans un fichier temporaire et renommez-la en original. Cela pourrait être fait en utilisant queue ou awk ou perl selon les commandes que vous avez disponibles.

1

Si vous voulez traiter un fichier comme une pile, puis une meilleure approche serait d'avoir le haut de la pile à la fin du fichier.

Ainsi, vous pouvez facilement couper le fichier au début de la dernière ligne (= pop), et simplement ajouter au fichier que vous appuyez.

4

Ooh, c'est un one-liner amusant.

Bon, voici l'affaire. Ce que vous voulez, c'est un programme qui, lorsqu'il est appelé, imprime la première ligne du fichier sur stdout, puis supprime cette ligne du fichier. On dirait un travail pour sed (1).

Essayez

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

Je suis sûr que quelqu'un qui avait déjà eu leur café pourrait changer le programme sed pas besoin de la tête (1) appel, mais qui fonctionne, et montre à l'aide d'un subshell ("(foo)" s'exécute dans un sous-processus.)

+0

Nice. Vos parenthèses ne correspondent pas, d'ailleurs. – Svante

+0

Augh. J'ai dit que j'étais pré-café. THX. –

+0

Cela fonctionne sur Windows? – jfs

0

Vous ne pouvez pas écrire au début d'un fichier, donc découper la ligne 1 serait beaucoup de travail (réécrire le reste du fichier (ce qui n'est pas vraiment beaucoup de travail pour le programmeur (c'est ce que tout autre poste de réponse a écrit pour vous :)))).

Je vous recommande de garder le tout en mémoire et d'utiliser une pile classique plutôt qu'un fichier.

+0

Contrepoint: sed -i – Svante

+0

Comment gardez-vous le tout en mémoire et obtenez-vous toujours le pipeline décrit dans le cas d'utilisation? Pour un petit fichier, réécrire ce n'est vraiment pas beaucoup de travail de toute façon. –

1

Vous pouvez utiliser un petit script bash; nommez-le "popcmd":

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

modifier: En utilisant sed pour les deux moyennes lignes, comme Charlie Martin a montré, est beaucoup plus élégant, bien sûr:

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

modifier: Vous peut utiliser exactement comme dans votre exemple code d'utilisation:

proc_A | proc_B | popcmd cmdstack.lst | proc_D
2

Je suppose que vous êtes constamment en train d'ajouter à la f ile aussi, donc réécrire le fichier vous met en danger d'écraser des données. Pour ce type de tâche, je pense que vous feriez mieux d'utiliser des fichiers individuels pour chaque entrée de file d'attente, en utilisant la date et l'heure pour déterminer l'ordre, puis vous pouvez ajouter les fichiers à un fichier journal puis supprimer le fichier de trigger.

Vraiment besoin de plus d'informations afin de suggérer une bonne solution. Il est important de savoir comment le fichier est mis à jour. Est-ce beaucoup de processus séparés, juste un processus, etc.