How to send `SIGINT` over `systemctl` to custom daemon/service - linux

I have a script that I would like to run as service on my Linux machine, let's call it my_script.sh. It is executable and can be run over ./path/to/my_scrit.sh.
I also have script that kills my_script.sh, let's call it kill_my_scprit.sh. The contents of kill_my_script.sh are:
#!/bin/bash
sudo kill -SIGINT $(pgrep my_script)
In essence, this should mimic Ctrl+C for my_script.sh.
This works perfectly fine if I run the scripts from a terminal, i.e. in ttyX I run ./path/to/my_scrit.sh to start it and in ttyY ./path/to/kill_my_scrit.sh to initiate the shut down sequence of my_script.sh.
As mentioned before, the goal is to run this as deamon, so I created /etc/systemd/system/my_script.service
[Unit]
....
[Service]
Type=simple
User=root
WorkingDirectory=/path/to/dir/
ExecStart=/path/to/my_script.sh
ExecStop=/path/to/kill_my_script.sh
Restart=on-failure
[Install]
...
Using sudo systemctl start my_script.service starts the script as expected, but using sudo systemctl stop my_script.service starts the shutdown sequence for my_script.sh, but doesn't let it finish... Am I missing something? The shutdown sequence takes roughly 10sec...

Related

Linux systemd service file to start and stop a minecraft server

I am trying to run a minecraft server on a remote linux instance.
I would like the instance to start up the server on a screen named serverscreen which is owned by the user named minecraft once the system boots up, and run a stop command to the serverscreen when the instance shuts down. Then, it needs to wait untill the server has stopped before actually shutting down.
I am quite new to linux but I have managed to come up with a few commands that work, but I have issues trying to start and stop the server automatically.
I have tried quite a few things, like creating a .sh script to run on startup with crontab -e #reboot script.sh, or create a file in etc/rc.local with #!/bin/sh sh script.sh, but those methods didn't seem to work properly for me. Also, they do not run un shutdown unfortunately. Therefore, I thought it would be best to create a service file named minecraft.service with the following commands:
[Unit]
Description=Minecraft Server
After=network.target
[Service]
User=minecraft
Nice=5
KillMode=none
SuccessExitStatus=0 1
InaccessibleDirectories=/root /sys /srv /media -/lost+found
NoNewPrivileges=true
WorkingDirectory=/opt/minecraft/server
ReadWriteDirectories=/opt/minecraft/server
#### Command to start the server.
ExecStart=sudo -u minecraft screen -dmS serverscreen java -Xms6G -Xmx6G -jar /opt/minecraft/server/forgeserver.jar nogui
#### Command to stop the server.
ExecStop=sudo -u minecraft screen -S serverscreen -p 0 -X eval "stuff stop^M"
##### Try to wait untill the server has stopped. I am not sure about this line of code since I haven't been able to test it properly.
ExecStop=/bin/bash -c "while ps -p $MAINPID > /dev/null; do /bin/sleep 1; done"
[Install]
WantedBy=multi-user.target
but when running this, it gives me an error saying that I did not provide an absolute path for something.
Could someone help me setup a service file that will boot up the server on a screen named serverscreen for the user minecraft, and run command stop when the instance shuts down after the server has been stopped?
Thanks to #Riz, the service now works as intended by using a bash script in order to run the commands.

How to make alive nohup process?

I am using the nohup command with Python and Flask for background process. After I close the terminal it is working fine but after 1 or 2 days the process stops. Can someone tell me how to keep the background process running? I am using below command:
screen
space
nohup python -m flask run --cert local.crt --key local.key --host=0.0.0.0 --port=443 &
ctrl+a+d
Let's assume all your Flask code resides in the folder /home/abc_user/flask_app.
Steps
Create a file flask-server.service in /etc/systemd/system.
[Unit]
Description=Flask server
After=network.target
[Service]
User=abc_user
Group=abc_user
WorkingDirectory=/home/abc_user/flask_app
ExecStart=python -m flask run --cert local.crt --key local.key --host=0.0.0.0 --port=443
Restart=always
[Install]
WantedBy=multi-user.target
Run sudo systemctl daemon-reload.
Start the service using systemctl start flask-server.service.
Check that it has started by systemctl status flask-server.service. Status should say "running".
If you want your flask server to auto-start after reboots, run systemctl enable flask-server.service
Some common operations
Check current status - systemctl status flask-server.service
Start the service - systemctl start flask-server.service
Stop the service - systemctl stop flask-server.service
Check logs - journalctl -u flask-server.service
Stream logs - journalctl -f -u flask-server.service
Check logs in past 1 hour - journalctl -u flask-server.service --since "1 hour ago"
Try nohup python -m flask run --cert local.crt --key local.key --host=0.0.0.0 --port=443 >/dev/null 2>&1&
Use nohup , you should redirct you print to /dev/null or log, Otherwise it will be create a file nohup.out occupy disk space.
Most times we use gunicorn and supervisor to manager flask application.
Did you maybe shut down the computer the flask server is running on ?
If so, the problem will be solved by either not shutting down your computer or starting the flask server again after shutting down !
nohup is a POSIX command to ignore the HUP (hangup) signal. The HUP signal is, by convention, the way a terminal warns dependent processes of logout.
Output that would normally go to the terminal goes to a file called nohup.out if it has not already been redirected.
See nohup.out for searching errors in ./ or executed directory. It is no nohup error. Look nohup.out and google error and will refresh question.

systemctl Exec format error when trying to run service

