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

113 linux bash scripting

我有像下面这样的bash脚本:

#!/bin/bash

echo "Please enter your username";
read username;

echo "Please enter your password";
read password;
Run Code Online (Sandbox Code Playgroud)

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

And*_*ong 252

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

$ read -s PASSWORD
$ echo $PASSWORD
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢这种方式.我会投票给你如果我没有达到我的每日限额 (9认同)
  • 提供上下文:`-s`在键入输入时显示_nothing_.(`-s`是非POSIX扩展,因此并非所有shell都支持它,例如BusyBox附带的`ash` shell;在这样的shell中使用`ssty -echo`方法) (4认同)
  • @electron"man"页面中没有任何内容实际上表明`-s`将文本颜色设置为与背景颜色相同.它只是"默默地回响".http://ss64.com/bash/read.html`静音模式.如果输入来自终端,则不回显字符 (3认同)
  • 只是评论:`read -s`在Android(busybox)中什么都不做. (2认同)
  • @electron我在我的盒子上测试过,不仅它没有移动光标,当我尝试突出显示我输入密码的行时,我似乎无法在以后粘贴它.如果书中所说的是真的,那么两者都应该发生.我猜可能是一种不同的shell(我正在使用bash 4.1.2(1)). (2认同)

Sie*_*geX 24

更新

如果您希望通过输入*他们键入的每个字符来获得想象力,您可以执行以下操作(使用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
Run Code Online (Sandbox Code Playgroud)

没有花哨

echo "Please enter your username";
read username;

echo "Please enter your password";
stty -echo
read password;
stty echo
Run Code Online (Sandbox Code Playgroud)

  • 不需要设置`IFS = $'\n'',因为read的默认分隔符是`-d $'\n'`.在新行上发生的断开字符串的if语句允许他们完成密码. (2认同)
  • 我懂了.我的FreeBSD测试基于你原来错误编辑的lesmana帖子中复制和粘贴的代码,其中包含一个重要的区别:你已经传递了`read` a` -d''`.当我稍后在Linux上重试时,我使用了重发版本.如果我尝试省略`-d'',当然它在FreeBSD上的工作方式相同!我真的很放心,这里没有一些神秘的平台魔法. (2认同)

les*_*ana 15

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

stty_orig=$(stty -g)
stty -echo
read password
stty $stty_orig
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 8

这是@ 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
Run Code Online (Sandbox Code Playgroud)

注意:

  • 至于为什么按退格键记录字符代码0x7f:"在现代系统中,退格键通常映射到删除字符(ASCII或Unicode中的0x7f)" https://en.wikipedia.org/wiki/Backspace
  • \b \b需要给出左边删除字符的外观 ; 只需使用\b将光标向左移动,但保持字符完整(非破坏性退格).通过打印空格并再次向后移动,角色似乎已被删除(谢谢,C中的"退格"转义字符'\ _',意外行为?).

在一个只有POSIX的外壳(例如,sh在Debian和Ubuntu,这里shdash),使用stty -echo方法(这是最理想的,因为它打印什么),因为read内置的将不支持-s-n选项.


yer*_*gin 8

与 @lesmana 的答案有点不同(但大多相似)

stty -echo
read password
stty echo
Run Code Online (Sandbox Code Playgroud)

简单地说:隐藏回声做你的事情显示回声