Last active
October 1, 2018 21:07
-
-
Save vijinho/89a0f458bcdc0dd6dab402af1bc7e6a1 to your computer and use it in GitHub Desktop.
execute a command in php and return the captured output and streams stdin, stdout, stderr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
define('VERBOSE', 1); | |
define('DEBUG', 1); | |
//----------------------------------------------------------------------------- | |
// required commands check | |
$commands = get_commands([ | |
'find' => 'System command: find', | |
'curl' => 'https://curl.haxx.se', | |
'wget' => 'https://www.gnu.org/software/wget/' | |
]); | |
if (empty($commands)) { | |
exit; | |
} | |
//----------------------------------------------------------------------------- | |
// main program | |
debug('Commands:' $commands); | |
debug('Memory used:'); | |
echo get_memory_used(); | |
verbose('Finished.'); | |
//----------------------------------------------------------------------------- | |
/** | |
* Dump debug data if DEBUG constant is set | |
* | |
* @param optional string $string string to output | |
* @param optional mixed $data to dump | |
* @return boolean true if string output, false if not | |
*/ | |
function debug($string = '', $data = '') | |
{ | |
if (DEBUG) { | |
echo trim('[D ' . get_memory_used() . '] ' . $string) . "\n"; | |
if (!empty($data)) { | |
print_r($data); | |
} | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Output string if VERBOSE constant is set | |
* | |
* @param string $string string to output | |
* @param optional mixed $data to dump | |
* @return boolean true if string output, false if not | |
*/ | |
function verbose($string, $data = '') | |
{ | |
if (VERBOSE && !empty($string)) { | |
echo trim('[V' .((DEBUG) ? ' ' . get_memory_used() : '') . '] ' . $string) . "\n"; | |
if (!empty($data)) { | |
print_r($data); | |
} | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Get memory used MB | |
* | |
* @return string memory used in MB | |
*/ | |
function get_memory_used() | |
{ | |
return( | |
ceil(memory_get_usage() / 1024 / 1024) . '/' . | |
ceil(memory_get_peak_usage() / 1024 / 1024)); | |
} | |
function get_commands($requirements = []) | |
{ | |
static $commands = []; // cli command paths | |
$found = true; | |
foreach ($requirements as $tool => $description) { | |
if (!array_key_exists($tool, $commands)) { | |
$found = false; | |
break; | |
} | |
} | |
if ($found) { | |
return $commands; | |
} | |
$errors = []; | |
foreach ($requirements as $tool => $description) { | |
$cmd = cmd_execute("which $tool"); | |
if (empty($cmd)) { | |
$errors[] = "Error: Missing requirement: $tool - " . $description; | |
} else { | |
$commands[$tool] = $cmd[0]; | |
} | |
} | |
if (!empty($errors)) { | |
echo join("\n", $errors) . "\n"; | |
} | |
return $commands; | |
} | |
/** | |
* Execute a command and return streams as an array of | |
* stdin, stdout, stderr | |
* | |
* @param string $cmd command to execute | |
* @return mixed array $streams | boolean false if failure | |
* @see https://secure.php.net/manual/en/function.proc-open.php | |
*/ | |
function shell_execute($cmd) | |
{ | |
$process = proc_open( | |
$cmd, | |
[ | |
['pipe', 'r'], | |
['pipe', 'w'], | |
['pipe', 'w'] | |
], $pipes | |
); | |
if (is_resource($process)) { | |
$streams = []; | |
foreach ($pipes as $p => $v) { | |
$streams[] = stream_get_contents($pipes[$p]); | |
} | |
proc_close($process); | |
return [ | |
'stdin' => $streams[0], | |
'stdout' => $streams[1], | |
'stderr' => $streams[2] | |
]; | |
} | |
return false; | |
} | |
/** | |
* Execute a command and return output of stdout or throw exception of stderr | |
* | |
* @param string $cmd command to execute | |
* @param boolean $split split returned results? default on newline | |
* @param string $exp regular expression to preg_split to split on | |
* @return mixed string $stdout | Exception if failure | |
* @see shell_execute($cmd) | |
*/ | |
function cmd_execute($cmd, $split = true, $exp = "/\n/") | |
{ | |
$result = shell_execute($cmd); | |
if (!empty($result['stderr'])) { | |
throw new Exception($result['stderr']); | |
} | |
$data = $result['stdout']; | |
if (empty($split) || empty($exp) || empty($data)) { | |
return $data; | |
} | |
return preg_split($exp, $data); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment