如何通过Paramiko在远程服务器运行Python文件并解决命令失效问题
问题原因
Paramiko 调用exec_command时默认启动非交互式非登录Shell,不会自动加载/etc/profile、~/.bashrc、~/.bash_profile等用户环境配置文件。你手动登录时配置的 Conda、Python 路径都属于用户环境变量,没有被加载到当前会话的PATH中,自然无法识别对应命令。而ls、pwd、cd这类基础命令存放在系统默认路径(/bin、/usr/bin)下,不受用户环境配置影响,所以可以正常运行。
解决方案
方案1:强制启动登录Shell执行命令
在执行的命令前加bash -lc参数,让命令在登录Shell环境下运行,自动加载所有用户环境配置,写法如下:
# 单条Python命令示例 command = "bash -lc 'python my_code.py'" stdin, stdout, stderr = cli.exec_command(command) # 多命令串联示例(激活conda环境后跑脚本) command = "bash -lc 'conda activate your_ml_env && python my_code.py'" stdin, stdout, stderr = cli.exec_command(command)
注意命令字符串里的引号不要嵌套冲突,外层用双引号的话内层用单引号即可。
方案2:调用交互式Shell通道
连接建立后启动和手动登录完全一致的交互式伪终端,适合需要连续执行多条依赖环境的命令的场景:
import time cli.connect(server, username=user, password=pwd) # 分配伪终端,启动交互式Shell channel = cli.invoke_shell() # 等待环境配置加载完成 time.sleep(1) # 发送执行命令,末尾必须加\n模拟回车 channel.send("python my_code.py\n") # 等待命令执行完成后读取输出 time.sleep(3) print(channel.recv(65535).decode('utf-8'))
方案3:使用程序绝对路径执行
先手动登录远程服务器,执行which python、which pip拿到对应程序的完整绝对路径,直接写全路径调用,完全绕过Shell环境配置问题,稳定性最高:
# 示例:假设查到虚拟环境下Python路径为/home/ubuntu/miniconda3/envs/ml/bin/python command = "/home/ubuntu/miniconda3/envs/ml/bin/python my_code.py" stdin, stdout, stderr = cli.exec_command(command)
如果需要安装依赖,直接用对应虚拟环境下pip的绝对路径即可,不需要单独执行conda activate。
避坑提示
- 每一次调用
exec_command都会生成独立的新Shell会话,上一次执行的cd切目录、conda activate激活环境操作不会保留到下一次exec_command调用,多步操作需要写在同一个command字符串里用&&串联。 - 如果执行命令返回权限错误,注意检查
my_code.py的存放路径是否对ubuntu用户开放读写权限。
内容的提问来源于stack exchange,提问作者임승원
相关产品推荐
相关产品推荐

