Um processo unix pode ler / dev / tty e assim contornar o redirecionamento.
Uma coisa com o programa mysql
chamou minha atenção. Ele pode ser solicitado a solicitar a senha interativamente com o sinalizador -p
. Nesse caso, como seria de se esperar, um prompt será exibido no terminal e o que quer que seja colocado será aceito como senha. O que me surpreendeu é que isso acontece mesmo se você redirecionar todos os três std{in,out,err}
:
$ mysql -p </dev/null >/dev/null 2>/dev/null
Enter password:
Ele lê a senha corretamente também. Se você redirecionar stderr
para um arquivo, poderá verificar se o login falhou.
Como o processo sabe em qual terminal solicitar a senha? Verifica se há terminais conectados aos processos pai?
usa getpass()
da libc (onde disponível), que é descrito nas páginas man da seguinte forma:
The getpass() function opens /dev/tty (the controlling terminal of the process), outputs the string prompt, turns off echoing, reads one line (the "password"), restores the terminal state and closes /dev/tty again.
Ele pode chamar a função 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.
Provavelmente, como observou @Gerard H. Pille, o mysql não verifica nada, mas simplesmente usa /dev/tty
quando você o chama com -p
.
Eu verifiquei em fontes glibc as implementação isatty .
Ele simplesmente usa a função tcgetattr
para obter os recursos de terminal do descritor de arquivo. Se a função retornar true, então é um terminal.