Take the following command:
mysql -u root -p < load_data.sql > output.tab
The -p flag tells the mysql client – a C program – to provide the user with an interactive prompt to enter the password.
AFAIK, input like this is typically handled by writing a prompt to stderr and then blocking on a call like gets, which reads a line from stdin.
But the shell has already opened the load_data.sql file and set the stdin of the mysql client to its file descriptor – so shouldn’t calling gets just get the first line from the file?
My initial thought was that the program seeks to the end before reading a line – but you can’t seek like that on pipes!
So how does this work? Is there some magic?
Applications that prompt for passwords generally don’t actually read them from stdin, on the grounds that this would (a) cause the password to appear on the screen if it was being typed in interactively and (b) encourage plain-text passwords to be bandied around in publicly-visible places when things need to be automated (e.g. in command lines visible to others via
ps). PostgreSQL’spsqlSQL shell opens the terminal device directly, and I suspect mysql will do the same.Some quick searching found this related question. The top-rated answer mentions the GNU function
getpass(), which does indeed open a direct connection to the terminal, bypassing stdin. I suspect that function is what most password-prompting programs use in *nix.