For a week, I struggled to execute a Perl script and grab it’s output, all to be done within a PHP program. Finally, after an exhaustive search, I found my savior – “Shell_exec” command in PHP. Although, the “shell_exec” command does exactly what I wanted, the road ahead was full of thorny issues. To help developers in the similar situation as of mine, here I present a structured document on the problems that one might encounter while trying to run “shell_exec” command.
Problem 1: Shell_exec() [function.shell-exec]: Cannot execute….. in Safe Mode:
Solution: In this case, the potential problem might be that your php is running in safe mode. Open php.ini file in a text editor and search for “safe_mode”. Make sure that it is turned off i.e
safe_mode = Off
Restart your webserver and try to run the php program again. "Shell_exec" command should be working now.
Problem 2: Able to execute simple commands such as “cmd”, “cd”, etc., but not perl script
Problem 3: Able to run perl script via command prompt but not using shell_exec
Solution: Problem 2 and 3 are related and, in most cases, are caused by the same problem. In both cases, probably, including the full path of perl.exe might solve the problem of running a perl script. For example
Shell_exec(“perl hello.pl”) // originally I was trying this
Another useful function that might was to consider is runExternal. It was contributed by one of the developers and is available on www.php.net. A copy of the runExternal function is below.
function runExternal($cmd,&$code) {
$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 file to write to
);
$pipes= array();
$process = proc_open($cmd, $descriptorspec, $pipes);
$output= "";
if (!is_resource($process)) return false;
#close child's input imidiately
fclose($pipes[0]);
stream_set_blocking($pipes[1],false);
stream_set_blocking($pipes[2],false);
$todo= array($pipes[1],$pipes[2]);
while( true ) {
$read= array();
if( !feof($pipes[1]) ) $read[]= $pipes[1];
if( !feof($pipes[2]) ) $read[]= $pipes[2];
if (!$read) break;
$ready= stream_select($read, $write=NULL, $ex= NULL, 2);
if ($ready === false) {
break; #should never happen - something died
}
foreach ($read as $r) {
$s= fread($r,1024);
$output.= $s;
}
}
fclose($pipes[1]);
fclose($pipes[2]);
$code= proc_close($process);
return $output;
}
?>
here is how to use it:
$result= runExternal("ls -l some-file.txt",$code);
print "";
\n";
print $result;
print "
print "code: $code\n";
?>
As you might already noticed, runExternal command replaces shell_exec. While shell_exec only returns output and no errors, runExternal returns output as well as errors. Thus runExternal is a useful during debugging process.
1 comment:
Hello There. I found your blog using msn. This is an extremely well written article. I'll make sure to bookmark it and return to read more of your useful information. Thanks for the post. I will certainly comeback.
Post a Comment