Skip to content
Advertisement

php using exec with screen

I have a need to start three processes through my PHP script. Those processes live in the /home/user/server directory, named server-one, server-two and server-three. The process are also capable of accepting commands through their consoles, so I would need them to live in their own screen with a name so I can use -X stuff to give them commands. As well, each of the processes gives status information and debug information through stdout on their consoles, so I want to log the output to display in case I ever need to check up on the process and what the last debug was through my console

So, in other words, I need to start a process in a named screen, output the stdout console information log to a file, as well as have the ability to send commands directly to the screen if I need.

I have the PHP all below, in one file:

 <?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 %sn'", $serverPath));
 exec(sprintf("screen -S server-one -X stuff $'./%s > %sn'", $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 %sn'", $serverPath));
 exec(sprintf("screen -S server-two -X stuff $'./%s > %sn'", $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 %sn'", $serverPath));
 exec(sprintf("screen -S server-three -X stuff $'./%s > %sn'", $serverThreeExec, $threeOut));
 ?>

The screens are all created correctly, but the servers are not started. As a debug test I changed all the exec commands to echo what the sprintf is passing to exec and it is definitely correct. As a test I ran the commands in SSH and they executed properly and had the desired effect, so it’s not anything in the actual command as outputted that’s causing trouble.

All the permissions to the executables and logs are correct as the log files are created, but the log file is not filled with anything, it’s empty. I can’t access the screens directly as the user where php is running is www-data and you can’t login to www-data through SSH. If I run the server through the web browser without screen and just throw the process into the background, it works correctly, so not a permission issue there, either, but I need those processes to be in a screen so I can manipulate them later through their consoles.

Am I missing anything here?

Advertisement

Answer

I’ve solved this by removing the $'' around the command to send to the screen and instead used "" with the n surrounded in ticks.

So, for example, changed:

 exec(sprintf("screen -S server-three -X stuff $'./%s > %sn'", $serverThreeExec, $threeOut));

…to….

 exec(sprintf("screen -S server-three -X stuff "./%s > %s"'n'", $serverThreeExec, $threeOut));

And it now works.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement