Linux脚本:将用户输入隐藏在终端上。

时间:2022-02-07 11:23:17

I have bash script like the following:

我有如下的bash脚本:

#!/bin/bash

echo "Please enter your username";
read username;

echo "Please enter your password";
read password;

I want that when the user types the password on the terminal, it should not be displayed (or something like *******) should be displayed). How do I achieve this?

我希望当用户在终端上输入密码时,不应该显示密码(或者应该显示类似于******* ****的内容)。我该如何做到这一点?

8 个解决方案

#1


203  

Just supply -s to your read call like so:

只要像这样为你的阅读电话提供-s:

$ read -s PASSWORD
$ echo $PASSWORD

#2


21  

Update

In case you want to get fancy by outputting an * for each character they type, you can do something like this (using andreas' read -s solution):

如果你想为他们输入的每个字符输出一个*,你可以这样做(使用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

Without being fancy

没有花哨的

echo "Please enter your username";
read username;

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

#3


11  

for a solution that works without bash or certain features from read you can use stty to disable echo

对于不使用bash或read中的某些特性的解决方案,可以使用stty禁用echo

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

#4


6  

Here's a variation on @SiegeX's excellent *-printing solution for bash with support for backspace added; this allows the user to correct their entry with the backspace key (delete key on a Mac), as is typically supported by password prompts:

下面是@SiegeX关于bash的优秀*打印解决方案的一个变体,它支持添加回退空间;这允许用户使用backspace密钥(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

Note:

注意:

  • As for why pressing backspace records character code 0x7f: "In modern systems, the backspace key is often mapped to the delete character (0x7f in ASCII or Unicode)" https://en.wikipedia.org/wiki/Backspace
  • 至于为什么按下backspace记录字符代码0x7f:“在现代系统中,backspace键通常映射到delete字符(ASCII或Unicode中的0x7f)”https://en.wikipedia.org/wiki/Backspace
  • \b \b is needed to give the appearance of deleting the character to the left; just using \b moves the cursor to the left, but leaves the character intact (nondestructive backspace). By printing a space and moving back again, the character appears to have been erased (thanks, The "backspace" escape character '\b' in C, unexpected behavior?).
  • \b \b需要提供删除左边字符的外观;只需使用\b将光标移到左边,但保留字符不变(非破坏性回格)。通过打印一个空格并再次移动,这个字符看起来已经被删除(谢谢,C中的“backspace”转义字符“\b”,意外行为?)

In a POSIX-only shell (e.g., sh on Debian and Ubuntu, where sh is dash), use the stty -echo approach (which is suboptimal, because it prints nothing), because the read builtin will not support the -s and -n options.

在纯posix shell(例如,Debian和Ubuntu上的sh,其中sh是dash)中,使用stty -echo方法(这是次优方法,因为它不打印任何内容),因为read builtin不支持-s和-n选项。

#5


2  

Here is a variation of @SiegeX's answer which works with traditional Bourne shell (which has no support for += assignments).

下面是@SiegeX的一个变体,它与传统的Bourne shell兼容(不支持+= assignments)。

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

#6


2  

I always like to use Ansi escape characters:

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

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

8m makes text invisible and 0m resets text to "normal." The -e makes Ansi escapes possible.

8m将文本重置为“normal”。e使Ansi逃脱成为可能。

The only caveat is that you can still copy and paste the text that is there, so you probably shouldn't use this if you really want security.

唯一要注意的是,您仍然可以复制和粘贴那里的文本,因此如果您真的想要安全性,您可能不应该使用这个。

It just lets people not look at your passwords when you type them in. Just don't leave your computer on afterwards. :)

它只是让人们在你输入密码时不用看你的密码。不要把你的电脑一直开着。:)


NOTE:

注意:

The above is platform independent as long as it supports Ansi escape sequences.

只要支持Ansi转义序列,以上是独立于平台的。

However, for another Unix solution, you could simply tell read to not echo the characters...

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

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

#7


2  

A bit different from (but mostly like) @lesmana's answer

这和@lesmana的回答有点不同(但主要是类似的)

stty -echo
read password
stty echo

simply: hide echo do your stuff show echo

简单来说:隐藏echo做你的东西显示echo

#8


0  

Get Username and password

获得用户名和密码

Make it more clear to read but put it on a better position over the screen

让它读起来更清晰,但是把它放在屏幕上更好的位置

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


203  

Just supply -s to your read call like so:

只要像这样为你的阅读电话提供-s:

$ read -s PASSWORD
$ echo $PASSWORD

#2


21  

Update

In case you want to get fancy by outputting an * for each character they type, you can do something like this (using andreas' read -s solution):

如果你想为他们输入的每个字符输出一个*,你可以这样做(使用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

Without being fancy

没有花哨的

echo "Please enter your username";
read username;

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

#3


11  

for a solution that works without bash or certain features from read you can use stty to disable echo

对于不使用bash或read中的某些特性的解决方案,可以使用stty禁用echo

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

#4


6  

Here's a variation on @SiegeX's excellent *-printing solution for bash with support for backspace added; this allows the user to correct their entry with the backspace key (delete key on a Mac), as is typically supported by password prompts:

下面是@SiegeX关于bash的优秀*打印解决方案的一个变体,它支持添加回退空间;这允许用户使用backspace密钥(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

Note:

注意:

  • As for why pressing backspace records character code 0x7f: "In modern systems, the backspace key is often mapped to the delete character (0x7f in ASCII or Unicode)" https://en.wikipedia.org/wiki/Backspace
  • 至于为什么按下backspace记录字符代码0x7f:“在现代系统中,backspace键通常映射到delete字符(ASCII或Unicode中的0x7f)”https://en.wikipedia.org/wiki/Backspace
  • \b \b is needed to give the appearance of deleting the character to the left; just using \b moves the cursor to the left, but leaves the character intact (nondestructive backspace). By printing a space and moving back again, the character appears to have been erased (thanks, The "backspace" escape character '\b' in C, unexpected behavior?).
  • \b \b需要提供删除左边字符的外观;只需使用\b将光标移到左边,但保留字符不变(非破坏性回格)。通过打印一个空格并再次移动,这个字符看起来已经被删除(谢谢,C中的“backspace”转义字符“\b”,意外行为?)

In a POSIX-only shell (e.g., sh on Debian and Ubuntu, where sh is dash), use the stty -echo approach (which is suboptimal, because it prints nothing), because the read builtin will not support the -s and -n options.

在纯posix shell(例如,Debian和Ubuntu上的sh,其中sh是dash)中,使用stty -echo方法(这是次优方法,因为它不打印任何内容),因为read builtin不支持-s和-n选项。

#5


2  

Here is a variation of @SiegeX's answer which works with traditional Bourne shell (which has no support for += assignments).

下面是@SiegeX的一个变体,它与传统的Bourne shell兼容(不支持+= assignments)。

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

#6


2  

I always like to use Ansi escape characters:

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

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

8m makes text invisible and 0m resets text to "normal." The -e makes Ansi escapes possible.

8m将文本重置为“normal”。e使Ansi逃脱成为可能。

The only caveat is that you can still copy and paste the text that is there, so you probably shouldn't use this if you really want security.

唯一要注意的是,您仍然可以复制和粘贴那里的文本,因此如果您真的想要安全性,您可能不应该使用这个。

It just lets people not look at your passwords when you type them in. Just don't leave your computer on afterwards. :)

它只是让人们在你输入密码时不用看你的密码。不要把你的电脑一直开着。:)


NOTE:

注意:

The above is platform independent as long as it supports Ansi escape sequences.

只要支持Ansi转义序列,以上是独立于平台的。

However, for another Unix solution, you could simply tell read to not echo the characters...

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

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

#7


2  

A bit different from (but mostly like) @lesmana's answer

这和@lesmana的回答有点不同(但主要是类似的)

stty -echo
read password
stty echo

simply: hide echo do your stuff show echo

简单来说:隐藏echo做你的东西显示echo

#8


0  

Get Username and password

获得用户名和密码

Make it more clear to read but put it on a better position over the screen

让它读起来更清晰,但是把它放在屏幕上更好的位置

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