7
votes

Bash: Comment interrompre ce script quand il y a un CTRL-C?

J'ai écrit un petit script Bash pour trouver toutes les modifications de la Mercuriale (à partir de la pointe) qui contient la chaîne passée dans l'argument: xxx

si je l'interrèse en frappant CTRL-C, plus souvent que la commande actuellement exécutée est "HG Log" et c'est cette commande qui est interrompue, mais alors mon script continue.

Je pensais à vérifier le statut de retour du "Journal HG", mais Parce que je suis en train de passer à Grep, je ne suis pas trop sûr de savoir comment y aller ...

Comment devrais-je continuer à quitter ce script quand il est interrompu? (BTW Je ne sais pas si ce script est bon du tout pour ce que je veux faire, mais cela fait le travail et de toute façon je suis intéressé par le problème "interrompu")


0 commentaires

3 Réponses :


1
votes

Le $ pipestatus La variable vous permettra de vérifier les résultats de chaque membre du tuyau.


0 commentaires

6
votes

endroit au début de votre script: piège 'Echo interrompu; EXIT 'INT

edit: Comme indiqué dans les commentaires ci-dessous, ne fonctionne probablement pas pour le programme de l'OP en raison de la pipe. Le $ pipestatus fonctionne fonctionne, mais il peut être plus simple de définir le script pour quitter si tout programme dans la conduite passe avec un état d'erreur: set -e -o pipefail < / p>


7 commentaires

La commande Piège ne fonctionne que avec des processus qui ne pénètrent pas eux-mêmes. Si le script recevait l'interruption, cela s'orporterait déjà.


Ah, désolé à ce sujet, j'ai raté le tuyau dans le script de l'OP. Une meilleure réponse pourrait être de:


Votre première solution (le piège) fonctionnerait avec tout processus qui ne piège pas l'interruption de lui-même - trouver est un bon exemple de processus de longue exécution qui passera à travers l'interruption, ce qui entraînera le script avorter. Le piège peut être utilisé pour empêcher le script d'abandonner immédiatement le nettoyage, de sorte qu'un destructeur ou un finaliste. C'est une commande pratique de savoir.


Cela devrait être SET -O PICHEFAIL .


En réalité, je voulais dire jeu -e -o pipefail, le -e pour rendre le script de programme Quitter sur l'erreur et la fabrication de tuyauterie pour rendre l'échec du tuyau si HG renvoie un statut d'erreur.


Vous ne voulez peut-être pas que le script quitte cependant d'autres erreurs.


@Musiphil Si vous ne voulez pas que le script quitte sur d'autres erreurs, placez simplement le set -e -o pipefail juste avant le tuyau que vous voudriez que cela affecte, puis non définissez ces options à l'aide de SET + E + O PICHEFAIL Après le tuyau, vous souhaitez l'appliquer.



5
votes

Réécrivez votre script comme celui-ci, à l'aide de la matrice $ Pipestatus pour rechercher une défaillance:

#!/bin/bash

CNT=$(hg tip | awk '{ print $2 }' | head -c 3)
while [ $CNT -gt 0 ]
do
    echo rev $CNT
    hg log -v -r$CNT | grep $1
    if [ 0 -ne ${PIPESTATUS[0]} ] ; then
            echo hg failed
            exit
    fi     
    let CNT=CNT-1
done


4 commentaires

Je devrais probablement souligner que les deux $ Pipestatus et l'option Pipestail que ARKKU mentionné sont spécifiques à Bash version 3+. Ils ne sont pas pris en charge par d'autres coquillages.


Merci, sur mes Linux de Debian, j'ai en effet Bash 3+ mais sur mes Mac, c'est bash 2.05.


Ah bon? C'est surprenant. Je cours Bash 3.2.48 sur mon MacBook Pro, et je ne me souviens pas de l'améliorer moi-même. Quelle version d'OSX utilisez-vous?


Leopard sur mon MacBook Pro qui vient d'avoir un crash de disque dur ce matin, alors ne peut pas vérifier;) et 10.4.11 sur mon Mac Minis (c'est celles qui ont des bash 2.05), que j'ai besoin spécifiquement de tester parce que nous avons Applications d'expédition sur 10.4, 10.5 et 10.6 et nous avons donc besoin de ces anciennes versions de OS X pour tester notre logiciel.