I'm trying to optimize some experiments with a Java application. The same application is on many machines. I want to run all of them via a bash script with ssh.
I have a bash script that has a while loop to run the application. Like this
while [ $COUNTER -lt $WORKERS ]
do
ssh ubuntu#host "java java-app.jar" > /data/some-logs.log
((COUNTER++))
((IP_BEGINS++))
done
However when I run the script I have to wait a moment and press Ctrl+C for every machine. How can I run every aplication on background?
prefix with nohup and append a & to the command, that will run it in the background.
while [ $COUNTER -lt $WORKERS ]
do
ssh ubuntu#host "nohup java -jar java-app.jar > /data/some-logs.log 2>&1 &"
((COUNTER++))
((IP_BEGINS++))
done
You might need to muck around with the quotes and placements of the & to make sure the remote ssh command gets backgrounded and not your local ssh
EDIT - I fixed the answer based on your comment. Also added the stderr redirect to the same log file, that might help when things go wrong
Related
update:
I have followed spring boot deployment for Installation as an init.d Service (System V). I start my application successfully.But, after one day.My application closed again......Is there any ways to help me ?
I hava one spring boot application which names my.jar. I put it into my ubuntu server(20.04) and use the command of nohup java -jar my.jar &.In the first few hours, my application is in good condition.But,after one or two days,it will shut down automatically.
I have seen the log of my application which don't recorded any error and saved the last correct log before exiting
The current situation is my application is very simple and have only a small number of visits.
According to my guess,it is seems that ubuntu kill my process for inactivity?
My scripts are as follow,
stop.sh:
#!/bin/bash
PID=$(ps -ef | grep centre-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{ print $2 }')
if [ -z "$PID" ]
then
echo Application is already stopped
else
echo kill $PID
kill $PID
fi
run.sh:
#!/bin/bash
echo stop application
source stop.sh
echo start application
source start.sh
start.sh:
#!/bin/bash
nohup java -jar centre-0.0.1-SNAPSHOT.jar &
I need my application will run all the time.
Is there any ways to resolve the issue?
nohup is more suited for running processes that are expected to end after a while. For example running a lengthy batch script.
As of why it is killed, there may be a number of reasons: memory leak, server security policy .... The server probably decided your program wasn't behaving correctly. Logs of the server, like dmesg or /var/log/ contents may have some clues about it.
What you said about your app receiving visits feels like it is more a service rather than a script.
You may want to
daemonize your program
. this will make your program tied to the server availability.
Here is an explanation of the differences between nohup and daemons.
Also check this link at baeldung for help on setting up the daemon
After I check the memory usage, so I realized that my spring boot have used a lot of memory abnormally.
I solved it in the following way:
I updated my start.sh with the command of "nohup java -Xms100m -Xmx300m -jar ./target/centre-0.0.1-SNAPSHOT.jar &"
But, I did not figure out why did my spring boot application use a lot of memory?
Is there anyone can explain this phenomenon?
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
i usually use this bash script to check if my java application is running and start it again if not. I use crontab to check it
#!/bin/bash
if [ "$(pidof java)" ]
then
# process was found
echo "application running"
else
# process not found
cd /home/assist/emanager
setsid java -jar emanager-1.0.0.jar </dev/zero &>/dev/null &
fi
Now the problem is that there are other java applications running on the server, so the script does not start my app because the if condition is true. Is there a way to check if a specific java application is running?
Thanks
Your question is very similar to this one:
Start a Java application using Bat file if not already started
The main difference is you are asking for bash while the other one is in Windows. Hence replace jcmd with jps, the rest is still applicable.
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" &!
I have a Java application executed from a ([ba]sh) shell script and unfortunately sometimes the people responsible for deploying it and starting it fail to switch to the appropriate user before starting the application. In this situation I'd like the application to not run at the very least, and ideally issue a warning not to do that. I thought about trying to alias java or change the path for root to include a fake java which does so, but this might have undesirable side effects and isn't going to be effective easily since the shell script specifies the full path to the java binary.
So, is there a standard idiom in shell scripts for 'don't run if I'm root'?
Example in bash:
if [ `id -u` = 0 ]; then
echo "You are root, go away!"
exit 1
fi
In BASH, you can take the output of whoami and compare it to root.
I use something like this at the beginning of scripts that I want to
be run under a service account:
LUSER='my-service'
if [ `id -un` != $LUSER ]; then
exec su $LUSER -s $SHELL -c "$0 $#"
fi
# actual script commands here.
If run as the correct user, execution will continue as planned. If run
as root, privileges are dropped to the wanted user-id. Other users
will get a password prompt which should tell them that something is
wrong.
su -s $SHELL ... is used to override the shell set in /etc/passwrd
-- it may be set to /bin/false for the service account.
I have used this on Debian systems, using bash and dash. Feel free
to comment if portability can be improved.