Chapter 8. Process Management

Create Custom Unit and Start at Boot

Create Custom Unit and Start at Boot
Tag:

You can create your custom unit file and run your designed processes at boot. On this topic page, we'll explain how Linux OS starts multiple processes at boot and how to create a custom unit file that can autostart at boot.

default.target and multi-user.target

By using the functionalities of systemd, you can build programs that auto-start at boot. As explained briefly in the previous sections, when Linux OS starts, systemd triggers default.target. In the default.target unit file, which is a symbolic link to another target, e.g., graphical.target, you can see that multi-user.target is set under the Requires directive. This means default.target triggers multi-user.target at boot.

Below is the unit file named graphical.target, which is set as default.target in this example.

graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes

By default, default.target and multi-user.target are stored under the /usr/lib/systemd/system directory.

.wants directory

A target or unit may have its .wants directory, which is used to trigger other units with want dependencies. Basically, the unit files stored in the .wants directory will be run when the unit owning the .wants directory is started.

Unit files under the .wants directories are generated when another unit file specifies the target or unit in the WantedBy directive, and the unit file is enabled by the systemctl enable command. When the systemctl enable command is executed, the unit file's symbolic link is created under the .wants directory whose target or unit is specified by the unit file. By default, targets or units may not have their .wants directories. The directories are created along with symbolic links.

Creating an auto start custom service unit with the multi-user.target.wants directory

The multi-user.target.wants directory is often used to trigger custom units at boot. When you want to create an autostart custom service unit, you can do it with the following two steps

  • Step 1. Create a unit file for the service under the /etc/systemd/system directory. Make sure to include the following directives
    • Under the [Service] section, include the commands you want to execute at boot (e.g., use ExecStart or other command trigger directives)
    • Under the [Install] section, include WantedBy=multi-user.target
  • Step 2. Run the systemctl enable command to create a symbolic link of the custom unit file under the multi-user.target.wants directory. If you want to run the unit right away, you can use the --now option in the command.

When you complete Step 2, the unit should be set to start at boot. If you want to disable the auto start function, you can use the systemctl disable command. By running the command, the symbolic link is deleted, and the multi-user.target no longer wants the unit.

Practice

Objective:
Create and configure an auto-start program at boot

Step 0. Create a test shell script

To test the auto-start service unit, create a test shell script first. For easier understanding, we will create it under the home directory.

This example command executes two things:

  • Creates a file name with the timestamp of the command execution
  • Counts down from 1,000,000 and records the countdown
Command Line - INPUT
cd ~/dir_ch8
mkdir auto_countdown
cd auto_countdown
vim auto_countdown.sh

Press the i key to activate the insert mode. Next, copy the code below and paste it into the file. After pasting the code, press the esc key followed by the : key and save the file by pressing the w + q keys. To learn how to use Vim, check Chapter 3. Vim Editor .

auto_countdown.sh
#!/bin/bash

name=`date "+%b%d%H%M%S"`
touch /home/ubuntu/dir_ch8/auto_countdown/$name.txt

count=1000000
while [ $count -ge 0 ]
do
    echo "countdown $count" >> /home/ubuntu/dir_ch8/auto_countdown/$name.txt
    count=$((count - 1))
done

Add an execution permission and execute the shell script as a background job.

Command Line - INPUT
sudo chmod u+x auto_countdown.sh
./auto_countdown.sh &

Check if a new file is created and the job is running in the background.

Command Line - INPUT
ls
Command Line - RESPONSE
Jan12152259.txt  auto_countdown.sh
Command Line - INPUT
jobs
Command Line - RESPONSE
[1]+  Running                 ./auto_countdown.sh &

Step 1. Create a unit file

Create a unit file under the /etc/systemd/system directory.

Command Line - INPUT
sudo vim /etc/systemd/system/auto_countdown.service

In the unit file, include the following key directives.

  • ExecStart : specify the file path to the auto_countdown.sh file
  • Restart : use the keyword ‘always’ to check that the program is continuously running as a background job
  • WantedBy : use multi-user.target
auto_countdown.service
[Unit] 
Description = execute a countdown command

[Service]
Type = simple
ExecStart = /home/ubuntu/dir_ch8/auto_countdown/auto_countdown.sh
Restart = always

[Install]
WantedBy = multi-user.target

Check if the unit file is being properly made by running the systemctl list-unit-files command with grep. You can see that the file is recognized by systemd but its status is still disabled.

