Run a shell script and immediately background it, however keep the ability to inspect its output
Asked Answered
E

4

96

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.

Ebberta answered 28/5, 2017 at 0:59 Comment(0)
B
178

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.
Bock answered 28/5, 2017 at 1:7 Comment(10)
wow i've been looking for this for years (what you said about "Run the bg command ..." )Ebberta
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 &Luzon
Good tips, @mklement0. I should have thought to use ; in my example since I do not care about the success/failure state of sleep.Bock
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.Paedogenesis
@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...Homeroom
@Homeroom if the process is doing a long calculation until it produces output it will be a solutionPaedogenesis
Recently i've noticed that ctrl Z actually stops the process. As in the process exits. So be careful with this.Expellant
@Expellant In my experience sending a stopped job to background does not resume the processes. But if I run fg the job, it starts to run again.Millennium
@jarno, that's been my experience too, until recently...Expellant
@Expellant Until you started using a specific version of Bash? Or a specific program you stopped?Millennium
J
31

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.

Joyjoya answered 17/10, 2018 at 14:55 Comment(3)
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.Lashelllasher
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.Lashelllasher
How do I do if I want to "nohup cmd params &" with other commands, like echo "test" && nohup cmd params & && zip blablaCottbus
A
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

Astrometry answered 30/5, 2022 at 8:26 Comment(0)
T
2

I tried nohup but my process was getting stopped after a day or two , so i tried this simple bash script to rerun my command after it stops

run.sh

while true; do
[ -e stopme ] && break
python3 main.py # your command here
done

then do

nohup bash run.sh &
Transistor answered 5/11, 2023 at 4:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.