Bash 在子 shell 内的后台运行命令

Nel*_*son 3 c++ bash subprocess process subshell

我希望能够在子 shell 中设置进程,就好像它不在子 shell 中一样。

$( sleep 3 & )只是忽略 & 符号。

我试过了:

$( sleep 3 & )
$( sleep 3 & ) &
$( sleep 3 ) &
Run Code Online (Sandbox Code Playgroud)

但没有任何改变。

然后我尝试$( disown sleep 3 & )返回

disown:无法操作子 shell 中的作业

这促使我尝试$( set -m; disown sleep 3 & ),但得到了相同的输出。

我什至尝试创建一个可以自行守护的 C++ 程序:

#include <unistd.h>
#include <chrono>
#include <thread>
using namespace std;

int main() {
    int ret = fork();
    if (ret < 0) return ret;  // fork error
    if (ret > 0) return 0;  // parent exits

    this_thread::sleep_for(chrono::milliseconds(3000));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但运行后,意识到因为我正在forking 而不是separate_from_parent_and_let_parent_dieing,子 shell 仍将等待进程结束。

为了走出我的 MCVE,从子 shell 调用一个函数,在该函数中,我需要从服务器提取数据,并且需要在 bg 中运行。我唯一的限制是我无法在子 shell 中编辑函数调用。

有没有什么方法可以不分叉,而是与 C++ 程序中的父进程分离,以便它可以在没有后果的情况下死亡,或者强制命令与 bash 中的子 shell 分离?

最好是后者。

Bar*_*mar 5

命令替换机制等待子 shell连接到的$(...)管道上的 EOF 。stdout因此,即使您在子 shell 中后台执行命令,主 shell 仍会等待它完成并关闭其stdout. 为了避免等待,您需要将其输出重定向到远离管道的位置。

echo "$( cat file1; sleep 3 >/dev/null & cat file2 )"
Run Code Online (Sandbox Code Playgroud)

  • 如果需要捕获,则必须等待它完成。否则主命令将开始执行而没有输出。 (2认同)
  • `$(...)` 将使用连接到其 `stdout` 的管道运行子命令,并且它将等待管道上的 EOF。这基本上意味着它必须等待命令完成,即使它在后台。那么将其放在后台有什么意义呢? (2认同)
  • 如果你不想等待它,你还需要重定向它的输出: `git ... &gt;/dev/null &amp;` (2认同)