632 Stimmen

Wie man ein Passwort aus einem Shell-Skript ohne Echo abfragt

Ich habe ein Skript, das einen Prozess automatisiert, der Zugang zu einem passwortgeschützten System benötigt. Der Zugriff auf das System erfolgt über ein Befehlszeilenprogramm, das das Benutzerkennwort als Argument akzeptiert.

Ich möchte den Benutzer auffordern, sein Kennwort einzugeben, es einer Shell-Variablen zuweisen und dann diese Variable verwenden, um die Befehlszeile des Zugriffsprogramms zu erstellen (das natürlich eine Stream-Ausgabe erzeugt, die ich verarbeiten werde).

Ich bin ein einigermaßen kompetenter Shell-Programmierer in Bourne/Bash, aber ich weiß nicht, wie ich die Benutzereingabe akzeptieren kann, ohne dass sie als Echo an das Terminal gesendet wird (oder vielleicht mit '*'-Zeichen).

Kann mir jemand dabei helfen?

901voto

wsware Punkte 8060

Hier ist eine andere Möglichkeit:

#!/bin/bash
# Read Password
echo -n Password: 
read -s password
echo
# Run Command
echo $password

El read -s schaltet das Echo für Sie aus. Ersetzen Sie einfach die echo in der letzten Zeile mit dem Befehl, den Sie ausführen möchten.

312voto

thecloud Punkte 2899

Eine POSIX-konforme Antwort. Beachten Sie die Verwendung von /bin/sh anstelle von /bin/bash . (Es funktioniert zwar mit der Bash, aber nicht mit der erfordern bash).

#!/bin/sh
stty -echo
printf "Password: "
read PASSWORD
stty echo
printf "\n"

127voto

smendola Punkte 2183

Nur eine Zeile:

read -s -p "Password: " password

Unter Linux (und cygwin) funktioniert diese Form in bash und sh. Es ist aber nicht unbedingt das Standard-Unix sh.

Weitere Informationen und Optionen erhalten Sie, wenn Sie in der Bash "help read" eingeben.

$ help read
read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
Read a line from the standard input and split it into fields.
  ...
  -p prompt output the string PROMPT without a trailing newline before
            attempting to read
  ...
  -s                do not echo input coming from a terminal

80voto

Susam Pal Punkte 29750

El -s Option von read ist im POSIX-Standard nicht definiert. Siehe http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html . Ich wollte etwas, das für jede POSIX-Shell funktioniert, also habe ich eine kleine Funktion geschrieben, die stty um das Echo zu deaktivieren.

#!/bin/sh

# Read secret string
read_secret()
{
    # Disable echo.
    stty -echo

    # Set up trap to ensure echo is enabled before exiting if the script
    # is terminated while echo is disabled.
    trap 'stty echo' EXIT

    # Read secret.
    read "$@"

    # Enable echo.
    stty echo
    trap - EXIT

    # Print a newline because the newline entered by the user after
    # entering the passcode is not echoed. This ensures that the
    # next line of output begins at a new line.
    echo
}

Diese Funktion verhält sich ganz ähnlich wie die read Befehl. Hier ist eine einfache Verwendung von read gefolgt von einer ähnlichen Verwendung von read_secret . Die Eingabe in read_secret erscheint leer, weil es nicht an das Terminal zurückgesendet wurde.

[susam@cube ~]$ read a b c
foo \bar baz \qux
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=bar c=baz qux
[susam@cube ~]$ unset a b c
[susam@cube ~]$ read_secret a b c

[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=bar c=baz qux
[susam@cube ~]$ unset a b c

Hier ein weiteres Beispiel, das die -r um die Backslashes in der Eingabe zu erhalten. Dies funktioniert, weil die read_secret Funktion, die oben definiert wurde, übergibt alle Argumente, die sie erhält, an die read comando.

[susam@cube ~]$ read -r a b c
foo \bar baz \qux
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=\bar c=baz \qux
[susam@cube ~]$ unset a b c
[susam@cube ~]$ read_secret -r a b c

[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=\bar c=baz \qux
[susam@cube ~]$ unset a b c

Zum Schluss noch ein Beispiel, das zeigt, wie man die read_secret Funktion, um ein Kennwort auf POSIX-konforme Weise zu lesen.

printf "Password: "
read_secret password
# Do something with $password here ...

18voto

Manuel Punkte 317

Ich fand, dass die askpass Befehl nützlich

password=$(/lib/cryptsetup/askpass "Give a password")

Jedes Eingabezeichen wird durch * ersetzt. Siehe: Passwort eingeben ****

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X