【问题标题】:How to avoid ^C getting printed after handling KeyboardInterrupt处理 KeyboardInterrupt 后如何避免打印 ^C
【发布时间】:2011-11-28 21:11:13
【问题描述】:

今天早上我决定在我的服务器程序中处理键盘中断并优雅地退出。我知道该怎么做,但我挑剔的自我并没有发现它足够优雅以至于^C 仍然被打印出来。如何避免^C 被打印?

import sys
from time import sleep
try:
  sleep(5)
except KeyboardInterrupt, ke:
  sys.exit(0)

按 Ctrl+C 退出上述程序并查看 ^C 正在打印。我可以使用一些sys.stdoutsys.stdin 魔法吗?

【问题讨论】:

  • 你可以尝试在curses package 中使用一些东西,但我认为这不是微不足道的(如果可能的话)。
  • 我看到 ^C 在 bash 和 csh 上打印出来,它要么在 shell 之间保持一致,要么在较低(内核)级别。

标签: python command-line command-line-interface


【解决方案1】:

这是你的shell在做的,python与它无关。

如果您将以下行放入~/.inputrc,它将抑制该行为:

set echo-control-characters off

当然,我假设您使用的是 bash,但情况可能并非如此。

【讨论】:

    【解决方案2】:
    try:
        while True:
            pass
    except KeyboardInterrupt:
        print "\r  "
    

    【讨论】:

    • 谢谢。最快和最干净的解决方案 +1。我建议您详细说明您的示例以更易于理解,并可能解释 \r 的作用
    • 更干净:sys.stderr.write("\r")
    【解决方案3】:

    这可以解决问题,至少在 Linux 中是这样

    #! /usr/bin/env python
    import sys
    import termios
    import copy
    from time import sleep
    
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    new = copy.deepcopy(old)
    new[3] = new[3] & ~termios.ECHO
    
    try:
      termios.tcsetattr(fd, termios.TCSADRAIN, new)
      sleep(5)
    except KeyboardInterrupt, ke:
      pass
    finally:
      termios.tcsetattr(fd, termios.TCSADRAIN, old)
      sys.exit(0)
    

    【讨论】:

      【解决方案4】:

      我不知道这是否是最好的方法,但我通过打印两个\b(退格转义序列)然后是一个空格或一系列字符来解决这个问题。这可能工作正常

      if __name__ == "__main__":
          try:
              # Your main code goes here
          except KeyboardInterrupt:
              print("\b\bProgram Ended")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-20
        • 2020-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-21
        • 2021-05-24
        相关资源
        最近更新 更多