Linux How To Run Python Script

Linux How To Run Python Script

Reading time1 min
#Linux#Python#Automation#Python3#Cron#Systemd

Mastering Python Script Execution in Linux: From Command Line to Automation

Python’s role on Linux isn’t limited to ad-hoc utilities. Consider: data processing pipelines, alerting agents, automated admin tasks—nearly every serious engineering environment uses Python scripts somewhere.

Below, you’ll find a practical field guide to running, optimizing, and scheduling Python scripts on modern Linux systems. Focus is on Ubuntu 22.04+ and Python 3.9–3.11, but techniques largely apply across distributions.


Immediate Script Execution

If you have hello.py:

print("Hello, Linux user.")

Run it directly:

python3 hello.py

On some distributions, python still points to Python 2.x. Explicitly use python3 (verify with python3 --version). On RHEL/CentOS, you may need to install Python 3 via dnf install python3.

Shebang Method

Add a shebang for direct execution:

#!/usr/bin/env python3
print("Direct execution enabled.")
chmod +x hello.py
./hello.py

Known issue: If your default shell environment is non-standard, the shebang can misbehave (especially with old /usr/bin/python symlinks).


Multiple Python Versions

Mixed environments are common—legacy apps, system scripts, modern user projects. For example:

which python
which python3
python --version
python3 --version

To force a specific interpreter (v3.10):

/usr/bin/python3.10 script.py

Side note: Containers (Docker, Podman) are increasingly used to sidestep on-host version conflicts.


Dependency Isolation with venv

Global pip installs can break system tooling. Use project-specific environments:

python3 -m venv venv-test
source venv-test/bin/activate
pip install requests flask==2.2.5

Inside the venv, which python now points to .../venv-test/bin/python.

Deactivate when done:

deactivate

Trade-off: System-wide security updates don’t trickle into venvs. Manually rebuild environments after major OS upgrades.


Argument Handling

Scripts run non-interactively. Accept parameters, fail fast if incompatible. Example:

#!/usr/bin/env python3
import argparse

parser = argparse.ArgumentParser(description="User greeting script")
parser.add_argument('name', help='Name to greet')
args = parser.parse_args()

print(f"Hello, {args.name}")

Invocation:

./greet.py sysadmin

For complex CLIs: prefer argparse over ad-hoc sys.argv checking—better error messages, simpler testing.


Scheduling Scripts

Cron

Set up a script for routine execution (e.g., backup at 01:30):

crontab -e

Append:

30 1 * * * /usr/bin/python3 /opt/scripts/backup.py >> /var/log/backup.log 2>&1

Gotcha: Cron runs with a limited environment—PATH and virtualenvs may not work as expected. Always specify absolute paths.

systemd Timers

Systemd timers are now preferred on most modern distros due to dependency management, logging, and better lifecycle integration.

Example unit in /etc/systemd/system/disk-report.service:

[Unit]
Description=Generates daily disk usage report

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /opt/scripts/disk_usage.py

Timer in /etc/systemd/system/disk-report.timer:

[Unit]
Description=Runs disk-report.service daily

[Timer]
OnCalendar=*-*-* 04:00:00
Persistent=true

[Install]
WantedBy=timers.target

Commands:

systemctl daemon-reload
systemctl enable --now disk-report.timer

Check logs:

journalctl -u disk-report.service --since "1 hour ago"

Note: Timers persist missed runs across reboot with Persistent=true. Not all distros enable user timers without additional setup.


Logging & Observability

Headless execution means silent failure is a risk.

Integrate Python’s logging:

import logging

logging.basicConfig(
    filename='/var/log/my_script.log',
    level=logging.INFO,
    format='%(asctime)s %(levelname)s %(message)s'
)
logging.info("Script execution started")

Cron output can be mailed to MAILTO=user@example.com in crontab. Systemd uses journalctl—don’t expect print() output to show up in standard user logs.

Example log entry produced:

2024-06-11 05:04:13,502 INFO Script execution started

For custom alerting, integrate with system mail or APIs—never assume log files alone are enough.


Practical Example and Non-Obvious Tip

Sample utility: Check disk usage daily.
/opt/scripts/disk_usage.py:

#!/usr/bin/env python3
import subprocess

def get_usage():
    cp = subprocess.run(['df', '-hT'], capture_output=True, text=True)
    print(cp.stdout)

if __name__ == "__main__":
    get_usage()

Tip: Use -hT in df for human-readable output including filesystem type. Omit /proc and similar with custom filtering if noise becomes a problem.

Make it executable and assign to systemd timer—never miss low disk space again.


Wrap-up

The craft of executing and automating Python scripts on Linux depends on rigor: explicit interpreter selection, correct dependency isolation (venv), robust scheduling (cron or systemd), and disciplined logging.

There’s room for improvement—containerized execution, secrets management, integration with monitoring—but the patterns above form a solid baseline. Critically, adapt details to your distro’s nuances and operational requirements.

Known alternative: For even finer scheduling, third-party tools like at or specialized job runners (Airflow, Jenkins) may be justified in larger deployments.


Questions about specific scheduling edge cases or integrating with orchestration tools? Request deeper coverage as needed.