使用shell_exec(bash read)的PHP适用于tty,但输入是通过管道输入时没有新行

时间:2016-11-20 21:15:24

标签: php bash terminal newline stdin

TL; DR - echo -n abc | bash -c 'read -s x && echo -n \$x'不会输出abc

我有一个PHP CLI脚本,需要从stdin读取密码。

<?php

function quiet_read_stdin ()
{
    return shell_exec ("bash -c 'read -s x && echo -n \$x'");
}

print "got: ###".quiet_read_stdin ()."###\n";
?>

如果我在终端中运行并输入,比如'xyz':

$> php /tmp/foo.php
got: ###xyz###

正如所料,这也有效

$> echo xyz | php /tmp/foo.php
got: ###xyz###

但事实并非如此。

$> echo -n xyz | php /tmp/foo.php
got: ######

如果密钥存储在没有换行符的文件中,这会导致我的脚本出现问题,相当于php /tmp/foo.php < keyfile

这不起作用(Inappropriate ioctl for device):

system ('stty -echo');
$password = trim (fgets (STDIN));
system ('stty echo');

我不想在任何阶段插入换行符来捏造它。 如何修改quiet_read_stdin,以便无论输入是否有尾随换行符,它都能正常工作?只支持Linux的解决方案。

2 个答案:

答案 0 :(得分:0)

对我而言,这有效:

$ cat test.php
<?php
// ignore error message
// stty: standard input: Inappropriate ioctl for device    
shell_exec('stty -echo 2>/dev/null'); 

$io = fopen("php://stdin", "r");
$password = fgets($io);
echo "foo: $password\n";

shell_exec('stty echo 2>/dev/null');

$ echo -n "xyz" | php test.php
foo: xyz

$ php test.php          # typing: abc[ENTER]
foo: abc

答案 1 :(得分:0)

这将读取包含或不包含换行符的行,并始终使用换行符打印

readslient.sh:

#!/bin/bash

while IFS= read -r -s LINE || [[ -n "$LINE" ]]; do
    echo $LINE
done
然后

PHP可以

$pw = rtrim (shell_exec ("readslient.sh"));

我无法看到如何将它作为shell-exec的单行,但是没有一个单独的文件会很好。