Home > Article > Backend Development > PHP method to execute external commands on linux
This article mainly introduces how PHP implements external commands on Linux. Interested friends can refer to it. I hope it will be helpful to everyone.
Directory:
1. Introduction to calling external commands in PHP
2. About security issues
3. Regarding the timeout issue
4. Regarding the problems with commands in PHP running in the Linux environment
##1. Introduction to calling external commands in PHP
To call external commands in PHP, you can use three methods: 1> call a special function, 2> backtick, 3>popen() function to open the process:Method 1: Use the specialized functions (four) provided by PHP:
PHP provides 4 specialized functions for executing external commands: exec(), system(), passthru(), shell_exec()1) exec()
Prototype: string exec ( string $command [, array &$output [, int &$return_var ] )Explanation: When exec executes a command external to the system, it does not output the result, but returns the last line of the result. If you want to get the result, you can use the second parameter to output it to the specified array. One record in this array represents a row of output. That is, if the output result has 20 lines, then this array will have 20 records. Therefore, if you need to repeatedly output the results of calling different system external commands, it is best to clear the array unset($output) when outputting the results of each system external command. To prevent confusion. The third parameter is used to obtain the status code of command execution. Usually, 0 is returned if the execution is successful.<?php exec("dir",$output); print_r($output); ?>
2) system()
Prototype: string system ( string $command [, int &$return_var ] )Explanation: The difference between system and exec is that when system executes a command external to the system, it executes the given command, outputs and returns the result. The second parameter is optional and is used to get the status code after the command is executed.<?php system("pwd",$result); print $result;//输出命令的结果状态码 ?>
A brief introduction to the second parameter result status code:
If 0 is returned, the operation is successful. In Bash, when an error occurs in a fatal signal, bash will return 128 signal number as the return value. If the command cannot be found, 127 will be returned. If the command is found but the command is not executable, 126 will be returned. In addition, Bash itself will return the return value of the last instruction. If an error occurs during execution, a non-zero value will be returned. Fatal Signal : 128 signoCan't not find command : 127
Can't not execute : 126
Shell script successfully executed : return the last command exit status
Fatal during execution: return non-zero
3) passthru()
Prototype: void passthru ( string $command [, int &$return_var ] )Explanation: The difference between passthru and system. passthru directly outputs the results to the browser without returning any value, and it can output binary, such as image data. The second parameter is optional and is the status code.<?php header("Content-type:image/gif"); passthru("/usr/bin/ppm2tiff /usr/share/tk8.4/demos/images/teapot.ppm"); ?>
4) shell_exec()
Prototype: string shell_exec ( string $cmd )Instructions: Directly execute the command $cmd<?php $output = shell_exec('ls -lart'); echo "<pre class="brush:php;toolbar:false">$output"; ?>
##Method 2: BackticksPrototype: backtick ` (with ~ in the same key) to execute system external commands
Description: When using this method to execute system external commands, make sure that the shell_exec function is available. Otherwise, you cannot use this backtick to execute commands external to the system.
<?php echo `dir`; ?>
Method 3: Use popen() function to open the processPrototype: resource popen (string $command, string $mode)
Description: Able to interact with commands. The method introduced before can only simply execute the command, but cannot interact with the command. Sometimes you need to enter something into the command. For example, when adding a system user, you need to call su to change the current user to the root user. The su command must enter the root password on the command line. In this case, it is obviously not possible to use the method mentioned before.
Thepopen() function opens a process pipe to execute the given command and returns a file handle that can be read and written to. The return value is the same as the fopen() function, returning a file pointer. Unless a single mode is used to open (read or write), it must be closed using the pclose() function. This pointer can be called by fgets(), fgetss(), fwrite(). On error, returns FALSE.
<?php error_reporting(E_ALL); /* Add redirection so we can get stderr. */ $handle = popen('/path/to/executable 2>&1', 'r'); echo "'$handle'; " . gettype($handle) . "\n"; $read = fread($handle, 2096); echo $read; pclose($handle); ?>
2. Regarding security issues: Since PHP is basically used for WEB Program development, so security has become an important aspect that people consider.
So PHP designers added a door to PHP: safe mode.
Setting safe_mode = On
in php.ini如果运行在安全模式下,那么PHP脚本中将受到如下四个方面的限制:
执行外部命令
在打开文件时有些限制
连接MySQL数据库
基于HTTP的认证
在安全模式下,只有在特定目录中的外部程序才可以被执行,对其它程序的调用将被拒绝。这个目录可以在php.ini文件中用safe_mode_exec_dir指令,或在编译PHP 是加上–with-exec-dir选项来指定,默认是/usr/local/php/bin。
当你使用这些函数来执行系统命令时,可以使用escapeshellcmd()和escapeshellarg()函数阻止用户恶意在系统上执行命令,escapeshellcmd()针对的是执行的系统命令,而escapeshellarg()针对的是执行系统命令的参数。这两个参数有点类似addslashes()的功能。
三、关于超时问题
当执行命令的返回结果非常庞大时,可以需要考虑将返回结果输出至其他文件,再另行读取文件,这样可以显著提高程序执行的效率。
如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运行。但在默认情况下,象system()等函数要等到这个命令运行完才返回(实际上是在等命令的输出结果),这肯定会引起PHP脚本的超时。解决的办法是把命令的输出重定向到另外一个文件或流中,如:
<?php system("/usr/local/bin/order_proc > /tmp/abc "); ?>
但我调用的DOS命令需要几分钟的时间,而且为了批处理不能简单的把结果写入文件了事,要顺序执行以下的程序
PHP设置了调用系统命令的时间限制,如果调用命令超时,虽然这个命令还是会被执行完,但PHP没有得到返回值,被终止了(最可恨的是,不显示任何错误)
修改php.ini并重启Apache以允许系统命令运行更长的时间
max_execution_time = 600
四、关于PHP运行linux环境中命令出现的问题
php一般是以apache用户身份去执行的,也可能是www用户,把apache加入到存储你文件的父文件夹属组里去,然后改该父文件夹权限为775,这样属组成员就有写的权限,而apache属于这个组就可以改写该目录下所有文件的权限。
例如:chown www:www dirName
这样dirName目录才能被php所控制
注意:改apache/php的运行用户方法不安全
另外即使文件或目录已经是www,php的安全设置也都照顾到,一些自己安装linux的命令仍然可能无法运行,例如我曾经安装的ffmpeg软件,原因就是linux的运行权限问题,即使ffmpeg有www权限设置,但由于ffmpeg所依赖的库文件是不允许www用户运行,所以php运行此程序仍然会报127或126错误,通过 ldd 命令可以查看ffmpeg命令依赖的库情况。
这个时候就必须对ffmpeg的依赖库经行设置。具体方法属于linux管理中的话题,这里不就讨论了。
以上就是本文的全部内容,希望对大家的学习有所帮助。
相关推荐:
The above is the detailed content of PHP method to execute external commands on linux. For more information, please follow other related articles on the PHP Chinese website!