2009-12-17 2 views

Antwort

50

Als Mark Rushakoff wies darauf hin, read -s unterdrückt das Echo von Zeichen eingegeben an der Eingabeaufforderung. Sie können Verwendung dieser Funktion als Teil dieses Skript machen getippt Sternchen für jedes Zeichen Echo:

#!/bin/bash 
unset password 
prompt="Enter Password:" 
while IFS= read -p "$prompt" -r -s -n 1 char 
do 
    if [[ $char == $'\0' ]] 
    then 
     break 
    fi 
    prompt='*' 
    password+="$char" 
done 
echo 
echo "Done. Password=$password" 
+5

Sie müssen IFS 'aufheben' oder 'IFS =' zu Ihrer while-Schleife hinzufügen, sonst wird Ihre Schleife bei Passwörtern, die Leerzeichen enthalten, vorzeitig unterbrochen. Außerdem sollten Sie das '-r'-Flag zu' read' hinzufügen, damit Kennwörter umgekehrte Schrägstriche enthalten können. – SiegeX

+1

'password + =" $ char "' hat auf meinem System nicht funktioniert. Ich musste stattdessen "password =" $ {password} $ {char} "' tun. –

+2

@BradMace: Sie dürfen nicht Bash, Ksh (93) oder Zsh verwenden oder Sie verwenden eine sehr alte Version von Bash (z. B. 2.05b). –

2
stty -echo 
read something 
stty echo 

wird stoppen Benutzereingaben auf dem Bildschirm für diese gelesen werden. Je nachdem, was Sie mit Eingabeaufforderungen machen, möchten Sie möglicherweise einen zusätzlichen Befehl echo hinzufügen, um nach dem Lesen einen Zeilenumbruch zu generieren.

5

Ich weiß nicht, über Sterne, aber stty -echo ist dein Freund:

#!/bin/sh 
read -p "Username: " uname 
stty -echo 
read -p "Password: " passw; echo 
stty echo 

Quelle: http://www.peterbe.com/plog/passwords-with-bash

+0

Danke! Funktioniert gut! –

+1

Das scheint kaum nötig, da 'read' eine '-s'-Option hat (die Frage ist mit' bash' markiert, so dass wir bash-spezifische Funktionen annehmen können). Das Unterbrechen des "Lese" -Befehls (z. B. durch Eingeben von Steuerung-C) könnte die tty im "-echo" -Modus belassen. –

11

read -s sollte es im Silent-Modus setzen:

-s  Silent mode. If input is coming from a terminal, characters are not echoed. 

See die read Sektion in man bash.

+0

Er möchte ein Feedback, keine Noecho-Stille! – anthony

-1
#!/bin/bash 
echo "------------------------------" 

n=7 
echo " Enter Password :" 

for ((i=1;i<n;i++)) 
do 
    stty -echo 
    read -r -s -n 1 char 
    stty echo 

    echo -n "*" 
    pass+="$char" 

done 

echo " " 
echo " Your password : $pass " 

echo "" 
echo "-------------------------------" 
+0

Ich bin weit davon entfernt, ein Bash-Experte zu sein, aber ich denke, dass dieser Code mehrere Probleme hat (wie ein Passwort mit einer festen Länge von 6 und nicht mit Backspaces funktioniert) – kratenko

5

Ich möchte etwas Dennis Williamson ‚s Lösung hinzuzufügen:

#!/bin/bash 

unset password 
echo -n "Enter password: " 
while IFS= read -p "$prompt" -r -s -n 1 char 
do 
    # Enter - accept password 
    if [[ $char == $'\0' ]] ; then 
     break 
    fi 
    # Backspace 
    if [[ $char == $'\177' ]] ; then 
     prompt=$'\b \b' 
     password="${password%?}" 
    else 
     prompt='*' 
     password+="$char" 
    fi 
done 

Im obigen Beispiel behandelt Skript die Rücktaste korrekt.

Source

+0

Es behandelt DEL "korrekt". Mit der Rücktaste (Strg-H) macht es nichts Besonderes. –

+0

Benutzer "_Normal_" verwenden lieber Standardrückschritt, nicht Strg + H. Das obige Skript behandelt auch die Pfeiltasten nicht richtig, aber hey, es ist besser, Backspace und _not_ handle Strg + H zu behandeln, oder behandeln beide nicht? ;) – Wirone

+1

