I am trying to write my own (simple) systemd service which does something simple.( Like writing numbers 1 to 10 to a file, using the shell script).
My service file looks like below.
[Unit]
Description=NandaGopal
Documentation=https://google.com
After=multi-user.target
[Service]
Type=forking
RemainAfterExit=yes
ExecStart=/usr/bin/hello.sh &
[Install]
RequiredBy = multi-user.target
This is my shell script.
#!/usr/bin/env bash
source /etc/profile
a=0
while [ $a -lt 10 ]
do
echo $a >> /var/log//t.txt
a=`expr $a + 1`
done
For some reason, the service doesn't come up and systemctl is showing the below output.
root#TARGET:~ >systemctl status -l hello
* hello.service - NandaGopal
Loaded: loaded (/usr/lib/systemd/system/hello.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: https://google.com
Been trying to figure out what went wrong for the last 2 days.
You have set Type=Forking, but your service doesn't work. Try
Type=oneshot
You have a "&" your ExecStart line, which is not necessary.
The service is disabled, which means it was not enabled to start at boot. You should run systemctl enable hello to set it to start at boot.
You can check man systemd.directives to find an index of all the directives that you can use in your unit files.
Few points:
If you use Type=forking, it is recommended to specify PidFile.
In your case, Type=simple, and ExecStart without & will work.
use systemctl start service-name to start a service
Then use systemctl status service-name to check its status.
status will be inactive/dead if service is not started.
Related
I'm new in raspberry pi programming, and i want to be able to launch a minecraft server at the start of the pi.
For that, I've already loocked at Systemd files and screen command.
I manage to make them work separately, but not together, it's why I'm looking for help there.
Firstly, I'm using a Raspberry pi 4 4Go with raspbian v10, and forge 1.12.2 with java 8.
I did a .sh file to launch easier the server:
#!/bin/bash
screen -S mcserver -dm java -Xms1024M -Xmx2048M -jar /home/pi/MinecraftServer/server/forge-1.12.2-14.23.5.2854.jar nogui
When I run the file, the server start perfectly in a socket as I want.
Secondly, I have a systemd file (auto-run-server.service):
[Unit]
Description=Auto run mc server
[Service]
ExecStart=/home/pi/MinecraftServer/server/minecraft.sh
[Install]
WantedBy=multi-user.target
But when I execute the service, nothing is happening, the status of the service shows a sucess, but there is nothing in screens (screen -list)
And when i replace the ExecStart value by
ExecStart=java -Xms1024M -Xmx2048M -jar /home/pi/MinecraftServer/server/forge-1.12.2-14.23.5.2854.jar nogui
The server starts, but the problem is that I want to access to a terminal to run commands in minecraft server, and i didn't find solution to access from there.
( It's why I want to create a "screen" )
I'm fully open to your answers, even if they don't use "screen", as long as I can access to a server terminal.
Thanks in advance.
I'm using the follow systemd unit for testing:
[Service]
ExecStart=/tmp/screentest.sh
And this screentest.sh shell script:
#!/bin/sh
screen -S mcserver -dm sh -c 'while :; do date; sleep 5; done'
If I start the service (systemctl start screentest) and then run systemctl status screentest, I see:
● screentest.service
Loaded: loaded (/etc/systemd/system/screentest.service; static; vendor preset: enabled)
Active: inactive (dead)
The problem here is that the screen command exits immediately when running with -d, so systemd believes the command has completed and cleans everything up by removing any additional processes spawned by the service.
We can tell systemd that the service spawns a child and exits by setting the service type to forking:
[Service]
Type=forking
ExecStart=/tmp/screentest.sh
With this change in place, after starting the service we see:
● screentest.service
Loaded: loaded (/etc/systemd/system/screentest.service; static; vendor preset: enabled)
Active: active (running) since Sun 2021-01-10 09:58:11 EST; 4s ago
Process: 14461 ExecStart=/tmp/screentest.sh (code=exited, status=0/SUCCESS)
Main PID: 14463 (screen)
Tasks: 3 (limit: 4915)
CGroup: /system.slice/screentest.service
├─14463 SCREEN -S mcserver -dm sh -c while :; do date; sleep 5; done
├─14464 sh -c while :; do date; sleep 5; done
└─14466 sleep 5
And screen -list shows:
root#raspberrypi:/etc/systemd/system# screen -list
There is a screen on:
14612.mcserver (01/10/2021 10:01:55 AM) (Detached)
1 Socket in /run/screen/S-root.
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 &
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.
Curently, i want auditd service run forever and user can not stop this via any commands.
Current my auditd service:
~]# systemctl cat auditd
# /usr/lib/systemd/system/auditd.service
[Unit]
Description=Security Auditing Service
DefaultDependencies=no
After=local-fs.target systemd-tmpfiles-setup.service
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
RefuseManualStop=yes
ConditionKernelCommandLine=!audit=0
[Service]
ExecStart=/sbin/auditd -n
## To not use augenrules, copy this file to /etc/systemd/system/auditd.service
## and comment/delete the next line and uncomment the auditctl line.
## NOTE: augenrules expect any rules to be added to /etc/audit/rules.d/
ExecStartPost=-/sbin/augenrules --load
#ExecStartPost=-/sbin/auditctl -R /etc/audit/audit.rules
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/auditd.service.d/override.conf
[Service]
ExecReload=
ExecReload=/bin/kill -HUP $MAINPID ; /sbin/augenrules --load
I can't stop this service from command:
# systemctl stop auditd.service
Failed to stop auditd.service: Operation refused, unit auditd.service may be requested by dependency only.
But when i using service auditd stop command. I can stop this service normally.
# service auditd stop
Stopping logging: [ OK ]
How can i prevent it? Thanks
The administrator (root) will always be able to manually kill the auditd process (which is what the service command does). What systemd is doing here is only to prevent the administrator from doing it via the systemctl interface.
In both cases, unprivileged users can not kill the daemon.
If you want to restrict even what root can do, you will have to use SELinux and customize the policy.
Some actions of service command are not redirected to systemctl but run some specific scripts located in /usr/libexec/initscripts/legacy-actions.
In this case, stop command will call this script:
/usr/libexec/initscripts/legacy-actions/auditd/stop
If you want that, the audited service can't be stopped by service command, you can remove this script, the action "stop" will be redirected to systemctl, which will block it b/c of the parameter "RefuseManualStop=yes".
But this doesn't mean that you can't kill the process of course.
Using the apt-get package for ElasticSearh, how can I configure the service to restart itself automatically after crashing on Ubuntu?
Restart on failure option is missing in the default service of elasticsearch.
So, We can add Restart=always option in the service.
Steps to add - Restart=always
Edit elasticsearch service unit file using the command sudo systemctl edit elasticsearch.service. This command will create a file /etc/systemd/system/elasticsearch.service.d/override.conf.
Now, add the following lines in the unit file.
[Service]
Restart=always
Save the file and refresh the unit file using command sudo systemctl daemon-reload
Can check the changes using command sudo systemctl cat elasticsearch.service.
Note:
We can use Restart= always, on-abnormal, on-success, on-failure, etc based on the requirement. Reference.
Editing unit file - Reference
Write a #!/bin/sh script as follows:
if ps -ef | grep -v grep | grep elastic ; then
exit 0
else
/etc/init.d/elasticsearch start >> /var/run/elasticsearch.pid &
exit 0
fi
Auto restart elasticsearch services in 7.14.1:
Go to:
nano /usr/lib/systemd/system/elasticsearch.service
The location of the service file is changed in 7.14.1
Then add this line to the service file:
[Service]
Restart=always
After that save the file and restart the elasticsearch service.
Now you are good to go. (After this there won't be any crash)