i'll need some help to get back the prompt, right now i'm executing this block and don't throw me back the prompt, i'm using & at the end for run this command as a background task. how can get back to prompt after execute the script.
#!/bin/sh
sudo su - user << EOF
nohup program -p4xxx &
EOF
nota: if i press ctrl + c - kill the program.
Thank you in advance.
Without testing, I'm wondering if you want this:
#!/bin/bash
nohup sudo -u user program -p4xxx &
disown
That will background the sudo process, and disassociate it from the calling shell (the script).
(From https://askubuntu.com/questions/121559)
After you start a process (job), you can still do other things. You might want to write these down as a cheat sheet.
Ctrl+c Kill the running process (foreground job)
Ctrl+z Pause running process (foreground job) and return to the prompt
Type jobs Shows you all background jobs on the terminal
Type bg Makes the last paused job continue in the background
Type fg Returns the last pause job to the foreground
You can also type bg or fg with a number after, like fg 3. This will bring job #3 to the foreground.
Two alternative:
Bring background job foreground with fg and send signal with
ctrl+c
Directly kill background process(correspond to program job)
with pkill program
Related
Just switched from bash to zsh.
In bash, background tasks continue running when the shell exits. For example here, dolphin continues running after the exit:
$ dolphin .
^Z
[1]+ Stopped dolphin .
$ bg
[1]+ dolphin . &
$ exit
This is what I want as the default behavior.
In contrast, zsh's behavior is to warn about running jobs on exit, then close them if you exit again. For example here, dolphin is closed when the second exit-command actually exits the shell:
% dolphin .
^Z
zsh: suspended dolphin .
% bg
[1] + continued dolphin .
% exit
zsh: you have running jobs.
% exit
How do I make zsh's default behavior here like bash's?
Start the program with &!:
dolphin &!
The &! (or equivalently, &|) is a zsh-specific shortcut to both background and disown the process, such that exiting the shell will leave it running.
From the zsh documentation:
HUP
... In zsh, if you have a background job running when the shell exits, the shell will assume you want that to be killed; in this case it is sent a particular signal called SIGHUP... If you often start jobs that should go on even when the shell has exited, then you can set the option NO_HUP, and background jobs will be left alone.
So just set the NO_HUP option:
% setopt NO_HUP
I have found that using a combination of nohup, &, and disown works for me, as I don't want to permanently cause jobs to run when the shell has exited.
nohup <command> & disown
While just & has worked for me in bash, I found when using only nohup, &, or disown on running commands, like a script that calls a java run command, the process would still stop when the shell is exited.
nohup makes the command ignore NOHUP and SIGHUP signals from the shell
& makes the process run in the background in a subterminal
disown followed by an argument (the index of the job number in your jobs list) prevents the shell from sending a SIGHUP signal to child processes. Using disown without an argument causes it to default to the most recent job.
I found the nohup and disown information at this page, and the & information in this SO answer.
Update
When I originally wrote this, I was using it for data processing scripts/programs. For those kinds of use cases, something like ts (task-spooler), works nicely.
I typically use screen for keeping background jobs running.
1) Create a screen session:
screen -S myScreenName
2) Launch your scripts,services,daemons or whatever
3) Exit (detach) screen-session with
screen -d
or
shortcut ALT+A then d
After few hundreds of years - if you want to resume your session (reattach):
screen -r myScreenName
If you want to know if there's a screen-session, its name and its status (attached or detached):
screen -ls
This solution works on all terminal interpreters like bash, zsh etc.
See also man screen
I'm trying to achieve the following:
from a fish script, open a PDF reader as a background job. Once it is opened, spawn another fish process (that runs an infinite while loop), also as a background job.
Next, open an editor (neovim) and allow it to take control of the running terminal. Once neovim terminates, also suspend the previous 2 background jobs (mupdf and the other fish process).
My current attempt looks something along the lines of:
mupdf $pdfpath &
set pid_mupdf $last_pid
fish -c "while inotifywait ...; [logic to rebuild the pdf file..]; end" &
set pid_sub $last_pid
nvim $mdpath && kill -2 $pid_mudf $pid_sub
First I open mupdf as a background job and save its PID in a variable. Next I spawn the other fish process, also as a background job, and I save its PID as well.
Next I run nvim (but not as a background job, as I intend to actually control it), and after it is terminated by the user, I gracefully kill the previous 2 background jobs.
However this doesn't work as intended.
mupdf and the second fish process open successfully, and so does nvim, but it quickly closes after around half a second, after which I get the following in the controlling terminal window: image (bote is just the filename of the script from which the lines above originate)
The 2 background processes stay running after that and I have to kill them manually.
I understand that the script is sent a SIGHUP because the controlling terminal now executes another application (neovim), but why does neovim close after that?
I also tried disowning the background processes after they're spawned but that didn't help.
How would I solve this issue?
The problem is that $last_pid, in fish 3, and %last, in fish 2, doesn't work by default in scripts. See https://github.com/fish-shell/fish-shell/issues/5036. You can "fix" this by putting status job-control full at the top of the script or using the (jobs -lp) hack that Glenn mentioned.
Regarding the background process remaining running... I can't reproduce that. It works for me. However, note that your nvim && kill will only run the kill if nvim exits with a status of zero. If you always want the kill to be run you should just unconditionally execute it. Also, your use of signal two (SIGINT) should produce the desired result but is unusual. You should use kill -15 or just omit the signal in which case it defaults to 15 (SIGTERM).
You're getting the PID incorrectly. The $pid_mudf and $pid_sub variables are empty. You want
set pid_mupdf (jobs -lp)
I want to write a bash script that runs two commands in the background. I am using nohup for this:
nohup cmd1 &
nohup cmd2 &
However, only the 1st command runs in the background.
When I run nohup cmd1 & manually in the command line. First, I type nohup cmd1 & then hit enter; this starts the process:
But, then I need to hit enter again to be able to type another command:
I think this is "clogging" up the command line, and is causing my bash script to get stuck at the first nohup ... & command.
Is there a way to prevent this?
Nothing is "clogged". The first command, running in the background, prints some output after your shell prints its next prompt. The shell is waiting for you to type a command, even though the cursor is no longer on the same line as the prompt. That extra Enter is an empty command, causing the shell to print another prompt. It's harmless but unnecessary.
Let me say something to nohup because I'm not sure if you are certain about what it is doing. In short, the nohup command is not necessary to run a process in background. The ampersand at the end of the line is doing it.
nohup prevents the background process from receiving SIGHUP (hup for hang up) if you close the terminal where the starting shell runs it. SIGHUP would effectively terminate the process.
If started with nohup the process will not receive that event and will continue running, owned by the init process (pid 1) if the terminal will being closed.
Furthermore the nohup command will redirect standard output of the controlled process to a file, meaning it will not appear on screen any more. By default this file is called nohup.out.
Just switched from bash to zsh.
In bash, background tasks continue running when the shell exits. For example here, dolphin continues running after the exit:
$ dolphin .
^Z
[1]+ Stopped dolphin .
$ bg
[1]+ dolphin . &
$ exit
This is what I want as the default behavior.
In contrast, zsh's behavior is to warn about running jobs on exit, then close them if you exit again. For example here, dolphin is closed when the second exit-command actually exits the shell:
% dolphin .
^Z
zsh: suspended dolphin .
% bg
[1] + continued dolphin .
% exit
zsh: you have running jobs.
% exit
How do I make zsh's default behavior here like bash's?
Start the program with &!:
dolphin &!
The &! (or equivalently, &|) is a zsh-specific shortcut to both background and disown the process, such that exiting the shell will leave it running.
From the zsh documentation:
HUP
... In zsh, if you have a background job running when the shell exits, the shell will assume you want that to be killed; in this case it is sent a particular signal called SIGHUP... If you often start jobs that should go on even when the shell has exited, then you can set the option NO_HUP, and background jobs will be left alone.
So just set the NO_HUP option:
% setopt NO_HUP
I have found that using a combination of nohup, &, and disown works for me, as I don't want to permanently cause jobs to run when the shell has exited.
nohup <command> & disown
While just & has worked for me in bash, I found when using only nohup, &, or disown on running commands, like a script that calls a java run command, the process would still stop when the shell is exited.
nohup makes the command ignore NOHUP and SIGHUP signals from the shell
& makes the process run in the background in a subterminal
disown followed by an argument (the index of the job number in your jobs list) prevents the shell from sending a SIGHUP signal to child processes. Using disown without an argument causes it to default to the most recent job.
I found the nohup and disown information at this page, and the & information in this SO answer.
Update
When I originally wrote this, I was using it for data processing scripts/programs. For those kinds of use cases, something like ts (task-spooler), works nicely.
I typically use screen for keeping background jobs running.
1) Create a screen session:
screen -S myScreenName
2) Launch your scripts,services,daemons or whatever
3) Exit (detach) screen-session with
screen -d
or
shortcut ALT+A then d
After few hundreds of years - if you want to resume your session (reattach):
screen -r myScreenName
If you want to know if there's a screen-session, its name and its status (attached or detached):
screen -ls
This solution works on all terminal interpreters like bash, zsh etc.
See also man screen
I'm trying to use a shell script to start a command. I don't care if/when/how/why it finishes. I want the process to start and run, but I want to be able to get back to my shell immediately...
You can just run the script in the background:
$ myscript &
Note that this is different from putting the & inside your script, which probably won't do what you want.
Everyone just forgot disown. So here is a summary:
& puts the job in the background.
Makes it block on attempting to read input, and
Makes the shell not wait for its completion.
disown removes the process from the shell's job control, but it still leaves it connected to the terminal.
One of the results is that the shell won't send it a SIGHUP(If the shell receives a SIGHUP, it also sends a SIGHUP to the process, which normally causes the process to terminate).
And obviously, it can only be applied to background jobs(because you cannot enter it when a foreground job is running).
nohup disconnects the process from the terminal, redirects its output to nohup.out and shields it from SIGHUP.
The process won't receive any sent SIGHUP.
Its completely independent from job control and could in principle be used also for foreground jobs(although that's not very useful).
Usually used with &(as a background job).
nohup cmd
doesn't hangup when you close the terminal. output by default goes to nohup.out
You can combine this with backgrounding,
nohup cmd &
and get rid of the output,
nohup cmd > /dev/null 2>&1 &
you can also disown a command. type cmd, Ctrl-Z, bg, disown
Alternatively, after you got the program running, you can hit Ctrl-Z which stops your program and then type
bg
which puts your last stopped program in the background. (Useful if your started something without '&' and still want it in the backgroung without restarting it)
screen -m -d $command$ starts the command in a detached session. You can use screen -r to attach to the started session. It is a wonderful tool, extremely useful also for remote sessions. Read more at man screen.