Contents
1 Introduction
When we use the Linux system, we often encounter the need to run commands (or scripts) at startup. This article takes the startup of the tailscale relay server DERP on Debian 11 as an example to summarize the three most commonly used ways to run commands (or scripts) at startup.
2 Add as service
This is the Debian-recommended way to add a startup script. Registering the startup item as a service also facilitates management and operation.
Let's look at the format of defining the service file, using my configuration of the DERP service (see:Debian series build tailscale DERP server (relay server) for dummies) service as an example:
[Unit] Description=derper.service After=network.target [Service] Type=forking ExecStart=/usr/local/go/bin/runderper ExecStop=/usr/local/go/bin/stopderper [Install] WantedBy=multi- user.target
Because after registering as a service, you can usesystemctl startandsystemctl stopSo the corresponding behaviors of start and stop need to be defined in advance in the service file. Generally, we can write two scripts to correspond to each other. In the example of DERP,ExecStart=The following script/usr/local/go/bin/runderperIt corresponds to start;ExecStop=The following script/usr/local/go/bin/stopderperCorresponding to stop. Start must be present, but stop is not necessary. If you do not need it, you can leave it undefined.
First create the runderper script:
vim /usr/local/go/bin/runderper
Paste the following content and save and exit:
#!/bin/sh cd /root/go/bin nohup ./derper -hostname=ab.cd.ef -c=derper.conf -a=:45678 -http-port -1 -certdir=/usr/local/ cert -certmode=manual -verify-clients -stun & echo $! > /usr/local/go/bin/app.pid
The derper program path, domain name, port, certificate storage path, and app.pid path can be modified according to your actual situation.
Then create the stopderper script:
vim /usr/local/go/bin/stopderper
Paste the following content and save and exit:
#!/bin/sh kill `cat app.pid` rm -rf app.pid
Grant execution permissions to these two files respectively:
chmod +x /usr/local/gopath/bin/runderper chmod +x /usr/local/gopath/bin/stopderper
Register the service file:
vim /etc/systemd/system/derper.service
Paste the following content and save and exit:
[Unit] Description=derper.service After=network.target [Service] Type=forking ExecStart=/usr/local/go/bin/runderper ExecStop=/usr/local/go/bin/stopderper [Install] WantedBy=multi- user.target
Set the service to start at boot:
systemctl start derper systemctl enable derper
3 rc.local method
Loading scripts at startup through rc.local is an old method, but it is also a simple method that many people are used to. However, after Debian 9, the system no longer has the rc.local file by default, but only retains the rc.local service. For example, run the following command:
cat /lib/systemd/system/rc-local.service
You can see:

And the service is closed by default, run the following command to view:
systemctl status rc-local

Then, we need to reset the service corresponding to rc.local. First run the following command:
cp /lib/systemd/system/rc-local.service /etc/systemd/system/rc-local.service
Then edit the service file:
vim /etc/systemd/system/rc-local.service
Add at the end of the file[Install]`Part of the content:
[Install] WantedBy=multi-user.target
As shown below:

Because the location of the rc.local file has been defined in the rc-local.servive file, we only need to manually create the rc.local file first, as follows:
vim /etc/rc.local
Then paste the following content and save and exit:
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. exit 0
Grant execution permissions to the rc.local file:
chmod +x /etc/rc.local
Start the rc-local service:
systemctl enable rc-local # sets the service to start at boot
The following warning will pop up:

Don't worry about this warning, because this service is only associated with one file, rc.local.
Run the command again to view the service status:
systemctl status rc-local.service

You can see that the service status is normal.
In the future, you can add commands that need to be started at boot time to the rc.local file before exit 0. If it is a boot script, add it before exit 0 using bash xxx.sh.
Take the DERP server setting for auto-startup in another article as an example (see:Debian series build tailscale DERP server (relay server) for dummies), there are 2 ways:
1. Use screen:
Enter the following command before exit 0:
screen_name1="derper" screen -dmSscreen_name1 cmd1="sleep 10;/usr/local/go/bin/runderper"; screen -x -Sscreen_name1 -p 0 -X stuff "cmd1" screen -x -Sscreen_name1 -p 0 -X stuff '\n' screen -x -Sscreen_name1 -p 0 -X stuff "exit"
This method requires the installation of the screen command. The advantage of this method is that you can use the screen command to switch to the corresponding terminal. This is very useful when there are multiple programs running in the background. For example, when setting up the Trinitycore 3.5.5 World of Warcraft server, worldserver and authserver need to be started automatically at boot (see:Trinitycore Series World of Warcraft Trinitycore 3.3.5 (24011) version building for dummies).
2. Run the startup script directly
Enter the following command before exit 0:
bash /usr/local/go/bin/runderper
4 Using the Linux Panel's Process Daemon Manager
I use the Baota Linux panel, and there is a free program in the software center:

Install and enter the program, click Add Daemon in the red box:


This method is the simplest, so I won’t say much about it, but the prerequisite is that you have installed Baota Linux Bread or other panels with similar functions.