我想一次从PHP的命令行中一次读取一个字符,但是似乎从某处阻止了某种输入缓冲。
考虑以下代码:
#!/usr/bin/php <?php echo "input# "; while ($c = fread(STDIN, 1)) { echo "Read from STDIN: " . $c . "\ninput# "; } ?>
输入“ foo”作为输入(并按回车键),我得到的输出是:
input# foo Read from STDIN: f input# Read from STDIN: o input# Read from STDIN: o input# Read from STDIN: input#
我 期望 的输出是:
input# f input# Read from STDIN: f input# o input# Read from STDIN: o input# o input# Read from STDIN: o input# input# Read from STDIN: input#
(即,在键入字符时对其进行读取和处理)。
但是,当前,仅在按下回车键后才能读取每个字符。我怀疑TTY正在缓冲输入。
最终,我希望能够读取按键,例如向上箭头,向下箭头等。
我的解决方案是-icanon在TTY上设置模式(使用stty)。例如。:
-icanon
stty
stty -icanon
因此,现在可以使用的代码是:
#!/usr/bin/php <?php system("stty -icanon"); echo "input# "; while ($c = fread(STDIN, 1)) { echo "Read from STDIN: " . $c . "\ninput# "; } ?>
输出:
input# fRead from STDIN: f input# oRead from STDIN: o input# oRead from STDIN: o input# Read from STDIN: input#
完成操作后,别忘了还原TTY …
恢复tty配置
通过在更改终端状态之前保存tty状态,可以将终端重置回原来的状态。完成后,您可以恢复到该状态。
例如:
<?php // Save existing tty configuration $term = `stty -g`; // Make lots of drastic changes to the tty system("stty raw opost -ocrnl onlcr -onocr -onlret icrnl -inlcr -echo isig intr undef"); // Reset the tty back to the original configuration system("stty '" . $term . "'"); ?>
这是保存tty并将其放回用户开始之前的方式的唯一方法。
请注意,如果您不担心保留原始状态,只需执行以下操作即可将其重置回默认的“健全”配置:
<?php // Make lots of drastic changes to the tty system("stty raw opost -ocrnl onlcr -onocr -onlret icrnl -inlcr -echo isig intr undef"); // Reset the tty back to sane defaults system("stty sane"); ?>