【问题标题】:Connecting to remote linux machine via python subprocess using PuTTY or plink throws error使用 PuTTY 或 plink 通过 python 子进程连接到远程 linux 机器会引发错误
【发布时间】:2016-06-11 21:04:37
【问题描述】:

我正在尝试从 Windows 主机在远程 linux 机器上执行一些脚本。我希望使用 python subprocess +putty/plink 来实现这一点。 当我从 windows cmd 尝试 Putty 或 plink 命令时,它工作正常。但是如果我使用 python 子进程尝试相同的命令,我会得到很多错误。

C:\Users\username>plink.exe username@machinename -pw password

工作正常。但是当我从 python 中尝试时,

process = subprocess.Popen('plink.exe username@machinename -pw password'.split(),
                           env={'PATH':'C:\\Program Files (x86)\\PuTTY\\'},
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)

引发以下错误。

无法打开连接:

gethostbyname: 未知错误'

process = subprocess.Popen("putty.exe -ssh -2 -l username -pw password -m C:\\script.sh machinename",
                           env={'PATH':'C:\\Program Files (x86)\\PuTTY\\'},
                           stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT
                           ,shell=True);

无法打开连接:

gethostbyname: 未知错误'

我也尝试了 subprocess.check_ouput,但没有成功。

output = subprocess.check_output("putty.exe -ssh -2 -l username -pw password -m C:\\script.sh machinename", stderr=subprocess.STDOUT,shell=True)

抛出以下错误

CalledProcessError: Command 'putty.exe -ssh -2 -l username -pw 密码 -m C:\script.sh machinename' 返回非零退出状态 1

这可能是防火墙问题吗?

【问题讨论】:

  • 如果在调用Popen时不重置环境会怎样?
  • 尽可能避免使用shell=True,例如在这种情况下。也许 putty.exe 返回一个比 shell 的退出代码“1”(失败)更有用的退出代码。
  • 关于env,一般要修改os.environ.copy()。文档清楚地说明了这个参数的作用:“如果 env 不是None,它必须是定义新进程的环境变量的映射;使用这些来代替默认的继承行为当前进程的环境。注意:如果指定,env 必须提供程序执行所需的任何变量。在 Windows 上,为了运行并行程序集,指定的 env 必须 包括一个有效的SystemRoot" 加密API还需要SystemRoot
  • @alexis 如果我不提供路径,它就无法识别腻子。我收到“腻子无法识别的内部或外部错误”
  • @eryksun 如果我不使用 shell=True,我会在 Popen 中得到一个奇怪的“找不到文件”异常。

标签: python linux windows ssh putty


【解决方案1】:

我强烈建议不要使用 PuTT 或一般每个外部程序连接到 shh 然后与管道接口。

使用python库paramiko可以做得更好。

例如:

# ... connect like one of the examples on github
stdin, stdout, stderr = client.exec_command('ls')
for line in stdout:
    print '... ' + line.strip('\n')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 2014-02-25
    • 2013-01-24
    • 1970-01-01
    • 2012-09-14
    • 2018-02-07
    相关资源
    最近更新 更多