回声测试| stty -echo -> stty:标准输入:设备的 ioctl 不合适

回声测试| stty -echo -> stty:标准输入:设备的 ioctl 不合适

我正在使用一个 perl 脚本,该脚本接受用户输入以下内容:

system( qw( stty -echo ) );
$? == 0 or die "Error unable to disable character printing.\n";
print "$prompt: ";
my $input = <STDIN>;

我以为我可以使用 echo 通过管道输入响应,但它似乎与 stty -echo 命令冲突并产生以下错误:

stty: standard input: Inappropriate ioctl for device

在不更改 perl 脚本的情况下,在 bash 中可以做什么来传递输入?造成问题的原因是什么?

答案1

stty -echo更改输入文件描述符的设置。如果您将某些内容通过管道传输到 stty 命令,则输入文件描述符就是管道,而管道上的 stty 是不合适的(就像错误消息所说的那样)。

目前尚不清楚您想要实现什么目标。如果您想将文本发送test到 Perl 脚本以在行中读取my $input = <STDIN>;,那么只需删除 stty 内容即可。

如果您还想读取文本作为用户输入(即输入),并在执行此操作时防止文本被回显(例如密码),则在执行 stty 之前测试标准输入是否为 tty(终端):

system( qw( stty -echo ) ) if -t 0;

也就是说,不要为各种各样的事情付出代价,这不是 Perl 的用途(否则你还不如用 shell 编写整个事情)。您可以在 perl 中更改 stty 设置,google 是您的朋友。

答案2

stty连接到终端的标准输入。您需要运行 Perl 脚本,并将其标准输入连接到要操作的终端。如果 Perl 脚本本身是从标准输入重定向到终端以外的某个范围调用的,则可以使用/dev/tty来引用进程的控制终端:

that_perl_script </dev/tty

如果您希望能够将输入传递给脚本,并且您不关心脚本对终端设置的作用,则可以使用预计。使用期望将密码提供给需要终端的命令常见。

如果 Perl 脚本仅通过调用命令来访问终端stty,则另一种方法是提供虚拟stty命令。

mkdir dummy-stty
echo '#!/bin/sh' >dummy-stty/stty
chmod a+rx dummy-stty/stty
echo swordfish | PATH=$PWD/dummy-stty:$PATH that_perl_script

相关内容