Avindra Goolcharan
Avindra Goolcharan

Reputation: 4211

PHP: non blocking shell_exec WITH command output

I'm using php's shell_exec to call bash files, system programs and Ksh files.

One issue with shell_exec is that if you need the output, your web server will lock up (i.e., no new requests will be served) until the process is finished. A common trick is to set the process to run in the background (> /dev/null 2> /dev/null &), but this of course, discards any output.

I tried switching from apache to nginx thinking that this would solve my problem but the underlying issue appears to be how php's shell_exec blocks i/o. Even with nginx, shell_exec completely blocks any new http requests from completing.

Does anyone know how to make system calls using php without locking up the server, while also capturing the output?

I'm thinking of making a library that manages asynchronous system calls whereby the output can be retrieved later using Ajax.

But I'd prefer not to go that route. Any suggestions?

Upvotes: 1

Views: 5333

Answers (5)

Albert S
Albert S

Reputation: 2602

How about running it in the background, but redirecting output to a file?
You could use >> or | tee.

Upvotes: 1

Erki Aring
Erki Aring

Reputation: 2096

If you want your PHP script to continue executing while the external program is running, you can use proc_open().

If you want your PHP script not to block other requests, you have to make sure that your PHP script does not have any locks that will prevent other requests from being served. Most common is session lock, for what you can use session_write_close() as suggested by sectus.

Upvotes: 1

Tanmay Narang
Tanmay Narang

Reputation: 21

Try putting your shell execution in a screen session with typescript, i.e.

shell_exec("screen -dmS scriptname /bin/bash -c /path/to/script | typescript");

Then when you want to read the output:

shell_exec("sed -e 's/$/<br>/' typescript; rm typescript");

Not entirely sure if this is what you wanted but I hope it helps!

EDIT: forgot a / in the sed expression :P

Upvotes: 0

user3632719
user3632719

Reputation: 47

Might be way off here but how about creating a new thread? http://php.net/manual/en/class.thread.php. Not much experience with php and linux but the general solution for an issue like this is multi threading your web application

Upvotes: 0

sectus
sectus

Reputation: 15464

It's common session issue.

By default when session starts php locks session file until session would close. All other requests waits for unlock the session file to continue.

Try to put session_write_close before shell_exec

Upvotes: 2

Related Questions