Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop an infinite while loop repeatedly invoking os.system

Thank you guys for seeing my post.

First, the following is my 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)
"""

My problem is that Ctrl + C does not work!

I tried changing position of try block, and making signal(SIGINT) catching function.

But those also does not work.

I have seen https://stackoverflow.com/a/8335212/5247212, https://stackoverflow.com/a/32923070/5247212, and other several answers about this problem.

I am using MAC OS(10.12.3) and python 3.5.2.

like image 953
Yonggoo Noh Avatar asked Mar 09 '17 10:03

Yonggoo Noh


1 Answers

This is expected behaviour, as os.system() is a thin wrapper around the C function system(). As noted in the man page, the parent process ignores SIGINT during the execution of the command. In order to exit the loop, you have to manually check the exit code of the child process (this is also mentioned in the man page):

import os
import signal

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

However, the preferred (and more pythonic) way to achieve the same result is to use the subprocess module:

import subprocess

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

Your code would then look like something like this:

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)

As an added note, subprocess.run() is only available in Python 3.5+. You can use subprocess.call() to achieve the same effect in older versions of Python.

like image 165
farsil Avatar answered Oct 19 '22 04:10

farsil