Shell脚本中隐藏密码输入的首选方法是使用read -s命令,它自动禁用终端回显、安全可移植;次选stty -echo配合trap恢复;须避免明文输出、命令行传参等泄露风险。

在Shell交互式脚本中隐藏密码输入,核心是让终端不显示用户键入的字符,同时确保密码不被记录、泄露或残留。最稳妥的做法不是靠“遮掩”,而是从输入源头关闭回显机制。
用 read -s 直接读取(推荐首选)
这是最简洁、安全、可移植的方式,适用于 Bash 和大多数现代 shell:
- read -s 自动禁用当前终端回显,输入过程完全不可见;
- 配合 -p 可自定义提示语,避免换行混乱;
- 无需手动调用 stty,也不依赖 trap 恢复,出错风险低。
示例:
#!/bin/bash read -s -p "请输入密码: " password echo # 输出换行,保持界面整洁 # 后续可用 "$password" 进行校验或传递
用 stty -echo 手动控制终端状态
适合需要精细控制回显开关的场景,比如密码输入前后还要执行其他交互命令:
- 执行 stty -echo 关闭回显,再用普通 read 读取;
- 必须配对使用 stty echo 恢复,否则终端会持续“失明”;
- 建议用 trap 'stty echo' EXIT 确保异常退出时也能恢复。
示例:
#!/bin/bash trap 'stty echo' EXIT stty -echo echo "请输入密码:" read password stty echo echo
避免常见陷阱
很多看似可行的做法其实存在安全隐患:
- 不用
echo "$password"调试输出——密码可能留在历史或日志里; - 不通过命令行参数传密码,如
./script.sh "$pwd"——ps 和 history 都能看见; - 不在 expect 脚本里硬编码或拼接密码字符串;
- 不用
read -n1循环模拟 * 显示——这本身不防窥探,还增加复杂度。
进阶:配合 Expect 处理远程交互
当脚本需自动登录 SSH 或执行交互式命令时,密码仍应避免明文出现在 Shell 层:
- Bash 中用 read -s 获取密码;
- 通过 here-document 或管道把密码传给 expect;
- expect 脚本内用
gets stdin password接收,绝不写死或命令行传参。
这样既隔离了密码生命周期,又规避了 ps、/proc/cmdline、Shell history 等泄露渠道。

















