0

So I did some research on bash, and found that if you run:

command &

Then the process that is executing command will do so in the background as a job. If you end the process that is the parent of the process executing command, then command will also terminate.

However, if you run:

(command&)

Then the process will not exit once you exit the terminal.

I want to know what the round brackets represent, it was very hard finding that you can do this in the first place, and I don't know where else to search to find what the round brackets represent.

Yiannis128
  • 138
  • 1
  • 2
  • 9
  • `( ... )` launches a subshell. i am sorry; i am not sufficiently informed to elaborate. but i hope this helps you start your journey of learning – kevinnls Apr 05 '21 at 14:29
  • The statement in the question is not always true. If by "exit the terminal" you mean actually close it, you need to also detach stdin, stdout and stderr; and might need to reroute HUP to make the process reliably survive. Otherwise, the process will get a HUP (which it may or may not choose to die on), and will also receive a SIGPIPE when it tries to read from stdin or write to stdout or stderr. – Charles Duffy Apr 05 '21 at 15:58
  • That said, I'm not sure this question is on-topic here. "How can I detach a shell command from the terminal a script was started from without using `nohup`?" would be completely on-topic, but this question isn't about an _actual problem you face_; you have no bug you're trying to fix, no feature you don't know how to implement. ["Why" questions about language design are general off-topic here](https://meta.stackexchange.com/questions/170394), and "I didn't want to read the manual" questions are frowned on for other reasons (we don't need a question about every fact a manual sets out!). – Charles Duffy Apr 05 '21 at 16:01
  • 1
    ...for that matter, it's not even true that `command &` will always terminate when the script that launched it exits. `foo /dev/null 2>&1 & disown -h` does a much more thorough job of detaching `foo` than `(foo &)` does. – Charles Duffy Apr 05 '21 at 16:04
  • _However_, the linked duplicate tells you how the `(foo &)` practice got started. Subshells -- as created by parens -- do a fork; creating a background process with `&` does another fork; so by forking twice you get the same effect as the traditional C double-fork-on-daemonization practice, of ensuring that your process can't be considered the session leader or considered to have a controlling TTY. That doesn't mean it's a good idea, just that there's historical reasons why it's an idea that folks coming from a C background would think of when they're writing shell scripts. – Charles Duffy Apr 05 '21 at 16:06
  • @CharlesDuffy can you explain why `foo /dev/null 2>&1 & disown -h` does a better job than `(foo&)`, also if `(...)` creates a sub shell, then is it the equivalent of `&`? – Yiannis128 Apr 06 '21 at 11:14
  • `(...)` creates a subshell _but doesn't detach it_ -- the parent process waits for that subshell to exit. Whereas `... &` runs `...` in a _detached_ subshell. – Charles Duffy Apr 06 '21 at 14:51
  • `/dev/null 2>&1` is a necessary component of detaching something _thoroughly_, because it ensures that it can't get EPIPEs thrown when trying to read from stdin or write to stdout or stderr after the terminal exits. `(foo&)` doesn't do that at all, so you can have your backgrounded processes die for that reason. – Charles Duffy Apr 06 '21 at 14:52
  • `disown -h` tells the shell not to forward a SIGHUP to the job in question on terminal exit. That behavior is only present for interactive shells in the first place -- so it's optional in scripts -- but it achieves a good chunk of what you would have gotten from the double-fork maneuver (wherein the shell created by the first fork has already exited and isn't around to forward anything). – Charles Duffy Apr 06 '21 at 14:54

0 Answers0