Скрытие пользовательского ввода на терминале в скрипте Linux

У меня bash script, как показано ниже:

#!/bin/bash

echo "Please enter your username";
read username;

echo "Please enter your password";
read password;

Я хочу, чтобы, когда пользователь вводит пароль на терминал, он не должен отображаться (или что-то вроде *******) должен отображаться). Как достичь этого?

Ответ 1

Просто поставьте -s на ваш запрос на чтение следующим образом:

$ read -s PASSWORD
$ echo $PASSWORD

Ответ 2

Update

Если вы хотите получить фантазию, выставив * для каждого символа, который они набирают, вы можете сделать что-то вроде этого (используя 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

Без фантазии

echo "Please enter your username";
read username;

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

Ответ 3

для решения, которое работает без bash или определенных функций из read, вы можете использовать stty, чтобы отключить эхо

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

Ответ 4

Здесь добавлена ​​вариация на превосходное * -печатное решение @SiegeX для bash с поддержкой backspace; это позволяет пользователю исправить свою запись с помощью клавиши backspace (delete на Mac), как правило, поддерживается подсказками с паролем:

#!/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

Примечание:

  • Что касается того, почему нажатие обратного пробела записывает символьный код 0x7f: "В современных системах ключевой элемент backspace часто отображается на символ удаления (0x7f в ASCII или Unicode)" https://en.wikipedia.org/wiki/Backspace
  • \b \b необходим, чтобы придать стилю символ слева; просто используя \b, перемещает курсор влево, но оставляет символ неповрежденным (неразрушающим обратным пространством). Путем печати пробела и повторного перемещения символ, кажется, был удален (спасибо, "backspace" escape-символ "\b" в C, неожиданное поведение?).

В POSIX-сервере (например, sh на Debian и Ubuntu, где sh есть dash), использует подход stty -echo (который является субоптимальным, поскольку он ничего не печатает), поскольку встроенный read не поддерживает параметры -s и -n.

Ответ 5

Немного отличается от (но чаще всего) ответа @lesmana

stty -echo
read password
stty echo

просто: скрыть эхо делай свои вещи показать эхо

Ответ 6

Вот вариант ответа @SiegeX, который работает с традиционной оболочкой Bourne (которая не поддерживает назначения +=).

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

Ответ 7

Мне всегда нравятся escape-символы Ansi:

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

8m делает текст невидимым, а 0m сбрасывает текст в "обычный". "-e" делает возможным Ansi.

Единственное предостережение состоит в том, что вы все равно можете скопировать и вставить текст, который есть, поэтому вы, вероятно, не должны использовать его, если действительно хотите обеспечить безопасность.

Это просто позволяет людям не смотреть на ваши пароли, когда вы вводите их. Просто не оставляйте свой компьютер после этого.:)


Примечание:

Вышеупомянутая версия является независимой от платформы, если она поддерживает escape-последовательности Ansi.

Однако для другого решения Unix вы можете просто сказать read не повторять символы...

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

Ответ 8

Получить имя пользователя и пароль

Сделайте его более понятным для чтения, но поместите его в лучшее положение на экране

#!/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