2024年PHP开发者大会日本站

system

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

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

描述

system(字符串 $command, 整数 &$result_code = null): 字符串|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 . '
<hr />返回值: '
. $retval;
?>

注释

警告

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

注意:

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

参见

添加注释

用户贡献的注释 18条注释

64
no at mail dot com
12年前
这是针对 WINDOWS 用户的。我正在运行 Apache,并且已经尝试了几个小时来捕获命令的输出。

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

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

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

system("yourCommandName 2>&1",$output) ;
13
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("返回错误: $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 database 返回的文件扩展名
$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].' 已被接受 <br />';
if(!
file_exists($uploaddir)){
// 将文件复制到某个永久位置
if(move_uploaded_file($_FILES["uploadedfile"]["tmp_name"], $uploaddir))
{
echo
$uploaddir." 已上传! <br />";
}
else
{
echo
"上传新文件时出现问题,请联系管理员。";
}
}
else echo
'该文件已存在于数据库中,请上传前重命名。';
}
}else echo
$_FILES['uploadedfile']['error'].'<br />';
?>
4
[email protected]
25年前
如果尚未打印任何报头,则调用 system() 函数将把报头刷新到客户端并插入换行符;不会将更多报头或 Cookie 传输到浏览器。在 3.0.7 版本中,不会警告您 Header() 函数失败,但如果尝试设置 Cookie,则会收到警告。如果要在函数调用后继续发送报头,请改用 exec()。
4
[email protected]
24年前
如果您尝试将需要参数的 CGI 脚本解析到您的 Web 服务器,请查看 virtual() 函数……我花了很长时间才发现它的存在……
使用方法如下
<?php
virtual
("/cgi-bin/lastuser.cgi?argument");
?>
现在对我来说效果很好
3
Jim Belton
21年前
要从 PHP CLI 脚本运行全屏程序,请将输入和输出重定向到 /dev/tty。例如

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

System 将等待程序完成才能继续。
1
匿名用户
5年前
需要 GUI 的 Windows 命令。

关于此主题的许多信息来自 2010-2012 年期间,指的是 XP,并且基本上不起作用。我正在 Windows 7 中使用 apache/php/mysql。

当需要具有 GUI 的 Windows 系统命令时——例如 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 个'\'。

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

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

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

我执行的命令非常长,包含多个命令行输入,其中许多都用双引号括起来,所以我认为将它们放在批处理文件中并只调用 bat 文件是最简单的。效果很好,远程用户加载网页会导致可执行文件在 Web 服务器上弹出,执行其分析并消失。LabVIEW 可以使用 ActiveX 函数读取本机 Excel 文件并写入 MySQL 数据库以存储结果等,因此这是一个非常强大的功能组合。
2
[email protected]
19年前
可以只捕获错误流 (STERR)。如下所示……

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

-首先将 STDOUT 重定向到 /dev/null。
-通过使用括号,可以再次控制 STERR 和 STOUT。
-然后交换 STERR 和 STOUT。

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

此链接提供了此信息
http://www.cpqlinux.com/redirect.html
2
[email protected]
21年前
使用 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 调用产生的 view/source

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 而不是 system 的 view source

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
[email protected]
21年前
对于在 Web 服务器内部运行的 PHP

通过以下方式调用进程时
system("your_process &");
使其在后台运行,请注意,当 Web 服务器重新启动时,此进程将被终止。
0
[email protected]
15年前
如果您看不到 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引起的。
0
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");
}
?>
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文件解决此问题的方案。
-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等。
-1
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);
}
-2
lc at _REMOVE__THIS_lc dot yi dot org
21年前
回复:cpmorris at hotmail dot com 和 WINNT。

我刚刚花了一些时间学习使用php system函数。我成功地使长文件名对我起作用。似乎你需要采用与批处理文件、WSH和大多数其他编程语言在WinNT/2K/XP下相同的做法。在路径+文件名周围加上双引号似乎有效。所以,类似这样的东西应该对你有用

"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调用时,变量为空。
To Top