Execute shell commands in PHP

By | March 27, 2012

Like any other language php applications often need to execute system commands like they are run from the terminal/console/commandline. Php has multiple functions to do this task. Lets take a look at each of these

1. system

"system() is just like the C version of the function in that it executes the given command and outputs the result.
The system() call also tries to automatically flush the web server's output buffer after each line of output if PHP is running as a server module."

2. passthru

"The passthru() function is similar to the exec() function in that it executes a command. This function should be used in place of exec() or system() when the output from the Unix command is binary data which needs to be passed directly back to the browser. A common use for this is to execute something like the pbmplus utilities that can output an image stream directly. By setting the Content-type to image/gif and then calling a pbmplus program to output a gif, you can create PHP scripts that output images directly."

3. exec

"exec() executes the given command."

4. shell_exec

"This function is identical to the backtick operator."

Portable solution

A common problem with the above functions is that they are often disabled selectively on shared hostings. For example all function expect passthru may be disabled , or only exec would be available and so on. So it creates a small issue to keep changing code to fit according to the hosting server.

Here is a function that combines all the above functions into 1 and creates a portable solution that tries to work on all kinds of shared hostings where atleast 1 of them is enabled :

/**
	Method to execute a command in the terminal
	Uses :
	
	1. system
	2. passthru
	3. exec
	4. shell_exec

*/
function terminal($command)
{
	//system
	if(function_exists('system'))
	{
		ob_start();
		system($command , $return_var);
		$output = ob_get_contents();
		ob_end_clean();
	}
	//passthru
	else if(function_exists('passthru'))
	{
		ob_start();
		passthru($command , $return_var);
		$output = ob_get_contents();
		ob_end_clean();
	}
	
	//exec
	else if(function_exists('exec'))
	{
		exec($command , $output , $return_var);
		$output = implode("n" , $output);
	}
	
	//shell_exec
	else if(function_exists('shell_exec'))
	{
		$output = shell_exec($command) ;
	}
	
	else
	{
		$output = 'Command execution not possible on this system';
		$return_var = 1;
	}
	
	return array('output' => $output , 'status' => $return_var);
}

To use :

$o = terminal('ls');
if($status == 0)
{
    echo $o['output'];
}
else
{
    //some problem
}

system and passthru echo the output directly to output stream , hence its necessary to use buffering to catch their output before it gets dumped. shell_exec and exec simply return the output.

So using the terminal function your code is more portable across different kinds of hostings and lot of command execution issues can be avoided.

About Silver Moon

A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at [email protected].

2 Comments

Execute shell commands in PHP
  1. Carl

    Hi Silver,
    Your code is pretty cool! Works as expected when tested, but the results are useless since they are not revealing the expected methods that execute the command in the terminal as you have mentioned for the purpose of using the code. What should be expected is an array of the methods that passes the test which mean those methods are available to execute a command.
    Example:
    return array(‘system_’=>’disabled’, ‘passthru_’=>passthru’, ‘exec_’=>’exec’, ‘shell_exec_’=>’disabled’, ‘error_’=>’ ‘);
    Then your code will be a lot more robust and functional by using the “in_array() function for a command method to use.

  2. !Shoorf

    Hi Silver Moon,

    Thank you for article. But please in example above:

    if($status == 0)
    With:
    if($o[‘status’] == 0)

Leave a Reply

Your email address will not be published. Required fields are marked *