Question

I have a script that makes of stdin. It also includes internal calls to curl, that are constructed based on the stdin data, and that require password authentication via form variables in the url.

I'd like to be able to type my password when I run the script, rather than storing it somewhere, but stdin is "taken". What's a good way to write a script like this? I'd be interested in either a good way to keep it in the filesystem or if there's some conceivable way to get it as live input without fouling up the incoming pipe.

Was it helpful?

Solution

Read it from the TTY:

if terminal=$(tty < /dev/tty || tty || tty 0<&1 || tty 0<&2) 2> /dev/null
then
  echo "Enter password: " > "$terminal"
  IFS= read -r password < "$terminal"
else
  echo "There is no terminal to read a password from." >&2
  exit 1
fi

This tries to get the terminal associated with /dev/tty, or stdin/stdout/stderr if the OS doesn't support it, and uses it to read and write directly to the user.

If it doesn't have to be portable, e.g. when using use Bash on Linux or FreeBSD, you can simplify and improve this:

if ! IFS= read -rs -p "Enter password: " password < /dev/tty 2> /dev/tty
then
  echo "Password entry failed"
  exit 1
fi

OTHER TIPS

At risk of muddying the question, I needed to switch over to perl and thought it might be useful to some people who find themselves here if I posted a perl translation of "that other guy"'s answer. (Don't know if this is the cleanest way, but it worked for me.)

open (TTY, "+< /dev/tty" )
  or eval 'sub Term::ReadLine::findConsole { ("&STDIN", "&STDERR") }';
    die $@ if $@;

print TTY "Enter your password: ";
use Term::ReadKey;
ReadMode('noecho', *TTY);
my $password = ReadLine(0, *TTY);
chomp $password;
ReadMode('normal', *TTY);
print TTY "\n";
close (TTY);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top