这不可能。

这不可能。

为了避免退出 shell 时进程停止,您可以通过nohup或启动命令screen。还可以使用以下命令否认现有进程:

mycommand
# Press CTRL-Z
bg
disown %1

但这只能从当前的 shell 启动。

我想使用另一个 shell/ssh 会话做同样的事情(命令启动于壳牌,但否认推出外壳B)。

可以从另一个 shell 将进程置于后台:

# CTRL-Z can be done via
kill -20 PID (SIGSTP)
# bg can be done via
kill -18 PID (SIGCONT)

但该进程仍然由初始 shell 拥有。如何从另一个 shell 中否认该进程?

我使用的是Linux 4.15

答案1

这不可能。

出色地,这是如果您准备好使用调试器并深入了解运行 shell 程序的进程的内部结构。更具体地说:在 shell 编程层面上,这是不可能以简单直接的方式实现的。

这是因为disown会影响 shell 程序在每个单独的 shell 进程的内存空间中维护的“作业”列表。

Shell(即作业控制进程)会记住它们在内部“作业表”中分叉的子进程,直到被指示忘记它们,disown或者子进程终止,并且 shell 已wait()为它们执行并报告终止工作”。 disown不影响子进程状态以任何方式。它会影响 shell 的功能。

因为它忘记了disowned 过程......

  • wait()……当通知它终止孩子时,它不再承认“工作”的完成;
  • exit…当它被告知/时,它不再关心进程是否仍在运行logout;和
  • …当子进程本身收到挂断信号时(或者,对于某些 shell 程序,当它退出并且知道它是交互式登录 shell 时),它不再向子进程发送挂断信号。

Shell 不共享这些列表,并且不容易从其他进程访问它们(如上所述,不启动调试器并附加它)。除了在disown相关 shell 进程本身内运行的内置命令之外,没有 IPC 机制或命令行工具来访问它们。 (这是为什么这是一个内置命令。)

这就是为什么disown即使在同一个登录会话中,您也无法从第二个 shell 执行作业。 disown完全是每个 shell 每个 shell 进程的事情。

此外 …

可以将进程从另一个 shell 置于后台。

事实上,这并不是你一直在做的事情。

的概念前景背景与会话的控制终端相关。具体来说,控制终端已知有一个进程组,即前台进程组。停止和继续进程本身并不在前台和后台之间切换进程。需要更新控制终端的前台进程组还有。 A前台进程仅凭借成为该前台进程组的成员而处于前台。该会话中的所有其他进程组以及这些进程组中的进程都位于后台。

讽刺的是,您并没有从另一个 shell 中执行此操作。你所做的事情正在触发原来的shell进程采取行动。它看到前台进程组的主进程停止,并作为响应调整终端的前台进程组(回到它自己的进程组)。

SIGTSTP顺便说一句,正确的信号是。

进一步阅读

答案2

如果您使用的是 Solaris,您可以致电:

nohup -p <pid>

这将删除当前控制终端并将 stdout 连接到文件系统中的文件。

为了能够做到这一点,您需要获得内核的支持(在本例中为 /proc 文件系统)。 Solaris 已于 2001 年添加了对该程序的支持nohup。如果其他平台能够将调试器附加到来自其他终端的正在运行的进程,则可以添加此功能。

顺便说一句:如果您查看之前运行该进程的 shell,您可能会在 shell 中的 wait() 调用中看到“无子进程”错误消息。

我目前不知道其他平台上有类似的构造。

相关内容