プログラムの1つがmysql
私の注目を集めました。フラグを使用して、対話的にパスワードを要求するように指示できます-p
。この場合、期待どおりにプロンプトが端末に表示され、入力した内容がパスワードとして受け入れられます。しかし、驚くべきことに、3つすべてをリダイレクトしても、これが起こりますstd{in,out,err}
。
$ mysql -p </dev/null >/dev/null 2>/dev/null
Enter password:
また、パスワードを正しく読みます。ファイルにリダイレクトすると、stderr
ログインに失敗したかどうかを確認できます。
どの端末でパスワードを要求するのか、どのようにプロセスがわかりますか?親プロセスに接続されている端末を確認していますか?
答え1
Unixプロセスはリダイレクトをバイパスすることによって/ dev / ttyからデータを読み取ることができます。
答え2
それ使用 getpass()
libc(利用可能な場合)では、マニュアルページは次のことを説明します。
getpass() 関数は /dev/tty(プロセス制御端末) を開き、文字列プロンプトを印刷し、エコーをオフにし、行 ("password") を読み込み、端末状態を復元し、/dev/tty を再び閉じます。
答え3
isatty
unistd関数を呼び出すことができます。
NAME
isatty - test whether a file descriptor refers to a terminal
SYNOPSIS
#include <unistd.h>
int isatty(int fd);
DESCRIPTION
The isatty() function tests whether fd is an open file descriptor
referring to a terminal.
/dev/tty
おそらく@Gerard H. Pilleが指摘したように、mysqlはまったく確認せずに-p
。
いくつかの追加の詳細
glibcのソースコードを確認しました。イサティの実装。
tcgetattr
ファイル記述子をインポートするには、ターミナル機能を使用します。関数が true を返す場合は端末です。