PHP调用Linux系统的常用函数

本文介绍了如何使用PHP调用Linux系统的常见命令,包括exec、system、passthru、popen和proc_open等函数的使用方法及注意事项。

PHP调用Linux系统的常用函数

  1、exec函数

  <?php

  $test = "ls /tmp/test"; //ls是linux下的查目录,文件的命令

  exec($test,$array); //执行命令

  print_r($array);

  ?>

  2、system函数

  <?php

  $test = "ls /tmp/test";

  $last = system($test);

  print "last: $last\n";

  ?>

  3、passthru函数

  <?php

  $test = "ls /tmp/test";

  passthru($test);

  ?>

  4、popen函数

  <?php

  $test = "ls /tmp/test";

  $fp = popen($test,"r"); //popen打一个进程通道

  while (!feof($fp)) { //从通道里面取得东西

  $out = fgets($fp, 4096);

  echo $out; //打印出来

  }

  pclose($fp);

  ?>

  5、proc_open函数

  <?php

  $test = "ls /tmp/test";

 

  $arrayarray = array(

  array("pipe","r"), //标准输入

  array("pipe","w"), //标准输出内容

  array("pipe","w") //标准输出错误

  );

  $fp = proc_open($test,$array,$pipes); //打开一个进程通道

  echo stream_get_contents($pipes[1]); //为什么是$pipes[1],因为1是输出内容

  proc_close($fp);

  ?>

  6、proc_open函数

  <?php

  $test = "ls /tmp/test";

  $arrayarray = array(

  array("pipe","r"), //标准输入

  array("pipe","w"), //标准输出内容

  array("pipe","w") //标准输出错误

  );

  $fp = proc_open($test,$array,$pipes); //打开一个进程通道

  echo stream_get_contents($pipes[1]); //为什么是$pipes[1],因为1是输出内容

  proc_close($fp);

  ?>

  7、shell_exec函数

  <?php

  $test = "ls /tmp/test";

  $out = shell_exec($test);

  echo $out;

  ?>


很多情况下需要php调用其他程序如shell命令、shell脚本、可执行程序等等,此时需要使用到诸如exec/system/popen/proc_open等函数,每种函数有各自适合使用的场景以及需要注意的地方。

前提:PHP没有运行在安全模式
如果PHP运行在安全模式下,那么在执行外部命令、打开文件、连接数据库、基于HTTP的认证这4个方面将会受到制约,可能在调用外部程序时无法获取预期的结果,此时需要设置特定目录,可以在php.ini中编辑safe_mode_exec_dir参数来指定。

1. exec
原型:string exec ( string command [, array &output [, int &return_var]] )
描述:返回值保存最后的输出结果,而所有输出结果将会保存到$output数组,$return_var用来保存命令执行的状态码(用来检测成功或失败)。
例子:$ret = exec("ls -al", $output, $var);
注意:
A. 输出结果会逐行追加到$output中,因此在调用exec之前需要unset($output),特别是循环调用的时候。
B. 如果想通过exec调用外部程序后马上继续执行后续代码,仅仅在命令里加"&"是不够的,此时exec依然会等待命令执行完毕;需要再将标准输出做重定向才可以,例如:exec("ls -al >/dev/null &", $output, $var);
C. 要学会善用EscapeShellCmd()和EscapeShellArg()。函数EscapeShellCmd把一个字符串 中所有可能瞒过Shell而去执行另外一个命令的字符转义。这些字符在Shell中是有特殊含义的,象分号(|),重定向(>)和从文件读入 (<)等。函数EscapeShellArg是用来处理命令的参数的。它在给定的字符串两边加上单引号,并把字符串中的单引号转义,这样这个字符串 就可以安全地作为命令的参数。

2. system
原型:string system ( string command [, int &return_var] )
描述:执行给定的命令,返回最后的输出结果;第二个参数是可选的,用来得到命令执行后的状态码。
例子:$ret = system("ls -al", $var);
注意:略。

3. passthru
原型:void passthru (string command [, int return_var])
描述:执行给定的命令,但不返回任何输出结果,而是直接输出到显示设备上;第二个参数可选,用来得到命令执行后的状态码。
例子:passthru("ls -al", $var);
注意:略。

4. popen
原型:resource popen ( string command, string mode )
描述:打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。 返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用 pclose() 来关闭。此指针可以用于 fgets(),fgetss() 和 fwrite()。 
例子:$fd = popen("command", 'r'); $ret = fgets($fd);
注意:只能打开单向管道,不是'r'就是'w';并且需要使用pclose()来关闭。

