我需要通过PHP脚本启动三个进程。这些进程位于/home/user/server
目录中,名为server-one
,server-two
和server-three
。该过程还能够通过其控制台接受命令,因此我需要它们以自己的名字存在于自己的屏幕中,以便我可以使用-X stuff
为它们提供命令。同样,每个进程通过其控制台上的stdout提供状态信息和调试信息,因此我想记录输出以显示以防我需要检查进程以及通过我的控制台进行的上一次调试
因此,换句话说,我需要在命名屏幕中启动一个进程,将stdout控制台信息日志输出到一个文件,并且能够在需要时将命令直接发送到屏幕。
我在下面的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));
?>
屏幕都已正确创建,但服务器未启动。作为调试测试,我更改了所有exec命令,以回显sprintf传递给exec的内容,这绝对是正确的。作为测试,我在SSH中运行命令并且它们正确执行并具有所需的效果,因此实际命令中的任何内容都不会导致出现问题。
在创建日志文件时,对可执行文件和日志的所有权限都是正确的,但日志文件没有填充任何内容,它是空的。我无法直接访问屏幕,因为运行php的用户是www-data,您无法通过SSH登录www-data。如果我在没有屏幕的情况下通过Web浏览器运行服务器并将进程放到后台,它可以正常工作,所以也不是那里的权限问题,但是我需要这些进程在屏幕上,以便我可以稍后通过它来操作它们他们的游戏机。
我在这里遗漏了什么吗?
答案 0 :(得分:2)
我已经解决了这个问题,方法是删除命令周围的$''
以发送到屏幕,而是使用\"\"
并将\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));
它现在有效。