J'ai un processus externe qui commence à écrire dans un fichier.
Comment écrivez-moi un script qui attend que le fichier soit fermé (lorsque l'autre processus effectué avec l'écriture). P>
5 Réponses :
Le moyen facile: laissez le script exécuter le programme et attendre que ce soit fini. P>
Ce n'est pas agréable, et ça me fait me sentir sale l'écrire ... /tmp/foo.txt est le fichier testé ...
#!/bin/bash
until [ "$( find /proc/*/fd 2> /dev/null |
xargs -i{} readlink {} |
grep -c '^/tmp/foo.txt$' )" == "0" ]; do
sleep 1;
done;
Il y a plusieurs façons d'y parvenir: P>
Si vous le pouvez, démarrez le processus à partir de votre script. Le script se poursuivra lorsque le processus se termine et cela signifie qu'il ne peut plus écrire de données dans le fichier. P> li>
Si vous ne pouvez pas contrôler le processus, vous savez que le processus se termine après avoir rédigé le fichier, vous pouvez trouver l'ID de processus, puis vérifier si le processus est toujours en cours d'exécution avec Si ce n'est pas possible, vous pouvez utiliser La renommée s'assure que tout le monde voit tout le fichier avec toutes les données ou rien. P> kill -0 $ PID code>. Si $? Code> est 0 code> par la suite, le processus est toujours en vie. P> li>
lsof -np $ pid code> pour obtenir une liste de tous les fichiers ouverts pour ce processus et vérifier si votre fichier est dans la liste. C'est quelque peu lent, cependant. P> li>
ul>
Que diriez-vous de ! lsof - / chemin / à / à / fichier code>?
@RubyTuesdaydono: qu'en est-il?
Je suggérant qu'il s'agissait d'une manière plus directe d'interroger si tout processus a ce fichier spécifique ouvert (versus grep code> à travers une liste de tous les fichiers ouverts par le processus le plus probable). Votre recommandation secondaire autour de renommer des fichiers temporaires en place une fois que vous êtes terminé, semble être une option supérieure - je veux juste mettre en évidence que lsof code> est une commande sophistiquée avec plusieurs vecteurs pour acclamer exactement les informations souhaitées.
@RubyTuesdaydono: ah. Je suggère de toujours spécifier l'option -n code> pour utiliser des cas comme celui-ci, donc lsof code> ne passe pas beaucoup de temps à faire des recherches DNS.
Je n'ai observi aucune recherche DNS sur mon VPS Fedora (OpenVz) lors de l'utilisation de Strace Code> avec un argument de nom de fichier (par exemple, Cat >> File & Strace -F -E Trace = réseau LSOF - - Fichier code>) - Bien que je conviens que c'est une bonne habitude d'être explicite dans la mesure du possible, car les implémentations peuvent varier sauvagement:]
Le comportement ne dépend pas de lsof code> mais sur le processus que lsof code> analyses. Exécutez-le sur un serveur Web occupé et il peut prendre une demi-heure pour résoudre toutes les adresses clientes.
Ah, à droite ... surtout depuis d'autres processus (en plus de celui que nous prévoyons) pourrait avoir le fichier cible ouverte.
LOOP jusqu'à ce que le fichier soit une approche stable, cela devrait fonctionner si vous attendez des résultats expérimentations (vous n'avez donc pas besoin de manipulation d'événements en temps réel):
EXPECTED_WRITE_INTERVAL_SECONDS=1
FILE="file.txt"
while : ; do
omod=$(stat -c %Y $FILE)
# echo "OLD: $omod"
sleep $EXPECTED_WRITE_INTERVAL_SECONDS
nmod=$(stat -c %Y $FILE)
# echo "NEW: $nmod"
if [ $omod == $nmod ] ; then
break
fi
done
Créer un petit programme C à l'aide de inotify code> . Le programme devrait: P>
inotify code> instance. li>
- Ajoutez une montre à l'instance pour le
in_close_write CODE> Evénement pour le chemin du fichier d'intérêt. LI>
- Attendez l'événement. LI>
- Sortie avec un code approprié. LI>
ol>
Puis dans votre script, appelez le programme avec le chemin de fichier comme argument. P>
Vous pouvez l'étendre en ajoutant un argument de délai d'attente et permettant de spécifier différents événements. P>