Python ships with most Linux servers by default. But there is a meaningful gap between "run a script manually once" and "run it correctly in the right environment with the right dependencies." Here is every method, in order of complexity.
Check Whether Python Is Installed
Before running anything — confirm the interpreter is present:
python3 --version
On modern distributions, Python 3 is available as python3. The python command without a version number may point to Python 2 (no longer supported) or may not exist at all.
which python3
Shows the path to the executable — /usr/bin/python3 on most systems.
If Python is not installed:
sudo apt install python3 # Debian/Ubuntu
sudo dnf install python3 # Fedora/RHEL
sudo pacman -S python # Arch Linux
Method 1: Pass the Script to the Interpreter
The most straightforward approach:
python3 myscript.py
With a full path to the script:
python3 /home/user/scripts/myscript.py
Or navigate to the directory first:
cd /home/user/scripts
python3 myscript.py
Passing arguments to the script — add them after the filename:
python3 myscript.py arg1 arg2
Inside the script they are available through sys.argv:
import sys
print(sys.argv) # ['myscript.py', 'arg1', 'arg2']
Method 2: Shebang — Running Without python3 in Front
A shebang (#!) is the first line of the script that tells the system which interpreter to use. After adding it, the script can be called directly without specifying python3 each time.
Add this as the very first line of the script:
#!/usr/bin/env python3
/usr/bin/env python3 is preferable to a hardcoded path like /usr/bin/python3 — env finds the interpreter via PATH, making the script portable across different systems.
Then make the file executable:
chmod +x myscript.py
Now it can be run like this:
./myscript.py
Or by absolute path:
/home/user/scripts/myscript.py
Method 3: Run From Anywhere via PATH
When a script is needed globally — like a system command — place it in a directory listed in PATH:
sudo cp myscript.py /usr/local/bin/myscript
sudo chmod +x /usr/local/bin/myscript
The .py extension is dropped — cleaner as a command name. A shebang inside the script is required. After this, the script runs simply as:
myscript
Check that the directory is in PATH:
echo $PATH
/usr/local/bin is there by default on most systems.
Virtual Environments: Running With Isolated Dependencies
In real server setups, scripts rarely work without dependencies. Installing packages globally with pip is bad practice — different projects may require incompatible versions. Virtual environments solve this.
Create an environment:
python3 -m venv /opt/myapp/venv
Activate it:
source /opt/myapp/venv/bin/activate
After activation, python and pip point to the versions inside the environment:
pip install requests pandas
python myscript.py
Deactivate:
deactivate
Running Without Activating the Environment
For scripts, cron jobs, and systemd services it is more reliable to call the interpreter directly from inside the environment — without activating it:
/opt/myapp/venv/bin/python3 myscript.py
This approach is more robust in automation because it does not depend on activation state in the current session.
Interactive Mode
The -i flag runs the script and then drops into the Python REPL after it finishes. Useful for debugging — variables from the script remain accessible:
python3 -i myscript.py
After the script completes, the >>> prompt appears with all script variables still in scope.
Running in the Background
To keep a script running after the terminal is closed:
nohup python3 myscript.py &
nohup protects the process from the HUP signal when the session ends. & sends it to the background. Output goes to nohup.out by default.
With output redirected to a specific log:
nohup python3 myscript.py >> /var/log/myscript.log 2>&1 &
Find the PID of the running script:
pgrep -f myscript.py
Stop it:
pkill -f myscript.py
Scheduled Runs With cron
For scripts that need to run on a schedule:
crontab -e
Example entries:
# Every 5 minutes
*/5 * * * * /opt/myapp/venv/bin/python3 /opt/myapp/myscript.py
# Every day at 03:00
0 3 * * * /opt/myapp/venv/bin/python3 /opt/myapp/backup.py >> /var/log/backup.log 2>&1
# Every Sunday at 01:00
0 1 * * 0 /usr/bin/python3 /opt/scripts/cleanup.py
cron has no user environment — PATH and variables differ from a normal session. Always use full paths to both the interpreter and the script.
Running as a systemd Service
For long-running scripts or daemons, systemd is the correct tool — more reliable than nohup.
Create a unit file:
sudo nano /etc/systemd/system/myscript.service
Contents:
[Unit]
Description=My Python Script
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/venv/bin/python3 /opt/myapp/myscript.py
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable myscript.service
sudo systemctl start myscript.service
Check status and logs:
sudo systemctl status myscript.service
sudo journalctl -u myscript.service -f
Common Errors
python3: command not found Python is not installed or not in PATH. Install via the package manager.
ModuleNotFoundError: No module named 'requests' The module is not installed in the environment being used. Run pip install requests inside the correct virtual environment — or verify the right interpreter is being called.
Permission denied The script lacks execute permission. Fix: chmod +x myscript.py. Alternatively, call it explicitly via python3 myscript.py — the file itself does not need execute permission in that case.
SyntaxError when using python instead of python3 The script is Python 3 code being run by Python 2. Always use python3.
Script runs manually but does nothing in cron Usually a PATH or working directory issue. Add to the top of the crontab: SHELL=/bin/bash and PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin. Or use absolute paths for everything.
Quick Reference
| Task | Command |
|---|---|
| Run a script | python3 script.py |
| Run with arguments | python3 script.py arg1 arg2 |
| Make executable | chmod +x script.py + shebang #!/usr/bin/env python3 |
| Run as executable | ./script.py |
| Run in background | nohup python3 script.py >> app.log 2>&1 & |
| Run inside venv | /path/to/venv/bin/python3 script.py |
| Interactive mode after run | python3 -i script.py |
| Find PID | pgrep -f script.py |
| Stop the process | pkill -f script.py |
Summary
For one-off tasks — python3 script.py. For scripts with dependencies — a virtual environment with the interpreter called by full path. For scheduled automation — cron with absolute paths. For persistent processes — a systemd service.
All of this works the same on any Linux VPS. To find a server for a Python project, the PQ.Hosting catalog has options across a wide range of configurations.