web-dev-qa-db-fra.com

Masquer les entrées de l'utilisateur sur le terminal dans un script Linux

J'ai un script bash comme celui-ci:

#!/bin/bash

echo "Please enter your username";
read username;

echo "Please enter your password";
read password;

Je veux que lorsque l'utilisateur tape le mot de passe sur le terminal, il ne devrait pas être affiché (ou quelque chose comme *******) devrait être affiché). Comment puis-je y arriver?

109
JP19

Fournissez juste -s à votre appel lu comme ceci:

$ read -s PASSWORD
$ echo $PASSWORD
244
Andreas Wong

Mise à jour

Au cas où vous voudriez avoir envie en sortant un * _ pour chaque caractère qu’ils tapent, vous pouvez faire quelque chose comme ceci (en utilisant andreas 'read -s Solution):

unset password;
while IFS= read -r -s -n1 pass; do
  if [[ -z $pass ]]; then
     echo
     break
  else
     echo -n '*'
     password+=$pass
  fi
done

Sans être chic

echo "Please enter your username";
read username;

echo "Please enter your password";
stty -echo
read password;
stty echo
23
SiegeX

pour une solution qui fonctionne sans bash ou certaines fonctionnalités de read, vous pouvez utiliser stty pour désactiver echo

stty_orig=$(stty -g)
stty -echo
read password
stty $stty_orig
15
lesmana

Voici une variante de l'excellente solution d'impression * de @ SiegeX pour bash et la prise en charge du retour arrière a été ajoutée. cela permet à l'utilisateur de corriger son entrée avec la touche backspace (delete sur un Mac) , tel quel généralement pris en charge par les invites de mot de passe:

#!/usr/bin/env bash

password=''
while IFS= read -r -s -n1 char; do
  [[ -z $char ]] && { printf '\n'; break; } # ENTER pressed; output \n and break.
  if [[ $char == $'\x7f' ]]; then # backspace was pressed
      # Remove last char from output variable.
      [[ -n $password ]] && password=${password%?}
      # Erase '*' to the left.
      printf '\b \b' 
  else
    # Add typed char to output variable.
    password+=$char
    # Print '*' in its stead.
    printf '*'
  fi
done

Remarque:

  • Pourquoi appuyez sur la touche Retour pour enregistrer le code de caractère 0x7f: "Dans les systèmes modernes, la touche Retour arrière est souvent associée au caractère de suppression (0x7f dans ASCII ou Unicode)" https://en.wikipedia.org/wiki/Backspace
  • \b \b est nécessaire pour donner l'apparence de supprimer le caractère à gauche; simplement en utilisant \b déplace le curseur vers la gauche, mais laisse le caractère intact ( non destructif retour arrière). En imprimant un espace et en revenant en arrière, le caractère semble avoir été effacé (merci, Le caractère d'échappement "backspace" '\ b' en C, comportement inattendu? ).

Dans un POSIX-only Shell (par exemple, sh sur Debian et Ubuntu, où sh est dash), utilise la méthode stty -echo (qui est sous-optimale, car elle affiche rien ), car le read intégré ne supportera pas les options -s et -n.

8
mklement0

Un peu différent de (mais surtout comme) la réponse de @ lesmana

stty -echo
read password
stty echo

simplement: masquer écho faire votre truc montrer écho

3
yerlilbilgin

Voici une variante de la réponse de @ SiegeX qui fonctionne avec Bourne Shell traditionnel (qui ne prend pas en charge les assignations +=).

password=''
while IFS= read -r -s -n1 pass; do
  if [ -z "$pass" ]; then
     echo
     break
  else
     printf '*'
     password="$password$pass"
  fi
done
2
tripleee

J'aime toujours utiliser les caractères d'échappement Ansi:

echo -e "Enter your password: \x1B[8m"
echo -e "\x1B[0m"

8m rend le texte invisible et 0m réinitialise le texte à "normal". Le -e rend possible les fuites Ansi.

Le seul inconvénient est que vous pouvez toujours copier et coller le texte qui s'y trouve. Vous ne devriez donc probablement pas l'utiliser si vous voulez vraiment la sécurité.

Cela permet simplement aux gens de ne pas regarder vos mots de passe lorsque vous les tapez. Ne laissez pas votre ordinateur allumé après. :)


REMARQUE:

Ce qui précède est indépendant de la plate-forme tant qu'il prend en charge les séquences d'échappement Ansi.

Cependant, pour une autre solution Unix, vous pourriez simplement dire à read de ne pas faire écho aux caractères ...

printf "password: "
let pass $(read -s)
printf "\nhey everyone, the password the user just entered is $pass\n"
2
dylnmc

Obtenir un nom d'utilisateur et un mot de passe

Faites-le plus clair à lire mais placez-le mieux sur l'écran

#!/bin/bash
clear
echo 
echo 
echo
counter=0
unset username
Prompt="  Enter Username:"
while IFS= read -p "$Prompt" -r -s -n 1 char
do
    if [[ $char == $'\0' ]]; then
        break
    Elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
        Prompt=$'\b \b'
        username="${username%?}"
        counter=$((counter-1))
    Elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
        Prompt=''
        continue
    else
        counter=$((counter+1))
        Prompt="$char"
        username+="$char"
    fi
done
echo
unset password
Prompt="  Enter Password:"
while IFS= read -p "$Prompt" -r -s -n 1 char
do
    if [[ $char == $'\0' ]]; then
        break
    Elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
        Prompt=$'\b \b'
        password="${password%?}"
        counter=$((counter-1))
    Elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
        echo
        Prompt="  Enter Password:"
        continue
    else
        counter=$((counter+1))
        Prompt='*'
        password+="$char"
    fi
done
1
MikeW