【发布时间】:2011-08-19 00:17:17
【问题描述】:
是否可以使用 unix 管道将数据传输到命令行 php 脚本中?我试过了
$> data | php script.php
但预期的data 没有出现在$argv 中。有没有办法做到这一点?
【问题讨论】:
标签: php command-line pipe
是否可以使用 unix 管道将数据传输到命令行 php 脚本中?我试过了
$> data | php script.php
但预期的data 没有出现在$argv 中。有没有办法做到这一点?
【问题讨论】:
标签: php command-line pipe
我需要获取一个 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
希望这对您有所帮助,并让您了解自己还能做多少!
【讨论】:
PHP 可以从标准输入中读取,并且还提供了一个不错的快捷方式:STDIN。
有了它,您可以使用stream_get_contents 和其他人来执行以下操作:
$data = stream_get_contents(STDIN);
这只会将所有管道数据转储到$data。
如果您想在读取所有数据之前开始处理,或者输入大小太大而无法放入变量中,您可以使用:
while(!feof(STDIN)){
$line = fgets(STDIN);
}
STDIN 只是$fh = fopen("php://stdin", "r"); 的快捷方式。
同样的方法可以应用于读写文件和tcp流。
【讨论】:
最好的选择是使用 -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() { ... }
【讨论】:
如果您的data 是一个类似的,您还可以使用 -F 或 -R 标志(-F 读取并执行其后的文件,-R 逐字执行)如果您使用这些标志,则已通过管道输入将出现在(常规)全局变量 $argn
简单示例:
echo "hello world" | php -R 'echo str_replace("world","stackoverflow", $argn);'
【讨论】:
-R 将一次读取一行,并执行每一行的所有代码。
看到这篇文章,希望制作一个行为类似于 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;
}
【讨论】:
这对我有用:
stream_get_contents(fopen("php://stdin", "r"));
【讨论】:
如果你想让它显示在$argv,试试这个:
echo "Whatever you want" | xargs php script.php
这会将标准输入中的任何内容转换为命令行参数。
【讨论】:
您可以通过管道输入数据,是的。但它不会出现在$argv 中。它将进入标准输入。您可以通过多种方式阅读本文,包括fopen('php://stdin','r')
有很好的例子in the manual
【讨论】:
据我了解,$argv 将显示程序的参数,换句话说:
php script.php arg1 arg2 arg3
但是,如果您将数据通过管道传输到 PHP,您将不得不从标准输入中读取它。我从未尝试过,但我认为它是这样的:
$fp = readfile("php://stdin");
// read $fp as if it were a file
【讨论】: