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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4316730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 23:55:35  来源:igfitidea点击:

Hiding user input on terminal in Linux script

linuxbashscripting

提问by

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?

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

采纳答案by Andreas Wong

Just supply -s to your read call like so:

只需将 -s 提供给您的 read 调用,如下所示:

$ read -s PASSWORD
$ echo $PASSWORD

回答by SiegeX

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 -ssolution):

如果您想通过*为他们键入的每个字符输出一个来获得幻想,您可以执行以下操作(使用 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

回答by lesmana

for a solution that works without bash or certain features from readyou can use sttyto disable echo

对于无需 bash 或某些功能的解决方案,read您可以使用它stty来禁用 echo

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

回答by tripleee

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

这是@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

回答by mklement0

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

这是@SiegeX 出色的*打印解决方案的变体bash,支持添加退格键;这允许用户使用backspace密钥(deleteMac 上的密钥)更正他们的输入,这通常由密码提示支持:

#!/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
  • \b \bis needed to give the appearance ofdeleting the character to the left; just using \bmoves the cursor to the left, but leaves the character intact (nondestructivebackspace). 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?).
  • 至于为什么按退格键会记录字符代码0x7f:“在现代系统中,退格键通常映射到删除字符(ASCII 或 Unicode 中的 0x7f)” https://en.wikipedia.org/wiki/Backspace
  • \b \b需要给出删除左侧字符的外观;仅使用\b将光标向左移动,但保持字符不变(非破坏性退格)。通过打印一个空格并再次向后移动,该字符似乎已被删除(感谢,C 中的“退格”转义字符 '\b',意外行为?)。


In a POSIX-onlyshell (e.g., shon Debian and Ubuntu, where shis dash), use the stty -echoapproach(which is suboptimal, because it prints nothing), because the readbuiltin will not support the -sand -noptions.

仅 POSIX 的shell 中(例如,sh在 Debian 和 Ubuntu 上,shis在哪里dash),使用该stty -echo方法(这是次优的,因为它不打印任何内容),因为read内置程序将不支持-s-n选项。

回答by dylnmc

I always like to use Ansi escape characters:

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

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

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

8m使文本不可见并将0m文本重置为“正常”。-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 readto not echo the characters...

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

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

回答by yerlilbilgin

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

简单地说:隐藏回声做你的东西显示回声

回答by MikeW

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 == $'##代码##' ]]; 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 == $'##代码##' ]]; 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