How to Create a Bash Script That Only Executes from Cron
Bash scripts are a powerful way to automate tasks on Linux systems. However, in some cases, you may want a script to only execute under…
Bash scripts are a powerful way to automate tasks on Linux systems. However, in some cases, you may want a script to only execute under specific circumstances — such as when it’s run by the cron scheduler and not manually. This can be useful for sensitive scripts where manual execution could cause issues or for scripts designed specifically for automated environments.
In this article, we’ll walk through the steps to create a Bash script that only executes when run from cron or when a specific parameter, like --force, is provided manually.
Table of Contents
- Understanding the Requirements
- Creating the Script
- Adding the Script to Cron
- Testing the Script
- Summary
1. Understanding the Requirements
Our goal is to create a script that:
- Runs only from
cronby default. - Allows manual execution only if a specific parameter (e.g.,
--force) is provided. - Rejects manual execution without
--force, providing a message that explains the restriction.
We’ll accomplish this by:
- Checking for a non-interactive environment, which indicates that the script is being executed by
cron. - Adding a parameter check to allow manual execution with a specific flag.
2. Creating the Script
Start by creating a new Bash script file. For this example, let’s call it cron_protected_script.sh. Open the file with a text editor and add the following code:
#!/bin/bash
# Check for the --force parameter
FORCE=false
if [ "$1" == "--force" ]; then
FORCE=true
fi
# Function to check if the script is running from cron
is_running_from_cron() {
[ -z "$PS1" ] && [ -z "$(tty)" ]
}
# Main execution condition
if $FORCE || is_running_from_cron; then
echo "Script is running..."
# Place your main script code here
else
echo "This script can only be run from cron or with the --force parameter."
exit 1
fiCode Explanation
- Parameter Check (
--force): The script checks if--forceis passed as the first argument when executed. If--forceis present, it sets theFORCEvariable totrue. - Function to Detect
cron: Theis_running_from_cronfunction checks forcron-specific conditions. In acronjob, the$PS1variable (which defines the shell prompt) is typically absent, andtty(which identifies the terminal) is empty, as there’s no interactive terminal. Thus, the function will return true only if the script is run in a non-interactive environment likecron. - Main Execution Condition: The script will run if either the
--forceparameter is provided or the script is running fromcron. Otherwise, it prints a message and exits.
3. Adding the Script to Cron
To schedule the script with cron, follow these steps:
- Make the Script Executable: First, save the file and give it executable permissions:
chmod +x /path/to/cron_protected_script.sh2. Edit the Crontab: Open the cron table (crontab) for editing:
crontab -e3. Add a Cron Entry: Schedule the script by adding a line to the crontab. For example, to run the script daily at midnight:
0 0 * * * /path/to/cron_protected_script.sh4. Testing the Script
After setting up the script, it’s essential to test both the cron execution and manual execution scenarios.
- Manual Execution without
--force: Try running the script without any parameters:
/path/to/cron_protected_script.shYou should see the following output:
This script can only be run from cron or with the --force parameter.2. Manual Execution with --force: Now, try running the script with the --force parameter:
/path/to/cron_protected_script.sh --forceThis time, the script should execute normally and display the message:
Script is running...Automated Execution via Cron: Wait for the scheduled time or manually trigger the cron job to verify that the script runs successfully in the cron environment. You can check the system logs (often located in /var/log/syslog on Linux systems) for confirmation that the cron job ran as expected.
5. Summary
In this article, we created a Bash script that only runs when executed by cron or with a specific parameter (--force). This setup provides a layer of protection, ensuring that sensitive or automated scripts are not accidentally triggered in an unintended environment.
Key Points:
- Parameter Check: Allows manual execution only with
--force. - Environment Check: Ensures the script runs in a non-interactive environment, typical of
cronjobs. - Cron Scheduling: Automates script execution using
cron, while protecting against accidental manual runs.
This technique is valuable for scripts that should be tightly controlled and run only under specific conditions. By combining parameter checks and environment validation, you can create secure, automated workflows tailored to your needs.
6. Bonus
tty
The `tty` (short for “teletype”) variable in Unix-like systems refers to the terminal associated with a process. When you run the `tty` command in a terminal, it outputs the file path of the terminal device (like `/dev/tty1`), showing that the session has an interactive terminal.
In scripts, checking `tty` is a way to determine if a script has been started in an interactive session or by an automated process like `cron`. Since `cron` jobs run without an attached terminal, `tty` will return an empty result when the script is run by `cron`, making it useful for detecting non-interactive environments.
$PS1
The `$PS1` variable in Unix-like systems defines the primary prompt string in an interactive shell. It controls what you see as the command prompt (e.g., `user@host:~$`).
When `$PS1` is set, it typically indicates that the shell is interactive (like a terminal session). In automated or non-interactive environments, such as scripts run by `cron`, `$PS1` is usually not set. This makes checking `$PS1` useful for distinguishing between interactive and non-interactive environments in scripts.