Search code examples
c++bashprocesssubprocesssubshell

Bash run command in background inside subshell


I want to be able to bg a process inside a subshell as if it were not in a subshell.

$( sleep 3 & ) just ignores the ampersand.

I've tried:

$( sleep 3 & )
$( sleep 3 & ) &
$( sleep 3 ) &

but nothing changes.

Then I tried $( disown sleep 3 & ) which returned

disown: can't manipulate jobs in subshell

which led me to try $( set -m; disown sleep 3 & ) but I got the same output.

I even tried creating a c++ program that would daemonize itself:

#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;
}

But after running it, realized that because I am forking instead of separate_from_parent_and_let_parent_dieing the subshell will still wait for the process to end.

To step out of my MCVE, a function is being called from a subshell, and in that function, I need to pull data from a server and it needs to be run in the bg. My only constraint is that I can't edit the function call in the subshell.

Is there any way to not fork but separate from the parent process in a c++ program so that it can die without consequence or force a command to separate from a subshell in bash?

Preferably the latter.


Solution

  • The $(...) command substitution mechanism waits for EOF on the pipe that the subshell's stdout is connected to. So even if you background a command in the subshell, the main shell will still wait for it to finish and close its stdout. To avoid waiting for this, you need to redirect its output away from the pipe.

    echo "$( cat file1; sleep 3 >/dev/null & cat file2 )"