Ubuntu下如何检测Python脚本是终端直接运行还是被其他脚本调用
区分Python脚本直接运行与被shell脚本调用的方案
我来帮你解决这个问题——你遇到的核心困扰是两种调用方式下Python脚本的父进程名都是bash,没法直接通过进程名区分,但其实我们可以通过检查父进程的命令行参数或者遍历进程调用链来识别是否是通过script.sh启动的。下面给你两种可行的实现方式:
方案1:使用psutil模块(推荐,更可靠)
psutil是一个强大的跨平台进程管理库,能方便地获取进程及其父进程的详细信息。
步骤1:安装psutil
在Ubuntu上可以通过系统包管理器安装:
sudo apt install python3-psutil
或者用pip安装:
pip install psutil
步骤2:修改testpython.py脚本
#!/usr/bin/env python3 import os import psutil def is_invoked_by_script(): current_proc = psutil.Process(os.getpid()) # 遍历当前进程的所有父进程 for parent_proc in current_proc.parents(): # 将父进程的命令行参数拼接成字符串,检查是否包含script.sh if "script.sh" in " ".join(parent_proc.cmdline()): return True return False if __name__ == "__main__": if is_invoked_by_script(): print("通过script.sh调用,执行操作A") # 这里写入你需要的操作逻辑 else: print("直接从终端运行,执行操作B") # 这里写入你需要的操作逻辑
原理说明
当你直接运行./testpython.py时,进程链是:终端bash → Python脚本,父进程的命令行就是终端bash的启动参数,不会包含script.sh;
当你通过./script.sh运行时,进程链是:终端bash → 执行script.sh的bash子进程 → Python脚本,中间的bash子进程的命令行里会明确包含./script.sh(或完整路径),所以我们能通过这个特征识别出来。
方案2:不使用第三方库(依赖系统ps命令)
如果不想安装额外模块,可以通过调用系统ps命令来获取父进程的命令行信息。
修改testpython.py脚本
#!/usr/bin/env python3 import os def is_invoked_by_script(): pid = os.getpid() # 获取父进程PID ppid = os.getppid() # 通过ps命令获取父进程的命令行 parent_cmd = os.popen(f"ps -o cmd= -p {ppid}").read().strip() # 检查命令行是否包含script.sh return "script.sh" in parent_cmd if __name__ == "__main__": if is_invoked_by_script(): print("通过script.sh调用,执行操作A") else: print("直接从终端运行,执行操作B")
注意事项
这种方法依赖Ubuntu系统的ps命令格式,兼容性不如psutil,但胜在无需额外依赖。如果你的script.sh用绝对路径调用,只要命令行里包含script.sh就能被检测到。
测试验证
- 直接运行脚本:
./testpython.py
输出:直接从终端运行,执行操作B
- 通过shell脚本运行:
./script.sh
输出:通过script.sh调用,执行操作A
内容的提问来源于stack exchange,提问作者Natesh bhat
相关产品推荐
相关产品推荐

