Linux下如何从进程cmdline中提取原始可执行路径及参数?
获取Popen启动进程的原始命令行参数(无需写入文件)
针对你遇到的内核修改进程标题、cmdline()返回动态加载器相关内容的问题,提供两个无需写入文件的可行方案:
方案1:通过进程真实路径匹配定位原始命令
动态加载器(如ld-linux-x86-64.so.2)启动进程时,最终执行的二进制路径会被psutil.Process.exe()准确返回,我们可以利用这个真实路径在cmdline()结果中定位原始命令的起始位置:
import psutil import os def get_original_cmdline(pid): p = psutil.Process(pid) exe_real_path = p.exe() cmdline_list = p.cmdline() # 优先匹配完整路径 try: target_idx = cmdline_list.index(exe_real_path) return cmdline_list[target_idx:] except ValueError: # 路径匹配失败时,尝试匹配二进制文件名 exe_basename = os.path.basename(exe_real_path) for idx, arg in enumerate(cmdline_list): if os.path.basename(arg) == exe_basename: return cmdline_list[idx:] # 所有匹配失败,返回原始cmdline return cmdline_list
这个方法不依赖--分隔符,即使原始参数中包含--也不会出错,同时兼容静态编译二进制的正常场景。
方案2:注入自定义环境变量存储原始命令
启动进程时,将原始命令序列化为JSON并存入自定义环境变量,后续通过读取进程环境变量直接获取:
启动进程时的代码:
import json import os from subprocess import Popen # 原始命令行 original_cmd = ['/path/to/binary', 'arg1', 'arg2', '--with-dash'] # 复制当前环境并注入自定义变量 proc_env = os.environ.copy() # 使用独特的变量名避免冲突 proc_env['MY_APP_ORIGINAL_CMD'] = json.dumps(original_cmd) # 启动进程 p = Popen(original_cmd, env=proc_env, cwd='/your/cwd', start_new_session=True)
获取原始命令的代码:
import psutil import json def get_original_cmdline(pid): p = psutil.Process(pid) proc_env = p.environ() # 优先读取自定义环境变量 if 'MY_APP_ORIGINAL_CMD' in proc_env: try: return json.loads(proc_env['MY_APP_ORIGINAL_CMD']) except json.JSONDecodeError: pass # 环境变量读取失败时,回退到方案1 exe_real_path = p.exe() cmdline_list = p.cmdline() try: target_idx = cmdline_list.index(exe_real_path) return cmdline_list[target_idx:] except ValueError: exe_basename = os.path.basename(exe_real_path) for idx, arg in enumerate(cmdline_list): if os.path.basename(arg) == exe_basename: return cmdline_list[idx:] return cmdline_list
这个方案的可靠性最高,因为原始命令是主动注入的,完全不受进程标题修改的影响,只要进程存活就能读取到。
内容的提问来源于stack exchange,提问作者Slav
相关产品推荐
相关产品推荐

