2010-10-20 11 views
243

Tengo un script que automatiza un proceso que necesita acceso a un sistema protegido con contraseña. Se accede al sistema a través de un programa de línea de comandos que acepta la contraseña del usuario como argumento.Cómo obtener una contraseña de un script de shell sin repetir

Me gustaría pedirle al usuario que escriba su contraseña, asignarla a una variable de shell y luego usar esa variable para construir la línea de comando del programa de acceso (que producirá la salida de flujo que procesaré))

Soy un programador de shell razonablemente competente en Bourne/Bash, pero no sé cómo aceptar la entrada del usuario sin tener que hacer eco en el terminal (o tal vez hacer que se repita con los caracteres '*').

¿Alguien puede ayudar con esto?

+1

posible duplicado de [¿Cómo hacer un script bash para pedir una contraseña?] (Http://stackoverflow.com/questions/2654009/how-to-make-bash-script -ask-por-una-contraseña) –

Respuesta

373

Aquí hay otra manera de hacerlo:

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

El read -s se apagará eco para usted. Simplemente reemplace el echo en la última línea con el comando que desea ejecutar.

+56

Algunas conchas le permiten especificar el símbolo para el ' read' comando: 'leer -s -p "Contraseña:" password' –

+5

definitivamente prefiero 'leer -s -p', muchas gracias por la simplificación de mis guiones. –

+25

Tenga en cuenta que 'read -s' no está en POSIX, su script depende de bash si lo usa. Si quiere cumplir con POSIX, debería usar la solución 'stty -echo' que se sugiere a continuación, porque' stty' y su parámetro 'echo' están definidos en POSIX. – scy

3

Apague echo usando stty, luego vuelva a encenderlo después.

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

@RichardRiley - asumiendo que usted quiere decir "leer-CONTRASEÑA" aquí, ¿es correcto? –

+0

Originalmente aceptado como la mejor solución, y utilizado en el script que estaba escribiendo, pero la contraseña de "lectura -s-p": "CONTRASEÑA" parece mucho más simple. –

+38

No, en realidad, _do_ use 'stty' si quiere cumplir con POSIX. El código en esta respuesta funciona perfectamente incluso en bash, pero en realidad en _todos_ shells que se ajustan a POSIX. – scy

57

Un forro:

read -s -p "Password: " password 

En Linux (y cygwin) esta forma funciona en bash y sh. Sin embargo, puede no ser el estándar Unix sh.

Para obtener más información y opciones, en bash, escriba "help read".

$ 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 
+1

Si el comando genera "leer: Ilegal opción -s" significa que el guión debe ser ejecutado directamente (./script vs ./script sh) ... ver http://stackoverflow.com/questions/30554353/linux- -opción ilegal-Read-a –

-4
echo yourpassword | passwd --stdin youruser 
33

La opción -s de read no está definido en el estándar POSIX. Ver http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html. Quería algo que funcionara para cualquier shell POSIX, así que escribí una pequeña función que usa stty para desactivar el eco.

#!/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 "[email protected]" 

    # 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 
} 

Esta función se comporta bastante similar al comando read. Aquí hay un uso simple de read seguido del uso similar de read_secret. La entrada a read_secret aparece vacía porque no se repitió en el terminal.

[[email protected] ~]$ read a b c 
foo \bar baz \qux 
[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=bar c=baz qux 
[[email protected] ~]$ unset a b c 
[[email protected] ~]$ read_secret a b c 

[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=bar c=baz qux 
[[email protected] ~]$ unset a b c 

Aquí es otro que utiliza la opción -r para preservar las barras invertidas en la entrada. Esto funciona porque la función read_secret definida anteriormente pasa todos los argumentos que recibe al comando read.

[[email protected] ~]$ read -r a b c 
foo \bar baz \qux 
[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=\bar c=baz \qux 
[[email protected] ~]$ unset a b c 
[[email protected] ~]$ read_secret -r a b c 

[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=\bar c=baz \qux 
[[email protected] ~]$ unset a b c 

Por último, aquí es un ejemplo que muestra cómo utilizar la función read_secret para leer una contraseña de una manera compatible con POSIX.

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

probablemente debe asegurarse de que el eco no está ya desactivada en la cáscara y no permite que si no era antes ... probablemente puede usar 'oldtty = stty -g' y luego al final' stty $ oldtty' para restaurar la configuración anterior. De lo contrario, es genial. – Perkins

-3

En primer lugar, si alguien va a almacenar las contraseñas en un archivo. Me aseguraría de que sea hash. No es la mejor seguridad, pero al menos no estará en texto plano.

  1. En primer lugar crear la contraseña y el hash que:

    echo "password123" | md5sum | cut -d '-' -f 1>/tmp/secret

  2. Ahora crea tu programa para usar el hash, en este caso este pequeño programa recibe la entrada del usuario para una contraseña sin eco y luego la convierte en hash para ser en comparación con el hash almacenado. Si coincide con el hash almacenado a continuación, se le concede acceso:

    #/bin/bash

    PASSWORD_FILE="/tmp/secret" 
    MD5_HASH=$(cat /tmp/secret) 
    PASSWORD_WRONG=1 
    
    
    while [ $PASSWORD_WRONG -eq 1 ] 
    do 
        echo "Enter your password:" 
        read -s ENTERED_PASSWORD 
        if [ "$MD5_HASH" != "$(echo $ENTERED_PASSWORD | md5sum | cut -d '-' -f 1)" ]; then 
         echo "Access Deniend: Incorrenct password!. Try again" 
        else 
         echo "Access Granted" 
         PASSWORD_WRONG=0 
        fi 
    done 
    
+1

Sugiero mantener el carácter de nueva línea '\ n' provocado por la orden 'echo' lejos de hash mediante el uso de' eco -n' lugar, ya que '\ n 'no es realmente parte de la contraseña proporcionada - por supuesto, tanto para la creación de '/ tmp/secret' y la comparación que sigue en tu ejemplo. –

2

me pareció ser el de la utilidad carácter

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

Cada entrada askpass comando es reemplazado por *. Ver: Dar una contraseña ****

+0

¿De dónde viene este '/ lib/cryptsetup/askpass'? Ciertamente no es una herramienta estándar * nix (ni GNU/Linux). –

+0

Es la mejor solución que he visto hasta ahora.Es de cryptsetup, que es el estándar para cifrar discos duros, por lo que se usa bastante comúnmente. 'sudo apt-get install cryptsetup'. –

+0

Traté de usar esto y las estrellas no aparecieron, además dañó mi gran terminal hasta que lo cerré. ¡Cualquier entrada de shell adicional está oculta! – Jeff

Cuestiones relacionadas