How to create a custom systemd service file

dos2unix

Well-Known Member
Joined
May 3, 2019
Messages
3,260
Reaction score
3,015
Credits
28,917
Create or Identify Your Bash Script: Make sure you have a Bash shell script that you want to run. If it's not already in place, create one and make it executable by running chmod +x your_script.sh in the terminal. Typically you will want to make the permissions so non-root users can't do anything with this file.

Create a systemd Service File:

Open a text editor to create a service unit file with a .service extension. You can use a command-line text editor like nano or vim. For example:

sudo nano /etc/systemd/system/your_script.service
Replace your_script with a meaningful name for your service. You can name this anything. Halloween.service if you want.

Edit the Service File:

Add the following lines to your service file. Modify the ExecStart line to point to the location of your Bash script:
---------------------------------------------------------------------------

[Unit]
Description=Your Script Description

[Service]
Type=simple
ExecStart=/path/to/your_script.sh
Restart=always

[Install]
WantedBy=multi-user.target

-------------------------------------------------------------------------

Description: Provide a description for your service.
ExecStart: Set the full path to your Bash script.
Restart: This line specifies when the service should be restarted. In this example, it's set to always.
Reload systemd:

After creating the service file, you should reload the systemd configuration to make it aware of the new service:

sudo systemctl daemon-reload

To enable your service so that it starts at boot, use the following command:

sudo systemctl enable your_script.service

To start the service immediately, use:

sudo systemctl start your_script.service

You can check the status of your service to ensure it's running without errors:

sudo systemctl status -l your_script.service
This command will display information about the service, including its status and any recent logs.

Your bash script can be pretty much anything a bash script does.

#!/bin/bash
Echo "Checkout Linux.org today!" > /some/text_file.text
# Sleep for five minutes, then print it again"
sleep 300
/path/to/your_script.sh

That's a silly example, but it gets the point across.

If at some point you don't want this to run anymore, Just do the following.

systemctl stop your_script.service

To keep it from automatically starting at next reboot.

systemctl disable your_script.service
 
Last edited:


I would like to create a service to run a script at system startup and would like to know if I have it right before I actually create it.

What I would like is to delay Deluge for 4 minutes at system boot to give my external drives time to actually mount before Deluge starts.

From what I've gathered so far is putting the below in a txt file, naming it delugedlay.sh, make it executable, place it in my desired location. Once I do that I need to know if I understand correctly what is needed for a systemd service.

Code:
#!/bin/bash
sleep 240 && deluge

Open a terminal in the folder it's located and run chmod +x delugedelay.sh

Code:
[Unit]
Description=delugedelay

[Service]
Type=simple
ExecStart=/home/cccp/.config/delugedelay.sh
Restart=always

[Install]
WantedBy=multi-user.target

Save that as delugedelay.service in /etc/systemd/system/ . Then the below.

sudo systemctl daemon-reload
sudo systemctl enable delaydeluge.service
sudo systemctl start delugedelay.service
sudo systemctl status -l delugedelay.service

Thanks
 
This looks good to me. Make sure your bash script has executable permissions.
I'm assuming this is for bitTorrent?

Tip: when working with systemctl, you don't have to type the "service" extension.
For example, you can just type

systemctl enable delaydeluge

without the ".service" at the end.
 
Yes that's for torrents. Now for making the script executable I do want "chmod +x delugedelay.sh", right? And that will give me my 4 minute delay on Deluge at reboot without affecting anything else? Thanks for the quick reply by the way.
 
Ok just did everything above and all checks out perfectly, but when I reboot Deluge is still started immediately.

Code:
~  systemctl start delugedelay                                                            ✔  02:35:46 
 ~  systemctl status delugedelay                                                      ✔  10s  02:36:10
● delugedelay.service - delugedelay
Loaded: loaded (/etc/systemd/system/delugedel
ay.service; enabled; preset: disabled)
Active: active (running) since Mon 2025-01-06 02:35:53 PST; 35s ago
Invocation: 7cdb423631404e3ca1610ee3e7608f48
Main PID: 8196 (delugedelay.sh)
Tasks: 2 (limit: 75538)
Memory: 728K (peak: 2M)
CPU: 4ms
CGroup: /system.slice/delugedelay.service
├─8196 /bin/bash /home/cccp/.config/delugedelay.sh
└─8200 sleep 240

