3

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.

1
  • 2
    What are you really trying to do? $(...) is for running a command and putting its output into the current shell command. If you run the command in the background, how can you capture its output? Commented May 30, 2018 at 22:23

2 Answers 2

7

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 )" 
Sign up to request clarification or add additional context in comments.

11 Comments

"My only constraint is that I can't edit the function call in the subshell." Even if I could remove the $ from the subshell, I wouldn't because the function produces output that needs to be captured.
If it needs to be captured, you have to wait for it to finish. Otherwise the main command will just start executing without the output.
$(...) will run the subcommand with a pipe connected to its stdout, and it will wait for EOF on the pipe. That basically means it has to wait for the command to finish, even though it's in the background. So what's the point of putting it in the background?
& is a command separator just like ;. Putting ; after it creates an empty command, and that's not allowed.
If you don't want to wait for it, you'll also need to redirect its output: git ... >/dev/null &
|
2

I hope I've got you right. Fix me if I'm wrong- you want that your main thread will ba able to die before the sub-threads ends? I f this is the situation you can use detach method on the thread.

4 Comments

as in replace the first 3 lines of main() with thread::detach(); ?
thread t(somefunction, somearguments); t.detach(); this_thread::sleep_for(chrono::milliseconds(3000));
It works, thank you!! Moving from bash to c++ is not ideal but I think it's the best I'm going to get.
You're welcome, glad to help :) BTW, you might find something more helpful about the bush here: superuser.com/questions/178587/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.