如何用Python区分脚本是直接以root运行还是通过sudo运行?
Great question! The core issue here is that sudo creates a process with a root effective UID but retains traces of your original user session—traces we can detect in Python to enforce your desired behavior. Let's break down the solution:
Key Differences to Exploit
When running via sudo:
- The real user ID (ruid) remains your regular user's ID (e.g.,
1000), while the effective user ID (euid) is0(root) sudoautomatically sets theSUDO_USERenvironment variable to your original username
In a direct root session:
- Both ruid and euid are
0 - No
SUDO_USERenvironment variable exists
Step-by-Step Solution
We'll combine these checks to cover all edge cases:
1. Check if We're Running as Root (Effective UID)
First, verify we have root privileges at all—this catches regular users trying to run the script directly.
2. Detect Sudo Sessions
Use either the SUDO_USER variable or a mismatch between real and effective UIDs to identify sudo-run processes. Combining both makes the check more robust.
Full Script Implementation
import os import sys def validate_root_session(): # Check if we have root effective privileges if os.geteuid() != 0: print("Kindly refuse this: Please run this script as the root user directly, not as a regular user.") sys.exit(1) # Check for sudo-specific traces is_sudo_session = os.environ.get('SUDO_USER') is not None or os.getuid() != 0 if is_sudo_session: print("Deny this: Please do not run this script with sudo. Log in as root directly instead.") sys.exit(1) # If we reach here, it's a valid direct root session print("Allow this: Running in direct root session, proceeding...") if __name__ == "__main__": validate_root_session() # Your script logic goes here
How It Handles Your Test Cases
[root@hostname ~]# python script.py: Passes all checks (euid=0, ruid=0, noSUDO_USER) → allowed[user@hostname ~]$ sudo python script.py:SUDO_USERexists + ruid != 0 → denied[user@hostname ~]$ sudo -E python script.py:sudo -Epreserves your env but still setsSUDO_USER→ denied[user@hostname ~]$ sudo PATH=$PATH python script.py: Custom PATH doesn't removeSUDO_USER→ denied[user@hostname ~]$ python script.py: euid != 0 → kindly refused
This method works reliably across standard Linux environments, as sudo consistently sets these variables and UID values by default.
内容的提问来源于stack exchange,提问作者user7851115