Command Line - INPUT
systemctl list-unit-files | grep auto_countdown
Command Line - RESPONSE
auto_countdown.service         disabled        enabled

Step 2. Enable the unit

Before enabling the unit, check the current status. First, check if the unit is active by running the systemctl list-units command with grep. You can see that there are no units named auto_countdown running.

Command Line - INPUT
systemctl list-units | grep auto_countdown

To enable the unit, run the systemctl enable command.

Command Line - INPUT
sudo systemctl enable auto_countdown
Command Line - RESPONSE
Created symlink /etc/systemd/system/multi-user.target.wants/auto_countdown.service → /etc/systemd/system/auto_countdown.service.

Run the systemctl status command. You can see that the unit is enabled but still inactive. This is because the system has not gone through the boot process yet.

Command Line - INPUT
systemctl status auto_countdown
Command Line - RESPONSE
● auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; enabled; vendor preset: >
     Active: inactive (dead)
        :

To exit the view mode, press the q key.

To make the unit active, run the systemctl enable command with the --now option. Alternatively, use the systemctl start command.

Command Line - INPUT
sudo systemctl enable --now auto_countdown

To check if the unit is running, run the systemctl status command. You can see that the unit is now running properly.

Command Line - INPUT
systemctl status auto_countdown
Command Line - RESPONSE
 auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; enabled; vendor preset: >
     Active: active (running) since Thu 2023-01-12 15:52:17 UTC; 7s ago
   Main PID: 2586 (auto_countdown.)
      Tasks: 1 (limit: 2372)
     Memory: 6.6M
     CGroup: /system.slice/auto_countdown.service
             └─2586 /bin/bash /home/ubuntu/dir_ch8/auto_countdown/auto_countdown.sh

You can also use the systemctl list-units command with grep.

Command Line - INPUT
systemctl list-units | grep auto_countdown
Command Line - RESPONSE
auto_countdown.service loaded active running   execute a count
down command

Check the home directory with the ls command. You can see that several files are being created. This is because we set the Restart directive with ‘always’. The use of ‘always’ ensures that the command keeps restarting after finishing its process.

Command Line - INPUT
ls ~/dir_ch8/auto_countdown
Command Line - RESPONSE
Jan12161817.txt  Jan12162038.txt  Jan12162300.txt  Jan12163108.txt  auto_countdown.sh

Step 3. Check auto start at boot

Finally, check if the unit starts automatically at boot.
To check the status, delete the existing files by running the rm command (change the month (e.g., Jan) and use wildcard). You may see that there is one file remaining as the unit still keeps running.

Command Line - INPUT
cd ~/dir_ch8/auto_countdown
sudo rm Jan*
ls
Command Line - RESPONSE
Jan12163951.txt  auto_countdown.sh

To reboot, run the reboot command with sudo.

Command Line - INPUT
sudo reboot

The reboot may take a few minutes. As ssh is disconnected during the reboot, reconnect it again. If you are using VS Code, reopen the window.

Create-Custom-Unit-and-Start-at-Boot

Once you relaunch the terminal, check the status again.

Command Line - INPUT
systemctl status auto_countdown

You can see that the unit is running.

Command Line - RESPONSE
 auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-01-12 16:50:14 UTC; 9s ago
   Main PID: 1979 (auto_countdown.)
      Tasks: 1 (limit: 2372)
     Memory: 6.4M
     CGroup: /system.slice/auto_countdown.service
             └─1979 /bin/bash /home/ubuntu/dir_ch8/auto_countdown/auto_countdown.sh

Also, you can check that new files are being created by running the ls command.

Command Line - INPUT
cd ~/dir_ch8/auto_countdown
ls
Command Line - RESPONSE
Jan12164913.txt  Jan12165040.txt  Jan12165129.txt  Jan12165216.txt  
Jan12165014.txt  Jan12165103.txt  Jan12165152.txt  Jan12165239.txt
:

To disable and stop the unit, run the systemctl disable command with the --now option.

Command Line - INPUT
sudo systemctl disable --now auto_countdown
Command Line - RESPONSE
Removed /etc/systemd/system/multi-user.target.wants/auto_countdown.service.

Upon checking the status again, you can see that the unit has already been disabled and stopped.

