8
votes

BASH Script avec lecture non bloquante

Je veux envoyer des données à un processus racine avec un tuyau nommé. Voici le script et cela fonctionne bien:

#!/bin/sh
pipe=/tmp/ntp

if [[ ! -p $pipe ]]; then
    mknod -m 666 $pipe p
fi

while true
do
    if read line <$pipe; then
         /root/netman/extra/bin/ntpclient -s -h $line > $pipe 2>&1
    fi
done


3 commentaires

Pourquoi voulez-vous combiner des opérations distinctes en un seul script? S'ils travaillent chacun correctement autonome, laissez-les autonomes. C'est beaucoup plus facile que d'essayer de plier la coquille à faire des lectures non bloquantes. Les processus sont bon marché. Les processus simples sont également plus sécurisés que complexes et les processus racines doivent être sécurisés.


Je conviendrais avec vous, mais chaque processus mange 628k de RAM (c'est une copie de la bash) et je suis dans un environnement intégré. Je préférerais économiser autant de mémoire que possible.


S'il s'agit d'une grande partie d'un problème, écrivez le code dans C.


3 Réponses :



3
votes

Il suffit de mettre le cycle de lecture en arrière-plan (Ajouter et après)?


4 commentaires

Super! J'ai de moitié la consommation de mémoire!


@Michelemarcon: Êtes-vous sûr que vous économisez une mémoire? Lorsque je l'ai testé, ajouter & forcé la boucle tandis que la boucle tandis que vous exécutez dans un sous-groupe = autre processus = plus de mémoire utilisée.


Testé avec PS, chaque script mange 628K. Avec '&', chaque processus mange 240K. Et BTW, puisque chaque "tandis que" est en arrière-plan, le script "mère" est sorti et libéré sa mémoire


@Gordondavisson Subshells Les instances de bash peuvent utiliser la sémantique de la vache de la fourchette () sur des systèmes modernes Unix, tandis que les instances de Bash Fork-Ed séparément ne peuvent pas.



21
votes

La commande Embedded Lecture de Bash a un paramètre -t pour définir un délai d'attente: xxx pré>

Cela devrait vous aider à résoudre ce problème. P>

EDIT: P> Il existe certaines restrictions pour que cette solution fonctionne car la page d'homme indique: cette option n'a aucun effet si la lecture n'est pas la lecture de l'entrée du terminal ou d'un tuyau. EM> P>

Si je crée un tuyau in / tmp: p> xxx pré>

lecture directement à partir du tuyau ne fonctionne pas: p>

$ read -t 1 -u 7  ; echo $?
1


6 commentaires

La Cette option n'a aucun effet si la lecture n'est pas la lecture de l'entrée du terminal ou d'un tuyau. a une implication. Je modifie la réponse pour inclure des exemples de travail


Je ne travaille toujours pas pour moi, mais peut-être que je gère une bash personnalisée.


@Michelemarcon lire avec l'option Timeout est en bash. Je pense que vous utilisez Dash , à quoi vous utilisez Shebang? / bin / sh ?


@Majid Azimi gnu Bash, version 2.05A.0 (1) -Release (bras-linux-linux-gnu)


Il n'est pas nécessaire d'utiliser EXEC . L'astuce est plutôt que votre suggestion exec 7 <> fichier ouvre le fichier en mode lecture / écriture et évite ainsi le blocage d'un tuyau, s'il n'y a pas d'écrivain. Mais l'ouverture du tuyau en mode lecture-écriture peut également être effectuée directement avec la lecture de lecture: lecture -t 1 <> / tmp / code va lire une ligne et attendre au plus une seconde pour cette ligne .


@Keipetzke a raison. exécuté n'est pas la partie importante. La redirection de lecture-écriture est importante. EXEC avec une redirection en lecture seule échoue de la même manière que la lecture en lecture seule. Il est en quelque sorte laid de devoir ouvrir une redirection d'écriture juste pour obtenir un comportement de délai d'attente, mais au moins cela fonctionne.