在 PHP 中使用命令行工具 shell(2)

例如,如果您仅希望计算该目录下的前 5 个文本文件的单词数,那么可以使用竖线 (|) 将 wc 和 head 命令连接起来。另外,您还可以将输出结果放到 pre 标记内部,让它能够更美观地呈现在 Web 浏览器中,如下所示。


清单 5. 更加复杂的 shell 命令

<?php $results = shell_exec('wc -w *.txt | head -5'); echo "<pre>".$results . "</pre>"; ?>  

图 2 演示了运行清单 5 的脚本得到的结果。


图 2. 从 shell_exec() 运行更复杂的 shell 命令得到的结果

从 shell_exec() 运行更复杂的 shell 命令得到的结果



在本文的后面部分,您将学习如何使用 PHP 为这些脚本传递参数。现在您可以将它看作运行 shell 命令的一种方法,但要记住您只能看到标准输出。如果命令或脚本出现错误,您将看不到标准的错误 (stderr),除非您通过竖线将它添加到 stdout。

passthru()

passthru() 允许您运行外部程序,并在屏幕上显示结果。您不需要使用 echo 或 return 来查看结果;它们会显示在浏览器上。您可以添加可选的参数,即保存从外部程序返回的代码的变量,比如表示成功的 0,这为调试提供更好的机制。

在清单 6 中,我使用 passthru() 命令运行在前面小节运行的单词计数脚本。如您所见,我还添加一个包含返回代码的 $returnval 变量。


清单 6. 使用 passthru() 命令运行单词计数脚本

<?php passthru('wc -w *.txt | head -5',$returnval); echo "<hr/>".$returnval; ?>  

注意,我不需要使用 echo 返回任何东西。结果会直接显示在屏幕上,如下所示。


图 3. 使用 return 代码运行 passthru() 命令的结果

passthru() 命令的示例结果



在清单 7 中,我通过删除脚本头部的 5 前面的短横线 (-) 引入一个小错误。


清单 7. 在单词计数脚本中引入一个错误

<?php //we introduce an error below (removing - from the head command) passthru('wc -w *.txt | head 5',$returnval); echo "<hr/>".$returnval; ?>  

注意,脚本未能按照预期运行。您得到的是一个空白的屏幕,一条水平线和返回值 1,如图 4 所示。这个返回代码通常表明发生了某些错误。如果能够测试返回代码,查找和修复错误就容易多了。


图 4. 使用 passthru() 时查看错误代码

passthru() 错误返回代码



exec()

exec() 命令与 shell_exec() 相似,不同之处是它返回输出的最后一行,并且可选地用命令的完整输出和错误代码填充数组。清单 8 展示了当运行 exec() 而不捕捉数据数组中的数据时发生的事情。


清单 8. 运行 exec() 而不捕捉数据数组中的数据

<?php $results = exec('wc -w *.txt | head -5'); echo $results; #would print out just the last line or results, i.e.: #3847 myfile.txt ?>  

为了捕捉数组中的结果,要将该数组的名称作为第二个参数添加到 exec()。我在清单 9 中执行了这个步骤,并以 $data 作为数组的名称。


清单 9. 从 exec() 捕捉数据数组的结果

<?php $results = exec('wc -w *.txt | head -5',$data); print_r($data); #would print out the data array: #Array ( [0]=> 555 text1.txt [1] => 283 text2.txt) ?>  

在捕捉数组中的结果之后,您可以对每行进行一些处理。例如,您可以在第一个空格处进行划分,将分离的值存储在数据库表中,或对每个行应用特定的格式或标记。

system()

如清单 10 所示,system() 命令是一种混合体。它像 passthru() 一样直接输出从外部程序接收到的任何东西。它还像 exec() 一样返回最后一行,并使返回代码可用。


清单 10. system() 命令

<?php system('wc -w *.txt | head -5'); #would print out: #123 file1.txt 332 file2.txt 444 file3.txt #and so on ?>  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/17623a6abbd69f0e2bfd67bae64072d8.html