Get bg jobs to fg after closing terminal window/session - terminal

TL;DR How can I get a bg (background) job into fg (foreground) after I close the terminal window?
FULL I'm using terminal to start Spotify and put it into background with CTRL+Z and bg. Everything works as expected within this window: fg puts the process again in forground and jobs shows me Spotify as a running process. The problem occurs if I close the terminal window.
After I close the terminal window and open a new terminal window, the jobs command can't find Spotify running in the background. Therefore I can't access the process for stopping or closing anymore.
What is the advantage of this behaviour CTRL+Z, fg, bg & jobs ? And how can I get back my process?

You can search your old process via ps -A. Or ps -A | grep <application name>.
If you found it, then use reptyr <pid> to get the application on your new console.
But if you closed the old terminal, all the terminal applications will probably be closed also, so it's too late.
Use screen, before you start your app. This will help you to reconnect to your session from another terminal.

The job numbers only refer to background processes running under your current shell. The shell couldn't know the job numbers associated with the old shell.

Related

Neovim process spawned from fish script terminates immediately

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)

executing a script which runs even if i log off

So, I have a long running script (of order few days) say execute.sh which I am planning to execute on a server on which I have a user account...
Now, I want to execute this script so that it runs forever even if I logoff or disconnect from the server??
How do i do that?
THanks
You have a couple of choices. The most basic would be to use nohup:
nohup ./execute.sh
nohup executes the command as a child process and detaches from terminal and continues running if it receives SIGHUP. This signal means sig hangup and will getting triggered if you close a terminal and a process is still attached to it.
The output of the process will getting redirected to a file, per default nohup.out located in the current directory.
You may also use bash's disown functionality. You can start a script in bash:
./execute.sh
Then press Ctrl+z and then enter:
disown
The process will now run in background, detached from the terminal. If you care about the scripts output you may redirect output to a logfile:
./execute.sh > execute.log 2>&1
Another option would be to install screen on the remote machine, run the command in a screen session and detach from it. You'll find a lot of tutorials about this.
nohup (no hangup) it and run it in the background:
nohup execute.sh &
Output that normally would have gone to the screen (STDOUT) will go to a file called nohup.out.

Automate a Ruby command without it exiting

This hopefully should be an easy question to answer. I am attempting to have mumble-ruby run automatically I have everything up and running except after running this simple script it runs but ends. In short:
Running this from terminal I get "Press enter to terminate script" and it works.
Running this via a cronjob runs the script but ends it and runs cli.disconnect (I assume).
I want the below script to run automatically via a cronjob at a specified time and not end until the server shuts down.
#!/usr/bin/env ruby
require 'mumble-ruby'
cli = Mumble::Client.new('IP Address', Port, 'MusicBot', 'Password')
cli.connect
sleep(1)
cli.join_channel(5)
stream = cli.stream_raw_audio('/tmp/mumble.fifo')
stream.volume = 2.7
print 'Press enter to terminate script';
gets
cli.disconnect
Assuming you are on a Unix/Linux system, you can run it in a screen session. (This is a Unix command, not a scripting function.)
If you don't know what screen is, it's basically a "detachable" terminal session. You can open a screen session, run this script, and then detach from that screen session. That detached session will stay alive even after you log off, leaving your script running. (You can re-attach to that screen session later if you want to shut it down manually.)
screen is pretty neat, and every developer on Unix/Linux should be aware of it.
How to do this without reading any docs:
open a terminal session on the server that will run the script
run screen - you will now be in a new shell prompt in a new screen session
run your script
type ctrl-a then d (without ctrl; the "d" is for "detach") to detach from the screen (but still leave it running)
Now you're back in your first shell. Your script is still alive in your screen session. You can disconnect and the screen session will keep on trucking.
Do you want to get back into that screen and shut the app down manually? Easy! Run screen -r (for "reattach"). To kill the screen session, just reattach and exit the shell.
You can have multiple screen sessions running concurrently, too. (If there is more than one screen running, you'll need to provide an argument to screen -r.)
Check out some screen docs!
Here's a screen howto. Search "gnu screen howto" for many more.
Lots of ways to skin this cat... :)
My thought was to take your script (call it foo) and remove the last 3 lines. In your /etc/rc.d/rc.local file (NOTE: this applies to Ubuntu and Fedora, not sure what you're running - but it has something similar) you'd add nohup /path_to_foo/foo 2>&1 > /dev/null& to the end of the file so that it runs in the background. You can also run that command right at a terminal if you just want to run it and have it running. You have to make sure that foo is made executable with chmod +x /path_to_foo/foo.
Use an infinite loop. Try:
while running do
sleep(3600)
end
You can use exit to terminate when you need to. This will run the loop once an hour so it doesnt eat up processing time. An infinite loop before your disconnect method will prevent it from being called until the server shuts down.

Multiple process from one bash script [duplicate]

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.

Stop derby server hanging onto the terminal window

Im running derby server from the command line on ubuntu. Problem is when i start it, it stays running in the terminal window, so it print all its logs straight to terminal. When i close the terminal window, the server shuts down. Is there anyway i can start derby from the command line, and then be able to close the terminal without shutting down the server?
You can suspend it with CTRL-z and run it in the background with bg and then disown %1 (or substitute 1 with the job number shown between the brackets in the suspend message).
Example...
$ bundle exec script/rails s
[1] + 14192 suspended bundle exec script/rails s
$ bg
[1] + 14192 continued bundle exec script/rails s
$ disown %1
$ exit
Another technique is to use your window manager. Set up an application menu item that starts the network server for you, with the various output redirected to files. Then start your server by choosing that menu item.

Resources