system

(PHP 4, PHP 5, PHP 7, PHP 8)

system执行外部程序并显示输出

说明

system(string $command, int &$result_code = null): string|false

system() 与 C 语言版本的函数类似,它执行给定的 command 并输出结果。

如果 PHP 作为服务器模块运行,system() 调用还会尝试在每行输出后自动刷新 Web 服务器的输出缓冲区。

如果您需要执行命令并将命令的所有数据直接传递回来,而没有任何干扰,请使用 passthru() 函数。

参数

command

将要执行的命令。

result_code

如果存在 result_code 参数,则执行命令的返回状态将写入此变量。

返回值

成功时返回命令输出的最后一行,失败时返回 false

示例

示例 #1 system() 示例

<?php
echo '<pre>';

// 输出 shellcommand "ls" 的所有结果,并将
// 最后一行输出返回到 $last_line。将 shell 命令的返回值
// 存储在 $retval 中。
$last_line = system('ls', $retval);

// 打印额外信息
echo '
</pre>
<hr />Last line of the output: '
. $last_line . '
<hr />Return value: '
. $retval;
?>

注释

警告

当允许用户提供的数据传递到此函数时,请使用 escapeshellarg()escapeshellcmd() 来确保用户无法欺骗系统执行任意命令。

注意:

如果使用此函数启动程序,为了让程序在后台继续运行,程序的输出必须重定向到文件或其他输出流。如果这样做,PHP 将挂起,直到程序执行结束。

参见

添加注释

用户贡献的注释 19 个注释

63
no at mail dot com
12 年前
这是针对 WINDOWS 用户的。我正在运行 apache,我尝试了几个小时,但始终无法捕获命令的输出。

我尝试了这里写的所有方法,然后继续在线搜索,但仍然没有结果。命令的输出从未被捕获。我只得到一个空数组。

最后,我在某个很棒的家伙的博客中找到了一条评论,它解决了我的问题。

在命令名称中添加字符串 ' 2>&1' 最终返回了输出!这在 PHP 中的 exec() 和 system() 中都有效,因为它使用流重定向将输出重定向到正确的位置!

system("yourCommandName 2>&1",$output) ;
14
dan at thecsl dot org
18 年前
您可能需要检查系统调用是否有错误。惯例是返回 0 表示“无错误”,这与 FALSE 相同,这可能会造成混淆。您需要执行类似的操作

<?php
$cmd
= "/usr/bin/pngtopnm $png_file > $pnm_file";
system($cmd,$return_value);
(
$return_value == 0) or die("returned an error: $cmd");
?>
8
mortoray at ecircle-ag dot com
20 年前
如果您使用 "php.ini" 选项,请勿使用 "system"
zlib.output_compression = On

这样做会导致浏览器接收垃圾数据(我猜是标头/缓冲区混淆了)。

在这种情况下,请使用 passthru,它似乎按预期工作。
6
timgolding_10 at hotmail dot com
17 年前
使用 system 在 Linux 服务器上调用 file 命令的示例。此脚本检测用户发布的文件是否是 jpeg、gif 或 png

<?PHP

$accepted_types
=array("JPEG" , "GIF", "PNG");

// 上传文件在服务器上存储的临时文件名。
if(!empty($_FILES["uploadedfile"]))
{
$uploaddir = $_SERVER['DOCUMENT_ROOT']."/images/";
$uploaddir.=basename( $_FILES['uploadedfile']['name']);

// 使用 Linux FILE 命令验证文件
$last_line = system('file '.escapeshellarg($_FILES['uploadedfile']['tmp_name']), $retval);

// 通过 magic 数据库获取文件扩展名
$splitvals=explode(' image data' , $last_line);
$vals=explode(':', $splitvals[0]);
$vals[1]=str_replace(' ','', $vals[1]);

if (
in_array($vals[1], $accepted_types))
{
echo
$vals[1].' was accepted <br />';
if(!
file_exists($uploaddir)){
// 将文件复制到永久存储位置
if(move_uploaded_file($_FILES["uploadedfile"]["tmp_name"], $uploaddir))
{
echo
$uploaddir." was uploaded! <br />";
}
else
{
echo
"上传新文件时出现问题,请联系管理员。";
}
}
else echo
'此文件已存在于数据库中,请重命名文件后再上传。';
}
}else echo
$_FILES['uploadedfile']['error'].'<br />';
?>
4
ccurtis at aet-usa dot com
25 年前
如果还没有打印任何头部信息,调用 system() 函数将把头部信息刷新到客户端并插入一个换行符;不会再有头部信息或 cookie 传输到浏览器。在 3.0.7 版本中,你不会收到 Header() 函数失败的警告,但会收到尝试设置 cookie 时失败的警告。如果你想在函数调用后继续发送头部信息,请使用 exec() 代替。
3
Jim Belton
20 年前
要从 PHP CLI 脚本运行全屏程序,请将输入重定向到 /dev/tty,并将输出重定向到 /dev/tty。例如

