1

First of all, I would like to point out that this is NOT a duplicate to this or this and other related questions. I am asking how to get the output as well and my question is mostly related to that.

I need to run a bash script from PHP and get its output in PHP. However, doing:

echo shell_exec('script');

dies out on the 60th second due to Apache's FcgidIOTimeout. If I use the following to run it in the background, I won't be able to get the output:

shell_exec('<myscript> > /dev/null 2>/dev/null &');

I cannot:

  • Modify the bash script;
  • The code and all the functionality needs to be in a single file (unless I use a temp file);
  • If I were to write the output of the shell_exec() function to a temp file, I would also need to find a way to verify whether the process has finished;
  • Using a database is an overkill which I cannot afford;

My current and only idea is to create a tmp file using PHP and write the output to it, then using top -c | grep <myscript> (with a refresh button) and if it returns true then it is still ongoing. However, I suspect that would not be practical and efficient in most of the time.

It is important that I use a temp file and not actually creating a "permanent" file to write to.

Community
  • 1
  • 1
McJohnson
  • 193
  • 8
  • instead of `top -c | grep` could you use `pgrep`? You still have the same problem but [this question](http://stackoverflow.com/questions/3111406/checking-if-process-still-running) shows how to check if the process is still running from php – Eric Renouf Aug 07 '16 at 12:22
  • Is it 'safe' to use? Under 'safe' I mean whether it is reliable all the time. – McJohnson Aug 07 '16 at 12:33
  • `pgrep` is reliable for finding processes with the right name (more so than `top` + `grep` I'd wager), but whether it's your same instance of the script, it probably is if it has the same name and PID, but there's always a chance you could get unlucky. – Eric Renouf Aug 07 '16 at 12:36
  • I -should- be running only one instance at a time. More than that is highly unlikely in my scenario. Thank you for the heads-up, will try it later and let you know if it works. – McJohnson Aug 07 '16 at 12:41

1 Answers1

3
  • Solution for a similar problem: A few years ago I had a similar problem. I had to upload a file to a FTP server. I wondered how to communicate to the FTP server that the file was uploaded completely, so that the FTP server can perform some tasks on it. My solution was to rename the file to something like *.completed after it was uploaded completely. Then the process on the FTP server could look for *.completed files only.

  • Solution adjusted to your problem: I'd suggest you to rename your temp file after it was generated by your bash script. This way you can independently find out if the script was executed successfully. shell_exec() could look like this:

    shell_exec('<myscript> > tmp-file && mv tmp-file tmp-file.completed &');
    

    Be aware that this only redirects the channel STDOUT into the the tmp-file. If you also want to redirect STDERR into the tmp-file, try this:

    shell_exec('<myscript> &> tmp-file && mv tmp-file tmp-file.completed &');
    
delx
  • 374
  • 1
  • 7
  • That is a good idea. Thank you for taking some of your time to write it down for me. I will try it in a bit and accept the answer if it works out as expected. – McJohnson Aug 07 '16 at 12:40