Jan 06 02:35:53 CCCP systemd[1]: delugedelay.service: Scheduled restart job, restart counter is at 3.
Jan 06 02:35:53 CCCP systemd[1]: Started delugedelay.
~ 
 
Last edited:
Ok just did everything above and all checks out perfectly, but when I reboot Deluge is still started immediately.

Code:
~  systemctl start delugedelay                                                            ✔  02:35:46
 ~  systemctl status delugedelay                                                      ✔  10s  02:36:10
● delugedelay.service - delugedelay
Loaded: loaded (/etc/systemd/system/delugedel
ay.service; enabled; preset: disabled)
Active: active (running) since Mon 2025-01-06 02:35:53 PST; 35s ago
Invocation: 7cdb423631404e3ca1610ee3e7608f48
Main PID: 8196 (delugedelay.sh)
Tasks: 2 (limit: 75538)
Memory: 728K (peak: 2M)
CPU: 4ms
CGroup: /system.slice/delugedelay.service
├─8196 /bin/bash /home/cccp/.config/delugedelay.sh
└─8200 sleep 240

Jan 06 02:35:53 CCCP systemd[1]: delugedelay.service: Scheduled restart job, restart counter is at 3.
Jan 06 02:35:53 CCCP systemd[1]: Started delugedelay.
~ 
Because of the timing requirement in the script, a more optimal fit for this situation is to write the system unit file with the [Unit] and [Service] sections with suitable alterations, and then write a systemd .timer file that will trigger the service file using the configuration: OnBootSec=##, with the number of seconds after boot that you wish the service file to be triggered. The systemd.timer manpage has fairly clear details and there's more detailed info here:
https://wiki.archlinux.org/title/Systemd/Timers
 
You failed to include a suitable script in /etc/init.d/

Signed,

Matthew Campbell
 
You failed to include a suitable script in /etc/init.d/

Signed,

Matthew Campbell
I have no init.d folder.

Screenshot_20250106_042508.png
 
You failed to include a suitable script in /etc/init.d/

systemd does not use sysVinit scripts.

Many distros (such as fedora 41 for example ) do not have /etc/rc.init.d directories.
Mine does have /etc/rc.d/init.d, but all it has in it is a README file.

Code:
cat README  
You are looking for the traditional init scripts in /etc/rc.d/init.d,
and they are gone?

Here's an explanation on what's going on:

You are running a systemd-based OS where traditional init scripts have
been replaced by native systemd services files. Service files provide
very similar functionality to init scripts. To make use of service
files simply invoke "systemctl", which will output a list of all
currently running services (and other units). Use "systemctl
list-unit-files" to get a listing of all known unit files, including
stopped, disabled and masked ones. Use "systemctl start
foobar.service" and "systemctl stop foobar.service" to start or stop a
service, respectively. For further details, please refer to
systemctl(1).

Note that traditional init scripts continue to function on a systemd
system. An init script /etc/rc.d/init.d/foobar is implicitly mapped
into a service unit foobar.service during system initialization.

Thank you!

Further reading:
        man:systemctl(1)
        man:systemd(1)
        https://0pointer.de/blog/projects/systemd-for-admins-3.html
        https://systemd.io/INCOMPATIBILITIES
 
Last edited:
systemd does not use sysVinit scripts.

Many distros (such as fedora 41 for example ) do not have /etc/rc.init.d directories.
Mine does have /etc/rc.d/init.d, but all it has in it is a README file.

Code:
cat README 
You are looking for the traditional init scripts in /etc/rc.d/init.d,
and they are gone?

Here's an explanation on what's going on:

You are running a systemd-based OS where traditional init scripts have
been replaced by native systemd services files. Service files provide
very similar functionality to init scripts. To make use of service
files simply invoke "systemctl", which will output a list of all
currently running services (and other units). Use "systemctl
list-unit-files" to get a listing of all known unit files, including
stopped, disabled and masked ones. Use "systemctl start
foobar.service" and "systemctl stop foobar.service" to start or stop a
service, respectively. For further details, please refer to
systemctl(1).

Note that traditional init scripts continue to function on a systemd
system. An init script /etc/rc.d/init.d/foobar is implicitly mapped
into a service unit foobar.service during system initialization.

Thank you!

Further reading:
        man:systemctl(1)
        man:systemd(1)
        https://0pointer.de/blog/projects/systemd-for-admins-3.html
        https://systemd.io/INCOMPATIBILITIES
