与 Windows 的 Paramiko 连接无提示地失败(似乎成功)
Paramiko connection to Windows fails silently (appears to succeed)
我正在尝试使用 paramiko 通过 ssh 将 powershell 命令发送到装有 OpenSSH 的 Windows 盒子。这些命令似乎是成功的(return 代码 0),即使它们应该会失败,而且我没有在管道上得到任何输出。当我尝试创建目录之类的命令时,它并没有被创建,这使得这些命令看起来好像没有到达远程系统,但也没有抛出错误。
首先,这是我的代码:
version = self.oscall.run_remote(['java', '-version'])
def run_remote(self, command): # Command is a list of command + args
string = ""
self.timeout = 300
for arg in command:
string = string + " " + arg
self.client.connect(self.host, username=self.user, password=self.pw, timeout=self.timeout)
self.transport = self.client.get_transport()
self.transport.set_keepalive(1)
self.channel = self.transport.open_session(timeout=self.timeout) # transport is abstract connection, session is socket
if self.channel.gettimeout() == None: self.channel.settimeout(self.timeout)
self.channel.exec_command(string)
self.out = self.channel.makefile()
self.err = self.channel.makefile_stderr()
self.output = CallOutput(self.out, self.err, None)
self.output.returncode = self.channel.recv_exit_status()
self.channel.close()
return self.output
class CallOutput(object):
def __init__(self, out, err, rc):
self.out = out.readlines()
self.err = err.readlines()
self.outfile = tempfile.TemporaryFile()
for line in self.out:
if isinstance(line, unicode): line = line.encode('utf-8')
self.outfile.write(line + '\n')
self.outfile.seek(0)
self.errfile = tempfile.TemporaryFile()
for line in self.err:
if isinstance(line, unicode): line = line.encode('utf-8')
self.errfile.write(line + '\n')
self.errfile.seek(0)
self.returncode = rc
抱歉文字墙,但我是为了完整。这是一个更大的应用程序的一部分。
这段代码可以完美地连接到 Linux,所以我预计不会有很多小错误。 returncode 始终为 0,即使是垃圾也是如此,并且管道上永远不会有任何输出。如果我 运行 只使用终端的命令,我得到正确的输出:
$ ssh testuser@testwin.internal.com 'java -version'
Warning: Permanently added 'testwin.internal.com,10.10.10.12' (ECDSA) to the
list of known hosts.
testuser@testwin.internal.com's password:
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
$ echo $?
0
$ ssh testuser@testwin.internal.com 'foo'
foo : The term 'foo' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path
is correct and try again.
At line:1 char:1
+ foo
+ ~~~
+ CategoryInfo : ObjectNotFound: (foo:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
$ echo $?
1
我能想到的 Linux 和 Windows 进程之间的唯一区别是 Windows 我们必须使用密码,因为我们没有设置无密码 ssh然而。我缺少什么奇怪的 Windows 特质?任何见解将不胜感激。
像往常一样,事实证明它比我想象的要简单得多。
string = ""
for arg in command:
string = string + " " + arg
上面的代码产生了“传入的任何命令”,事实证明 Windows 对前面的 space 反应极差,而 linux 并不关心。新的代码片段是:
string = ""
first = True
for arg in command:
if first:
string = string + arg
first = False
else:
string = string + " " + arg
我保留标题和详细信息相同,希望能帮助任何犯了与我完全相同的错误的人。
我正在尝试使用 paramiko 通过 ssh 将 powershell 命令发送到装有 OpenSSH 的 Windows 盒子。这些命令似乎是成功的(return 代码 0),即使它们应该会失败,而且我没有在管道上得到任何输出。当我尝试创建目录之类的命令时,它并没有被创建,这使得这些命令看起来好像没有到达远程系统,但也没有抛出错误。
首先,这是我的代码:
version = self.oscall.run_remote(['java', '-version'])
def run_remote(self, command): # Command is a list of command + args
string = ""
self.timeout = 300
for arg in command:
string = string + " " + arg
self.client.connect(self.host, username=self.user, password=self.pw, timeout=self.timeout)
self.transport = self.client.get_transport()
self.transport.set_keepalive(1)
self.channel = self.transport.open_session(timeout=self.timeout) # transport is abstract connection, session is socket
if self.channel.gettimeout() == None: self.channel.settimeout(self.timeout)
self.channel.exec_command(string)
self.out = self.channel.makefile()
self.err = self.channel.makefile_stderr()
self.output = CallOutput(self.out, self.err, None)
self.output.returncode = self.channel.recv_exit_status()
self.channel.close()
return self.output
class CallOutput(object):
def __init__(self, out, err, rc):
self.out = out.readlines()
self.err = err.readlines()
self.outfile = tempfile.TemporaryFile()
for line in self.out:
if isinstance(line, unicode): line = line.encode('utf-8')
self.outfile.write(line + '\n')
self.outfile.seek(0)
self.errfile = tempfile.TemporaryFile()
for line in self.err:
if isinstance(line, unicode): line = line.encode('utf-8')
self.errfile.write(line + '\n')
self.errfile.seek(0)
self.returncode = rc
抱歉文字墙,但我是为了完整。这是一个更大的应用程序的一部分。
这段代码可以完美地连接到 Linux,所以我预计不会有很多小错误。 returncode 始终为 0,即使是垃圾也是如此,并且管道上永远不会有任何输出。如果我 运行 只使用终端的命令,我得到正确的输出:
$ ssh testuser@testwin.internal.com 'java -version'
Warning: Permanently added 'testwin.internal.com,10.10.10.12' (ECDSA) to the
list of known hosts.
testuser@testwin.internal.com's password:
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
$ echo $?
0
$ ssh testuser@testwin.internal.com 'foo'
foo : The term 'foo' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path
is correct and try again.
At line:1 char:1
+ foo
+ ~~~
+ CategoryInfo : ObjectNotFound: (foo:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
$ echo $?
1
我能想到的 Linux 和 Windows 进程之间的唯一区别是 Windows 我们必须使用密码,因为我们没有设置无密码 ssh然而。我缺少什么奇怪的 Windows 特质?任何见解将不胜感激。
像往常一样,事实证明它比我想象的要简单得多。
string = ""
for arg in command:
string = string + " " + arg
上面的代码产生了“传入的任何命令”,事实证明 Windows 对前面的 space 反应极差,而 linux 并不关心。新的代码片段是:
string = ""
first = True
for arg in command:
if first:
string = string + arg
first = False
else:
string = string + " " + arg
我保留标题和详细信息相同,希望能帮助任何犯了与我完全相同的错误的人。