I - Intro
During my help-desk, service-desk… and something-desk days, where tasks were basically a wide variety of technical interventions with no end users but internal company employees, I used to watch SysAdmins perform some of their tasks on Windows or Linux servers. Sometimes I even got to run them myself.
I wanted to learn more about Linux. I was curious about how they made their own programs run as a service, for example.
That’s exactly what we’ll do in this post: create our own basic service to gather information and monitor system resources.
II Planning
First, let’s make an action plan with a diagram-style checklist for the lab.
Then, as we develop each point, we’ll work on the more granular aspects.
-
Requirements.
-
The script.
-
The service.
-
Running the complete workflow.
-
Conclusion.
III Requirements
- Read the previous posts! Since they’re completely tied to this topic, the idea is to do a hands-on lab with the concepts, terms, and commands learned in:
-
Have a Linux distro with Systemd as the service manager.
-
Access to
sudo.
IV The Script
What is a script and what is it for?
A script is essentially a screenplay for computers. In a way, that’s what a script does in IT.
A computer script is a program that executes commands sequentially, just like a screenplay… first one command, then another, and so on.
What’s the script’s function in our workflow?
In our lab case, the script is responsible for collecting general information and system resources at the moment of execution.
It does this by running multiple commands and displaying the information it obtains from them.
This is an example of what it will show each time it runs:
***Execution start***
***Current date and time: Fri Oct 18 2025 09:23:47 CEST***
***Basic Monitoring Service***
***General System Information:
Operating System: Ubuntu 24.04.1 LTS
System name: slimbook-dev
Kernel Version: 6.8.0-45-generic
Chassis: laptop 💻
Hardware Model: Slimbook Executive 14
Network: default via 192.168.0.1 dev wlp3s0 proto dhcp src 192.168.0.105 metric 600
Public IP: 2a02:c7e:3012:4800::1
***System Resources:
Number of CPUs: 8
CPU Model: Intel Core i7-1165G7 @ 2.80GHz
Total RAM: 16Gi
Available RAM: 9.2Gi
Used RAM: 4.8Gi
Total space on / partition: 512G
Available space on /: 387G
Percentage used on /: 24%
Uptime: up 3 hours, 42 minutes
Connected users: 1
***End of execution***
-
Notice that the commands it runs are varied, yet almost all begin with
echo.Echois a command that prints to the terminal, meaning it “displays on screen” text. In our use case, we’re combiningechowith other commands.I recommend experimenting with these commands by running them without the script, manually one at a time, and also modifying the script as you like.
The following line of code tells the program to save the execution result, that is, the output to the
/var/log/systemInfo.logfile:LOG_FILE="/var/log/systemInfo.log" -
Create the following file with your favorite text editor - in my case I used
vim:sudo vim /usr/local/bin/systemInfo_v1.sh -
Copy and paste the following content, then save the changes:
#!/bin/bash #Published on **Proyecto LEETI*** #---> https://www.proyectoleeti.com <--- LOG_FILE="/var/log/systemInfo.log" { echo '***Execution start***' echo '***Current date and time:' $(date)'***' echo '' echo '***Basic Monitoring Service***' echo '' echo '***General System Information:' echo '' source /etc/os-release echo 'Operating System:' $PRETTY_NAME echo 'System name:' $(hostname) echo 'Kernel Version:' $(uname -r) echo $(hostnamectl | grep 'Chassis') echo $(hostnamectl | grep 'Hardware Model') echo 'Network:' $(ip route | grep default) echo 'Public IP:' $(curl -s ifconfig.me) echo '' echo '***System Resources:' echo '' echo 'Number of CPUs:' $(nproc) echo 'CPU Model:' $(lscpu | grep 'Model name' | sed 's/Model name: *//') echo 'Total RAM:' $(free -h | grep Mem | awk '{print $2}') echo 'Available RAM:' $(free -h | grep Mem | awk '{print $7}') echo 'Used RAM:' $(free -h | grep Mem | awk '{print $3}') echo 'Total space on / partition:' $(df -h / | tail -1 | awk '{print $2}') echo 'Available space on /:' $(df -h / | tail -1 | awk '{print $4}') echo 'Percentage used on /:' $(df -h / | tail -1 | awk '{print $5}') echo 'Uptime:' $(uptime -p) echo 'Connected users:' $(who | wc -l) echo '' echo '***End of execution***' echo '' } | tee -a "$LOG_FILE" -
It’s necessary to add execution permission to the file to be able to, well, execute it:
sudo chmod +x /usr/local/bin/systemInfo_v1.sh -
Test the script, it should display the information obtained from the system, just like the example shown at the beginning of this chapter IV.
sudo /usr/local/bin/systemInfo_v1.shOr by checking the file with the
output:cat /var/log/systemInfo.log
V The Service
What’s the service’s function in our workflow?
The service will allow us to manage our script directly with systemd, which gives us the following advantages:
-
Easy administration (start it, stop it, check status).
-
Run it in an automated way.
-
Register logs.
-
Practice a typical professional environment workflow with our own program.
-
As we saw in the previous post, the
unitfile provides the service with the necessary configurations for its execution. In our case, we’ll create the followingunitfile. The filename will also give the service its name:sudo vim /etc/systemd/system/systemInfo.service -
The service will run only once at system startup (
oneshot) and will do so after network services load (network.online.target). -
Copy and paste the content:
[Unit] Description=Basic Monitoring Service Documentation=https://www.proyectoleeti.com After=network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart=/usr/local/bin/systemInfo_v1.sh StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target -
To test it, we first need to reload
systemctlsince there’s a new service to manage:sudo systemctl daemon-reload -
Now yes, almost there! First check the service status with
sudo systemctl status systemInfo, it will show output similar to the following:sudo systemctl status systemInfo -
○ systemInfo.service - Basic Monitoring Service Loaded: loaded (/etc/systemd/system/systemInfo.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: https://www.proyectoleeti.com -
Then start it with
sudo systemctl start systemInfo:sudo systemctl start systemInfo -
At this point, the following should have happened:
-
Start the
systemInfoservice. -
Execute the script
/usr/local/bin/systemInfo_v1.sh. -
Write the collected information to the
/var/log/systemInfo.logfile. -
Stop the
systemInfoservice.
-
-
How do we verify if it ran correctly? We have more than one way:
-
Run
sudo systemctl status systemInfowhich will show us valuable information like last execution date/time, process ID and its execution state, as well as the last log lines:Active: inactive (dead) since Sun 2025-10-19 17:01:52 CEST; 3s ago Main PID: 31006 (code=exited, status=0/SUCCESS) oct 19 17:01:52 slimbook-dev systemInfo_v1.sh[31008]: Available RAM: 5.9Gi oct 19 17:01:52 slimbook-dev systemInfo_v1.sh[31008]: Used RAM: 6.8Gi oct 19 17:01:52 slimbook-dev systemInfo_v1.sh[31008]: Total space on / partition: 476G -
Check the service logs through:
sudo journalctl -u systemInfo.service -
To show more logs, press the spacebar until reaching the end of the
journal:sudo journalctl -u systemInfo oct 17 12:56:13 slimbook-dev systemd[1]: Starting systemInfo.service - Basic Monitoring Service... oct 17 12:56:13 slimbook-dev systemInfo_v1.sh[21142]: ***Execution start*** oct 17 12:56:13 slimbook-dev systemInfo_v1.sh[21142]: ***Basic Monitoring Service*** oct 17 12:56:13 slimbook-dev systemInfo_v1.sh[21142]: ***General System Information: oct 17 12:56:13 slimbook-dev systemInfo_v1.sh[21142]: Date and time: Fri Oct 17 2025 12:56:13 CEST ... oct 19 17:01:52 slimbook-dev systemInfo_v1.sh[31008]: Uptime: up 4 hours, 55 minutes oct 19 17:01:52 slimbook-dev systemInfo_v1.sh[31008]: Connected users: 3 oct 19 17:01:52 slimbook-dev systemInfo_v1.sh[31008]: ***End of execution*** oct 19 17:01:52 slimbook-dev systemd[1]: systemInfo.service: Deactivated successfully. oct 19 17:01:52 slimbook-dev systemd[1]: Finished systemInfo.service - Basic Monitoring Service. -
Check the script’s own log file, review the file content with commands like
cat,lessorview:view /var/log/systemInfo.log -
Once confirmed it works, enable the service so it starts automatically on each OS boot, that is, loaded by
init:sudo systemctl enable systemInfo -
We’ll get output similar to the following:
Created symlink /etc/systemd/system/multi-user.target.wants/systemInfo.service → /etc/systemd/system/systemInfo.service.
-
Screenshots gallery:

VI Running the Complete Workflow
To recreate a complete test, just restart the system. The service should have executed along with the script, and finished after writing the collected information to the systemInfo.log file.
Check it with any of the three methods shown in the previous chapter V. Remember that the script records the date and time of each execution on one hand, and on the other hand, the journal does the same with the service. Both executions should match.
I’ll share another example of the script, but executed on a VM (virtual machine) with Ubuntu under Proxmox on a BMS (bare metal server):
***Execution start***
***Current date and time: Thu Oct 23 2025 09:31:54 UTC***
***Basic Monitoring Service***
***General System Information:
Operating System: Ubuntu 22.04.5 LTS
System name: vm-dev-ubu-22-04
Kernel Version: 5.15.0-160-generic
Chassis: vm
Hardware Model: Standard PC _i440FX + PIIX, 1996_
Network: default via 10.0.0.1 dev ens18 proto static
Public IP: 43.70.61.121
***System Resources:
Number of CPUs: 1
CPU Model: QEMU Virtual CPU version 2.5+
Total RAM: 1.9Gi
Available RAM: 1.6Gi
Used RAM: 130Mi
Total space on / partition: 15G
Available space on /: 6.9G
Percentage used on /: 51%
Uptime: up 0 minutes
Connected users: 0
***End of execution***
VII Conclusion
“Creating a service in Linux” - sounds complicated, right? We can see that it’s actually quite simple and straightforward.
The most important thing is to understand how it works and its potential. By running each command yourself, reading the man files for the commands, doing at least one end-to-end configuration, we can imagine different use cases and the potential these tools have for applying them in different personal and professional scenarios.
🐧 I encourage you to try your own scripts, break things, fix them, read… keep learning and sharing!
Until the next post! 🐧