My Debian system does have an /etc/init.d/ directory and uses it.

Signed,

Matthew Campbell
 
My Debian system does have an /etc/init.d/ directory and uses it.

That's because Debian is hybrid and uses both sysVinit and systemd. The more modern distro's seem to
getting away from sysVinit.

Also, even with hybrid systems, you should never have both an rc.init file and a systemd service file for the same
application. That will cause conflicts and break things.

I would expect the next release of Debian not to support sysVinit.


However, there is always Devuan.

 
That's because Debian is hybrid and uses both sysVinit and systemd. The more modern distro's seem to
getting away from sysVinit.

Also, even with hybrid systems, you should never have both an rc.init file and a systemd service file for the same
application. That will cause conflicts and break things.

I would expect the next release of Debian not to support sysVinit.


However, there is always Devuan.

I don't believe my system uses rc.init either.

Signed,

Matthew Campbell
 
There are other options like runit. openrc, I think PuppyLinux uses something else based on busybox.
 
My Debian system does have an /etc/init.d/ directory and uses it.

I don't believe my system uses rc.init either.

Those are the same thing. Any files in /etc/init.d would be sysVinit init service files.

example
Code:
#!/bin/sh
### BEGIN INIT INFO
# Provides:          my_service
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example init script for my_service
# Description:       This file should be used to start and stop my_service.
### END INIT INFO

# Path to the service executable
DAEMON_PATH="/usr/local/bin/my_service"

# Name of the service
NAME=my_service
DESC="My Service"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Load the LSB init functions
. /lib/lsb/init-functions

do_start() {
    log_daemon_msg "Starting $DESC" "$NAME"
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON_PATH --background
    log_end_msg $?
}

do_stop() {
    log_daemon_msg "Stopping $DESC" "$NAME"
    start-stop-daemon --stop --quiet --pidfile $PIDFILE
    log_end_msg $?
}

case "$1" in
  start)
    do_start
    ;;
  stop)
    do_stop
    ;;
  restart|force-reload)
    do_stop
    do_start
    ;;
  status)
    status_of_proc "$DAEMON_PATH" "$NAME" && exit 0 || exit $?
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|status}" >&2
    exit 3
    ;;
esac

exit 0

sysVinit came from the early UNIX days. It's been around since at least 1984 or earlier,
 
sysVinit came from the early UNIX days. It's been around since at least 1984 or earlier,

Hmm... That would have been AT&T's UNIX System III. So, a bit earlier than 1984, as you suggested.

Don't quote me on that, actually. I'm pretty sure...
 
The sysVinit scripts that are in debian are actually run by systemd, and not by the traditional sysVinit means of being called by init which traversed the /etc/rc* files. Systemd does this through the systemd-sysv-generator, of which there is a manpage explaining the matter. The current manpage on systemd-sysv-generator also notes that this means of dealing with sysVinit scripts will be deprecated soon, and advises that such scripts should be written as native systemd unit files.

Whilst it's still possible to write a sysVinit script in debian and configure systemd to run it, it does look like that in the near future this route will be closed off as @dos2unix suggested in post #12. Can't say when though.
 
Now I have tried it and Deluge still starts as soon as the system lands back on the desktop. I've posted on RebornOS forums and had a couple of suggestion made but none seem to address the issue.
 
Last edited by a moderator:
I would do this like @osprey mentioned, with a timer.

Create a timer unit file: Create a file named delugedelay.timer in /etc/systemd/system/ with the following content:

Code:
[Unit]
Description=Timer to delay Deluge start

[Timer]
OnBootSec=240s
Unit=delugedelay.service

[Install]
WantedBy=timers.target

Modify your service unit file: Ensure your delugedelay.service file remains as it is:

Code:
[Unit]
Description=delugedelay

[Service]
Type=simple
ExecStart=/home/cccp/.config/delugedelay.sh
Restart=always

[Install]
WantedBy=multi-user.target

Enable and start the timer: Enable and start the timer instead of the service directly:

Code:
sudo systemctl enable delugedelay.timer
sudo systemctl start delugedelay.timer

Code:
sudo systemctl status delugedelay.timer
 
Last edited:
Thank you for that, much appreciated. After my last post I did some more searching and I came across doing just that, since @osprey and you recommend it as well I will give it a go. Thanks again.
 

Staff online


Top