python wget 卡住_python – Paramiko在执行大型wget命令时挂起

嗨,我在执行一个通过Ubuntu 10服务器执行100mb文件的wget的命令时遇到问题.除此之外,较短的命令工作正常.下面的类包含我如何使用paramiko和我克服这个问题的不同尝试(请参阅不同的run或exec方法).在exec_cmd的情况下,执行挂起在这一行:

out = self.in_buffer.read(nbytes, self.timeout)

来自paramiko的channel.py模块的recv方法.

使用Mac中的普通ssh实用程序,相同的wget命令在shell中完美运行.

"""

Management of SSH connections

"""

import logging

import os

import paramiko

import socket

import time

import StringIO

class SSHClient():

def __init__(self):

self._ssh_client = paramiko.SSHClient()

self._ssh_client.load_system_host_keys()

self._ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

self.time_out = 300

self.wait = 5

def connect(self, hostname, user, pkey):

retry = self.time_out

self.hostname = hostname

logging.info("connecting to:%s user:%s key:%s" % (hostname, user, pkey))

while retry > 0:

try:

self._ssh_client.connect(hostname,

username=user,

key_filename=os.path.expanduser(pkey),

timeout=self.time_out)

return

except socket.error, (value,message):

if value == 61 or value == 111:

logging.warning('SSH Connection refused, will retry in 5 seconds')

time.sleep(self.wait)

retry -= self.wait

else:

raise

except paramiko.BadHostKeyException:

logging.warning("%s has an entry in ~/.ssh/known_hosts and it doesn't match" % self.server.hostname)

logging.warning('Edit that file to remove the entry and then try again')

retry = 0

except EOFError:

logging.warning('Unexpected Error from SSH Connection, retry in 5 seconds')

time.sleep(self.wait)

retry -= self.wait

logging.error('Could not establish SSH connection')

def exists(self, path):

status = self.run('[ -a %s ] || echo "FALSE"' % path)

if status[1].startswith('FALSE'):

return 0

return 1

def shell(self):

"""

Start an interactive shell session on the remote host.

"""

channel = self._ssh_client.invoke_shell()

interactive_shell(channel)

def run(self, command):

"""

Execute a command on the remote host. Return a tuple containing

an integer status and a string containing all output from the command.

"""

logging.info('running:%s on %s' % (command, self.hostname))

log_fp = StringIO.StringIO()

status = 0

try:

t = self._ssh_client.exec_command(command)

except paramiko.SSHException:

logging.error("Error executing command: " + command)

status = 1

log_fp.write(t[1].read())

log_fp.write(t[2].read())

t[0].close()

t[1].close()

t[2].close()

logging.info('output: %s' % log_fp.getvalue())

return (status, log_fp.getvalue())

def run_pty(self, command):

"""

Execute a command on the remote host with a pseudo-terminal.

Returns a string containing the output of the command.

"""

logging.info('running:%s on %s' % (command, self.hostname))

channel = self._ssh_client.get_transport().open_session()

channel.get_pty()

status = 0

try:

channel.exec_command(command)

except:

logging.error("Error executing command: " + command)

status = 1

return status, channel.recv(1024)

def close(self):

transport = self._ssh_client.get_transport()

transport.close()

def run_remote(self, cmd, check_exit_status=True, verbose=True, use_sudo=False):

logging.info('running:%s on %s' % (cmd, self.hostname))

ssh = self._ssh_client

chan = ssh.get_transport().open_session()

stdin = chan.makefile('wb')

stdout = chan.makefile('rb')

stderr = chan.makefile_stderr('rb')

processed_cmd = cmd

if use_sudo:

processed_cmd = 'sudo -S bash -c "%s"' % cmd.replace('"', '\\"')

chan.exec_command(processed_cmd)

result = {

'stdout': [],

'stderr': [],

}

exit_status = chan.recv_exit_status()

result['exit_status'] = exit_status

def print_output():

for line in stdout:

result['stdout'].append(line)

logging.info(line)

for line in stderr:

result['stderr'].append(line)

logging.info(line)

if verbose:

print processed_cmd

print_output()

return exit_status,result

def exec_cmd(self, cmd):

import select

ssh = self._ssh_client

channel = ssh.get_transport().open_session()

END = "CMD_EPILOGqwkjidksjk58754dskhjdksjKDSL"

cmd += ";echo " + END

logging.info('running:%s on %s' % (cmd, self.hostname))

channel.exec_command(cmd)

out = ""

buf = ""

while END not in buf:

rl, wl, xl = select.select([channel],[],[],0.0)

if len(rl) > 0:

# Must be stdout

buf = channel.recv(1024)

logging.info(buf)

out += buf

return 0, out

解决方法:

我遇到了同样的问题,当我在远程ssh客户端上运行shell脚本时,我的python脚本挂起,在400Mb文件上执行了wget命令.

我发现在wget命令中添加超时可以解决问题.

原来我有:

现在用这个:

它就像一个魅力!

希望能帮助到你.

标签:python,linux,ssh,paramiko

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值