5. proc_open
原型:resource proc_open ( string cmd, array descriptorspec, array &pipes [, string cwd [, array env [, array other_options]]] )
描述:与popen类似,但是可以提供双向管道。具体的参数读者可以自己翻阅资料,比如该博客:http://hi.baidu.com/alex_wang58/blog/item/a28657de16fec55195ee372a.html
注意:
A. 后面需要使用proc_close()关闭资源,并且如果是pipe类型,需要用pclose()关闭句柄。
B. proc_open打开的程序作为php的子进程,php退出后该子进程也会退出。
C. 笔者在使用的时候遇到获取外部程序输出阻塞的问题,也就是在例子中的fgets($pipes[1])语句阻塞了,无法继续进行。经过多方查证后发现,问题一般出在外部程序中,比如外部程序是C程序,使用fprintf(stdin, "**** \n");输出结果,此时需要加上fflush(stdout);才行,否则输出结果可能会暂留缓存中,无法真正输出,而php也就无法获取输出了。
例子:

// /< 打开管道
$pwd   =   " ***** " ;
$pipes   =   array ();
$command   =   " ***** " ;
$desc   =   array ( array ( ' pipe ' ,   ' r ' ) ,   array ( ' pipe ' ,   ' w ' ) ,   array ( ' pipe ' ,   ' w ' ));
$handle   =   proc_open ( $command ,   $desc ,   $pipes ,   $pwd );
if  ( ! is_resource ( $handle )) {
    
fprintf (STDERR ,   " proc_open failed.\n " );
    
exit ( 1 );
}
// /< 读写
fwrite ( $pipes [ 0 ] ,   " *****\n " );
$ret   =   rtrim ( fgets ( $pipes [ 1 ]) ,   " \n " );
// /< 关闭管道
fclose ( $pipes [ 0 ]);
fclose ( $pipes [ 1 ]);
fclose ( $pipes [ 2 ]);
proc_close ( $handle );



<think>好的,我需要帮助用户在Linux环境下找到调用系统命令的函数或方法,并提供示例。首先,我需要回顾用户提供的引用内容,看看哪些信息相关。 引用[1]、[3]、[4]提到了系统调用的概念,即应用程序通过操作系统接口执行特权操作。但用户的问题可能更偏向于如何在程序中执行系统命令,比如shell命令,而不仅仅是系统调用。例如,用户可能想执行类似ls或echo这样的命令。 引用[2]和[5]讨论了在PHP中使用exec、system函数调用Linux命令,以及shell脚本中的函数调用。这说明在不同编程语言中,有不同的方法来实现系统命令的调用。比如,C语言可以使用system()函数,而Python可能有subprocess模块。 接下来,我需要整理常见的Linux环境下调用系统命令的方法,涵盖不同编程语言。比如: 1. C语言:使用system()函数,属于标准库函数,但实际可能涉及系统调用fork和execve。 2. Python:可以使用os.system(),或者更推荐的subprocess模块。 3. Shell脚本:直接执行命令,或者通过函数封装。 4. PHP:如exec、system函数。 同时,用户可能需要示例代码。根据引用中的内容,例如引用[2]提到了PHP的exec,引用[5]讲到了shell脚本中的函数和局部变量。需要确保示例正确,并符合各语言的语法。 还要注意区分系统调用和库函数。比如,system()是库函数,而底层可能使用系统调用如fork和execve。根据引用[3],系统调用需要切换到内核态,而函数调用则不需要。 用户可能需要了解不同方法的区别,比如直接使用系统调用与使用库函数的区别,或者不同函数之间的安全性、灵活性差异。例如,subprocess模块比os.system()更灵活,能更好地处理输入输出。 最后,生成相关问题,可能涉及如何选择合适的方法、各方法的优缺点、错误处理等。需要确保问题与主题相关,帮助用户深入理解。</think>在Linux环境下调用系统命令的常用方法及示例: ### 一、C语言实现 1. **system()函数** ```c #include <stdlib.h> int main() { system("ls -l /home"); // 执行ls命令 return 0; } ``` *底层通过`fork()`+`execve()`系统调用实现[^4]* 2. **exec系列函数**(直接系统调用) ```c #include <unistd.h> int main() { execl("/bin/ls", "ls", "-l", NULL); // 替换当前进程 return 0; } ``` ### 二、Python实现 1. **os.system()** ```python import os os.system('echo "Hello Linux"') # 执行简单命令 ``` 2. **subprocess模块**(推荐方式) ```python import subprocess result = subprocess.run(['ls', '-l'], capture_output=True, text=True) print(result.stdout) ``` ### 三、Shell脚本实现 ```bash #!/bin/bash # 直接调用系统命令 date +"%Y-%m-%d" # 函数封装示例 show_files() { local path=$1 # 局部变量定义[^5] ls -l $path } show_files /tmp ``` ### 四、PHP实现 ```php <?php $output = shell_exec('free -h'); // 获取命令输出 echo "<pre>$output</pre>"; system("mkdir new_folder", $retval); // 执行命令并获取返回值 ?> ``` ### 方法对比 | 方法 | 执行方式 | 输出获取 | 底层实现 | |---------------|--------------|----------|---------------------| | system() | 同步执行 | 有限支持 | fork+execve系统调用[^3] | | exec系列 | 进程替换 | 无 | 直接系统调用 | | subprocess | 精细控制 | 完整支持 | 封装系统调用 | | shell_exec | 异步/同步可选 | 完整获取 | 通过shell解释器 |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值