system("timeconfig > /dev/tty < /dev/tty");

System 会等待程序完成,然后继续执行。
3
nospam at php dot net
24 年前
如果你尝试解析一个需要参数的 CGI 脚本到你的 Web 服务器,请看看 virtual() 函数... 我找了很久才发现它的存在...
使用方法如下
<?php
virtual
("/cgi-bin/lastuser.cgi?argument");
?>
现在对我来说,这非常有效
3
morris_hirsch at hotmail dot com
20 年前
使用 shell_exec 而不是 system 的另一个原因是当结果是多行时,例如 grep 或 ls

<?php

// 这会将 answer 字符串正确地设置为找到的所有行
//$answer = shell_exec ("grep 'set of color names' *.php ");
//echo "answer = $answer";

// 这会将所有行传递到输出(它们显示在页面上)
// 并将 answer 字符串设置为最后一行
$sys = system ("grep 'set of color names' *.php ");
echo
"sys =(($sys))";

?>

这是从 system 调用生成的视图/源代码

setprefs.php:// 标准的颜色名称集是
setprefs.php:// 大多数浏览器接受更广泛的颜色名称集
silly.php: //$answer = shell_exec ("grep 'set of color names' *.php ");
silly.php: $sys = system ("grep 'set of color names' *.php ");
sys =((silly.php: $sys = system ("grep 'set of color names' *.php ");))

这是使用 shell_exec 代替生成的视图源代码

answer = setprefs.php:// 标准的颜色名称集是
setprefs.php:// 大多数浏览器接受更广泛的颜色名称集
silly.php: $answer = shell_exec ("grep 'set of color names' *.php ");
silly.php:// $sys = system ("grep 'set of color names' *.php ");
1
匿名
5 年前
需要 GUI 的 Windows 命令。

有关此主题的大量信息来自 2010-2012 年,指的是 XP,并且基本上不起作用。我使用的是 Windows 7 上的 apache/php/mysql。

当在 Windows 中需要带有 GUI 的系统命令时 - 例如 LabVIEW 可执行文件、记事本等...,其他人提到了来自 Sysinternals 的 psexec 命令,因为 cmd /c 不起作用,但具体用法没有明确定义。以下是在 Windows 7 上对我有用的方法

system('C:/nttools/2019/psexec \\\\10.100.100.101 -i -u administrator -p password -accepteula -nobanner C:\\htdocs\\test\\test.bat');

psexec 可执行文件的路径使用正斜杠,远程 PC 网络位置(实际上是本地 PC,而不是远程)是 \\ip_address,每个反斜杠都带有一个额外的反斜杠,因此需要 4 个 \'s。

要由 psexec 执行的命令的路径需要反斜杠,这也需要双反斜杠。

-i 选项用于交互式程序,对于正确运行是必需的,否则它会显示在任务管理器中,但如果给出了命令行参数,则不会可见或正确执行。

-accepteula -nobanner 用于抑制有关 Sysinternals 许可证的消息框。

我的要执行的命令非常长,有多个命令行输入,其中许多被双引号包围,所以我认为最简单的方法是把它放到一个批处理文件中,然后调用批处理文件。效果很好,远程用户加载网页会导致可执行文件在 Web 服务器上弹出,进行分析然后消失。LabVIEW 可以使用 ActiveX 函数读取本机 Excel 文件,并将数据写入 MySQL 数据库以存储结果等,因此这是非常强大的功能组合。
2
vdweij at hotmail dot com
19 年前
只捕获错误流 (STERR) 是可能的。以下是步骤...

(some_command par1 par2 > /dev/null) 3>&1 1>&2 2>&3

- 首先,STDOUT 重定向到 /dev/null。
- 通过使用圆括号,可以重新获得对 STERR 和 STOUT 的控制权。
- 然后用 STOUT 交换 STERR。

交换使用的是标准变量交换方法 - 需要 3 个变量(桶)来交换 2 个变量。 (你只有 2 个变量,你需要交换它们的内容 - 你必须引入一个第 3 个临时变量来保存一个值的内容,以便你可以正确地交换它们)。

这个链接给了我这些信息
http://www.cpqlinux.com/redirect.html
1
grytolle at gmail dot com
15 年前
这是一个解决方法,它使程序在自己的目录中运行,而不是在脚本的目录中运行。

示例用法
<?php runAsynchronously("c:\games\jazz2\jazz2.exe","-connect 1.2.3.4"); ?>

<?php
function runAsynchronously($path,$arguments) {
$WshShell = new COM("WScript.Shell");
$oShellLink = $WshShell->CreateShortcut("temp.lnk");
$oShellLink->TargetPath = $path;
$oShellLink->Arguments = $arguments;
$oShellLink->WorkingDirectory = dirname($path);
$oShellLink->WindowStyle = 1;
$oShellLink->Save();
$oExec = $WshShell->Run("temp.lnk", 7, false);
unset(
$WshShell,$oShellLink,$oExec);
unlink("temp.lnk");
}
?>
1
kexianin at diyism dot com
14 年前
如果你看不到 system()、shell_exec() 等的任何输出或错误,可以尝试以下方法

