php -- PHP在linux上执行外部命令,system(),exec(),shell_exec()
目录:
一、PHP中调用外部命令介绍
二、关于安全问题
三、关于超时问题
四、关于PHP运行linux环境中命令出现的问题
一、PHP中调用外部命令介绍
在PHP中调用外部命令,有三种方法:
1. 调用专门函数
2. 反引号
3. popen()函数打开进程
方法一:调用PHP提供的专门函数(四个):
PHP提供4个专门的执行外部命令的函数:exec(), system(), passthru(), shell_exec()
1)exec():替换原有进程
原型: string exec ( string $command , array &$output , int &$return_var )
string $command:要执行的命令(必需)
array &$output:返回的结果(可选),exec执行系统外部命令时不会输出结果,而是返回结果的最后一行,所有如果想得到结果,可以使用第二个参数,让其输出到指定的数组
int &$return_var:是否执行成功(可选),用来取得命令执行的状态码,通常执行成功都是返回0
<?php
exec("dir",$output);
print_r($output);
?>
2)system():开启新的进程
原型: string system ( string $command [, int &$return_var ] )
string $command:要执行的命令(必需)
int &$return_var:是否执行成功(可选),用来取得命令执行的状态码,通常执行成功都是返回0
说明: system和exec的区别在于,system在执行系统外部命令时,它执行给定的命令,输出和返回结果。
<?php
system("pwd",$result);
print $result;//输出命令的结果状态码
?>
关于第二个参数结果状态码的简单介绍:
如果返回0是运行成功,
在Bash中,当错误发生在致命信号时,bash会返回128+signal number做为返回值。
如果找不到命令,将会返回127。
如果命令找到了,但该命令是不可执行的,将返回126。
除此以外,Bash本身会返回最後一个指令的返回值。
若是执行中发生错误,将会返回一个非零的值。
Fatal Signal : 128 + signo
Can'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()
原型: void passthru ( string $command [, int &$return_var ] )
string $command:要执行的命令(必需)
int &$return_var:是否执行成功(可选),用来取得命令执行的状态码,通常执行成功都是返回0
说明: passthru与system的区别,passthru直接将结果输出到游览器,不返回任何值,且其可以输出二进制,比如图像数据
<?php
header("Content-type:image/gif");
passthru("/usr/bin/ppm2tiff /usr/share/tk8.4/demos/images/teapot.ppm");
?>
4)shell_exec()
原型: string shell_exec ( string $cmd )
说明: 直接执行命令$cmd
<?php
$output = shell_exec('ls -lart');
echo "<pre>$output</pre>";
?>
方法二:反撇号
原型: 反撇号`(和~在同一个键)执行系统外部命令
说明: 在使用这种方法执行系统外部命令时,要确保shell_exec函数可用,否则是无法使用这种反撇号执行系统外部命令的。
<?php
echo `dir`;
?>
方法三:用popen()函数打开进程
popen()也常常被用来执行一个程序。
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
popen() 函数用创建管道的方式启动一个 进程, 并调用 shell. 因为管道是被定义成单向的, 所以 type 参数只能定义成只读或者只写, 不能是两者同时, 结果流也相应的是只读或者只写. command 参数是一个字符串指针, 指向的是一个以 null 结束符结尾的字符串, 这个字符串包含一个 shell 命令. 这个命令被送到 /bin/sh 以 -c 参数执行, 即由 shell 来执行. type 参数也是一个指向以 null 结束符结尾的字符串的指针, 这个字符串必须是 'r' 或者 'w’ 来指明是读还是写.
popen() 函数的返回值是一个普通的标准I/O流, 它只能用 pclose() 函数来关闭, 而不是 fclose() 函数. 向这个流的写入被转化为对 command 命令的标准输入; 而 command 命令的标准输出则是和调用 popen(), 函数的进程相同,除非这个被command命令自己改变. 相反的, 读取一个 “被popen了的” 流, 就相当于读取 command 命令的标准输出, 而 command 的标准输入则是和调用 popen, 函数的进程相同.
注意, popen 函数的 输出流默认是被全缓冲的.
pclose 函数等待相关的进程结束并返回一个 command 命令的退出状态
二、关于安全问题:
由于PHP基本是用于WEB程序开发的,所以安全性成了人们考虑的一个重要方面。
于是PHP的设计者们给PHP加了一个门:安全模式。
在php.ini中的设置safe_mode = On
如果运行在安全模式下,那么PHP脚本中将受到如下四个方面的限制:
1. 执行外部命令
2. 在打开文件时有些限制
3. 连接MySQL数据库
4. 基于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管理中的话题,这里不就讨论了
php -- PHP在linux上执行外部命令,system(),exec(),shell_exec()的更多相关文章
- PHP在linux上执行外部命令
PHP在linux上执行外部命令 一.PHP中调用外部命令介绍二.关于安全问题三.关于超时问题四.关于PHP运行linux环境中命令出现的问题 一.PHP中调用外部命令介绍在PHP中调用外部命令,可以 ...
- Linux培训教程 浅谈:PHP在linux上执行外部命令(整理)
一.PHP中调用外部命令介绍 二.关于安全问题 三.关于超时问题 四.关于PHP运行linux环境中命令出现的问题 一.PHP中调用外部命令介绍 在PHP中调用外部命令,可以用,1>调用专门函数 ...
- php在linux中执行外部命令
目录:一.PHP中调用外部命令介绍二.关于安全问题三.关于超时问题四.关于PHP运行linux环境中命令出现的问题 一.PHP中调用外部命令介绍在PHP中调用外部命令,可以用,1>调用专门函数. ...
- PHP 执行系统外部命令 system() exec() passthru()
区别: system() 输出并返回最后一行shell结果. exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面. passthru() 只调用命令,把命令的运 ...
- 【转】linux中执行外部命令提示" error while loading shared libraries"时的解决办法
今天在Centos下编译kapar 后执行时出错,老说: [root@dc01 ~]# kapar kapar: error while loading shared libraries: libsc ...
- 【JVM】【linux】linux上执行jmap命令查看JVM内存使用情况,报错:sun.jvm.hotspot.debugger.NoSuchSymbolException: Could not find symbol "gHotSpotVMTypes" in any of the known library name
运行命令: jmap -heap 报错如下: Attaching to process ID , please wait... sun.jvm.hotspot.debugger.NoSuchSymbo ...
- 在linux上用dd命令实现ghost功能
ghost和g4l 安装操作系统,速度太慢,整个过程太冗长乏味了. 安装过程中,需要回答若干问题,系统需要安装无数个软件,创建和写入无数的文件.因为涉及到大量的文件定位和读写,速度一定是快不起来的. ...
- Java中执行外部命令
在项目中执行一个linux的shell脚本,于是需要在java环境下执行外部命令如系统命令.linux命令的需求,本人小小研究了一下,又上网查了一些资料先整理如下. java执行外部命令主要依赖两个类 ...
- Powershell 执行外部命令
Powershell 执行外部命令 724 11月, 2011 在 Powershell tagged Powershell教程 / 程序 by Mooser Lee本文索引[隐藏]1通过nets ...
随机推荐
- [转]WCF类型共享技巧
调用过WCF服务的同学可能都会遇到这样的问题,同一个实体类型,不同的服务Visual Studio生成了不同的版本,例如Service1.User和Service2.User,对于C#来说,这是两个不 ...
- hdu4901The Romantic Hero
#include<iostream> #include<map> #include<string> #include<cstring> #include ...
- js中push和join方法使用介绍
push和join方法想必大家并不陌生吧,在本文将为大家详细介绍下js中的push和join方法的使用.代码: <script type="text/javascript"& ...
- [k8s]容器化node-expolore(9100)+cadvisor(8080)+prometheus(9090) metric搜集,grafana展示
Prometheus 的核心,多维数据模型 传统监控工具统计数据方式 指标多 - 需求1,统计app1-3,的(总)内存,则定义3个指标 container.memory_usage_bytes.we ...
- 【Android】20.4 录音
分类:C#.Android.VS2015: 创建日期:2016-03-13 一.简介 利用Android提供的MediaRecorder类可直接录制音频. 1.权限要求 录制音频和视频需要下面的权限: ...
- 【Android】11.5 创建和管理Fragments
分类:C#.Android.VS2015: 创建日期:2016-02-22 一.简介 想要管理activity中的fragment,可以用FragmentManager类来实现.通过在activity ...
- 【Android】6.2 AlertDialog(警告对话框)
分类:C#.Android.VS2015: 创建日期:2016-02-08 一.简介 AlertDialog也是Android系统当中常用的对话框之一. 在一个AlertDialog中,可以有一个Bu ...
- 把UIView转成UIImage,解决模糊失真问题
近期工作中,遇到一个需求,须要把一个UIView对象转成UIImage对象显示.经过网络搜索.找到例如以下答案: ? 1 2 3 4 5 6 7 8 -(UIImage*)convertViewToI ...
- 设置PDF文件默认缩放比例
- linux安装mysql全纪录[包括yum和rpm安装,编码,远程连接以及大小写问题]
linux安装mysql全纪录[包括yum和rpm安装,编码,远程连接以及大小写问题] 一.查看mysql是否已经安装 使用“whereis mysql”命令来查看mysql安装路径: [root@h ...