• PHP > envoyer des commandes Shell

      GENERALITES

      exec ( "commande" );

       

      ou

       

      exec ( "fichier.sh" );

       

      Pour afficher le résultat :

       

      exec("php fichier.php",$result);

       

      ou

       

      print_r($result);

       

      ou

       

      print_r($result);
      foreach ($result as $key => $value) {
         echo '<br>'.$value.'';
      ;}

      ERREURS

      Warning: exec() has been disabled for security reasons in /home/user/www/testexec.php on line 7

       

      Plus : la doc.

       

      http://php.net/manual/fr/function.shell-exec.php

      http://php.net/manual/fr/function.exec.php

      AVEC JQUERY AJAX

      Avec .get() :

       

      <html><head>
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
      <script>
      $(document).ready(function() {
         $("button").click(function() {
            $.get("script.php?code=myFunction", function(data, status) {
               console.log("Data: " + data + "\nStatus: " + status);
            });
         });
      });
      </script>
      </head><body>
      <button>Execute Command</button>
      </body></html>

       

      script.php

       

      if (!empty($_GET['code']) {
         $output = shell_exec(<do shell command here>);
         echo $output;
      }

       

      The following assumes that xxx is your PHP file and output is the response from the xxx file:

       

      button.onclick = function() {
         $.ajax({
            url: '/my/site/xxx.php',
            data: {action: 'test'},
            type: 'post',
            success: function(output) {
               console.log(output);
            }
         });
      };

      Executer un shell_exec avec retours en direct

      Différence entre exec, shell_exec, system, et passthru.

      Use passthru() instead of shell_exec() – Mike B Nov 20 ’13 at 21:14

      To read the output of a process, popen() is the way to go.

      But if you just want to dump it’s result straight to the user you can cut the crap and use passthru():

       

      echo '<pre>';
      passthru($cmd);
      echo '</pre>';

       

      Mais pour afficher la sortie at run time as the program goes :

       

      while (@ ob_end_flush()); // end all output buffers if any
      $proc = popen($cmd, 'r');
      echo '<pre>';
      while (!feof($proc)){
         echo fread($proc, 4096);
         @ flush();
      }
      echo '</pre>';

       

      Ce code should run the command and push the output straight to the end user at run time.

      L’astuce est de to enforce that no buffering will happen at all.

      D’ordinaire, PHP will only flush output when it accumulates at least 4KB of data.

       

      Le même code un peu modifié :

       

      <?php
      *  @param  string cmd         : command to be executed
      *  @return array  exit_status : exit status of the executed command
      *                 output      : console output of the executed command
      
      function liveExecuteCommand($cmd){
      
         while (@ ob_end_flush()); // end all output buffers if any
         $proc = popen("$cmd 2>&1 ; echo Exit status : $?", 'r');
         $live_output     = "";
         $complete_output = "";
         while (!feof($proc)){
            $live_output     = fread($proc, 4096);
            $complete_output = $complete_output . $live_output;
            echo "$live_output";
            @ flush();
         }
         pclose($proc);
         // get exit status
         preg_match('/[0-9]+$/', $complete_output, $matches);
         // return exit status and intended output
         return array (
            'exit_status' => intval($matches[0]),
            'output'      => str_replace("Exit status : " . $matches[0], '', $complete_output)
         );
      }
      ?>

       

      Exemple d’usage :

       

      $result = liveExecuteCommand('ls -la');
      if($result['exit_status'] === 0){
          // do something if command execution succeeds
      } else {
          // do something on failure
      }
      Pour appeler un script issue d’un fichier Bash : liveExecuteCommand("sh /path/to/script.sh");
      note : throw an intval( … ) on the exit_status to return it as an integer rather than a string.
      Note : you should not write your shell command with a trailing semicolon, otherwise the exit_status will always be 0.

      Run process with realtime output in PHP

      $cmd = "ping 127.0.0.1";
      
      $descriptorspec = array(
         0 => array("pipe", "r"), // stdin is a pipe that the child will read from
         1 => array("pipe", "w"), // stdout is a pipe that the child will write to
         2 => array("pipe", "w")  // stderr is a pipe that the child will write to
      );
      flush();
      
      $process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
      
      echo "<pre>";
      if (is_resource($process)) {
          while ($s = fgets($pipes[1])) {
              print $s;
              flush();
          }
      }
      echo "</pre>";
      
      

      works for me, but only if I add ob_implicit_flush(true);ob_end_flush(); at the beginning

       

      I wrapped this in a function so I could call it just like shell_exec. Works nicely if you just want to show the output and not do any processing on it.

       

      This is a nice way to show real time output of your shell commands:

       

      <?php
      header("Content-type: text/plain");
      
      // tell php to automatically flush after every output
      // including lines of output produced by shell commands
      disable_ob();
      
      $command = 'rsync -avz /your/directory1 /your/directory2';
      system($command);

       

      You will need this function to prevent output buffering:

       

      function disable_ob() {
          // Turn off output buffering
          ini_set('output_buffering', 'off');
          // Turn off PHP output compression
          ini_set('zlib.output_compression', false);
          // Implicitly flush the buffer(s)
          ini_set('implicit_flush', true);
          ob_implicit_flush(true);
          // Clear, and turn off output buffering
          while (ob_get_level() > 0) {
              // Get the curent level
              $level = ob_get_level();
              // End the buffering
              ob_end_clean();
              // If the current level has not changed, abort
              if (ob_get_level() == $level) break;
          }
          // Disable apache output buffering/compression
          if (function_exists('apache_setenv')) {
              apache_setenv('no-gzip', '1');
              apache_setenv('dont-vary', '1');
          }
      }

       

      Ne fonctionne pas sur tous les serveurs.

       

      Voici la façon d’utiliser la fonction :

       

      <?php
      header("Content-type: text/plain");
      
      disable_ob();
      
      for($i=0;$i<10;$i++){
          echo $i . "\n";
          usleep(300000);
      }

       

      This doesn’t work with exec(). system() works fine though.

      This worked really well for me, It doesn’t update constantly but every so often.

       

      This works great for me (OS X 10.12, Apache 2.2.3, PHP 7.0.9), but for some reason only when the X-Content-Type-Options header is also set: header('X-Content-Type-Options: nosniff');

       

      try this :

       

      header('Content-Encoding: none;');
      set_time_limit(0);
      $handle = popen("<<< Your Shell Command >>>", "r");
      if (ob_get_level() == 0) ob_start();
      while(!feof($handle)) {
         $buffer = fgets($handle);
         $buffer = trim(htmlspecialchars($buffer));
         echo $buffer . "<br />";
         echo str_pad('', 4096);
         ob_flush();
         flush();
         sleep(1);
      }
      pclose($handle);
      ob_end_flush();

       

      Attention, ne fonctionne pas correctement. à tester.
      Voir la doc de exec.

       

      If you’re attempting to output binary data look into php’s header function, and ensure you set the proper content-type, and content-disposition. Review the documentation, for more information on using/disabling the output buffer.

      For command-line usage:

       

      function execute($cmd) {
         $proc = proc_open($cmd, [['pipe','r'],['pipe','w'],['pipe','w']], $pipes);
         while(($line = fgets($pipes[1])) !== false) {
            fwrite(STDOUT,$line);
         }
         while(($line = fgets($pipes[2])) !== false) {
            fwrite(STDERR,$line);
         }
         fclose($pipes[0]);
         fclose($pipes[1]);
         fclose($pipes[2]);
         return proc_close($proc);
      }

       

      If you’re trying to run a file, you may need to give it execute permissions first:

       

      chmod('/path/to/script',0755);

       

      In PHP you do something like:

      function setupStreaming() {
          // Turn off output buffering
          ini_set('output_buffering', 'off');
          // Turn off PHP output compression
          ini_set('zlib.output_compression', false);
          // Disable Apache output buffering/compression
          if (function_exists('apache_setenv')) {
              apache_setenv('no-gzip', '1');
              apache_setenv('dont-vary', '1');
          }
      }
      function runStreamingCommand($cmd){
          echo "\nrunning $cmd\n";
          system($cmd);
      }
      ...
      
      setupStreaming();
      runStreamingCommand($cmd);

       

      Try changing the php.ini file set "output_buffering = Off".

       

      You should be able to get the real time output on the page Use system command instead of exec.. system command will flush the output

       

      Found solution Here

       

      It works on windows (i think this answer is helpful for users searching over there)

       

      <?php
      $a = popen('ping www.google.com', 'r'); 
      
      while($b = fgets($a, 2048)) {
      echo $b."<br>\n";
      ob_flush();flush();
      }
      pclose($a);
      ?>

 

Aucun commentaire

 

Laissez un commentaire