0

I'm trying to create a PHP wrapper class around the Linux Screen utility. I need to be able to start a screen session by name and get back the PID of the screen that was created.

I cannot assume the session name is unique so it can't parse the session -ls output to find the PID.

Based on examples and suggestions around the internet, I have tried the following approach using PHP's exec() function:

screen -D -m -S 'screen_name' 2>&1 &

The -D parameter tells screen to not fork the process, so it has the same PID as the background process.

So, then I can parse the PID from the output of the & background shell operator which is in this format:

[<number>] <pid>

This command works from the Linux shell (terminates immediately), but when I run it from PHP it freezes and the browser never loads the page.

I have tried executing it with both PHP's exec() and shell_exec() and it's the same result.

I have also tried lots of different combinations with the last part of the command such as the ones described HERE.

Edit:

If I use this command:

screen -D -m -S 'screen_name' 1> /dev/null 2> /dev/null & 2>&1

Then the PHP exec() works. It starts the screen session but then I don't get any output from the & background operator. I'm assuming it's because I'm redirecting the stdout and stderr to /dev/null but as far as I know it should only be doing that for the screen command, not the & operator.

ALMOST SOLUTION:

screen -D -m -S 'screen_name' 1> /dev/null 2> /dev/null & echo $!

I realized that the text showing in the terminal from the & background operator wasn't actually coming from the command stdout or stderr. It's the shell displaying it. So I added echo $! after the & operator which will print the PID of the process created by the last command.

This works in the terminal, it prints the correct PID. But when it's executed in PHP, the actual screen PID value is 4 more than the one returned by the echo. It's like the echo is being executed before the & operator. Is there any way to make it wait?

SOLUTION:

I was wrapping the command in sudo, and the background operator was acting on the sudo command instead of the screen command. Make sure you escape your command arguments! :)

Bradley Odell
  • 1,248
  • 2
  • 15
  • 28
  • of course php will freeze. you did an `exec` call, which blocks until the external app you're running exits. screen never exits/returns,s ince you told it to stay attached/running, so your whole php script freezes waiting for exec() to return, and it'll never return until screen exits/detaches. – Marc B Jul 15 '16 at 21:25
  • That's not what the `-D` parameter means. It tells `screen` to detach an old screen session. – Barmar Jul 15 '16 at 21:28
  • @MarcB But he's running it in the background with `&`, so the shell should exit immediately without waiting for the command to finish. – Barmar Jul 15 '16 at 21:29
  • @Barmar: good point. glad it's friday... I need a nap. maybe something wonky with how screen interacts with the terminal? – Marc B Jul 15 '16 at 21:31
  • @Barmar According to https://www.gnu.org/software/screen/manual/screen.html, when the -D option is paired with the -m option, then a new screen session is started in detached mode without forking the process. – Bradley Odell Jul 15 '16 at 22:05

1 Answers1

0

ALMOST SOLUTION:

screen -D -m -S 'screen_name' 1> /dev/null 2> /dev/null & echo $!

I realized that the text showing in the terminal from the & background operator wasn't actually coming from the command stdout or stderr. It's the shell displaying it. So I added echo $! after the & operator which will print the PID of the process created by the last command.

This works in the terminal, it prints the correct PID. But when it's executed in PHP, the actual screen PID value is 4 more than the one returned by the echo. It's like the echo is being executed before the & operator. Is there any way to make it wait?

SOLUTION:

I was wrapping the command in sudo, and the background operator was acting on the sudo command instead of the screen command. Make sure you escape your command arguments! :)

– Bradley Odell

Armali
  • 18,255
  • 14
  • 57
  • 171