简体   繁体   中英

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 (ie, 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?

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

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.

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

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

Try putting your shell execution in a screen session with typescript, ie

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM