paramiko连接失败主因是ssh配置不当或认证方式错误,需确认passwordauthentication开启或公钥正确部署;执行命令需加get_pty=true防交互卡住;sftp上传前应检查并创建目录;部署应加标记文件和版本号实现容错。

Paramiko连接失败:认证被拒或超时
多数人卡在第一步——连不上服务器。不是密码错,就是SSH配置没开对。
常见错误现象:AuthenticationException、socket.timeout、SSHException: No existing session
- 确认目标机器的
sshd_config允许密码登录(PasswordAuthentication yes),或已正确部署公钥到~/.ssh/authorized_keys - 用系统
ssh user@host先手动连一次,排除网络和防火墙问题;Paramiko 不会自动读取~/.ssh/config,所有参数得显式传 -
timeout=10必须设,否则默认阻塞无上限;如果用密钥,key_filename要传绝对路径,相对路径容易静默失败 - 别用
paramiko.Transport手动握手——直接用paramiko.SSHClient+set_missing_host_key_policy更稳
执行部署命令时 stdout 为空或输出截断
你以为命令跑完了,其实卡在交互式提示(比如 sudo 密码、git pull 冲突、pip install 等待输入),Paramiko 默认不分配伪终端,根本收不到回显。
使用场景:拉代码、安装依赖、重启服务——这些操作都可能隐含交互或长输出
- 加
get_pty=True到exec_command(),否则像sudo systemctl restart nginx这种会直接报错或卡住 - 别只读
stdout.read(),要等channel.recv_exit_status()返回后才代表执行完;否则可能读到一半就停了 - 长命令建议拆成多步,每步用
stdin.write()+channel.send()控制输入,比如自动应答git pull的冲突提示 - 注意编码:远程输出可能是
utf-8或latin-1,stdout.read().decode('utf-8', errors='replace')比硬解更安全
文件上传失败:SFTP通道未复用或路径权限不对
用 sftp.put() 传代码包,结果报 IOError: Failure 或目标目录不存在——不是网络问题,是路径或权限没对齐。
参数差异:sftp 是独立通道,不继承 SSHClient 的用户身份上下文,chdir() 和 mkdir() 都得自己调
- 上传前先用
sftp.stat()检查目标目录是否存在,不存在就sftp.mkdir();注意权限掩码,mkdir('logs', 0o755)比默认更可靠 - 别传大文件时用
put()默认参数——加callback函数可监控进度,避免超时中断 - 上传后立刻
chmod可能失败,因为 SFTP 会话不保证命令顺序;稳妥做法是上传完再开一个exec_command('chmod -R 755 /path/to/app') - Windows 本地路径用
os.path.normpath()处理反斜杠,Paramiko 的 SFTP 对路径分隔符敏感,\会直接报错
部署脚本中途崩溃导致远端状态不一致
最麻烦的不是报错,而是脚本报到一半挂了:代码更新了但依赖没装全,或者 Nginx 配置改了一半就断开——线上服务直接 502。
性能影响不大,但可靠性差;Paramiko 本身不支持事务,得靠你设计容错边界
- 关键步骤前加标记文件,比如
exec_command('touch /var/www/myapp/.deploying'),异常时靠它判断是否需回滚 - 用
cd /var/www/myapp && git reset --hard HEAD做轻量回滚,比备份整个目录快且确定 - 不要把
pip install和systemctl restart写在同一行命令里;失败时前者成功后者失败,很难定位 - 每次部署建议生成唯一版本号(如时间戳或 git commit hash),写进
VERSION文件,方便排查和灰度切换
远端环境差异永远比本地想的多:Python 版本、shell 类型(sh/bash)、PATH 路径、SELinux 状态……别信“我本地能跑”。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











