subprocess.run执行nohup ./nps &这样的后台命令
然后,nohup的作用是忽略SIGHUP信号,让进程在终端关闭后继续运行。而&是将进程放到后台执行。这两个组合起来通常用于启动后台服务。但问题在于,当通过subprocess.run执行时,即使加上&,父进程(也就是Python脚本)可能会等待子进程结束,因为shell可能会立即返回,但实际进程可能还在运行。这时候可能需要处理标准输入输出,因为nohup默认会输出到nohup.out,或者需要重定向。
接下来考虑具体的代码实现。用户可能想用类似subprocess.run(["nohup", "./nps", "&"])的方式,但这样不行,因为&是shell的操作符,不是命令参数。所以必须通过shell=True来执行整个命令字符串。正确的写法应该是subprocess.run("nohup ./nps &", shell=True, check=True)。不过,这里可能需要处理输入输出,比如关闭stdin、stdout、stderr,或者重定向到文件,否则subprocess可能会因为管道问题而挂起。
另外,使用shell=True时,要注意命令注入的风险。如果./nps的路径或参数是用户可控的,可能会有安全问题。但用户这里的情况是固定的命令,所以问题不大,不过还是应该提醒这一点。
还需要注意subprocess.run的选项,比如detach进程。可能需要设置start_new_session参数,类似于nohup的效果,但这里已经用了nohup,所以可能不需要。不过,有时候双重保障可能更好,但需要测试。
还有,当使用shell=True时,子进程的PID可能不是nps的PID,而是shell的PID,所以如果需要获取子进程的PID,可能需要使用其他方法,比如pgrep,但用户的问题可能不需要这个。
总结步骤应该是:使用shell=True执行整个命令字符串,处理输入输出重定向,确保进程正确后台运行,并且Python脚本不会等待。同时,提醒安全注意事项和可能需要的错误处理。在Python中使用subprocess.run
执行nohup ./nps &
这类后台命令时,需注意以下关键点:
1. 直接执行的问题
subprocess.run("nohup ./nps &", shell=True)
- 表面可行但存在隐患:虽然能启动后台进程,但
subprocess.run
默认会等待子进程结束。若nps
进程未完全脱离,可能导致Python脚本阻塞
2. 推荐解决方案
subprocess.run(
"nohup ./nps >/dev/null 2>&1 &",
shell=True,
check=True,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
- 关键参数说明:
>/dev/null 2>&1
:重定向输出,防止nohup生成默认的nohup.out
stdin/stdout/stderr=subprocess.DEVNULL
:关闭文件描述符,避免父进程挂起check=True
:检查命令执行是否成功
3. 更安全的替代方案(推荐)
with open(os.devnull, 'w') as devnull:
subprocess.Popen(
["./nps"],
stdout=devnull,
stderr=devnull,
stdin=devnull,
start_new_session=True # 替代nohup的作用
)
- 优势:
- 避免使用
shell=True
,降低安全风险 start_new_session=True
等效于nohup
的防SIGHUP功能- 更规范的输入输出处理
- 避免使用
4. 注意事项
安全警告:
shell=True
存在命令注入风险,若参数含用户输入内容需严格过滤- 推荐优先使用
Popen
+参数列表方式
环境依赖:
- 确保执行目录正确(可通过
cwd
参数指定工作目录) - 注意环境变量继承问题,必要时使用
env
参数
- 确保执行目录正确(可通过
日志管理:
with open("nps.log", "w") as logfile: subprocess.Popen(... , stdout=logfile, stderr=subprocess.STDOUT)
可自定义日志输出位置
5. 验证进程状态
执行后可通过以下命令验证:
ps aux | grep nps # 查看进程是否存在
lsof -p <PID> # 检查文件描述符是否正常关闭
通过以上方法,即可安全可靠地实现后台进程的启动与管理。
相关推荐


















