-
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 beginningI 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); ?>