web-dev-qa-db-ja.com

エコーテスト| 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で何ができるでしょうか?何が問題の原因ですか?

9
user2219808

_stty -echo_は、入力ファイル記述子の設定を変更します。 sttyコマンドに何かをパイプしている場合、入力ファイル記述子はパイプであり、パイプ上のsttyは、ええと、不適切です(エラーメッセージのように)。

何を達成しようとしているのかは不明です。 _my $input = <STDIN>;_行で読み取られるようにテキストtestをPerlスクリプトに送信する場合は、単にsttyを削除します。

テキストをユーザー入力(つまり、入力)として読み取り、テキストのエコー(パスワードなど)を防止する場合も、sttyを実行する前に、標準入力がtty(端末)であるかどうかをテストします。

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

そうは言っても、あらゆる種類のシェルを実行しないでください。それはPerlの目的ではありません(そうでない場合は、すべてをシェルで作成することもできます)。 Perl内からstty設定を変更できます。Googleはあなたの友達です。

5
wurtel

sttyは、標準入力でターミナルに接続します。動作させたい端末に接続されている標準入力でPerlスクリプトを実行する必要があります。 Perlスクリプト自体が、標準入力が端末以外にリダイレクトされるスコープから呼び出される場合、/dev/ttyを使用して、プロセスの制御端末を参照できます。

that_Perl_script </dev/tty

入力をスクリプトに渡せるようにしたい場合で、スクリプトがターミナル設定で何をするかを気にしない場合は、 expect を使用できます。 expect to 端末を必要とするコマンドにパスワードを入力する を使用するのが一般的です。

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