Shell——密码三两事

sudo 回显密码

在 linux 系统中,默认 sudo 命令是不能回显密码的,但是部分用户需要回显星号进行提示,可以配置 /etc/sudoers 文件修改回显方式。

  1. 回显星号

    /etc/sudoers 文件中添加 Defaults pwfeedback

  2. 修改提示语

    sudo 的提示语默认为 [sudo] password for %p:,在 /etc/sudoers 文件中通过如下设置进行修改。

    1
    2
    Defaults passprompt_override # 覆盖默认提示语开关
    Defaults passprompt="你的提示语" # 此处设置你的提示语

    也可以通过-p选项或SUDO_PROMPT环境变量覆盖。支持以下 % 转义序列:

    转义序列描述
    %H扩展为包含域名的本地主机名
    %h扩展为没有域名的本地主机名
    %p扩展为要求密码的用户
    %U扩展为将运行该命令的用户的登录名(默认为root)
    %u拓展为用户登录名
    %%一个%

脚本读取密码

在自己开发的脚本中,我们都希望能够进行输入密码。有两种处理方式,一是不进行任何回显,二是回显其他字符。

不回显

  1. 通过 stty 命令关闭终端自动打印输入字符的功能

    1
    2
    3
    4
    5
    6
    7
    8
    printf "Enter new password: "
    stty -echo
    read password < /dev/tty
    echo
    printf "Enter again: "
    read password2 < /dev/tty
    stty echo
    echo
  2. 通过 read 内建命令的选项 -s 进行无回显的读取

    1
    2
    3
    4
    5
    6
    printf "Enter new password: "
    read -s password < /dev/tty
    echo
    printf "Enter again: "
    read -s password2 < /dev/tty
    echo

回显

参考 vermilliontear 的《Shell 模拟密码输入》

每次获取一个输入,然后判断输入的是控制字符还是密码所接收的字符。

  1. 如果是控制字符,就进行对应操作。比如输入退格符,需要删除一个字符,并减少一个回显星号。
  2. 如果是密码所接受的字符,则回显星号,记录密码。

在进行判断控制字符时,推荐使用 vim 编辑器,比如 ctrl-v + backspace 可以得到退格符的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env bash
printf "Username: "
read username
printf "Password: "
# 保存 tty 当前设置
STTY_RESTORE=$(stty -g)
# 设置输入不回显、使能特殊字符
stty -echo -icanon
# 输入回显星号
while true; do
# 获取输入字符
ch=$(dd if=/dev/tty bs=1 count=1 2> /dev/null)
# 根据输入进行操作
case $ch in
# 结束输入
$(echo -ne "\n"))
break
;;
# 删除字符,ctrl-h对应的是\b,第二个对应的是 backspace
$(echo -ne "\b")|$(echo -ne ""))
if [ -n "$password" ]; then
echo -ne "\b \b"
password=$(echo "$password" | sed -e 's/.$//g')
fi
;;
# 其他字符拼接到密码后面
*)
password=$password$ch
printf '*'
;;
esac
done
# 恢复 tty 配置
stty $STTY_RESTORE

echo -e "\n\nUsername: $username"
echo "Password: $password"
本文结束感谢您的阅读
感谢打赏,继续前行!