使用 su 时,python 脚本未处理 CTRL+C

CTRL+C not handled in python script when using su

我有一个这样的 Python 代码。

try:
    while some_cond_is_still_true:
        ....
except KeyboardInterrupt: # Handle CTRL+C
    ...

虽然如果我自己 运行 python 脚本可以很好地处理 KeyboardInterrupt,但如果我 运行 作为另一个用户使用 su,它就不会被处理,像这样。

su <some_other_user> -c 'python myprogram.py <args>'

我该如何解决这个问题?

如果您使用 su <user> -c ...,那么将在指定用户的上下文中建立另一个 shell。

我认为:如果你点击CTRL+C这取决于shell,中断信号是否会到达python脚本。

试试su <user> -c 'watch ls'看看,如果CTRL + C会停止看ls。

不确定,你想用你的脚本做什么,但如果你 "only" 想中止一个 运行 脚本,你可以执行以下操作(或者 CTRL + C) :

CRTL + Z 停止此进程(用户 shell 进程)。显示作业编号和停止的进程。 现在您可以使用作业编号终止进程,例如 kill %1

su 命令创建一个新的交互式 shell 并在其中执行命令。 当您使用选项 -c (--command) 时,su 命令会创建一个与命令中指示的用户的新会话。要解决此问题,请使用选项 --session-command。 在这种情况下,命令将是这样的:

su user_name --session-command 'python myprogram.py <args>'

在这种情况下,您应该能够捕捉到 CTRL+C 中断

The Bndr 说的是真的。要解决此问题,您可以使用信号模块注册一个新的回调函数,该回调函数将在 SIGTERM 信号处调用。 在其中,您可以引发 KeyboardInterrupt() 或将控制程序流的全局变量设置为 False。 您也可以尝试再次注册默认回调,这会引发 KeyboardInterrupt() 异常。

这应该使新生成的 shell 正确传播信号。如果没有,那么你应该选择 shell 将通过 su 启动脚本,因为此时调用的脚本有问题。或者检查脚本顶部的执行行。 尝试通过调用脚本的组合来使用它,例如:

#! /usr/bin/env python

#! /usr/bin/python

#! /bin/sh python

#! /bin/bash python

等等,看看有什么用。这假设您的脚本是可执行的,并且您不必直接调用 Python 解释器。但是,如果您打算分发您的脚本,请小心您留在那里的内容。不同的发行版会有不同的反应,有些甚至可能没有您当前遇到的问题。