8

有谁知道在使用 SSHClient 时如何为 exec_command 调用注册环境变量?

我正在使用实例化 SSHClient 类的基本脚本,使用 connect 方法连接到另一台计算机,然后使用 exec_command 方法发送命令。但是,当我尝试发出命令时,似乎没有注册任何环境变量。我可以做一些基本的事情,比如“ls”并查看标准输出,但是在尝试运行已安装的程序时,缺少环境变量的事实使得无法运行它们。在命令行中使用 ssh 来做同样的事情,因为设置了用户的环境变量。

#!/usr/bin/python
import paramiko

ssh.connect('mymachine',username='myname',password='pass')    
stdin,stdout,stderr=ssh.exec_command('cd /myfolder/path')
stdin,stdout,stderr=ssh.exec_command('ls')

....

....

ssh.close()

注意:我无法更改 paramiko 中的目录。cd我将后续命令中的命令附加到单个ssh.exec_command('cd /dddd/ddd;ls'). 我已经ls举了一个例子,但我的实际后续命令是不同的。

4

3 回答 3

8

从 2.1.0 2016-12-09 版本开始,您可以将环境变量字典添加到exec_command

import paramiko
paramiko.util.log_to_file("paramiko.log")
ssh = paramiko.SSHClient()
k =   paramiko.RSAKey.from_private_key_file("<private_key_file>")
ssh.connect(<hostname>,username=<username>,pkey=k)
env_dict={"LC_TELEPHONE":"ET_HOME","LC_MEASUREMENT":"MILES_APART"}
stdin , stdout, stderr = ssh.exec_command('echo $LC_TELEPHONE; echo "..."; echo $LC_MEASUREMENT',environment=env_dict)
print stdout.read()

输出:

ET_HOME
...
MILES_APART

但为什么我选择了 LC_TELEPHONE 和 LC_MEASUREMENT?因为这是目标主机的 ssh 配置允许我设置的少数环境中的两个:

grep AcceptEnv /etc/ssh/sshd_config 

输出:

AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL

换句话说,这不起作用:

env_dict={"HELLO":"WORLD","GOODBYE":"CRUEL_WORLD"}
stdin , stdout, stderr = ssh.exec_command("echo $HELLO; echo '...'; echo $GOODBYE")
print stdout.read()

输出:

...

正如文档警告的那样,环境变量被默默拒绝 http://docs.paramiko.org/en/2.1/api/client.html http://docs.paramiko.org/en/2.1/api/channel.html# paramiko.channel.Channel.set_environment_variable

如果您无法控制目标服务器的 sshd 配置,请将环境变量放入文件并获取它的工作原理:

stdin , stdout, stderr = ssh.exec_command("cat .set_env;source .set_env; echo $HELLO; echo '...'; echo $GOODBYE")
print stdout.read()

输出:

# begin .set_env
HELLO="WORLD"
GOODBYE="CRUEL_WORLD"
# end .set_env
WORLD
...
CRUEL_WORLD
于 2017-04-18T14:29:10.413 回答
1
#!/usr/bin/python
import paramiko

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy)
client.connect(myhostname, theport, myuser, thepass)
stdin,stdout,stderr = client.exec_command('cd /tmp;pwd;ls -al')
#returns your output
print stdout.read()

这一切对我来说都很好。如果您有特殊的环境变量,您可能必须在远程命令提示符下设置它们。如果您将变量写入 myENV 文件然后调用可能会有所帮助

stdin,stdout,stderr = client.exec_command('source ./myEnv')

你有没有尝试过这样的事情?

于 2014-04-04T07:24:57.587 回答
1

你可以这样做:client.exec_command(..., get_pty=True)

这将使 paramiko 分配一个伪终端,类似于ssh.

于 2016-06-10T01:55:05.837 回答