1

I am running a shell script file through PHP. When the user click Run button it start executing the commands using the following lines:

 if( isset($_POST["runBtn"]) ){
      $command = file_get_contents('runScript.sh');
      exec("bash -c $command 2>&1 & echo $!", $output, $return_var);
      $pid = (int)$output[0];
      $_SESSION["PID"] = $pid;
}

These above lines run the script perfect and give me the PID after finishing the process.

However, in the same page I have a cancel button that when user click it, it should stop the exec function execution immediately and kill the bash commands that is running in background.

Here the cancel button:

<button type="button" name="cancelBtn" onclick="button1()">  Cancel Experiment</button>

Here what I am trying to do:

 function button1()
    {
    console.log("I am the cancel button"); //this just for debugging 
     $.ajax({
    type: "POST",
    url: 'myFunctions.php',
    dataType: 'json',
    data: {functionname: 'cancelEx'},
    success: function (obj, textstatus) {
       if( !('error' in obj) ) {
           console.log("I am the cancel success");
           console.log(obj.result);
        }else {
          console.log(obj.error);
       }
   }
});
}

Here is myFunction.php:

<?php
    header('Content-Type: application/json');

    $aResult = array();

    if( !isset($_POST['functionname']) ) { $aResult['error'] = 'No function name!'; }

    if( !isset($aResult['error']) ) {

        switch($_POST['functionname']) {
            
              case 'cancelEx':
                echo "<script> console.log('Test here pid from cnacel button')</script>";

                $command = "ps ax | awk '! /awk/ && /runScript.sh/ { print $1}'";
                $pid = shell_exec($command);
                echo "<script> console.log('Test here pid from cnacel button')</script>";
                echo "<script> console.log(".$pid.")</script>";
                shell_exec("kill -9 $pid");

                
            default:
               $aResult['error'] = 'Not found function '.$_POST['functionname'].'!';
               break;
        }

    }

    echo json_encode($aResult);

?>

The problem is that ajax call not working until the exec function and the bash commands finish execution. How could I make cancel button take effect while the process still running? How could cancel button stop the exec function of runBtn and kill the runScript.sh?

sysSTD
  • 87
  • 6
  • This sounds extremely unwise. PHP is not the correct program to be using if you want to manage core processes on a remote machine; try searching for a remote terminal application? Try VNC connect or Tiger VNC (assuming the server system is linux), otherwise winSCP is decent. – Martin Jun 28 '22 at 14:23
  • yes, I understand. But, I am creating a GUI (web page) that enable anybody to run the commands in background. – sysSTD Jun 28 '22 at 14:27
  • this might help: https://stackoverflow.com/questions/1652680/how-to-get-the-pid-of-a-process-that-is-piped-to-another-process-in-bash – Martin Jun 28 '22 at 14:27
  • I see red flag with the terms "anybody" and "system" and "process". I would recommend fundamentally reassessing why and how you're trying to achieve the server hijacking you're inviting.... – Martin Jun 28 '22 at 14:29
  • Or this might help: https://askubuntu.com/questions/924956/how-to-get-the-pid-of-a-recently-started-process-in-bash – Martin Jun 28 '22 at 14:31
  • not anybody (I am working on interface that run experiments on a dataset, and I want to automate that) so, an user of my group can enter all experiment parameter in a form and click on run the experiment button, that is working perfect. Now, I need to give an option for the user to cancel/kill the process in case he need to change a parameter. – sysSTD Jun 28 '22 at 14:37
  • You used the term "anybody" above. haha. Anyway, I did a web search myself and found multiple various answers to your exact question; about how to retrieve the PID of any process. I'm not clear why you're asking here unless you can explicitly state that you've dug out all of these answers and every answer you've found has been incorrect. Further, this web interface is still not the right tool for the job, and highly prone to accidental or otherwise abuse. I would recommend using an established VNC which are designed explicitly for this sort of thing. – Martin Jun 28 '22 at 14:41
  • Thank you for your solutions, all it give me the PID after the process is finished. The problem is that PHP wait until the exec function finished then call the other command that return the PID. I need to execute two exec function at the same time, how could I do that in PHP? – sysSTD Jun 28 '22 at 14:42
  • [This answer](https://stackoverflow.com/questions/46052139/how-to-execute-two-cmd-queries-in-php-simultaneously) took me 9 seconds to find. – Martin Jun 28 '22 at 14:44
  • Yes, I looked on many solutions all give the PID after finishing the process. I need to get the PID while the process is still running so I can kill it. – sysSTD Jun 28 '22 at 14:44
  • I think you did not understand my question correctly. I have struggled with this issue for a week now. I looked on 100 solutions out there before I asked my question and the last solutions is talking about executing a command2 if only if the command1 is succeeded. My question is executing two command at the same time using PHP. – sysSTD Jun 28 '22 at 14:49
  • Please can you edit your question to state exactly what you're trying to do, what you've researched so far, why it's failed and what you'd like to achieve. I can only know as much as your question tells me, and your question starts by asking for a current PID of a running process ( which is easy to find) and now you state you want to run two simultaneous processes via PHP. Please edit and clarify your questioon for us. Thank you `:-)` – Martin Jun 28 '22 at 14:51
  • I have edited the question and include more details about it. Thank you. – sysSTD Jun 28 '22 at 15:26
  • Thank you. Ok, try [this website](https://linuxconfig.org/how-to-kill-a-running-process-on-linux) to list all current processes (using grep to find the ones that fit your `$command` ) and then you can load this list into the PHP `$return_var` and retrieve the PID before then next running the `pkill` command on that retrieved PID – Martin Jun 28 '22 at 15:36
  • In order to kill a running process on Linux distro's you need to either identify the process or kill all processes that fit a certain criteria. Is the `$command` going to be the ONLY command with that name that is running on the system? – Martin Jun 28 '22 at 15:40
  • 1
    Thank you for your help with your help I found an answer and I posted it. – sysSTD Jun 28 '22 at 17:35

1 Answers1

1

I found the answer and I want to post to help anyone, who facing the same issue.

Instead of getting the pid from PHP, I just added this line as first line inside my script file runScript.sh :

echo $$>script_pid.txt

This line print the PID of the script on text file.

Then, inside ajax call and cancel function, I read the PID from the text file and kill the process:

<?php
    header('Content-Type: application/json');

    $aResult = array();

    if( !isset($_POST['functionname']) ) { $aResult['error'] = 'No function name!'; }
    
    if( !isset($aResult['error']) ) {

        switch($_POST['functionname']) {
            case 'cancelEx':
                $pid = file_get_contents('script_pid.txt');
                $pid  = str_replace(array("\r", "\n"), '', $pid );
                exec("kill -9 $pid");
                $aResult['result'] = "killing the process";
                break;

                
            default:
               $aResult['error'] = 'Not found function '.$_POST['functionname'].'!';
               break;
        }

    }

    echo json_encode($aResult);

?>
sysSTD
  • 87
  • 6