Ctrl-H * ist * Backspace (der Unicode-Standard nennt es 'BACKSPACE'). '$ '\ 177'' ist DEL (Unicode nennt es' DELETE'). Einige Terminalprogramme können optional den Backspace-Schlüssel dem DEL-Zeichen zuordnen, aber viele "* normal *" - Benutzer, einschließlich mir selbst, ordnen sie dem Backspace-Zeichen (Ctrl-H) zu. Eine robuste Lösung würde die Einstellungen des Benutzers prüfen. –

16

Ich mochte die Antwort, dass Wirone gab, aber ich mochte nicht, dass die Umsteuerung Zeichen auch wieder in das „Passwort eingeben:“ Entfernen fortsetzen würde prompt.

Ich hatte auch einige Probleme, wo Tasten zu schnell drücken würde dazu führen, dass einige der Zeichen tatsächlich auf dem Bildschirm drucken ... nie eine gute Sache, wenn Sie nach einem Passwort fragen. =)

Das Folgende ist meine modifizierte Version von Wirone ‚s Antwort, die diese Fragen behandelt werden:

#!/bin/bash 

unset PASSWORD 
unset CHARCOUNT 

echo -n "Enter password: " 

stty -echo 

CHARCOUNT=0 
while IFS= read -p "$PROMPT" -r -s -n 1 CHAR 
do 
    # Enter - accept password 
    if [[ $CHAR == $'\0' ]] ; then 
     break 
    fi 
    # Backspace 
    if [[ $CHAR == $'\177' ]] ; then 
     if [ $CHARCOUNT -gt 0 ] ; then 
      CHARCOUNT=$((CHARCOUNT-1)) 
      PROMPT=$'\b \b' 
      PASSWORD="${PASSWORD%?}" 
     else 
      PROMPT='' 
     fi 
    else 
     CHARCOUNT=$((CHARCOUNT+1)) 
     PROMPT='*' 
     PASSWORD+="$CHAR" 
    fi 
done 

stty echo 

echo $PASSWORD 
+0

Danke für das Update! – Wirone

+0

Eine erweiterte Version ist [ask_password_stars] (http://www.ict.griffith.edu.au/anthony/software/# ask_password_stars). Es wurde als Teil meiner persönlichen Notizen zu [Cryptogrphy, Password Input] (http://www.ict.griffith.edu.au/anthony/info/crypto/passwd_input.txt) entwickelt. – anthony

0

Wenn Sie nicht darüber ist interaktiv egal, können Sie einfach tun

read -s pass 
echo "$pass" | sed 's/./*/g' 

Dies zeigt ein * für jedes Zeichen des eingegebenen Passworts, nachdem Enter gedrückt wurde.

0

Ich habe gerade diese Bash-spezifische Funktion basierend auf Dennis Williamson 's, Wirone' s und Logan VanCuren ‚s Antworten:

ask() { 
    local 'args' 'char' 'charcount' 'prompt' 'reply' 'silent' 

    # Basic arguments parsing 
    while [[ "${1++}" ]]; do 
    case "${1}" in 
     ('--silent' | '-s') 
     silent='yes' 
     ;; 
     ('--') 
     args+=("${@:2}") 
     break 
     ;; 
     (*) 
     args+=("${1}") 
     ;; 
    esac 
    shift || break 
    done 

    if [[ "${silent}" == 'yes' ]]; then 
    for prompt in "${args[@]}"; do 
     charcount='0' 
     prompt="${prompt}: " 
     reply='' 
     while IFS='' read -n '1' -p "${prompt}" -r -s 'char'; do 
     case "${char}" in 
      # Handles NULL 
      ($'\000') 
      break 
      ;; 
      # Handles BACKSPACE and DELETE 
      ($'\010' | $'\177') 
      if ((charcount > 0)); then 
       prompt=$'\b \b' 
       reply="${reply%?}" 
       ((charcount--)) 
      else 
       prompt='' 
      fi 
      ;; 
      (*) 
      prompt='*' 
      reply+="${char}" 
      ((charcount++)) 
      ;; 
     esac 
     done 
     printf '\n' >&2 
     printf '%s\n' "${reply}" 
    done 
    else 
    for prompt in "${args[@]}"; do 
     IFS='' read -p "${prompt}: " -r 'reply' 
     printf '%s\n' "${reply}" 
    done 
    fi 
} 

Es ist wie verwendet werden könnte: