使用 Paramiko 时的环境变量差异

Posted

技术标签:

【中文标题】使用 Paramiko 时的环境变量差异【英文标题】:Environment variable differences when using Paramiko 【发布时间】:2015-11-04 23:55:59 【问题描述】:

我正在通过终端(在 Mac 上)连接到 SSH 并运行 Paramiko Python 脚本,出于某种原因,这两个会话的行为似乎不同。在这些情况下,PATH 环境变量是不同的。

这是我运行的代码:

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('host', username='myuser',password='mypass')
stdin, stdout, stderr =ssh.exec_command('echo $PATH')
print (stdout.readlines())

知道为什么环境变量不同吗?

我该如何解决?

【问题讨论】:

【参考方案1】:

SSHClient.exec_command 默认不为会话分配伪终端。因此,(可能)提供了一组不同的启动脚本(特别是对于非交互式会话,.bash_profile 没有提供)。和/或脚本中的不同分支基于TERM 环境变量的缺失/存在。


要使用 ssh 模拟默认 Paramiko 行为,请使用 -T 开关:

ssh -T myuser@host

ssh man:

-T禁用伪tty分配。


相反,要使用 Paramiko 模拟默认的 ssh 行为,请将 exec_commandget_pty 参数设置为 True

def exec_command(self, command, bufsize=-1, timeout=None, get_pty=False):

虽然不是通过在 Paramiko 中分配伪终端来解决此问题,您最好修复您的启动脚本,为所有会话设置相同的 PATH

请参阅Some Unix commands fail with "<command> not found", when executed using Python Paramiko exec_command。

【讨论】:

【参考方案2】:

使用Channel 对象而不是SSHClient 对象解决了我的问题。

chan=ssh.invoke_shell()
chan.send('echo $PATH\n')
print (chan.recv(1024))

更多详情,请查看documentation

【讨论】:

虽然这确实有帮助,但答案无法解释原因。这与ChannelSSHClient 无关。 SSHClient 在内部使用 Channel。不同之处在于您的原始代码使用“exec”通道,默认情况下不分配伪终端。虽然您的新代码使用“shell”通道,但默认情况下会分配一个伪终端。使用 shell 执行命令不是一个好习惯。同样,将您的帐户配置为使用不同的PATH 用于交互式和非交互式终端通常是一种不好的做法。 我试过你的代码,因为 exec_command 没有导入像 pandas 这样的模块,即使我的 ec2 中有它们。即使是刚刚编写了新文件的小型 py 文件也无法与您的代码一起使用。如何从上述方法中恢复错误

以上是关于使用 Paramiko 时的环境变量差异的主要内容,如果未能解决你的问题,请参考以下文章

使用 Github Actions 部署 Firebase Cloud 函数时的环境变量

访问进程环境变量environ时的一个坑

vue多环境配置之 .env配置文件

Eclipse配置C++时的三个关键环境变量

webpack 使用环境变量

Vue3 —— 使用Vite配置环境变量