<?php
function my_exec($cmd, $input='')
{
$proc=proc_open($cmd, array(0=>array('pipe', 'r'), 1=>array('pipe', 'w'), 2=>array('pipe', 'w')), $pipes);
fwrite($pipes[0], $input);fclose($pipes[0]);
$stdout=stream_get_contents($pipes[1]);fclose($pipes[1]);
$stderr=stream_get_contents($pipes[2]);fclose($pipes[2]);
$rtn=proc_close($proc);
return array(
'stdout'=>$stdout,
'stderr'=>$stderr,
'return'=>$rtn
);
}
var_export(my_exec('echo -e $(</dev/stdin) | wc -l', 'h\\nel\\nlo'));
?>

例如,“echo shell_exec('ls');” 将不会输出任何内容,
“my_exec('ls');” 将会得到 “sh: ls: command not found”,
“my_exec('/bin/ls');” 可能得到 “sh: /bin/ls: Permission denied”,
并且权限问题可能是由 selinux 引起的。
1
d dot kraft at szo dot de
21 年前
对于在 Web 服务器内运行的 PHP

当通过
system("your_process &");
调用进程以使其在后台运行时,请注意,当 Web 服务器重启时,此进程将被终止。
0
vlad dot sharanhovich at gmail dot com
16 年前
之前在评论中讨论的 Windows 平台上的双引号问题在 PHP 5.2.5 中仍然存在。如果 $command 包含超过 2 个 " 字符,则无法执行 system($command)。system('"echo" A'); 可以正常工作,而 system('"echo" "A"'); 则不能。搜索评论,那里有一个解决方案,通过临时 .bat 文件来解决这个问题。
0
eric_REMOVE at movementmovement_REMOVE dot com
20 年前
需要注意的是,如果您在循环中运行一系列 system() 命令,则需要包含第二个参数,以便它们同步运行。

即)

// 这将异步执行 process.php;在执行下一个命令之前不会等待它完成。
$array = array('apple', 'banana', 'pear');
foreach($array as $i)
{
system("php process.php \"fruit=$i\"");
}

// 这将执行 process.php 3 次,在启动一个新命令之前,等待上一个命令完成。
$array = array('apple', 'banana', 'pear');
foreach($array as $i)
{
system("php process.php \"fruit=$i\"", $status);
}
-1
Daniel Morris (danielxmorris.com)
16 年前
如何用 PHP 产生系统响铃。

<?php
function beep ($int_beeps = 1) {
for (
$i = 0; $i < $int_beeps; $i++): $string_beeps .= "\x07"; endfor;
isset (
$_SERVER['SERVER_PROTOCOL']) ? false : print $string_beeps;
}

?>

通过浏览器运行时,这不会做任何事情,如果通过 shell 运行,它将产生 $int_beeps 次的响铃。这应该在 Windows、Unix 等系统上工作。
-2
lc at _REMOVE__THIS_lc dot yi dot org
20 年前
Re: cpmorris at hotmail dot com 和 WINNT。

我刚花了一些时间学习使用 php system 函数。我设法让长文件名对我有用。似乎您需要采用与批处理文件、WSH 和大多数其他编程语言在 WinNT/2K/XP 下相同的做法。在 Path+Filename 周围加上双引号似乎可以正常工作。因此,类似以下内容应该对您有效

"c:\program files\apache group\apache2\bin\htpasswd"

请注意,如果您有参数,则它们在最后一个引号之外。哦,别忘了转义斜杠和引号!

我不知道 htpasswd 的参数是什么,但让我们假设

$cmd="\"c:\\program files\\apache group\\apache2\\bin\\htpasswd\" username password";
$str=system($cmd);

希望这能帮到别人!

Leonard
http:\\www.lc.yi.org
-3
cnoelker at softpearls dot de
21 年前
您好,
一些在 Windows 计算机上使用 system() 调用来执行批处理文件的技巧
* 使用双反斜杠编写可执行文件的路径,如下所示
C:\\path\\to\\prog.exe
* 如果您要引用其他路径,例如作为参数,一个反斜杠就可以了。
* 不要使用 SET 来声明参数 - 这不起作用!例如
SET PATH="C:\path\to\lib"
echo path is %PATH%
从命令行启动时,这可以正常工作,但从 PHP 调用时,变量为空。
-7
Alastair Irvine
6 年前
请注意,system() 在失败时返回 FALSE,但这在命令返回非零退出代码时不会发生。如果命令未找到,system() 甚至不会失败。(bash 在这种情况下返回退出代码 127。)我认为 system() 只有在发生严重错误时才会返回 FALSE,例如无法运行您的 shell。
To Top