ssh连接脚本需显式设置超时参数:-o connecttimeout=5防连接卡死,-o serveraliveinterval=30 -o serveralivecountmax=2防会话断连;禁用明文密码,优先用密钥认证,次选sshpass -f安全读取密码文件。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

SSH 连接脚本里 ssh 命令缺了 -o ConnectTimeout=10 会卡死
没加超时控制的脚本,在网络抖动或目标主机宕机时,ssh 默认会等 60 秒以上才失败,整个脚本就挂住不动。尤其在批量连接、CI/CD 或监控脚本里,这种“假死”比报错更难排查。
- 必须显式加
-o ConnectTimeout=5(单位秒),5 是较稳妥的下限,低于 3 容易误判临时丢包 - 如果还要防登录后卡住,补上
-o ServerAliveInterval=30 -o ServerAliveCountMax=2,避免 SSH 会话被中间防火墙静默断连 - 别用
timeout 10 ssh ...替代 —— 某些旧版timeout不兼容后台进程,且无法区分是连接超时还是认证失败
用 sshpass 自动输密码时,sshpass -p 'xxx' 会被 shell 记录到历史和 ps 输出
明文密码直接写在命令行,等于把密码暴露给所有能执行 ps aux 的人,也留在 ~/.bash_history 里。生产环境绝对禁止。
- 改用
sshpass -f /path/to/passfile,文件权限必须设为600(chmod 600 /path/to/passfile) - 更安全的做法是:提前用
ssh-keygen生成密钥,用ssh-copy-id推公钥,彻底绕过密码环节 - 如果非得用密码且不能改服务端,至少确保脚本本身不带密码字符串,通过环境变量传参(如
sshpass -e ssh ...,再SSHPASS='xxx' ./script.sh),但环境变量仍可能被/proc/PID/environ泄露,仅作临时方案
~/.ssh/config 里 Host 别名配错,ssh myserver 找不到主机
常见错误不是语法错,而是路径、权限或匹配逻辑不对。系统只读取 ~/.ssh/config,不会自动加载 /etc/ssh/ssh_config 里的 Host 段(那是客户端全局配置,不支持别名)。
- 确认文件存在且权限是
600:ls -l ~/.ssh/config,否则 SSH 直接忽略该文件 - Host 行必须顶格写,不能缩进;主机名大小写敏感,
Host MyServer和ssh myserver不匹配 - 通配符要小心:
Host *.prod匹配web.prod,但不匹配prod;想覆盖所有情况,加一行Host *放最后兜底 - 调试用
ssh -F ~/.ssh/config -v myserver看实际解析出的 HostName 和 User 是什么
脚本里用 ssh user@host 'cmd' 执行多条命令,引号嵌套一错全崩
单引号里不能有单引号,双引号里变量会提前展开 —— 这是 Shell 解析顺序导致的硬伤,不是 SSH 的问题。
- 最稳写法:用
cat 启动 here-document,避免任何引号干扰:<pre class="brush:php;toolbar:false;">ssh user@host <<'EOF' df -h uptime echo "done" EOF</pre> - 如果必须拼成一行,用单引号包裹整体,内部用
'\''转义单引号(即:单引号 + 反斜杠 + 单引号 + 单引号) - 注意
$PATH和~在远程 shell 中可能不是登录态,ssh user@host 'echo $HOME'可能输出空 —— 改用ssh user@host 'bash -l -c "echo \$HOME"'模拟登录 shell
$? 或把 2>&1 漏掉,出问题时你看到的永远是“脚本跑完了”,而不是“哪一步挂了”。










