Pytać o hasło w powłoce zgodnej z POSIX?

17

Kiedy chcę poprosić o hasło w bashskrypcie, robię to:

read -s

... ale kiedy uruchamiam bashw trybie POSIX sh, -sopcja jest odrzucana:

$ read -s
sh: 1: read: Illegal option -s

Jak bezpiecznie poprosić o dane wejściowe za pomocą polecenia zgodnego z POSIX?

Hej
źródło
1
Jeden z możliwych sposobów opisano w tej odpowiedzi na SO: stackoverflow.com/a/28393320/3691891
Arkadiusz Drabczyk

Odpowiedzi:

24
read_password() {
  REPLY="$(
    # always read from the tty even when redirected:
    exec < /dev/tty || exit # || exit only needed for bash

    # save current tty settings:
    tty_settings=$(stty -g) || exit

    # schedule restore of the settings on exit of that subshell
    # or on receiving SIGINT or SIGTERM:
    trap 'stty "$tty_settings"' EXIT INT TERM

    # disable terminal local echo
    stty -echo || exit

    # prompt on tty
    printf "Password: " > /dev/tty

    # read password as one line, record exit status
    IFS= read -r password; ret=$?

    # display a newline to visually acknowledge the entered password
    echo > /dev/tty

    # return the password for $REPLY
    printf '%s\n' "$password"
    exit "$ret"
  )"
}

Zwróć uwagę, że w przypadku tych powłok (mksh), w których printfnie jest wbudowane, hasło pojawi się na pswyjściu w postaci wyraźnej (przez kilka mikrosekund) lub może pojawić się w niektórych dziennikach kontroli, jeśli wszystkie wywołania poleceń z ich parametrami są kontrolowane.

Stéphane Chazelas
źródło
2
Czy cat+ heredoc może być bezpieczniejszą alternatywą dla printf?
John Kugelman wspiera Monikę
1
@JohnKugelman tutaj dokumenty są zapisywane jako pliki tymczasowe w większości powłok, podczas gdy printf jest wbudowany w większość powłok. Nie jestem pewien, co jest najlepsze.
Stéphane Chazelas,
Dziękujemy za pokazanie, jak zapisać i przywrócić stare sttyustawienia.
Barmar,
20

read -snie ma w POSIX. Jeśli chcesz być zgodny z POSIX, użyjstty -echo . sttya jego echoparametr jest zdefiniowany w POSIX.

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

Działa to na wszystkich powłokach zgodnych z POSIX.

Źródło

serenesat
źródło
7
aby podkreślić punkt z odpowiedzi w komentarzu @ arkadiusz-drabczyk, dobrym pomysłem byłoby przechwycenie wszystkich możliwych sygnałów w celu ponownego włączenia stty echo- na wypadek, gdyby użytkownik się zdezorientował i wcisnął Control-C podczas read PASSWORDsekcji .
Jeff Schaller
przeczytaj połączoną odpowiedź lub zobacz odpowiedź Stephane'a w tym wątku
Jeff Schaller
Nie powinieneś bezwarunkowo włączać echa, powinieneś zapisać i przywrócić stare ustawienie. Wiele osób pracuje w buforach powłoki Emacsa, a to zwykle wyłącza echo, ponieważ Emacs robi to samo. Druga odpowiedź pokazuje, jak to zrobić.
Barmar,