1

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?

5 Answers 5

2

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

Sign up to request clarification or add additional context in comments.

3 Comments

session_write_close() does the trick. I hope this doesn't get too messy in the future (i.e., closing the session and then trying to update the session).
@AvindraGoolcharan, you could start session again. Also you could change session handler.
Starting the session works perfectly. Just experienced it today.
1

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.

Comments

1

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

1 Comment

Yup, that can work. But for my particular case, my sessions were being blocked because I didn't call session_write_close(). It was unrelated to shell_exec, @sectus just had a lucky guess
0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.