Reputation: 5527
I have the following script:
#!/bin/bash
until java -jar "MyApplication.jar"; do
echo "---"
date
echo "Application crashed with exit code $?. Waiting to respawn..." >&2
sleep 60
echo "Respawning.." >&2
done
Which basically will relaunch the java application if it does not terminate with an exit code 0.
I currently invoke this program with:
nohup ./myapplication.sh &
Where myapplication.sh
is the file which contains above script.
I invoke this program from a given xterm under X11. I would like to be sure that the program keeps running even if I close the xterm or even terminate the whole X11 session.
Two questions related to this:
./myapplication.sh &
or ./myapplication.sh
?myapplication_20191118_1723.out
(i.e. the name and a timestamp -format of the timestamp is not that relevant-) instead of the default nohup.out
? That file shall contain both std err
and std out
.Upvotes: 0
Views: 4117
Reputation: 4327
Simple answer: yes, of course you can!
How and why, I hear you say?
What if I need to run a program that does not play well with the console, e.g. the KDE file explorer, Dolphin?
When I run that from the command line and it prints out streams of internal Qt low level messages and mostly (if it's working correctly) these are meaningless and can be ignored. There are sometimes so many that they tend to make the terminal useless.
The following would be a way to stop that happening. And (if properly configured) could also be used to make it send the terminal output STDOUT
to a named pipe, connected to a TCP server by using programs like netcat or the more capable socat.
This example is great if you want to run a noisy program from your login script.
function shush () { \
QC="$1"; \
shift; \
nohup "${QC}" $* >/dev/null 2>&1 & \
disown; \
}
This make use of the bash function
, alias
and job control
features.
How this works:
${QC}
as that will be the command we want to run latershift
is used to drop the 1st paramter so it does not get passed againnohup
is used to disconnect stdin
and stdout
from the app2>&1
is used to redirect stderr
to stdout
>/dev/null
pipes stdout
into /dev/null
to get swallowed into nothingness.${QC}
is the command we will run, the quotes are there just in case the path has spaces in it.$*
expands all the remaining parameters, the same as $1 $2 $3 ....
&
makes the command into a background jobdisown
disassociates the last job from the terminal that started the jobnohup
would normally create a file nohup.out
, so the pipe to /dev/null prevent that.
disown
is (usually) a shell built in statement and works by making the last background command (aka job) immune to signals such as HUP coming from the terminal. That means closing the terminal will not close the program.
BTW: I use this to allow me to run multiple GUI commands in Windows under WSL!
Now we can do...
> shush dolphin
Perhaps we would want to use it in a terminal too, we don't want to keep typing shush.
Then do this in ~/.bash_aliases
alias dolphin='shush dolphin'
Now we can do both, the now shushed dolphin
command works the same in a terminal or in a script, with or without command line parameters.
Ahh, I hear you say, but what if we need to undo that and "unshush" it, e.g. to use the --help
command line option?
There are at least two ways.
Quick and dirty, just bypass the alias using which
$(which dolphin) --help
Another way would be to modify the shush ()
function/script to extract the 2nd parameter (or scan all of them) and check if it is --noshush
and/or has other parameters that need the terminal and act accordingly, but lets make that homework for the reader ;)
Upvotes: 0
Reputation: 295954
nohup
doesn't actually do much of value.
/dev/null
, if-and-only-if it's initially connected to a TTY.nohup.out
, if-and-only-if they're initially connected to a TTY.All of these things you can simply do yourself, without using nohup
at all. (Moreover, a noninteractive shell doesn't propagate HUPs by default in the first place!).
#!/bin/bash
# Redirect stdin from /dev/null, and stdout and stderr to a log file
# (not having TTY handles is part of how/why programs started with nohup can survive
# a terminal dying).
#
# Note that printf %(...)T is a bash 4.3 feature
# ...you may need to use date if your bash is older.
printf -v logfile_name 'myapplication_%(%Y%m%d_%H%M%S)T' -1
exec </dev/null >"$logfile_name" 2>&1
# ignore any HUP signals we receive (even though we shouldn't get any regardless)
trap '' HUP
# prevent the JVM from getting any handles on X11, which would be broken on exit
unset DISPLAY
until java -jar "MyApplication.jar"; do
retval=$?
echo "---" >&2
date >&2
echo "Application crashed with exit code $retval. Waiting to respawn..." >&2
sleep 60
echo "Respawning.." >&2
done
Upvotes: 2