Terminate bash script if process already running - linux

I'm using a startup script to start our Minecraft server via webmin on CentOS. It backs up a few files before starting the server itself. Recently we messed up our data by accidentally executing the script twice in a row, which resulted two instances of the Minecraft server being run and everything went haywire with data files and such.
To prevent this from happening, I want the script to terminate if it detects that the process is running. I've searched around for similar problems, and things like lock files are suggested, but I don't have the opportunity to remove those since the startup script only sets up a screen for the Minecraft server process and stopping the server is usually done by terminating the screen or stopping the server through ingame commands.
The server process is started using this command:
screen -dmS minecraft java -Xincgc -Xmx2G -jar server.jar
How can I make the startup script detect if this process is already running, and then terminate itself?

Use this script:
#!/bin/bash
LOCKDIR="/path/to/lockdir"
if [ ! mkdir "$LOCKDIR" ]; then
echo >&2 "Server is already running"
exit 1
fi
# Here: when exiting, or receiving any of the mentioned signals, remove the lock file   
trap "rmdir \"$LOCKDIR\"" exit INT HUP TERM QUIT
 
# It would be tempting to exec instead, but DON'T DO IT: otherwise the trap is forgotten
minecraft java -Xincgc -Xmx2G -jar server.jar
exit $?
and launch it within your screen.

these links may give you some ideas: http://mywiki.wooledge.org/ProcessManagement - http://mywiki.wooledge.org/BashFAQ/042 - http://mywiki.wooledge.org/BashFAQ/033 - http://mywiki.wooledge.org/BashFAQ/045

Related

How do I make a while true loop only start the program/minecraft server again if it closes or crashes?

Hi I am running a Minecraft server with a restart plugin but it requires the program to restart itself, so I used a While true sleep 5 loop, and it seems to work fine but after some time it just starts opening again and again and there by it at some point gets to use 100% cpu usage all the time.
How do I make it not start the program again before the server closes or crashes?
#!/bin/sh
while true
do
java -Xms1G -Xmx6G -jar server.jar
sleep 5
done
Since sleep is set to 5 after it keeps opening again and again I see that is says failed to start the minecraft server every 5 secs but it is already running, and I want it to only run the while loop if the program is not running.
Using pgrep with the -f flag you can search for a running process with some arguments. You can use this to check if a server is already running.
For example:
#!/bin/bash
while true
do
if ! pgrep -f server.jar
then
java -Xms1G -Xmx6G -jar server.jar
fi
sleep 5
done

Executing bash script on wakeup

