Python /在bash终端中调用python脚本:当用户按下Ctrl-C时会发生什么?

时间:2014-08-21 21:47:01

标签: python linux bash robot ctrl

我需要帮助控制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时,将机器人返回原位(在手臂姿势列表中定义),然后完全退出所有内容。
  3. 我的主要问题是,ctrl-C实际上是如何工作的?我认为它只会退出脚本,但实际上它仍会打印东西并要求输入。这个广泛问题的一个子集是,我如何才能获得所需的行为(按ctrl-C时完全退出所有行为)?

    我意识到这是做我需要机器人做的事情的一种笨重的方式,但这是我用我对python的有限知识所能想到的最佳方式。

    谢谢,

    -Adrian

3 个答案:

答案 0 :(得分:0)

  

当用户按下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

答案 1 :(得分:0)

您可以使用以下代码处理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()

答案 2 :(得分:0)

关于信号的评论/答案在技术上是正确的(在UNIX上),但在Python中,CTRL + C处理整齐地远离你。在Python程序中发生的事情是,当您按CTRL + C时,会引发KeyboardInterrupt异常。

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

我猜你调用的代码或库代码都是这样的:

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

请注意裸except:。裸except几乎总是坏事。相反,您或图书馆应该这样做:

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

使用except Exception:不会捕获KeyboardInterrupt异常,这将允许您正确处理它,或者让程序退出。看看Exception class hierarchy