2017-03-09 2 views
3

Merci les gars d'avoir vu mon message.Arrête une boucle infinie tout en invoquant os.system

Tout d'abord, voici mon code:

import os 

print("You can create your own message for alarm.") 
user_message = input(">> ") 

print("\n<< Sample alarm sound >>") 

for time in range(0, 3): 
    os.system('say ' + user_message) # this code makes sound. 

print("\nOkay, The alarm has been set.") 

""" 
##### My problem is here ##### 
##### THIS IS NOT STOPPED ##### 

while True: 
    try: 
     os.system('say ' + user_message) 
    except KeyboardInterrupt: 
     print("Alarm stopped") 
     exit(0) 
""" 

Mon problème est que Ctrl + C ne fonctionne pas!

J'ai essayé de changer la position du bloc try, et de faire la fonction de capture de signal (SIGINT).

Mais cela ne fonctionne pas non plus.

J'ai vu https://stackoverflow.com/a/8335212/5247212, https://stackoverflow.com/a/32923070/5247212, et d'autres plusieurs réponses à propos de ce problème. Je utilise MAC OS (10.12.3) et python 3.5.2.

+0

Avez-vous vu [cette question] (http://stackoverflow.com/questions/18047657/stop-python-in- terminal-sur-mac)? – asongtoruin

+1

Semblait fonctionner correctement pour moi sur Windows 7 et Ubuntu 14.04 (bien que je devais évidemment remplacer la commande "say" spécifique à MACOS par un print.) Le point est que ctrl-C était correctement piégé, l'alarme imprimée s'est arrêtée et est sortie – heroworkshop

Répondre

3

Ce comportement est normal, comme os.system() est une enveloppe mince autour de la fonction C system(). Comme indiqué dans le man page, le processus parent ignore SIGINT lors de l'exécution de la commande. Pour sortir de la boucle, vous devez vérifier manuellement le code de sortie du processus enfant (ce qui est également mentionné dans la page de manuel): manière

import os 
import signal 

while True: 
    code = os.system('sleep 1000') 
    if code == signal.SIGINT: 
     print('Awakened') 
     break 

Cependant, le préféré (et plus pythonique) pour obtenir le même résultat est d'utiliser le module subprocess:

import subprocess 

while True: 
    try: 
     subprocess.run(('sleep', '1000')) 
    except KeyboardInterrupt: 
     print('Awakened') 
     break 

Votre code serait alors ressembler à quelque chose comme ceci:

import subprocess 

print("You can create your own message for alarm.") 
user_message = input(">> ") 

print("\n<< Sample alarm sound >>") 

for time in range(0, 3): 
    subprocess.run(['say', user_message]) # this code makes sound. 

print("\nOkay, The alarm has been set.") 

while True: 
    try: 
     subprocess.run(['say', user_message]) 
    except KeyBoardInterrupt: 
     print("Alarm terminated") 
     exit(0) 

comme une note ajoutée, subprocess.run() est seulement dispositi ble dans Python 3.5+. Vous pouvez utiliser subprocess.call()to achieve the same effect dans les anciennes versions de Python.

0

aussi attraper "SystemExit"

except (KeyboardInterrupt, SystemExit): 
    print("Alarm stopped") 
+2

.. Ca ne marche pas aussi Avez-vous essayé ce code? –

0

Le problème semble être que Ctrl + C est capturé par le sous-processus que vous appelez via os.system. Ce sous-processus réagit de manière correspondante, probablement en mettant fin à tout ce qu'il fait. Si c'est le cas, la valeur de retour de os.system() ne sera pas zéro. Vous pouvez l'utiliser pour rompre la boucle while.

Voici un exemple qui fonctionne avec moi (en remplaçant par saysleep):

import os 
import sys 

while True: 
    try: 
     if os.system('sleep 1 '): 
      raise KeyboardInterrupt 
    except KeyboardInterrupt: 
     print("Alarm stopped") 
     sys.exit(0)