|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2021-10-01 13:52 UTC] divinity76 at gmail dot com
 Description: ------------ doing exactly the same as the $result_code argument for system() and passthru() and exec() Test script: --------------- <?php $result_code=null; shell_exec(bin2hex(random_bytes(10))." 2>&1", $result_code); var_dump($result_code); Expected result: ---------------- platform-specific expected result, but at least on Linux one would expect: int(127) Actual result: -------------- PHP Warning: shell_exec() expects exactly 1 parameter, 2 given in /home/hansh/foo3.php on line 3 NULL PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 03:00:01 2025 UTC | 
@requinix to use exec() for the same task as shell_exec(), you'll have to (ab)use implode() like exec($cmd,$output,$ret); $output=implode("\n", $output); and to use system() for the same job, you'd have to (ab)use ob_* like ob_start(); system($cmd,$ret); $output=ob_get_clean(); same for passthru() as it stands now, if you want to do a shell_exec while also getting the os-level return value, you'll have to do a exec()+implode() workaround.. there would be no need for workarounds if shell_exec supported $result_codeactually the implode() workaround is non-binary-safe, take for example: <?php declare(strict_types=1); $cmd= "php -r ".escapeshellarg('echo '.var_export("\n",true).";"); exec($cmd,$output,$ret); $output=implode("\n",$output); var_dump($output); ?> it prints emptystring, not a string containing a newline, sooo data corruption>It's funny how we have so many of these functions and they all kinda suck. yeah... that reminds me, back in 2019 i made my own function to do this stuff, cus i didn't particularly like any of them (well, maybe except proc_open, but that one is kind-of too difficult to use, most of the time) i know it's not particularly relevant to this feature request, but i'd love for someone to tell me what sucks about this function <?php /** * better version of shell_exec(), * supporting both stdin and stdout and stderr and os-level return code * * @param string $cmd * command to execute * @param string $stdin * (optional) data to send to stdin, binary data is supported. * @param string $stdout * (optional) stdout data generated by cmd * @param string $stderr * (optional) stderr data generated by cmd * @param bool $print_std * (optional, default false) if you want stdout+stderr to be printed while it's running, * set this to true. (useful for long-running commands) * @return int */ function hhb_exec(string $cmd, string $stdin = "", string &$stdout = null, string &$stderr = null, bool $print_std = false): int { $stdouth = tmpfile(); $stderrh = tmpfile(); $descriptorspec = array( 0 => array( "pipe", "rb" ), // stdin 1 => array( "file", stream_get_meta_data($stdouth)['uri'], 'ab' ), 2 => array( "file", stream_get_meta_data($stderrh)['uri'], 'ab' ) ); $pipes = array(); $proc = proc_open($cmd, $descriptorspec, $pipes); while (strlen($stdin) > 0) { $written_now = fwrite($pipes[0], $stdin); if ($written_now < 1 || $written_now === strlen($stdin)) { // ... can add more error checking here break; } $stdin = substr($stdin, $written_now); } fclose($pipes[0]); unset($stdin, $pipes[0]); if (! $print_std) { $proc_ret = proc_close($proc); // this line will stall until the process has exited. $stdout = stream_get_contents($stdouth); $stderr = stream_get_contents($stderrh); } else { $stdout = ""; $stderr = ""; stream_set_blocking($stdouth, false); stream_set_blocking($stderrh, false); $fetchstd = function () use (&$stdout, &$stderr, &$stdouth, &$stderrh): bool { $ret = false; $tmp = stream_get_contents($stdouth); // fread($stdouth, 1); // if (is_string($tmp) && strlen($tmp) > 0) { $ret = true; $stdout .= $tmp; fwrite(STDOUT, $tmp); } $tmp = stream_get_contents($stderrh);// fread($stderrh, 1); // // var_dump($tmp); if (is_string($tmp) && strlen($tmp) > 0) { $ret = true; $stderr .= $tmp; fwrite(STDERR, $tmp); } return $ret; }; while (($status = proc_get_status($proc))["running"]) { if (! $fetchstd()) { // 100 ms usleep(100 * 1000); } } $proc_ret = $status["exitcode"]; proc_close($proc); $fetchstd(); } fclose($stdouth); fclose($stderrh); return $proc_ret; } ?>