Having to hit enter with nohup command in bash - java

I'm trying to run a java springboot server using the following nohup command.
nohup java -jar webservices-0.0.1-SNAPSHOT.jar > nohup.out 2>&1 &
But after running this, I'm getting the following output & I have to hit enter to run the subsequent commands.
$ + nohup java -jar -Dspring.config.additional-location=config/application-dev.properties webservices-0.0.1-SNAPSHOT.jar
Is there anyway to avoid this in bash?

It looks like you have shell debug tracing (set -x mode) turned on, meaning bash will print each command before executing it (but after expanding variables etc). Since the nohup java ... command is backgrounded, this happens asynchronously, and happens to get printed after the shell has printed its prompt, so you get "$ " (your shell prompt) followed by "+ nohup java ... (the debug trace).
(Note: you have errors & output from the command redirected to nohup.out, but since the trace is printed by the shell, not the command itself, the redirect doesn't apply.)
You don't actually need to press return at this point; the only thing pressing return does is get you a new, clean (not mixed with debug tracing) prompt. You could just enter another command as normal. However, since the shell is confused about where on the line you are, features like command editing and history recall may not work properly.
If you want to avoid this, I think your main options are to either turn off debug tracing (set +x) before running the command, or add a delay before the shell prints its next prompt:
nohup java -jar webservices-0.0.1-SNAPSHOT.jar > nohup.out 2>&1 & sleep 1
Here, the nohup java ... command runs in the background as usual, but the sleep 1 command runs in the foreground and so the shell won't print its next prompt for a second (which should be enough time for the background process to print its debug trace).

Related

Why making shell script background does not work as expected

For example, I was trying to start a java process
in background and ignoring SIGHUP.
The first way I tried is to write a shell script like
start.sh:
java -jar *.jar
and execute
nohup ./start.sh &
the process starts, but does not work as expected.
Another way I try is to direct execute nohup java -jar *.jar & in command line, which works well.
So I want to know what's the real difference that makes the first way not work as expected.

Run bash file on remote linux machine with java and keep it in background

I have a shell script on a remote linux machine which contains the following:
#!/bin/sh
for i in $(seq 1 10);
do
echo "CREATE TABLE ben$i (id NUMBER NOT NULL);
! sleep 30
select * from ben$i;
! sleep 30
DROP TABLE ben$i;" | sqlplus system/password &
done
wait
The name of this script is ben.sh.
In java, i want to execute this script and keep the script doing what it does in background.
I have a command that execute the script successfully:
sshshell.execute("su - oracle -c './ben.sh'");
I want the script to still run on the remote linux machine and i want to close the ssh connection right after i execute the command above, without interfering the script.
I thought if i put an & at the end of this command like so:
sshshell.execute("su - oracle -c './ben.sh' &");
But still the java program stuck and waits for the script to finish
Very important note: I don't want to use Threads OR any additional ssh connections.
What are my options here?
Use nohup and & to run the script in the background.
sshshell.execute("nohup su - oracle -c './ben.sh' &");
Nohup is short for “No Hangups". Nohup is a supplemental command that tells the Linux system not to stop another command once it has started. That means it’ll keep running until it’s done, even if the user that started it logs out. The syntax for nohup is as follows:
nohup sh your-script.sh &
The & at the end moves the command to the background, freeing up the terminal that you’re working in.
So, you canuse Nohup or Disown commands. With nohup system will avoid exit signals propagating to child processes.
nohup cmd &
Or you can use Disown to deatach it from child proceses.
cmd & disown

How do I pass a display to a qsub command?

I am running a bash script that, among other things, runs a java program that can be used via GUI or via command line (depending on a parameter).
splitstree --commandLineMode --commandFile comm.txt --version --verbose
EDIT:
When I run it via normal command line or via GUI, it works perfectly. If I echo this command into a file and $(cat file) it also works, and it works as well when I integrate it into a bash script and run the bash script.
If I qsub it to the cluster where I am doing the work, I get an error about a missing display:
java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed
an operation which requires it.
I tried to export DISPLAY=:0.0 within the bash script but the error didn't change.
EDIT 2:
If I pass the DISPLAY variable to the qsub command, the error goes away but the program terminates with an exit status of 1. Like:
qsub -v DISPLAY <job_file>
It also says Picked up _JAVA_OPTIONS: -Xmx4096M but performing unset on this variable didn't change the exit status (so probably is not harming the process).
Re-running the same command outside of qsub (that is: simply copy-paste the cmd into the shell) work perfectly again.
Any suggestion on how to make it so that the qsub command correctly passes the display information to the cluster node?
If you don't need the display run Java with -Djava.awt.headless=true property, as explained in Using Headless Mode in the Java SE Platform.
Alternatively, if your program can't run headless, you can try using Xvfb (X virtual framebuffer). It comes with xvfb-run command, take a look at Running without a Display wiki:
xvfb-run java MainClass
or by configuring DISPLAY environment variable:
sudo Xvfb :1 -screen 0 1024x768x24 </dev/null &
export DISPLAY=":1"
java MainClass
When in a headless environment, you need to use GraphicsEnvironment.isHeadless() in your code to avoid doing anything that requires AWT components. That means you can't do any input/output, of course.

Running Java Infinite Loop in Ubuntu

Hello I am making a Java program in an Ubuntu Web Server but it is always supposed to be running in an infinite loop, or at least until I stop it. When I run it in the Ubuntu console it won't allow me to keep using the console. To work around this I have been using the "screen" command and detaching the screen.
I was wondering if there is a better way of doing this without working with the screen command?
Run a program immune to hangups
If you're happy with starting the Java program up manually from the command line, but just want to not have screen running, you can use the "nohup" command to start the Java process in such as way that the Java program will continue running even if you close the console window or log out.
$ nohup java ...
nohup: ignoring input and appending output to `nohup.out'
$
Run a program in the background
If you don't mind the Java program stopping if you close the console window or log out, you can skip using "nohup" and only append a "&" to the end of the command to tell your shell to run the application in the background. You may also want to add " > program.log 2>&1" to the command to avoid having any output from the program show up in the console window while you're using it for other purposes.
$ java ... > program.log 2>&1 &
[2] 3128
$ jobs
[2]+ Running java ... > program.log 2>&1 &
$
Run a program as a daemon
If you want the Java program to automatically start up every time you reboot the machine, you should look into creating a SYSV init-script, or as you're running on Ubuntu, an Upstart Job definiton.

Background process in linux

I have developed a Java socket server connection which is working fine.
When started from a terminal, it starts from listening from client. But when I close the terminal it stops listening.
I need to continue even though the terminal closed by user from where jar file was started.
How can I run Java server socket application in Linux as background process?
There are several ways you can achieve such a thing:
nohup java -server myApplication.jar > /log.txt - this is pretty straight forward. It will just put the application in the background. This will work but it's just not a very good way to do so.
Use a shell wrapper and the above OR daemon app. This approach is used by many open source projects and it's quite good for most of the scenarios. Additionally it can be included in init.d and required run level with regular start, stop and status commands. I can provide an example if needed.
Build your own daemon server using either Java Service Wrapper or Apache Jakarta Commons Daemon. Again - both are extremely popular, well tested and reliable. And available for both Linux and Windows! The one from Apache Commons is used by Tomcat server! Additionally there is Akuma.
Personally I would go with solution 2 or 3 if you need to use this server in the future and/or distribute it to clients, end users, etc. nohup is good if you need to run something and have no time to develop more complex solution for the problem.
Ad 2:
The best scripts, used by many projects, can be found here.
For Debian/Ubuntu one can use a very simple script based on start-stop-daemon. If in doubt there is /etc/init.d/skeleton one can modify.
#!/bin/sh
DESC="Description"
NAME=YOUR_NAME
PIDFILE=/var/run/$NAME.pid
RUN_AS=USER_TO_RUN
COMMAND=/usr/bin/java -- -jar YOUR_JAR
d_start() {
start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --chuid $RUN_AS --exec $COMMAND
}
d_stop() {
start-stop-daemon --stop --quiet --pidfile $PIDFILE
if [ -e $PIDFILE ]
then rm $PIDFILE
fi
}
case $1 in
start)
echo -n "Starting $DESC: $NAME"
d_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
d_stop
echo "."
;;
restart)
echo -n "Restarting $DESC: $NAME"
d_stop
sleep 1
d_start
echo "."
;;
*)
echo "usage: $NAME {start|stop|restart}"
exit 1
;;
esac
exit 0
There's one crucial thing you need to do after adding a & at the end of the command. The process is still linked to the terminal. You need to run disown after running the java command.
java -jar yourApp.jar > log.txt &
disown
Now, you can close the terminal.
The key phrase you need here is "daemonizing a process". Ever wondered why system server processes often end in 'd' on Linux / Unix? The 'd' stands for "daemon", for historical reasons.
So, the process of detaching and becoming a true server process is called "daemonization".
It's completely general, and not limited to just Java processes.
There are several tasks that you need to do in order to become a truly independent daemon process. They're listed on the Wikipedia page.
The two main things you need to worry about are:
Detach from parent process
Detach from the tty that created the process
If you google the phrase "daemonizing a process", you'll find a bunch of ways to accomplish this, and some more detail as to why it's necessary.
Most people would just use a little shell script to start up the java process, and then finish the java command with an '&' to start up in background mode. Then, when the startup script process exits, the java process is still running and will be detached from the now-dead script process.
try,
java -jar yourApp.jar &
& will start new process thread,I have not tested this, but if still it not works then twite it in script file and start i with &
Did you try putting & at the end of the command line?
For example:
java -jar mySocketApp.jar &
You can also use bg and fg commands to send a process to background and foreground. You can pause the running process by CTRL+Z.
Check it out this article: http://lowfatlinux.com/linux-processes.html
Step 1.
To create new screen
screen -RD screenname
Step 2.
To enter into screen terminal
press Enter
Step 3.
Run your command or script (to run in the background) in the newly opened terminal
Step 4.
To come out of screen terminal
ctrl + A + D
Step 5.
To list screen terminals
screen -ls
that will print something like below
There is a screen on:
994.screenname (12/10/2018 09:24:31 AM) (Detached)
1 Socket in /run/screen/S-contact.
Step 6.
To login to the background process
screen -rd 994.screenname
for quite terminal and this process still working background. for me, the simple and fast way to run the process in the background is using the &! at end of the command:
if this app is built for X server: (eg: Firefox,Zathura,Gimp...)
$ java -jar yourApp.jar &!
if this app is cli (work on the terminal)
# st is my terminal like kitty alacritty
$ st -e bash -c "lookatme --style one-dark --one $1" &!

Categories