我需要通过我的 PHP 脚本启动三个进程。这些进程位于 /home/user/server
目录中,名为 server-one
、server-two
和 server-three
。该进程还能够通过他们的控制台接受命令,所以我需要他们在他们自己的 screen 上使用一个名字,这样我就可以使用 -X stuff
给他们命令。同样,每个进程都通过其控制台上的 stdout 提供状态信息和调试信息,因此我想记录要显示的输出,以防我需要检查进程以及最后一次调试是通过我的控制台进行的
因此,换句话说,我需要在命名 screen 中启动一个进程,将 stdout 控制台信息日志输出到一个文件,并且能够在需要时直接向 screen 发送命令。
我将以下所有 PHP 都放在一个文件中:
<?php
exec('screen -dmS server-one');
$serverPath = "/home/user/server";
$oneOut = "/var/www/log/server-one.log";
$serverOneExec = "server-one";
exec(sprintf("screen -S server-one -X stuff $'cd %s\n'", $serverPath));
exec(sprintf("screen -S server-one -X stuff $'./%s > %s\n'", $serverOneExec, $oneOut));
$screentwo = "screen -dmS server-two";
exec($screentwo);
$twoOut = "/var/www/log/server-two.log";
$serverTwoExec = "server-two";
exec(sprintf("screen -S server-two -X stuff $'cd %s\n'", $serverPath));
exec(sprintf("screen -S server-two -X stuff $'./%s > %s\n'", $serverTwoExec, $twoOut));
$screenthree = "screen -dmS server-three";
exec($screenthree);
$threeOut = "/var/www/log/server-three.log";
$serverThreeExec = "server-three";
exec(sprintf("screen -S server-three -X stuff $'cd %s\n'", $serverPath));
exec(sprintf("screen -S server-three -X stuff $'./%s > %s\n'", $serverThreeExec, $threeOut));
?>
screen 都创建正确,但服务器没有启动。作为调试测试,我更改了所有 exec 命令以回显 sprintf 传递给 exec 的内容,这绝对是正确的。作为测试,我在 SSH 中运行命令,它们正确执行并产生了预期的效果,因此输出的实际命令中没有任何内容导致问题。
创建日志文件时,对可执行文件和日志的所有权限都是正确的,但日志文件没有填充任何内容,它是空的。我无法直接访问 screen ,因为运行 php 的用户是 www-data 并且您无法通过 SSH 登录到 www-data。如果我在没有 screen 的情况下通过 Web 浏览器运行服务器并将进程置于后台,它可以正常工作,所以那里也不是权限问题,但我需要这些进程在 screen 中,以便稍后可以通过他们的游戏机。
我在这里遗漏了什么吗?
最佳答案
我已经通过删除发送到 screen 的命令周围的 $''
来解决这个问题,而是使用 \"\"
和 \n
被刻度包围。
因此,例如,更改:
exec(sprintf("screen -S server-three -X stuff $'./%s > %s\n'", $serverThreeExec, $threeOut));
……到……
exec(sprintf("screen -S server-three -X stuff \"./%s > %s\"'\n'", $serverThreeExec, $threeOut));
现在可以了。
关于php 在 screen 上使用 exec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29302071/