82

How can I run a shell script and immediately background it, however keep the ability to inspect its output any time by tailing /tmp/output.txt.

It would be nice if I can foreground the process too later.


P.S.

It would be really cool if you can also show me how to "send" the backgrounded process in to a GNU screen that may or may not have been initialized.

informatik01
  • 16,038
  • 10
  • 74
  • 104
american-ninja-warrior
  • 7,397
  • 11
  • 46
  • 80

3 Answers3

154

To 'background' a process when you start it

Simply add an ampersand (&) after the command.

If the program writes to standard out, it will still write to your console / terminal.


To foreground the process

Simply use the fg command. You can see a list of jobs in the background with jobs.

For example:

sh -c 'sleep 3 && echo I just woke up' & jobs


To background a currently running process

If you have already started the process in the foreground, but you want to move it to the background, you can do the following:

  1. Press Ctrl+z to put the current process to sleep and return to your shell. This process will be paused until you send it another signal.
  2. Run the bg command to resume the process, but have it run in the background instead of the foreground.
informatik01
  • 16,038
  • 10
  • 74
  • 104
Jon Wolski
  • 2,293
  • 2
  • 19
  • 21
  • 2
    wow i've been looking for this for years (what you said about "Run the `bg` command ..." ) – american-ninja-warrior May 28 '17 at 01:18
  • 7
    Good answer. As an aside: you can more simply send _multiple_ shell commands to the background with a subshell (`(sleep 3 && 'echo I just woke up') &`) or group command (`{ sleep 3 && echo 'I just woke up'; } &`). To make a redirection part of the background command, place it _before_ the `&`; e.g., `(sleep 3 && echo 'I just woke up') >/tmp/output.txt &` – mklement0 May 28 '17 at 01:36
  • 1
    Good tips, @mklement0. I should have thought to use `;` in my example since I do not care about the success/failure state of `sleep`. – Jon Wolski May 28 '17 at 01:38
  • 6
    Something that was not mentioned: if you don't want the output of the background command to go to your terminal (not redirected) do `stty tostop` and the process will receive a `SIGTTOU` signal, the you can `fg` and see the output. – Diego Torres Milano May 30 '17 at 18:02
  • @DiegoTorresMilano I tested your method and found that if we use `stty tostop` followed by `bg`, if the background process output to the terminal, it will be suspended immediately again. So this is not a solution... – jdhao Jun 22 '22 at 06:36
  • @jdhao if the process is doing a long calculation until it produces output it will be a solution – Diego Torres Milano Jun 22 '22 at 15:21
  • Recently i've noticed that ctrl Z actually stops the process. As in the process exits. So be careful with this. – Owl May 21 '23 at 07:59
28

Another way is using the nohup command with & at the end of the line.

Something like this

nohup whatevercommandyouwant whateverparameters &

This will run it in the background and send its output to a nohup.log file.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
israelss
  • 322
  • 3
  • 6
  • Explanation about `nohup`: it's work is to cut the stdin, stdout and stderr. Some execution environments force those closed when the starting environment is closed (e.g. terminal window on X server, login session in true terminal). You get exactly the same results if you redirect stdin, stdout and stderr by yourself. – Mikko Rantalainen Mar 25 '20 at 06:40
  • 4
    Also note that if your system has `systemd` and it has been configured to kill processes started by your user interface once you log out, there's no hack that can make any process survice your logout if the process is direct or indirect child of your user session. Double forking, `nohup` or any other trick cannot escape the `cgroup` containment used by `systemd`. A root process can change cgroups, though. – Mikko Rantalainen Mar 25 '20 at 06:42
  • 2
    How do I do if I want to "`nohup cmd params &`" *with other commands*, like `echo "test" && nohup cmd params & && zip blabla` – Olivier Pons Jul 29 '20 at 08:07
7

One easy to use approach that allows managing multiple processes and has a nice terminal UI is hapless utility.

Install with pip install hapless (or python3 -m pip install hapless) and just run

$ hap run my-command  # e.g. hap run python my_long_running_script.py
$ hap status  # check all the launched processes
$ hap logs 4  # output logs for you 4th background process
$ hap logs -f 2  # continuously stream logs for the 2nd process

See docs for more info.

ui

erik258
  • 14,701
  • 2
  • 25
  • 31
Most Wanted
  • 6,254
  • 5
  • 53
  • 70