Command Line - INPUT
systemctl status auto_countdown
Command Line - RESPONSE
● auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; disabled; vendor preset: enabled)
     Active: inactive (dead

To exit the view mode, press the q key.

You can create your custom unit file and run your designed processes at boot. On this topic page, we'll explain how Linux OS starts multiple processes at boot and how to create a custom unit file that can autostart at boot.

default.target and multi-user.target

By using the functionalities of systemd, you can build programs that auto-start at boot. As explained briefly in the previous sections, when Linux OS starts, systemd triggers default.target. In the default.target unit file, which is a symbolic link to another target, e.g., graphical.target, you can see that multi-user.target is set under the Requires directive. This means default.target triggers multi-user.target at boot.

Below is the unit file named graphical.target, which is set as default.target in this example.

graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes

By default, default.target and multi-user.target are stored under the /usr/lib/systemd/system directory.

.wants directory

A target or unit may have its .wants directory, which is used to trigger other units with want dependencies. Basically, the unit files stored in the .wants directory will be run when the unit owning the .wants directory is started.

Unit files under the .wants directories are generated when another unit file specifies the target or unit in the WantedBy directive, and the unit file is enabled by the systemctl enable command. When the systemctl enable command is executed, the unit file's symbolic link is created under the .wants directory whose target or unit is specified by the unit file. By default, targets or units may not have their .wants directories. The directories are created along with symbolic links.

Creating an auto start custom service unit with the multi-user.target.wants directory

The multi-user.target.wants directory is often used to trigger custom units at boot. When you want to create an autostart custom service unit, you can do it with the following two steps

  • Step 1. Create a unit file for the service under the /etc/systemd/system directory. Make sure to include the following directives
    • Under the [Service] section, include the commands you want to execute at boot (e.g., use ExecStart or other command trigger directives)
    • Under the [Install] section, include WantedBy=multi-user.target
  • Step 2. Run the systemctl enable command to create a symbolic link of the custom unit file under the multi-user.target.wants directory. If you want to run the unit right away, you can use the --now option in the command.

When you complete Step 2, the unit should be set to start at boot. If you want to disable the auto start function, you can use the systemctl disable command. By running the command, the symbolic link is deleted, and the multi-user.target no longer wants the unit.

Practice

Objective:
Create and configure an auto-start program at boot

Step 0. Create a test shell script

To test the auto-start service unit, create a test shell script first. For easier understanding, we will create it under the home directory.

This example command executes two things:

  • Creates a file name with the timestamp of the command execution
  • Counts down from 1,000,000 and records the countdown
Command Line - INPUT
cd ~/dir_ch8
mkdir auto_countdown
cd auto_countdown
vim auto_countdown.sh

Press the i key to activate the insert mode. Next, copy the code below and paste it into the file. After pasting the code, press the esc key followed by the : key and save the file by pressing the w + q keys. To learn how to use Vim, check Chapter 3. Vim Editor .

auto_countdown.sh
#!/bin/bash

name=`date "+%b%d%H%M%S"`
touch /home/ubuntu/dir_ch8/auto_countdown/$name.txt

count=1000000
while [ $count -ge 0 ]
do
    echo "countdown $count" >> /home/ubuntu/dir_ch8/auto_countdown/$name.txt
    count=$((count - 1))
done

Add an execution permission and execute the shell script as a background job.

Command Line - INPUT
sudo chmod u+x auto_countdown.sh
./auto_countdown.sh &

Check if a new file is created and the job is running in the background.

Command Line - INPUT
ls
Command Line - RESPONSE
Jan12152259.txt  auto_countdown.sh
Command Line - INPUT
jobs
Command Line - RESPONSE
[1]+  Running                 ./auto_countdown.sh &

Step 1. Create a unit file

Create a unit file under the /etc/systemd/system directory.

Command Line - INPUT
sudo vim /etc/systemd/system/auto_countdown.service

In the unit file, include the following key directives.

  • ExecStart : specify the file path to the auto_countdown.sh file
  • Restart : use the keyword ‘always’ to check that the program is continuously running as a background job
  • WantedBy : use multi-user.target
auto_countdown.service
[Unit] 
Description = execute a countdown command

[Service]
Type = simple
ExecStart = /home/ubuntu/dir_ch8/auto_countdown/auto_countdown.sh
Restart = always

[Install]
WantedBy = multi-user.target

Check if the unit file is being properly made by running the systemctl list-unit-files command with grep. You can see that the file is recognized by systemd but its status is still disabled.

Command Line - INPUT
systemctl list-unit-files | grep auto_countdown
Command Line - RESPONSE
auto_countdown.service         disabled        enabled

Step 2. Enable the unit

Before enabling the unit, check the current status. First, check if the unit is active by running the systemctl list-units command with grep. You can see that there are no units named auto_countdown running.

Command Line - INPUT
systemctl list-units | grep auto_countdown

To enable the unit, run the systemctl enable command.

Command Line - INPUT
sudo systemctl enable auto_countdown
Command Line - RESPONSE
Created symlink /etc/systemd/system/multi-user.target.wants/auto_countdown.service → /etc/systemd/system/auto_countdown.service.

Run the systemctl status command. You can see that the unit is enabled but still inactive. This is because the system has not gone through the boot process yet.

Command Line - INPUT
systemctl status auto_countdown
Command Line - RESPONSE
● auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; enabled; vendor preset: >
     Active: inactive (dead)
        :

To exit the view mode, press the q key.

To make the unit active, run the systemctl enable command with the --now option. Alternatively, use the systemctl start command.

Command Line - INPUT
sudo systemctl enable --now auto_countdown

To check if the unit is running, run the systemctl status command. You can see that the unit is now running properly.

Command Line - INPUT
systemctl status auto_countdown
Command Line - RESPONSE
 auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; enabled; vendor preset: >
     Active: active (running) since Thu 2023-01-12 15:52:17 UTC; 7s ago
   Main PID: 2586 (auto_countdown.)
      Tasks: 1 (limit: 2372)
     Memory: 6.6M
     CGroup: /system.slice/auto_countdown.service
             └─2586 /bin/bash /home/ubuntu/dir_ch8/auto_countdown/auto_countdown.sh

You can also use the systemctl list-units command with grep.

Command Line - INPUT
systemctl list-units | grep auto_countdown
Command Line - RESPONSE
auto_countdown.service loaded active running   execute a count
down command

Check the home directory with the ls command. You can see that several files are being created. This is because we set the Restart directive with ‘always’. The use of ‘always’ ensures that the command keeps restarting after finishing its process.

Command Line - INPUT
ls ~/dir_ch8/auto_countdown
Command Line - RESPONSE
Jan12161817.txt  Jan12162038.txt  Jan12162300.txt  Jan12163108.txt  auto_countdown.sh

Step 3. Check auto start at boot

Finally, check if the unit starts automatically at boot.
To check the status, delete the existing files by running the rm command (change the month (e.g., Jan) and use wildcard). You may see that there is one file remaining as the unit still keeps running.

Command Line - INPUT
cd ~/dir_ch8/auto_countdown
sudo rm Jan*
ls
Command Line - RESPONSE
Jan12163951.txt  auto_countdown.sh

To reboot, run the reboot command with sudo.

Command Line - INPUT
sudo reboot

The reboot may take a few minutes. As ssh is disconnected during the reboot, reconnect it again. If you are using VS Code, reopen the window.

Create-Custom-Unit-and-Start-at-Boot

Once you relaunch the terminal, check the status again.

Command Line - INPUT
systemctl status auto_countdown

You can see that the unit is running.

Command Line - RESPONSE
 auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-01-12 16:50:14 UTC; 9s ago
   Main PID: 1979 (auto_countdown.)
      Tasks: 1 (limit: 2372)
     Memory: 6.4M
     CGroup: /system.slice/auto_countdown.service
             └─1979 /bin/bash /home/ubuntu/dir_ch8/auto_countdown/auto_countdown.sh

Also, you can check that new files are being created by running the ls command.

Command Line - INPUT
cd ~/dir_ch8/auto_countdown
ls
Command Line - RESPONSE
Jan12164913.txt  Jan12165040.txt  Jan12165129.txt  Jan12165216.txt  
Jan12165014.txt  Jan12165103.txt  Jan12165152.txt  Jan12165239.txt
:

To disable and stop the unit, run the systemctl disable command with the --now option.

Command Line - INPUT
sudo systemctl disable --now auto_countdown
Command Line - RESPONSE
Removed /etc/systemd/system/multi-user.target.wants/auto_countdown.service.

Upon checking the status again, you can see that the unit has already been disabled and stopped.

Command Line - INPUT
systemctl status auto_countdown
Command Line - RESPONSE
● auto_countdown.service - execute a countdown command
     Loaded: loaded (/etc/systemd/system/auto_countdown.service; disabled; vendor preset: enabled)
     Active: inactive (dead

To exit the view mode, press the q key.

Tag: