linux:启动时挂起进程

Posted

技术标签:

【中文标题】linux:启动时挂起进程【英文标题】:linux: suspend process at startup 【发布时间】:2011-08-11 23:45:10 【问题描述】:

我想生成一个暂停的进程,可能在另一个用户的上下文中(例如通过 sudo -u ...),为生成的进程设置一些 iptables 规则,继续运行该进程,并删除 iptable 规则当进程存在时。

是否有任何标准方法(bash、corutils 等)可以让我实现上述目标?特别是,我怎样才能产生一个处于挂起状态的进程并获取它的 pid?

【问题讨论】:

为什么需要在配置环境之前启动进程?这听起来像是 fork/exec 组合的典型用法。 我必须确保所有通信都通过我的自定义 iptables。 @Let_Me_Be 因为 iptables 需要知道要操作的 PID,在这种情况下 @hanshans 你没有回答我的问题。我在问为什么您需要在配置它之前启动该过程。正常的流程是配置环境,然后启动流程。这看起来很奇怪。 @Robin 好吧,这仍然是正常的 fork/exec 场景。但没关系,我显然没有抓住重点。 【参考方案1】:

像这样写一个包装脚本start-stopped.sh

#!/bin/sh
kill -STOP $$                                    # suspend myself 
                                                 # ... until I receive SIGCONT
exec $@                                          # exec argument list

然后这样称呼它:

sudo -u $SOME_USER start-stopped.sh mycommand &  # start mycommand in stopped state
MYCOMMAND_PID=$!
setup_iptables $MYCOMMAND_PID                    # use its PID to setup iptables
sudo -u $SOME_USER kill -CONT $MYCOMMAND_PID     # make mycommand continue
wait $MYCOMMAND_PID                              # wait for its termination
MYCOMMAND_EXIT_STATUS=$?                         
teardown_iptables                                # remove iptables rules
report $MYCOMMAND_EXIT_STATUS                    # report errors, if necessary

然而,所有这些都太过分了。您无需将进程置于暂停状态即可完成工作。只需制作一个包装脚本setup_iptables_and_start:

#!/bin/sh
setup_iptables $$             # use my own PID to setup iptables
exec sudo -u $SOME_USER $@    # exec'ed command will have same PID

然后这样称呼它

setup_iptables_and_start mycommand || report errors
teardown_iptables

【讨论】:

【参考方案2】:

您可以为您的程序编写一个 C 包装器,它会执行以下操作:

    fork 并打印子 pid。 在子项中,等待用户按 Enter。这会使孩子进入睡眠状态,您可以使用 pid 添加规则。 添加规则后,用户按回车键。孩子使用execsystem 运行您的原始程序。

这行得通吗?

编辑: 实际上,您可以使用 shell 脚本执行上述过程。尝试以下 bash 脚本:

#!/bin/bash

echo "Pid is $$"
echo -n "Press Enter.." 
read 
exec $@

您可以将其运行为/bin/bash ./run.sh <your command>

【讨论】:

【参考方案3】:

您可能需要您正在启动的程序的PID在该程序实际开始运行之前。你可以这样做。

启动纯脚本 强制脚本等待 您可能可以使用 suspend,这是一个 bash 内置程序,但在最坏的情况下,您可以通过一个信号使其自行停止 以任何你想要的方式使用 bash 进程的PID 重新启动停止的 bash 进程 (SIGCONT) 并执行 exec - 另一个内置 - 启动您的真实进程(它将继承 PID)李>

【讨论】:

【参考方案4】:

我想您可以自己编写一个用于分叉的实用程序,其中分叉的子代在执行 exec 之前将自身挂起。否则,请考虑使用 LD_PRELOAD 库来执行您的“自定义”业务。

如果您关心确保安全,您可能应该看看更大的枪(使用 chroot,也许是半虚拟化,用户模式 ​​linux 等);

最后提示:如果您不介意进行更多编码,ptrace 接口应该允许您执行您描述的操作(因为它用于实现调试器)

【讨论】:

【参考方案5】:

一种方法是让gdb 在其主函数开始时暂停程序(使用命令“break main”)。这将保证进程足够快地挂起(尽管一些初始化例程可以在main 之前运行,但它们可能不会做任何相关的事情)。但是,为此,您需要为要暂停的程序提供调试信息。

我建议你先手动尝试一下,看看它是如何工作的,然后找出如何编写你所做的脚本。

或者,也可以限制进程(如果您确实要这样做!)使用 iptables,使用 SELinux 或基于 ptrace 的工具(如 sydbox)。

【讨论】:

不,这不起作用。我需要一个适用于任何应用程序的通用工具。 SELinux 或 sydbox 怎么样? (我现在看到我应该将我的答案的那部分变成一个单独的答案。) SELinux 对于我想做的事情似乎有点矫枉过正(Debian 6 甚至支持这个),但我会尝试研究 sydbox

以上是关于linux:启动时挂起进程的主要内容,如果未能解决你的问题,请参考以下文章

Erlang进程试图杀死自己时挂起

ffmpeg 在后台运行时挂起

在Mac上完成多处理时挂起,但不在Windows上挂起

托管在 Windows 服务中的 WCF 服务在停止时挂起

Spring Boot Reactive Mongo 在启动时挂起

如何防止 Eclipse 在启动时挂起?