使用shell_exec通过PID获取python脚本文件名 问题

使用shell_exec通过PID获取python脚本文件名 问题,python,php,linux,Python,Php,Linux,我使用PHP与许多Python服务交互 这是PHP使用bash启动进程并获取PID的方式: $created_pid= shell_exec("nohup python3.8 -u $python_filename >> $log_filename & echo $!"); echo json_encode([ "resolved"=>true, "pid"=>trim($created_pid) ]); 这完美地记录了启动的PID。但是,我还想

我使用PHP与许多Python服务交互

这是PHP使用bash启动进程并获取PID的方式:

$created_pid= shell_exec("nohup python3.8 -u $python_filename >> $log_filename & echo $!");
echo json_encode([
    "resolved"=>true,
    "pid"=>trim($created_pid)
]);
这完美地记录了启动的PID。但是,我还想编写一个函数来检查PID是否仍然处于活动状态,以及它是否与$python_filename中包含的正确脚本相关联

我试过的 因此,让我们假设$python_filename=test.py和$created_pid=29780

我已尝试使用此命令根据PID检索流程信息:

$ ps -p 29780
哪些产出:

29780 pts/0    00:00:00 python3.8
是的,它告诉我这是一个python3.8过程,我很高兴但不满意。我需要知道它是否是test.py脚本

另一方面,如果我执行:

$ ps -ef | grep "python"
其输出的内容太难解析:


这基本上接近于我所期望的解决方案。我想要的只是最后一个bash命令的一个更清晰的输出,它只包含test.py。

一个快速而肮脏的解决方案是只提取命令字符串中的最后一个字段,因为我们知道文件名位于该位置:

$ python test.py &
[1] 8040
$ ps -p 8040 --no-headers -o cmd | awk '{ print $NF }'
test.py
$
我们告诉ps只打印进程的命令字符串,而不打印列标题ps-p8040-no headers-o cmd,我们告诉awk只提取输入行awk{print$NF}的最后一个空格分隔字段$NF是awk中的一个自动变量,它保存当前记录中的字段数

如果文件名包含空格,则此操作将失败,因为默认情况下awk将空格解释为字段分隔符:

$ mv test.py test\ with\ spaces.py
$ python test\ with\ spaces.py &
[1] 9033
$ ps -p 9033 --no-headers -o cmd | awk '{ print $NF }'
spaces.py
$
正如我所说,这是一个快速而肮脏的解决方案,与我在评论中的第一次尝试相比略有改进

编辑 经过一些思考,我可能已经找到了一个更好的解决方案,它更具体地针对仍在运行的检查,而不是从命令中提取脚本文件名

由于您知道并存储了PID->filename关联,您可以在命令字符串中grep文件名,只需检查grep的退出代码:0 match,running;1没有比赛,没有跑步

ps -p 11873 -o cmd | grep -q 'test with spaces.py'
e、 g


kill-0检查进程是否处于活动状态。@jordann但它不会告诉我它是在该进程下运行的test.py python文件名,还是另一个脚本:与达到另一个进程当前正在重用pid的竞争条件相比,您可能更有机会赢得彩票。在再次重用该PID之前,大约需要执行65k个其他进程。@jordanm在我的基础结构中,我将py脚本文件名和相对PID存储在数据库中,以便以后检查该服务。这个过程是在nohup上的&因此它很可能会留在后台,而不会更改PID。解析输出并不难,您只需要最后一个字段。尝试ps-p5771-f | awk'NR==2{print$NF},其中5771是您的解决方案!上一个解决方案做得更好!你知道巴什。
ps -p 11873 -o cmd | grep -q 'test with spaces.py'
$ python test\ with\ spaces.py &
[4] 11873
$ ps -p 11873 -o cmd | grep -q 'test with spaces.py' && echo running || echo not running
running
$ ps -p 999 -o cmd | grep -q 'test with spaces.py' && echo running || echo not running
not running
$