Since some time I have a Prolbem with my Linux distribution (Kubuntu 18.04). Every time my linux comes back from standby modus the touchpad is not working properly anymore (can't grab and drag files or other objects).
I already found a solution for my Problem:
modprobe psmouse -r
modprobe psmouse
This code does solve the problem. However, after this the rightclick area which I always disable at sartup is enabled again.
I have a script that runs on startup which executes the following:
synclient RightButtonAreaLeft=0
synclient RightButtonAreaTop=0
What I am now trying to do, is to write a script that runs whenever the system is waking up form standby modus.
I wrote the script like this:
#!/bin/bash
exec 1> /home/luc/Schreibtisch/update.log 2>&1
set -x
case $1/$2 in
pre/*)
echo "Going to $2..."
# Place your pre suspend commands here, or `exit 0`
# if no pre suspend action required
exit 0
;;
post/*)
echo "Waking up from $2..."
sh /home/luc/Schreibtisch/test.sh
sh /home/luc/Schreibtisch/test2.sh
;;
esac
Where test.sh runs the modprobe commands and test2.sh runs the synclient commands.
After going to standby modus and waking up again I'm getting the following log:
+ case $1/$2 in
+ echo 'Waking up from suspend...'
Waking up from suspend...
+ sh /home/luc/Schreibtisch/test.sh
+ sh /home/luc/Schreibtisch/test2.sh
Failed to connect to X Server.
Failed to connect to X Server.
And the grabing and draging of the files works perfectly but the rightclick is still enabled.
My question is now if it is possible to execute the synclient commands after the X Server is ready?
Kind regards
Pepsilon
It looks like i have found a workaround for the problem of the touchpad not working properly after wakeup.
In my /etc/modprobe.d/blacklist.conf the module i2c_i801 was blacklisted.
After removing this module form the blacklist my touchpad now works fine after standby mode.

Running dispynode.py on multiple EC2 instances using SSH appears to work but it really doesn't

I've created a cluster of EC2 instances using cfncluster and now I need to run the dispynode.py command on all the nodes.
I do that by first creating a list of private IP addresses called "workers.txt" then running the following bash command
for host in $(cat workers.txt); do
ssh $host "dispynode.py --ext_ip_addr $host &";
done
this appears to work since I get the expected dispynode output for each IP address. For example, for each IP address I'll get an output similar to this
NOTE: Using dispy port 61591 (was 51348 in earlier versions)
2019-08-22 06:07:12 dispynode - dispynode version: 4.11.0, PID: 16074
2019-08-22 06:07:12 dispynode - Files will be saved under "/tmp/dispy/node"
2019-08-22 06:07:12 pycos - version 4.8.11 with epoll I/O notifier
2019-08-22 06:07:12 dispynode - "ip-172-31-8-242" serving 8 cpus
Enter "quit" or "exit" to terminate dispynode,
"stop" to stop service, "start" to restart service,
"release" to check and close computation,
"cpus" to change CPUs used, anything else to get status:
Enter "quit" or "exit" to terminate dispynode,
"stop" to stop service, "start" to restart service,
"release" to check and close computation,
"cpus" to change CPUs used, anything else to get status:
NOTE: Using dispy port 61591 (was 51348 in earlier versions)
the problem is, when I SSH into the node and check if the process is running, it's not.
ssh 172.31.8.242
kill -0 16074
-bash: kill: (16074) - No such process
And the dispy client doesn't work and can't discover the nodes.
Question: Why isn't my parallel ssh command starting the program on the nodes and/or why doesn't the process remain running if it was started
I haven't used dispy myself, but the "Enter 'quit' or 'exit' to terminate dispynode..." message suggests that dispynode is running interactively and reading from standard input. In that case, when you close the SSH session, dispynode will read an end-of-file condition on its standard input, and it might exit when that happens.
According to the dispy documentation, dispynode has a --daemon option which prevents it from running interactively:
--daemon option causes dispynode to not read from standard input, so dispynode can be run as background process, or started from (system startup) scripts. If this option is not given, dispynode prints menu of commands, and commands can be entered to get status and control dispynode.
So, try using the --daemon option:
for host in $(cat workers.txt); do
ssh $host "dispynode.py --ext_ip_addr $host --daemon &";
done
The "&" may be unnecessary here, because dispynode might put itself in the background.

Bash script on background: how to kill child processes

Well, I'm basically trying to make a bash script runs a node script forever. I made the following bash script:
#!/bin/bash
while true ; do
cd /myscope/
unlink nohup.out
node myscript.js
sleep 6
done & echo $! > pid
I'm expecting that when it runs, it starts up node with the given script, checks if node exits, sleeps for 6 seconds if so and reopen node. Also, I'm expecting it to run in background and writes it's pid (the bash pid) on a file called "pid".
Everything explained above works as expected, apparently, but I'm also expecting that when the pid of the bash script is killed, the node script would stop running, I don't know why that made sense in my mind, but when it comes to practice, it doesn't work. The bash script is killed indeed, but the node script keeps running and that is freaking me out.
I've tested it in the terminal, by not sending the bash script to the background and entering ctrl+c, both scripts gets killed.
I'm obviously miss understanding something on the way the background process works. For god sake, can anybody help me?
There are lots of tools that let you do what you're trying, just two off the top of my head:
https://github.com/nodejitsu/forever - A simple CLI tool for ensuring that a given script runs continuously (i.e. forever)
https://github.com/remy/nodemon - Monitor for any changes in your node.js application and automatically restart the server - perfect for development
Maybe the second it's not what you're looking for, but still worth a look.
If you can't or don't want to use those then the problem is that if you kill the parent process the child one is still there, so, you should kill that too:
pkill -TERM -P $PID
where $PID is the parent PID.

Can upstart expect/respawn be used on processes that fork more than twice?

I am using upstart to start/stop/automatically restart daemons. One of the daemons forks 4 times. The upstart cookbook states that it only supports forking twice. Is there a workaround?
How it fails
If I try to use expect daemon or expect fork, upstart uses the pid of the second fork. When I try to stop the job, nobody responds to upstarts SIGKILL signal and it hangs until you exhaust the pid space and loop back around. It gets worse if you add respawn. Upstart thinks the job died and immediately starts another one.
Bug acknowledged by upstream
A bug has been entered for upstart. The solutions presented are stick with the old sysvinit, rewrite your daemon, or wait for a re-write. RHEL is close to 2 years behind the latest upstart package, so by the time the rewrite is released and we get updated the wait will probably be 4 years. The daemon is written by a subcontractor of a subcontractor of a contractor so it will not be fixed any time soon either.
I came up with an ugly hack to make this work. It works for my application on my system. YMMV.
start the application in the pre-start section
in the script section run a script that runs as long as the application runs. The pid of this script is what upstart will track.
in the post-stop section kill the application
example
env DAEMON=/usr/bin/forky-application
pre-start script
su -s /bin/sh -c "$DAEMON" joeuseraccount
end script
script
sleepWhileAppIsUp(){
while pidof $1 >/dev/null; do
sleep 1
done
}
sleepWhileAppIsUp $DAEMON
end script
post-stop script
if pidof $DAEMON;
then
kill `pidof $DAEMON`
#pkill $DAEMON # post-stop process (19300) terminated with status 1
fi
end script
a similar approach could be taken with pid files.

Resources