我试图围绕Linux屏幕实用程序创建一个PHP包装类。 我需要能够按名称启动屏幕会话并获取创建的屏幕的PID。创建Linux屏幕会话,并得到它的PID
我不能假设会话名称是唯一的所以它不能解析session -ls
输出找到PID。
基于互联网附近的实例和建议,我一直在使用PHP的exec()功能尝试以下方法:
screen -D -m -S 'screen_name' 2>&1 &
的-D
参数告诉屏无法派生进程,因此它具有相同的PID为后台进程。
所以,那么我可以从&
背景壳操作者这是在这个格式的输出解析PID:
在Linux shell本命令(立即终止),但是当我运行它从PHP中冻结并且浏览器从不加载页面。
我试着用PHP的exec()和shell_exec()来执行它,它的结果是一样的。
我也尝试了许多不同的命令的最后部分,如HERE描述的组合。
编辑:
如果我使用这个命令:
screen -D -m -S 'screen_name' 1> /dev/null 2> /dev/null & 2>&1
然后PHP exec()
作品。它开始屏幕会话,但是我没有从&
背景算子得到任何输出。我假设这是因为我将stdout
和stderr
重定向到/dev/null
,但据我所知,它应该只对屏幕命令执行此操作,而不是&
操作员。
概SOLUTION:
screen -D -m -S 'screen_name' 1> /dev/null 2> /dev/null & echo $!
我意识到,在从&
背景操作者的终端显示文本实际上并没有从命令stdout或stderr到来。它是显示它的壳。所以我在&
运算符之后加上echo $!
,它将打印最后一个命令创建的进程的PID。
这在终端工作,它打印正确的PID。但是当它在PHP中执行时,实际的屏幕PID值比echo
返回的值多4。 这就像在&
运算符之前正在执行回声。有什么办法让它等待?
SOLUTION:
我在须藤包装命令,背景运算符作用于sudo命令而不是屏幕命令。确保你逃脱你的命令参数! :)
当然PHP将冻结。你做了一个'exec'调用,这个调用会阻止你运行的外部应用程序退出。屏幕从不退出/返回,因为你告诉它保持连接/运行,所以你的整个PHP脚本冻结等待exec()返回,并且它永远不会返回,直到屏幕退出/分离。 –
这不是'-D'参数的含义。它告诉'screen'分离一个旧的屏幕会话。 – Barmar
@MarcB但是他用'&'在后台运行它,所以shell应该立即退出而不等待命令完成。 – Barmar