Tuyau nommé tamponné non bloquant?

20

Je cherche quelque chose que je soupçonne n'existe pas: Un tube nommé non bloquant (fifo) à utiliser depuis la ligne de commande. Une telle chose existe t elle?

Voici le cas d'utilisation: Supposons que j'ai un processus qui va s'exécuter longtemps en arrière-plan et qui génère beaucoup de sortie stdout. Je ne me soucie pas vraiment de la sortie et je ne veux pas la stocker (peut-être que je n'ai pas assez de place pour), mais je voudrais "entrer" périodiquement et suivre ce qu'elle fait, puis abandonner à nouveau et le laisser faire son travail. Je voudrais donc rediriger sa sortie vers ce canal nommé théorique tamponné et non bloquant, puis y puiser périodiquement.

Donc, fondamentalement, je veux commencer comme ça ( 10Métant la taille du tampon):

mkmagicfifo magicfifo 10M
spewingprocess > magicfifo &

... et venez régulièrement voir ce qui se passe ...

tail -f magicfifo

... sans magicfifo stocker toute la sortie (donc, pas un fichier normal), et sans qu'il bloque le processus de crachat quand il se remplit et n'est pas tapé (donc, pas tout à fait un tube nommé normal).

Je ne pense pas que les solutions impliquent tailou le pruneferont (enfin, je peux penser à une solution de contournement impliquant tail), car il tailfaudrait toujours que je stocke toutes les données quelque part (si je veux entrer et sortir de la regarder), et prunedoit réécrire le fichier, vraisemblablement (j'admets que je n'ai pas essayé / prouvé cela) rompant la redirection du processus générant toute la sortie.

Je m'attends à ce que je puisse écrire un utilitaire pour le faire, mais * nix a tellement d' aspects sympas des fichiers et des tuyaux et ainsi de suite, je ne peux pas m'empêcher de penser que cela existe et je ne le sais pas.

Donc: existe-t-il une telle chose, et si oui, qu'est-ce que c'est?

TJ Crowder
la source
1
Ce que vous décrivez est un "tampon circulaire" ou un "tampon circulaire". Je ne connais aucun outil de ligne de commande pour maintenir une telle chose, bien que ce soit trivial à créer.
Shawn J. Goff,
2
Jetez un œil aux solutions décrites dans "Linux non bloquant fifo (journalisation à la demande)", stackoverflow.com/questions/7360473/… .
1
On dirait que cela a été résolu sur StackOverflow: stackoverflow.com/questions/7360473/…
James Blackburn
@JamesBlackburn: Merci! Très intéressant.
TJ Crowder du

Réponses:

16

Je pense que ce que vous cherchez, c'est GNU screen. Il maintient un tampon pour maintenir le dernier écran plein ou deux de sortie d'un ou plusieurs programmes et vous permet de vous déconnecter et de revenir plus tard.

psusi
la source
+1 pour suggérer l'écran. BTW, vous pouvez le configurer pour contenir beaucoup de "lignes d'historique".
M. Shunz
1
Merci. Pouvez-vous donner un exemple de la façon dont vous appliqueriez cela aux commandes que j'ai montrées dans ma question? La page de manuel indique que c'est un gestionnaire de fenêtres (je pense qu'ils signifient dans un sens terminal, pas dans un sens graphique, mais quand même). Et serais-je toujours en mesure de passer (via ssh) et d'abandonner si nécessaire? (Par exemple, opérations sur des serveurs distants.)
TJ Crowder
Oui, vous pouvez utiliser l'écran GNU de cette façon. Vous devez créer une nouvelle session (potentiellement nommée), exécuter votre commande à l'intérieur de cette session, puis vous déconnecter.
TML
2
Il y a aussi tmuxet dtach- tout dans la même classe d'application multiplexeur de terminal / gestionnaire de session devrait être capable de réaliser la même chose.
jw013
5

Vous pouvez l'utiliser pv, il fournit autant de mémoire tampon que vous le souhaitez dans un pipeline. Vous pouvez l'utiliser comme ceci:

sprewingprocess | pv -B 1g > ordinaryfifo &

Cela vous donnerait jusqu'à 1 Go de mémoire tampon entre spewingprocesset le fifo. La plupart des distributions Linux proposent pvdans un package appelé, croyez-le ou non pv,.

David Schwartz
la source
Merci, mais ce bloc ne serait-il pas une fois le tampon plein si je ne lisais pas le canal nommé cible?
TJ Crowder
1
Oui, mais quel choix avez-vous? Dans un univers fini, vous ne pouvez pas avoir un tampon littéralement illimité.
David Schwartz
L'autre choix est celui que j'ai décrit dans ma question: ne pas stocker toutes les sorties. Lorsque le tampon est plein, le contenu le plus ancien est jeté.
TJ Crowder du
Hmm, j'ai testé cela et cela ne fonctionne malheureusement pas entièrement. Si le processus de lecture du fifo arrête de lire pendant un certain temps, pv bloque en essayant d'écrire sur le fifo, et parce qu'il n'est pas multithread, cela bloque également la lecture des données dans le tampon de pv. Ainsi, le tampon de pv continuera à se remplir uniquement pendant que le processus de lecture du fifo continue à lire. pv peut être capable de lire et de mettre en mémoire tampon certaines données, mais cela n'empêche pas l'écrivain de bloquer complètement.
Daniel S. Sterling
1

J'ai eu le même problème. Ceci est ma première solution. Commencez par écrire la sortie dans un fichier que nous tronquons après chaque ligne afin qu'il ne se développe pas indéfiniment:

spewingprocess | while read line; do echo $line > buffer.txt ; done

Ensuite, lisez le fichier à l'aide de tail (où 2> /dev/nullse débarrasse du message d'erreur "fichier tronqué"):

tail -f ./buffer.txt 2> /dev/null

De cette façon, le tampon ne grandit pas et nous pouvons multiplexer, par exemple, exécuter autant de queues que nous voulons. Cependant, le problème avec cette approche est que nous pouvons perdre des données lorsque nous tronquons plus vite que queue ne peut lire comme le montre ce test:

for ((i=0; ; i++)) ; do echo "$i" ; done | while read line; do  echo $line > buffer.txt ; done
tail -f ./buffer.txt 2> /dev/null > log.txt

Après un certain temps, les première et dernière lignes sont:

$ head -n 1 log.txt
0
$ tail -n 1 log.txt
78783

Mais le fichier a moins de lignes, donc certaines sont perdues:

$ wc log.txt
67087  67087 392819 log.txt

Cela semble toujours une bonne solution si vous ne vous souciez pas tant de la perte de données ou lorsque votre processus de crachat n'est pas assez rapide pour que les données se perdent.

bterwijn
la source