Automating Bash scripts on Linux is essential for system administration tasks, such as installing applications and monitoring system logs. Cron is a job scheduler that runs tasks at specific intervals, while systemd is a service manager that handles applications through service profiles. This guide walks through writing two Bash scripts — one for log monitoring and one for backups — then automating them with a cron job and running one as a persistent systemd service. By the end, you'll have both a scheduled cron job and a managed systemd service running your own Bash scripts automatically.
Prerequisites
Before you begin:
- Have access to a Ubuntu server as your management workstation.
- Access the server using SSH as a non-root sudo user.
- Install a LAMP stack (Apache, MySQL, PHP).
Create Bash Scripts
Bash scripts support multiple commands and functions that define how tasks run in a system. Follow the steps below to create two Bash scripts: one to back up critical web application files, and one to monitor system logs for errors.
1. Switch to your user's home directory:
$ cd 2. Create a new log-monitor.sh script:
$ nano log-monitor.sh 3. Add the following contents to the log-monitor.sh file:
#!/bin/bash LOG_FILE="/var/log/syslog" ERROR_LOG="/opt/data/error_log.txt" WARNING_LOG="/opt/data/warning_log.txt" tail -F "$LOG_FILE" | while read line; do if echo "$line" | grep -q "error"; then echo "$line" >> "$ERROR_LOG" elif echo "$line" | grep -q "warning"; then echo "$line" >> "$WARNING_LOG" fi done Save and close the file. This script creates error_log.txt and warning_log.txt files in the /opt/data directory, filtering results from /var/log/syslog using a while loop. It writes each new line to the respective error or warning file as it appears.
4. Create another script named backup.sh:
$ nano backup.sh 5. Add the following contents to the file:
#!/bin/bash DB_USER="user" DB_PASSWORD="new-password" DB_NAME="mysql" DB_BACKUP_DIR="mysql_backup" WEB_FILES_DIR="web_backup" mkdir -p "$DB_BACKUP_DIR" mkdir -p "$WEB_FILES_DIR" DATE=$(date +"%Y%m%d_%H%M%S") mysqldump -u"$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" > "$DB_BACKUP_DIR/db_backup_$DATE.sql" echo "MySQL backup completed: $DB_BACKUP_DIR/db_backup_$DATE.sql" tar -czf "$WEB_FILES_DIR/web_backup_$DATE.tar.gz" /var/www/html echo "Web application backup completed: $WEB_FILES_DIR/web_backup_$DATE.tar.gz" Save and close the file. This script connects to the MySQL database server using the DB_... variables, then creates mysql_backup and web_backup directories to store the database and web application backups.
6. Move the Bash scripts to a system-wide directory like /opt:
$ sudo cp backup.sh log-monitor.sh /opt/ 7. Create a new data directory under the system-wide directory:
$ sudo mkdir -p /opt/data 8. Change the directory permissions to 777 to allow all users to write files:
$ sudo chmod 777 /opt/data Automate the Bash Script Using Cron
Cron creates jobs you can use to schedule and automatically run a Bash script at specific intervals. Follow the steps below to automate the backup.sh script to back up the MySQL database and web application files daily.
1. Open the crontab editor:
$ crontab -e Select your desired text editor when prompted — for example, select 1 to choose the nano text editor.
2. Add the following directive at the end of the file:
0 2 * * * /opt/backup.sh Save and close the file. This cron job runs backup.sh daily at 2:00 A.M. In the job:
-
0: Runs the script at the start of a minute. Set a value between0and59. -
2: Runs the script at 2:00 A.M. Specify an hour between0and23. -
*: Runs the script every day of the month. Specify a day between1and31. -
*: Runs the script every month. Specify a month between1and12. -
*: Runs the script daily. Specify a day of the week between0and7.
3. List all cron jobs and verify the new task is available:
$ crontab -l Output:
# # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command 0 2 * * * ~/backup.sh Automate the Bash Script as a System Service Using Systemd
Systemd starts system services automatically at boot and offers options for stopping and restarting them. Follow the steps below to set up the log-monitoring script as a system service.
1. Create a new system service file:
$ sudo nano /etc/systemd/system/logmonitor.service 2. Add the following contents to the logmonitor.service file:
[Unit] Description= Automatic System Logs Monitoring and Filtering After=network.target [Service] ExecStart=bash /opt/log-monitor.sh Restart=always [Install] WantedBy=multi-user.target Save and close the file. This service configuration runs the log-monitor.sh script from /opt to monitor and filter log entries in /var/log/syslog.
3. Reload systemd to apply the service file changes:
$ sudo systemctl daemon-reload 4. Enable the new system service to automatically start at boot:
$ sudo systemctl enable logmonitor.service Output:
Created symlink /etc/systemd/system/multi-user.target.wants/logmonitor.service → /etc/systemd/system/logmonitor.service. 5. Start the system service:
$ sudo systemctl start logmonitor 6. View the system service status and verify it's running:
$ sudo systemctl status logmonitor Output:
● logmonitor.service - Automatic System Logs Monitoring and Filtering Loaded: loaded (/etc/systemd/system/logmonitor.service; enabled; preset: enabled) Active: active (running) since Wed 2024-11-06 13:20:07 UTC; 11s ago Main PID: 14293 (bash) Tasks: 3 (limit: 1062) Memory: 784.0K (peak: 1.5M) CPU: 40ms CGroup: /system.slice/logmonitor.service ├─14293 bash /opt/log-monitor.sh ├─14308 tail -F /var/log/syslog └─14309 bash /opt/log-monitor.sh Nov 06 13:20:07 Linux-server systemd[1]: Started logmonitor.service - Automatic System Logs Monitoring and Filtering. 7. Run the following commands to simulate new error and warning entries in /var/log/syslog:
$ logger -p user.err "This is a simulated error log message from MySQL" $ logger -p user.err "This is a simulated warning log message from Apache" $ logger -p user.err "This is a simulated error log message from PHP" $ logger -p user.err "This is a simulated Warning log message from MySQL" 8. List all files in /opt/data and verify that error_log.txt and warning_log.txt are available:
$ ls /opt/data Output:
error_log.txt warning_log.txt 9. View the error_log.txt file and verify that only error entries are present:
$ cat error.log Output:
2024-11-06T13:33:48.010096+00:00 Server linuxuser: This is a simulated error log message from MySQL 2024-11-06T13:33:48.010096+00:00 Server linuxuser: This is a simulated error log message from PHP Next Steps
- Add more granular filters (by service name or severity) to
log-monitor.sh - Extend
backup.shwith retention logic to prune old backups automatically - Ship backups to remote or off-site storage so they survive a full server loss
- Add alerting (email or webhook) when new entries land in
error_log.txt
For the full guide with additional tips, visit the original article on Vultr Docs.
