php 对屏幕使用 exec
php using exec with screen
我需要通过 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 是 运行ning 的用户是 www-data 并且您无法通过 SSH 登录到 www-data。如果我 运行 服务器通过没有屏幕的网络浏览器并将进程放入后台,它工作正常,所以那里也不是权限问题,但我需要这些进程在屏幕中所以我可以稍后通过他们的控制台操纵他们。
我在这里遗漏了什么吗?
我已经通过删除要发送到屏幕的命令周围的 $''
来解决这个问题,而是使用 \"\"
和用刻度包围的 \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 脚本启动三个进程。这些进程位于 /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 是 运行ning 的用户是 www-data 并且您无法通过 SSH 登录到 www-data。如果我 运行 服务器通过没有屏幕的网络浏览器并将进程放入后台,它工作正常,所以那里也不是权限问题,但我需要这些进程在屏幕中所以我可以稍后通过他们的控制台操纵他们。
我在这里遗漏了什么吗?
我已经通过删除要发送到屏幕的命令周围的 $''
来解决这个问题,而是使用 \"\"
和用刻度包围的 \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));
现在可以使用了。