Currently I wanted to run my dedicated server on my vps. When I run system systemctl start csgo.service it gives me error Load: error (Reason: Exec format error) when I run systemctl status csgo.service it gives me /lib/systemd/system/csgo.service:12: Executable path is not absolute: killall -TERM srcds_linux. Below are the service file that I am trying to run, am I making any mistake since it says format error?
[Unit]
Description=CSGO Server
[Service]
Type=simple
User=steam
Group=steam
Restart=on-failure
RestartSec=5
StartLimitInterval=60s
StartLimitBurst=3
ExecStart=/home/steam/steamcmd/csgo/srcds_run -game csgo -console -usercon +game_type 0 +game_mode 1 -tickrate 128 +mapgroup mg_active +map de_dust2 +sv_setsteamaccount GsltKeyHere -net_port_try 1
ExecStop=killall -TERM srcds_linux
[Install]
WantedBy=multi-user.target
My dedicated server files are inside /home/steam/steamcmd/csgo
Quoting the manual on unit files:
Note that shell command lines are not directly supported. If shell command lines are to be used, they need to be passed explicitly to a shell implementation of some kind.
Example: ExecStart=sh -c 'dmesg | tac'
You'll need to either use sh like that or figure out the actual path to your killall executable, e.g.
[Unit]
ExecStop=sh -c 'killall -TERM srcds_linux'
or
[Unit]
ExecStop=/sbin/killall -TERM srcds_linux
As an aside, that's not the best of ExecStop commands; it'll ruthlessly kill all srcds_linux executables, no matter if they're related to this service or not. Having no ExecStop command will have systemd terminate the service by itself:
Note that it is usually not sufficient to specify a command for this setting that only asks the service to terminate (for example, by queuing some form of termination signal for it), but does not wait for it to do so. Since the remaining processes of the services are killed according to KillMode= and KillSignal= as described above immediately after the command exited, this may not result in a clean stop. The specified command should hence be a synchronous operation, not an asynchronous one.

Running bash script as a service and write to another bash script is not working

I have the following problem using bash script.
Here is what I have inside the 'startup' script file:
#!/bin/bash
java -cp ../lib/online-store.jar:../lib/* com.online.store.Main
OnlineStorePID=$!
if [$OnlineStorePID -ne 0] then
echo "kill $OnlineStorePID" > shutdown
fi
Basically what I do, is to run a java application, get the process id and write it to another bash file. All this process works when I execute the startup script, and the 'shutdown' script file is updated successfully with a line containing 'kill processIDNumber' cmd.
Now I have tried to create a service on Ubuntu for this script using the following commands:
sudo systemctl daemon-reload
sudo systemctl enable online-store.service
sudo systemctl start online-store
When I start the service the java application starts successfully, but the shutdown script file is not updated. It seems that the 'echo "kill $OnlineStorePID" > shutdown' line is not executed. I don't get any complain errors. Does anyone knows what's the problem here.
Here is my service file:
[Unit]
Description=Online store service
Requires=multi-user.target
After=multi-user.target
Wants=mysql.service
[Service]
WorkingDirectory=/home/user/Desktop/online-store-service
#path to executable.
ExecStart=/home/user/Desktop/online-store-service/bin/startup
ExecStop=/home/user/Desktop/online-store-service/bin/shutdown
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Change your script and run the java command like below as back ground process
java -cp ../lib/online-store.jar:../lib/* com.online.store.Main >/dev/null 2>&1 &

Register daemon controllable by start and stop command in Linux

Many system daemon can be started using start/stop command. I was just curious how start/stop works on Linux system. Say I wrote a daemon executable, how should I configure it so that it can be controlled by start/stop in Linux.
I make a daemon in linux (ArchLinux) few years ago, and it works every day perfectly.
There are 2 ways to do this. Short way and long way:
Short Way:
Create a file in /etc/systemd/system/ called for example mydaemon.service :
/etc/systemd/system/mydaemon.service
[Unit]
Description=This is my first daemon! - Fernando Pucci
After=network.target
[Service]
User=root
WorkingDirectory=/root
Type=oneshotmc
RemainAfterExit=yes
ExecStart=/bin/echo -e "Daemon started"
ExecStop=/bin/echo -e "Daemon Stopped"
[Install]
WantedBy=multi-user.target
This service does nothing but show Daemon Started or Stopped. You can change echoes by the sentences you need.
If you need to run some script, try the Long way:
Long way
Create a file in some directory, like root folder or /usr/lib/systemd/scripts called for example
/root/mydaemon.sh
start() {
<your start sentences here
and here>
}
stop() {
<your stop sentences here
and here>
}
case $1 in
start|stop) "$1" ;;
esac
You must to make it runnable (chmod x)
(And you can execute it with start or stop parameter to test it.)
And as second step, create another file in
/usr/lib/systemd/system/mydaemon.service
[Unit]
Description=Second daemon of Fernando Pucci
After=network.target
[Service]
User=root
WorkingDirectory=/root
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c '/root/mydaemon.sh start'
ExecStart=/bin/echo -e "MyDaemon Started"
ExecStop=/bin/bash -c '/root/mydaemon.sh stop'
ExecStop=/bin/echo -e "MyDaemon Stopped"
[Install]
WantedBy=multi-user.target
Starting and Stopping
systemctl start mydaemon
systemctl stop mydaemon
systemctl status mydaemon
systemctl enable mydaemon
systemctl disable mydaemon
You (and someone) can send me a private msg for help about that.

Resources