How To Run Python Script In Linux

How To Run Python Script In Linux

Reading time1 min
#Python#Linux#Automation#PythonScripts#LinuxAutomation#Systemd

Mastering Python Script Execution on Linux: Practical Methods for Automation

There’s more to running Python scripts on Linux than python3 script.py. Achieving predictable, maintainable automation—especially on production hosts—requires a disciplined approach: managed environments, precise permissions, robust scheduling, and service-level reliability.


Environment Isolation: Avoiding “Works on My Machine” Traps

Deploying Python 3.10 code on a fleet with mixed distributions (Ubuntu 22.04, CentOS 8) commonly surfaces dependency chaos. Direct use of system Python (/usr/bin/python3) means exposure to distro package updates and global pip installs.

Solution: Always encapsulate dependencies using venv:

python3.10 -m venv /opt/scripts/venv-myscript
source /opt/scripts/venv-myscript/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

Non-obvious tip: In some corporate environments, $HOME directories may be mounted with noexec. Use /opt or another exec-enabled mount for venvs.

Shebang best practice: Set your shebang to pick up the venv interpreter.

#!/usr/bin/env python3

But if you use compiled C extensions (e.g. via numpy/pandas), specify absolute path to the venv python to avoid environment bleed:

#!/opt/scripts/venv-myscript/bin/python

Permissions: File Ownership and Execution

Scripts must be executable, but avoid chmod 777. Assign correct group and limit write access.

chown root:automation my_script.py   # Ownership
chmod 750 my_script.py               # Execute for owner/group only
ls -l my_script.py

Known issue: Scripts run by cron as nobody or restricted users can silently error if they lack read/execute rights on the venv or script. Double-check with:

sudo -u nobody /opt/scripts/venv-myscript/bin/python my_script.py

Background Execution: Keeping Jobs Alive

Critical for data pipelines and ETL jobs—if your SSH session dies, don’t lose your script’s state:

MethodProsConsNotes
nohupLightweight, simpleHard to reattachDrops SIGHUP. Output to log.
screen/tmuxHot attach/detachExtra installCan recover terminal at will.
systemdManaged restartsMore setupBest for real daemons.

Basic nohup example:

nohup /opt/scripts/venv-myscript/bin/python my_script.py >> /var/log/myscript.log 2>&1 &

Screen for debugging:

screen -S myscript
cd /opt/scripts
source venv-myscript/bin/activate
python my_script.py

Detach: Ctrl-A D.
Reattach: screen -r myscript


Scheduling: Cron Reminders and Gotchas

Crontab is not your shell:
Don’t assume PATH, PYTHONPATH, or environment variables are available. Absolute everything.

Typical robust cron entry:

0,30 * * * * /opt/scripts/venv-myscript/bin/python /opt/scripts/my_script.py >> /var/log/myscript.log 2>&1
  • If your script expects environment variables (e.g., API_KEYS), source them in a wrapper:
#!/bin/bash
source /opt/scripts/venv-myscript/bin/activate
export API_KEY="xxx"
exec python /opt/scripts/my_script.py "$@"

Gotcha: Crontab logs errors to local mail by default, which often nobody reads. Redirect output to log files you’ll actually check.


Service Approach: systemd Unit for Resilience

Mission-critical tasks—scraping, continuous ingest, multi-hour runs—shouldn’t depend on users or cron. Use a systemd unit:

/etc/systemd/system/my_script.service

[Unit]
Description=Reliable Python Worker
After=network-online.target

[Service]
Type=simple
User=svc-python
WorkingDirectory=/opt/scripts
ExecStart=/opt/scripts/venv-myscript/bin/python my_script.py
Restart=on-failure
RestartSec=3
StandardOutput=append:/var/log/myscript.log
StandardError=append:/var/log/myscript.err

[Install]
WantedBy=multi-user.target

Reload and enable:

sudo systemctl daemon-reload
sudo systemctl enable --now my_script.service

Check logs:

journalctl -u my_script.service -f

Side note: When scripts write to files, confirm the User= specified matches file system permissions to avoid silent write failures.


Summary Table: Production-Ready Script Execution

AspectRecommendationReal-world Caveat
DependenciesUse venv, never system pythonDon’t trust pip freeze alone
EntrypointShebang with env or direct to venv pythonAbsolute path for C-extension
PermissionsRestrict with user/group, no “world write”Cron/external users may fail
Background runPrefer systemd, then screen/tmuxnohup drops output on script err
Schedulingcron with wrapper script, log all outputMissing environment is common
Daemon/servicesystemd with restart/restartsec, log filesRootless services are preferred

Advanced workflow:
For clustered jobs, combine systemd with a process supervisor (e.g., supervisord) when you need multiple, interdependent Python services.

Not perfect: systemd’s basic logging isn’t structured—consider stderr JSON output piped to journald for log aggregation.


Practical mastery is less about memorizing commands and more about assembling predictable, debuggable workflows. If your automation fails at 2am, you want every log, PID, and environment unfuzzed and reviewable.

For scenarios involving complex environment set-up, containerization with Docker or scheduling with Celery offers added reliability and scaling. This article intentionally omits those for direct host automation—another potential topic.