【问题标题】:Stop an infinite while loop repeatedly invoking os.system停止无限循环重复调用 os.system
【发布时间】:2017-07-30 07:56:36
【问题描述】:

感谢大家看到我的帖子。

首先,以下是我的代码:

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)
"""

我的问题是 Ctrl + C 不起作用!

我尝试改变try块的位置,并制作信号(SIGINT)捕捉功能。

但那些也行不通。

我已经看到https://stackoverflow.com/a/8335212/5247212https://stackoverflow.com/a/32923070/5247212,以及其他几个关于这个问题的答案。

我正在使用 MAC OS(10.12.3) 和 python 3.5.2。

【问题讨论】:

  • 你见过this question吗?
  • 似乎在 Windows 7 和 Ubuntu 14.04 上对我来说工作正常(尽管显然必须用打印替换 MACOS 特定的“say”命令。关键是 ctrl-C 被正确捕获,它打印警报停止并退出。

标签: python python-3.x loops try-catch os.system


【解决方案1】:

这是预期的行为,因为 os.system() 是 C 函数 system() 的薄包装。如man page 中所述,父进程在命令执行期间忽略 SIGINT。为了退出循环,您必须手动检查子进程的退出代码(这在手册页中也有提及):

import os
import signal

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

但是,实现相同结果的首选(和更 Pythonic)方法是使用 subprocess 模块:

import subprocess

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

您的代码将如下所示:

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)

作为补充说明,subprocess.run() 仅在 Python 3.5+ 中可用。您可以在旧版本的 Python 中使用 subprocess.call() to achieve the same effect

【讨论】:

    【解决方案2】:

    同时捕获“SystemExit”

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

    【讨论】:

      【解决方案3】:

      问题似乎是 Ctrl+C 被您通过os.system 调用的子进程捕获。这个子进程会做出相应的反应,可能会终止它正在做的任何事情。如果是这样,os.system() 的返回值将不为零。您可以使用它来打破while 循环。

      这是一个适用于我的示例(将 say 替换为 sleep):

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

      【讨论】:

        【解决方案4】:

        如果Ctrl-C被子进程捕获,这里就是这种情况,最简单的解决方法是检查os.system()的返回值。例如,在我的情况下,如果 Ctrl-C 停止它,它返回值 2,这是一个 SIGINT 代码。

        import os
        
        while True:
            r = os.system(my_job)
            if r == 2:
                print('Stopped')
                break
            elif r != 0:
                print('Some other error', r)
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-21
          • 2015-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多