在Linux脚本中隐藏终端上的用户输入

时间:2010-11-30 17:45:00

标签: linux bash scripting

我有以下的bash脚本:

#!/bin/bash

echo "Please enter your username";
read username;

echo "Please enter your password";
read password;

我希望当用户在终端上输入密码时,不应该显示密码(或者应该显示*******)。我如何实现这一目标?

9 个答案:

答案 0 :(得分:239)

只需为你的阅读电话提供-s:

$ read -s PASSWORD
$ echo $PASSWORD

答案 1 :(得分:22)

更新

如果您希望通过为他们输入的每个字符输出*来获得幻想,您可以执行以下操作(使用andreas'read -s解决方案):

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

答案 2 :(得分:13)

对于没有bash或read某些功能的解决方案,您可以使用stty来禁用回显

stty_orig=`stty -g`
stty -echo
read password
stty $stty_orig

答案 3 :(得分:7)

这是@ SiegeX优秀的*打印解决方案的变体 - bash 支持退格;这允许用户使用backspace键(Mac上的delete键)更正其条目,这通常是密码提示支持的:

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

注意:


仅POSIX shell中(例如,Debian和Ubuntu上的sh,其中shdash),使用{{ 1}}方法(这是次优的,因为它打印 nothing ),因为stty -echo内置不支持read-s选项

答案 4 :(得分:3)

与@ lesmana的回答有点不同(但大多数情况下)

stty -echo
read password
stty echo

简单地说:隐藏回声 做你的东西 show echo

答案 5 :(得分:2)

以下是@ SiegeX的答案的变体,它适用于传统的Bourne shell(不支持+=分配)。

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

答案 6 :(得分:2)

我总是喜欢使用Ansi转义字符:

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

8m使文字不可见,0m将文字重置为“正常”。 -e让Ansi逃脱成为可能。

唯一需要注意的是,你仍然可以复制并粘贴那里的文本,所以如果你真的需要安全性,你可能不应该使用它。

它只是让人们在你输入密码时不会看你的密码。只是不要让你的电脑继续使用。 :)


注:

只要它支持Ansi转义序列,上面就是平台无关的。

但是,对于另一个Unix解决方案,您可以简单地告诉read不回显字符......

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

答案 7 :(得分:1)

  

获取用户名和密码

     

让阅读更清晰,但将其放在屏幕上更好的位置

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

答案 8 :(得分:0)

@SiegeX和@ mklement0的杰出贡献都不同:掩盖用户输入;处理退步;但是只能使用退格键来保留用户输入内容的长度(因此我们不会清除同一行上的其他字符)并处理控制字符,等等。。。System.Classes.AllocateHWnd()经过大量挖掘后才找到了此解决方案!

ProcessRequests()