【问题标题】:Python/Calling python scripts within bash terminal: What exactly happens when user presses Ctrl-C?Python/在 bash 终端中调用 python 脚本:当用户按下 Ctrl-C 时究竟会发生什么?
【发布时间】:2023-04-11 06:18:01
【问题描述】:

我需要有关控制 python 脚本的帮助。我想运行一个控制两个机器人的脚本。例程由一系列运动组成,这些运动要么移动手臂,要么移动夹具。代码形式如下:

def robot_exec():
  # List of robot arm poses:
  *many_many_lines_of_position_vectors*

  # List of robot gripper poses:
  *open position*
  *close position*

  while 1:
    *Call a function that moves the robot arm(s) to a position on the list*
    *Call a function that moves the robot gripper(s) to a position on the list*
    *continue calling functions many times until the desired routine is complete*
    n = raw_input("Restart the routine? (Y/N)")
    if n.strip() == 'n' or 'N':
      break
    elif n.strip() == 'y' or 'Y':
      continue
    else:
      print "Invalid input. Exiting..."
      break

如果例程完成(即每个函数都被调用),它会询问我是否要重新启动,如果我选择是,则表现正常,这很好。

但是,如果我在例程中间按 ctrl-C,则会出现消息“重新启动例程?”仍然弹出并要求输入,我不希望那样。我想要的是以下之一:

  1. 当且仅当用户按下 ctrl-C 时,完全退出一切,不问任何问题。
  2. 当且仅当用户按下 ctrl-C 时,将机器人返回到初始位置(在该手臂姿势列表中定义),然后完全退出所有操作。

我的主要问题是,ctrl-C 实际上是如何工作的?我以为它只会退出脚本,但实际上它仍然会打印内容并要求输入。这个广泛问题的一个子集是,我怎样才能获得所需的行为(按 ctrl-C 时完全退出所有内容)?

我意识到这是一种笨拙的方式来做我需要机器人来做的事情,但这是我能想到的最好的方式,因为我对 python 的了解有限。

谢谢,

-阿德里安

【问题讨论】:

    标签: python linux bash robot ctrl


    【解决方案1】:

    关于信号的 cmets/answers 在技术上是正确的(在 UNIX 上),但在 Python 中,CTRL+C 处理巧妙地与您无关。在 Python 程序中发生的情况是,在您按下 CTRL+C 时,会引发 KeyboardInterrupt 异常。

    现在,您的问题似乎出在您从列表中删除的代码中,即“调用机器人例程”部分。该代码捕获了KeyboardInterrupt

    我猜你调用的代码或库代码会执行以下操作:

    try:
        # some long running code
        # ...
    except:
        # something, or just pass
    

    注意赤裸裸的except:。裸体excepts 几乎总是一件坏事。相反,您或图书馆应该这样做:

    try:
        # some long running code
        # ...
    except Exception:
        # something to fix the situation
    

    使用except Exception: 不会捕获KeyboardInterrupt 异常,这会让你适当地处理它,或者只是让程序退出。看看Exception class hierarchy

    【讨论】:

      【解决方案2】:

      当用户按下 Ctrl-C 时究竟会发生什么?

      发出一个信号。


      我怎样才能得到想要的行为

      >>> import signal
      >>> def handler(sig, stack_frame):
      ...     print "Handled"
      ... 
      >>> signal.signal(signal.SIGINT, handler)
      <built-in function default_int_handler>
      ^C   # <--- typed ctrl-c here
      >>> Handled
      

      详见signal的文档


      请注意:在 Linux 上我使用 signal.SIGINT。在 Windows 上,可能是 signal.CTRL_C_EVENT

      【讨论】:

        【解决方案3】:

        您可以使用此代码处理Ctrl_C

        #!/usr/bin/env python
        import signal
        import sys
        def signal_handler(signal, frame):
                #write your command here for example i write print below :
                print('You pressed Ctrl+C!')
                sys.exit(0)
        signal.signal(signal.SIGINT, signal_handler)
        print('Press Ctrl+C')
        signal.pause()
        

        【讨论】:

          猜你喜欢
          • 2014-04-20
          • 2023-04-01
          • 2018-02-10
          • 2023-03-29
          • 1970-01-01
          • 1970-01-01
          • 2013-12-23
          • 2011-01-29
          • 1970-01-01
          相关资源
          最近更新 更多