【问题标题】:Why bash puts process started via '&' to foreground?为什么 bash 将通过“&”启动的进程置于前台?
【发布时间】:2018-06-14 06:58:46
【问题描述】:

当进程以“&”启动时, bash 将新进程置于前台组一小段时间 然后放置 自己回到前台组。

据我所知,当我们运行任何外部 没有“&”后台操作符的命令,shell 会创建一个 该命令的新进程组并通知终端该进程组现在 在前台。当我们使用“&”运行时,前台进程组不得更改。

我在 linux 上使用了一个 C 程序,它只打印前台进程组和 启动时拥有自己的进程组,然后在睡眠后打印相同的进程组。

我得到以下结果:

tcgetpgrp=19981 getpgrp=19981
sleep(5)
tcgetpgrp=11996 getpgrp=19981

在本例中,11996 是 bash 的 pid。

我只在以(./test&) 运行并在重负载下(从不以./test&)运行时才注意到这种行为。

bash 的行为是否正确?

Bash 版本:4.4.12

编辑

按照@Costi 的建议添加了 pid 值:

tcgetpgrp=29148 getpgrp=29148 getpid=29149
sleep
tcgetpgrp=28566 getpgrp=29148 getpid=29149

28566 是 bash 的 pid

【问题讨论】:

    标签: bash job-control


    【解决方案1】:

    (...) 在 bash 中创建一个子 shell。根据 bash 手册:

    (list) list 在子shell环境中执行(参见下面的命令执行环境)

    我的猜测是您将该子外壳的 PID 视为前台进程,不是您的 test 命令的 PID。并且 subshel​​l 很快退出(在后台触发你的命令之后)。

    要验证这一点,请将getpid 返回的值添加到组合中,并检查它是否与在子shell 中运行时的getpgrp 值相同。

    【讨论】:

    • 你是对的 - 请参阅 OP 中的 EDIT。我使用括号来防止将作业控制消息打印到终端。在我的程序中,我使用tcgetpgrp+getpgrp 作为调试方式:比如prog - 所有消息将直接进入终端,无需打开日志文件;对于正常操作说prog&,所有消息都将进入日志文件。 OP中问题的解决方法是将getpgrp更改为getpid
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多