可以使用unix管道将数据传输到命令行php脚本中吗?我试过了
$> data | php script.php
但是预期的
data
并没有出现在$argv
中。有办法做到这一点吗?
PHP 可以从标准输入读取,并且还提供了一个很好的快捷方式:
STDIN
。
stream_get_contents
之类的东西来执行以下操作:
$data = stream_get_contents(STDIN);
这只会将所有管道数据转储到
$data
。
如果您想在读取所有数据之前开始处理,或者输入大小太大而无法放入变量中,您可以使用:
while(!feof(STDIN)){
$line = fgets(STDIN);
}
STDIN
只是 $fh = fopen("php://stdin", "r");
的快捷方式。
相同的方法可以应用于读写文件、tcp 流。
据我了解,
$argv
将显示程序的参数,换句话说:
php script.php arg1 arg2 arg3
但是如果将数据通过管道传输到 PHP,则必须从标准输入读取它。我从未尝试过这个,但我认为是这样的:
$fp = readfile("php://stdin");
// read $fp as if it were a file
如果您的
data
位于类似的位置,您还可以使用 -F 或 -R 标志(-F 读取并执行其后面的文件,-R 按字面意思执行它)。通过管道输入将出现在(常规)全局变量 $argn
简单的例子:
echo "hello world" | php -R 'echo str_replace("world","stackoverflow", $argn);'
这对我有用:
stream_get_contents(fopen("php://stdin", "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;
}
如果您希望它出现在
$argv
中,请尝试以下操作:
echo "Whatever you want" | xargs php script.php
这会将标准输入中的任何内容隐藏到命令行参数中。
最好的选择是使用 -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 别名中,例如 ie displayshares() { ... }
我需要获取 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
希望这对您有所帮助,并让您看到自己还能做多少事情!
也可以通过
STDIN
喂食。
echo 'Hi <?php echo getenv()["USER"];?>!' | php
php <<< 'Hi <?php echo getenv()["USER"];?>!'
将文件输入 STDIN:
cat code.php | php
php <<< $(cat somehtml.html)