管道数据到命令行php?

时间:2011-05-05 02:03:03

标签: php command-line pipe

可以使用unix管道将数据传输到命令行php脚本中吗?我试过了

$> data | php script.php

但预期的data未显示在$argv中。有没有办法做到这一点?

9 个答案:

答案 0 :(得分:31)

PHP可以从标准输入读取,也为它提供了一个很好的快捷方式:STDIN。

有了它,你可以做以下事情:

$data = stream_get_contents(STDIN);

这只会将所有管道数据转储到$ data。

如果要在读取所有数据之前开始处理,或者输入大小太大而无法放入变量,可以使用:

while(!feof(STDIN)){
    $line = fgets(STDIN);
}

STDIN只是$ fh = fopen(“php:// stdin”,“r”)的快捷方式; 相同的方法可以应用于读写文件和tcp流。

答案 1 :(得分:21)

据我了解,$argv将显示该程序的参数,换句话说:

php script.php arg1 arg2 arg3

但是如果将数据传输到PHP中,则必须从标准输入中读取它。我从来没有尝试过这个,但我认为它是这样的:

$fp = readfile("php://stdin");
// read $fp as if it were a file

答案 2 :(得分:16)

如果你的data就是这样,你也可以使用-F或-R标志(-F读取并执行后面的文件,-R按字面执行)如果你使用这些标志管道输入的字符串将出现在(常规)全局变量$ argn

简单示例:

echo "hello world" | php -R 'echo str_replace("world","stackoverflow", $argn);'

答案 3 :(得分:4)

您可以输入数据,是的。但它不会出现在$argv中。它会去stdin。您可以通过以下几种方式阅读,包括fopen('php://stdin','r')

有很好的例子in the manual

答案 4 :(得分:4)

这对我有用:

stream_get_contents(fopen("php://stdin", "r"));

答案 5 :(得分:3)

来看这篇文章,希望制作一个行为类似于shell脚本的脚本,为输入的每一行执行另一个命令...例如:

ls -ln | awk '{print $9}'

如果您正在寻找以类似方式运行的PHP脚本,这对我有用:

#!/usr/bin/php
<?php

$input = stream_get_contents(fopen("php://stdin", "r"));

$lines = explode("\n", $input);

foreach($lines as $line) {
    $command = "php next_script.php '" . $line . "'";
    $output = shell_exec($command);
    echo $output;
}

答案 6 :(得分:1)

如果您希望它显示在$argv中,请尝试以下操作:

echo "Whatever you want" | xargs php script.php

这将转换为命令行参数的标准输入。

答案 7 :(得分:0)

最佳选择是使用-r选项并从标准输入中获取数据。即,我使用它轻松地使用PHP解码JSON。 这样,您不必创建物理脚本文件。

它是这样的:

docker inspect $1|php -r '$a=json_decode(stream_get_contents(STDIN),true);echo str_replace(["Array",":"],["Shares","  -->  "],print_r($a[0]["HostConfig"]["Binds"],true));'

这段代码将显示主机和容器之间的共享文件夹。 请用容器名称替换$ 1或将其放入bash别名中,例如 displayshares(){...}

答案 8 :(得分:0)

我需要获取一个CSV文件并将其转换为TSV文件。当然,我可以将文件导入Excel,然后重新导出,但是有趣之处在于,通过转换器传递数据时,我可以留在命令行中并轻松完成工作!

因此,我的脚本(称为csv2tsv)是

#!/usr/bin/php
<?php
while(!feof(STDIN)){
    echo implode("\t", str_getcsv(fgets(STDIN))), PHP_EOL;
}

chmod +x csv2tsv

然后我可以运行它cat data.csv | csv2tsv > data.tsv,现在我将数据作为TSV了!

好。没有错误检查(数据是实际的CSV文件吗?)等,但是原理很好。

当然,您可以根据需要链接任意数量的命令。

如果您想进一步扩展这个想法,那么在命令中包含其他选项的能力又如何呢?

简单!

#!/usr/bin/php
<?php
$separator = $argv[1] ?? "\t";
while(!feof(STDIN)){
    echo implode($separator, str_getcsv(fgets(STDIN))), PHP_EOL;
}

现在,我可以将默认的分隔符从制表符覆盖为其他内容。可能是|

cat data.csv | csv2tsv '|' > data.psv

希望这会有所帮助,并让您看到还能做什么!