1

I am running a shell script (myscript.sh) using php.

myscript.sh is contains complicated commands, more than 500 commands including loops, creating database, running java jar files, storing some data in CSV files... and many other functions.

Using PHP, I have index.php page that contains a form with some values, when user submit the form it forward the user to display.php page that run the bash script.

index.php page contains a form and a cancel button

<form action="display.php" method="post" id="myForm">
   <label><b>Number of runs: </b></label>
  <select class="form-control" name="runningOcc" id="runningOcc" >
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
   </select>
   <button type="submit" name="submitPara"> Run </button>
</form>
   <button type="button" name="Cancel"> Cancel Running </button>

display.php page running (myscript.sh) using these lines:

    if( isset($_POST["submitPara"]) ){
       $runningOcc=$_POST["runningOcc"];
       $contents = file_get_contents('myscript.sh');
       $contents=str_replace("Occur_Run", $runningOcc, $contents);
       $output = null;
       $return_var = null;
       $contents = escapeshellarg($contents);
       exec("bash -c $contents 2>&1", $output, $return_var);
       print_r($contents);
       echo "<hr>";
       print_r($return_var);
       echo "<hr>";
       print_r($output);
    }

When the user click submit button, the script start execution in the background while the user still see the index page. When commands finish and return results the display page appear.

I want when the user click the cancel button the program stop all running shell commands, how could I do that?

sysSTD
  • 87
  • 6
  • 1
    A user can send one and only one request before a server responds. If you want to enable canceling you need to break your system up into something that can handle a sequence of requests and responses. One option is to send the start command using AJAX, have the server launch the process and immediately return with an ID (such as a PID) that the user can then send in a cancel command later, and otherwise poll the server every X seconds to see if it is done. Another way is to build a queue system. Users submit to the queue, a task runner looks for "jobs", runs them and reports back to the queue. – Chris Haas Jun 24 '22 at 17:09
  • How could I do the AJAX solution? should I send the exec function call inside AJAX function? – sysSTD Jun 24 '22 at 19:13
  • Nope, we're just using AJAX to effectively hijack the normal HTML form processing. So on button click, gather your fields and submit using AJAX. Server-side, ideally you'd create an ID or token, or better yet a [PID](https://stackoverflow.com/a/1471320/231316), to associate with that specific request and return that with the AJAX call. The client will use that to further communicate, either to check the status or to request to kill the process. – Chris Haas Jun 24 '22 at 19:40
  • I did not get that. How we kill bash commands by PID that created by AJAX during processing form fields? – sysSTD Jun 24 '22 at 19:58
  • How to kill is a little more complicated. You might just be able to issue a subsequent `kill` command using `exec` and the PID, but this depends on permissions. You can also find process [manager scripts](https://gist.github.com/keeguon/869846) out there that might work. And lastly, Symfony has a very [well-tested](https://symfony.com/doc/current/components/process.html) that includes a lot of options and scenario. – Chris Haas Jun 24 '22 at 21:30
  • I read about Symfony, but I can not figure out how to pass a `script.sh` file to process class. I need to execute the commands from the script.sh – sysSTD Jun 24 '22 at 22:50

0 Answers0