sshpass用于非交互式SSH密码认证,基本用法为sshpass -p'password' ssh user@host,支持密码从命令行(-p)、文件(-f)或环境变量(-e)传入,并可配合-o StrictHostKeyChecking=no处理首次连接信任问题。

sshpass 命令的基本用法:绕过交互式密码输入
sshpass 不是 OpenSSH 自带工具,它通过预设密码接管 SSH 的密码输入流程,让 ssh 在非交互环境下也能完成认证。核心逻辑是:sshpass 拦截 SSH 进程的 stdin,把明文密码“塞”进去。
最简调用形式是:
sshpass -p 'your_password' ssh user@host
注意:-p 后必须紧贴密码(中间无空格),且密码含特殊字符时需用单引号包裹,避免 shell 提前解析。
为什么直接用 -p 会失败?常见报错和规避方式
执行时如果看到 Permission denied, please try again. 或 sshpass: Failed to run command: No such file or directory,大概率是以下原因:
-
sshpass未安装(Ubuntu/Debian 执行sudo apt install sshpass;CentOS/RHEL 用sudo yum install sshpass或启用 EPEL) - 目标服务器禁用了密码登录(
/etc/ssh/sshd_config中PasswordAuthentication no),此时 sshpass 无效,必须改用密钥或开启密码认证 - SSH 客户端版本过高(如 OpenSSH 9.0+),默认禁用键盘交互式认证(
PreferredAuthentications缺省不含keyboard-interactive),需显式指定:sshpass -p 'pwd' ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no user@host
更安全的密码传递方式:避免命令行泄露
用 -p 参数传密码,密码会出现在 ps aux 和 shell 历史中,极不安全。推荐两种替代方案:
- 从文件读取密码:
echo 'mypass123' > /tmp/.sshpass && chmod 600 /tmp/.sshpass<br>sshpass -f /tmp/.sshpass ssh user@host
(注意-f后跟文件路径,文件权限必须为600) - 从环境变量读取:
SSHPASS='mypass123' sshpass -e ssh user@host
(-e表示读取$SSHPASS环境变量)
这两种方式都不会在进程参数里暴露密码,但文件路径或环境变量本身仍需做好权限控制。
与 expect 对比:什么场景下该选 sshpass
sshpass 是轻量级专用工具,只解决「自动输密码」这一件事;expect 更通用但依赖 Tcl 解释器、脚本体积大、调试复杂。实际选型看需求:
- 简单批量登录跳板机或测试机 → 用
sshpass,一行命令搞定 - 需要判断登录后返回内容、做条件分支、执行多步交互 → 必须用
expect - 生产环境自动化(Ansible/Chef/Puppet)→ 直接弃用密码登录,统一走 SSH 密钥 +
ssh-agent
sshpass 的最大盲区是:它无法处理二次认证(如 Google Authenticator)、密码过期提示、或者 SSH banner 中包含 “Password:” 字样导致误匹配——这些情况 expect 可以干预,sshpass 会直接卡住或输错。


















