有时我在一个不支持ps -p $PID
的环境中,我希望我的用户能够找到(以便携式POSIX方式)我作为另一个用户启动的进程是否仍在运行并且还要杀死它们如果太久了。
如果我的用户运行su anotherUser -c '/bin/sh script.sh'
并获得了PID,我的用户可以致电kill -0 $PID
以确定它是否仍在运行?
或者:什么是最便携的POSIX方式来监视和终止用户作为另一个用户启动的进程?我应该su anotherUser -c 'kill -0 $PID'
吗?
我的特殊用例:编写一个库,各种内核开发人员(显然所有的Linux,其中一些只支持-w
的{{1}}的BusyBox)都可以包含在他们的平台中,用于一堆应用程序。偶尔会发生某种系统事件(如重启)。他们都注册了他们想要运行的任意脚本。但内核方面希望确保这些都能及时终止,因为这不应该永远停止。
这些注册的脚本(和应用程序)作为各种用户运行。该库以root身份运行(我继承了一个设计),但是以拥有它们的用户身份启动这些脚本。因此,如果ps
有效,则库知道PID并且只能成功启动脚本。
这些脚本有什么作用?我不知道,但他们都是由内部友好的人写的,他们有着共同的兴趣。它应该都是良性的东西,如编写文本文件来保存应用程序状态。
(编辑:添加了用例,添加了缺少su username -c 'script.sh'
的示例环境)
答案 0 :(得分:2)
不,通常你不能,因为kill(1)
命令正在进行kill(2)系统调用(另请参阅signal(7))。另见POSIX kill function,记录并说
提供扩展安全控制的实现可能会对发送信号(包括空信号)施加进一步的实现定义限制。特别是,系统可能会拒绝pid指定的部分或全部进程的存在。
但是,Linux(但不是其他POSIX系统)有capabilities(7)
man
的Linux kill(2)
页面说:
对于有权发送信号的进程,它必须具有特权(在Linux下:具有
CAP_KILL
能力)或真实 或发送过程的有效用户ID必须等于真实或 已保存目标进程的set-user-ID。在SIGCONT
的情况下 当发送和接收进程属于同一个时,就足够了 会话。 (从历史上看,规则是不同的;参见注释。)
但是,您可以使用setuid技术来共享真实或已保存的set-user-ID。使用这些时要小心,错误会打开一个巨大的安全漏洞。
另请阅读SELinux(它可能会禁止你想做的事情)。
你的最后一招su anotherUser -c 'kill -0 $PID'
经常(但不总是)有效。邪恶在于细节(想想script.sh
运行的setuid程序,或者使用Linux上的功能,或者某些SELinux或docker的东西,......等等),细节是不是由POSIX标准化。
也许与您的特定约定设置一些明确的IPC通信(为了查询或终止进程,使用帮助程序“服务器”或“监视”进程),例如使用unix(7)套接字或fifo(7) - s或pipe(7) - s可能更明智。
也许你想要一些batch processing监视器或job scheduler,例如GNQS。另请参阅Docker。