經常使用paramiko工具對幾百臺裝置進行管理,但是由於伺服器本身或是網路原因,有時返回值回不來,然後程式就看在那裡一直等待,這個時候後需要設定一個超時值。paramiko模組中執行命令程式碼如下:

stdin, stdout , stderr = s.exec_command(command)

   這個地方在模組中只有一個引數,paramiko預設在這個是並不能設定超時值。

其實paramiko本身是可以在這個地方設定超時值的,只是預設情況下是沒有這個選項的,需要在paramiko的安裝目錄中修改他的原始碼,讓他支援,在程式碼中是有這個介面的。之所以他沒有這個這個超時值,我想是因為開發方考慮有些有些命令可能執行的時間比較長,比如大檔案的壓縮等,需要很長的時間才能執行完,超時值如果設定的話,有可能會中斷命令的執行,索性留下介面,並不設定超時值。但是我們用這個模組批量的去操作多臺裝置的話,有時超時值是很有必要的。

修改paramiko原始碼方法如下:

找到C:Python27Libsite-packagesparamiko目錄,下面有個client.py檔案,檔案中找到這段程式碼:

def exec_command(self, command, bufsize=-1):
    """
    Execute a command on the SSH server.  A new L{Channel} is opened and
    the requested command is executed.  The command`s input and output
    streams are returned as python C{file}-like objects representing
    stdin, stdout, and stderr.
    @param command: the command to execute
    @type command: str
    @param bufsize: interpreted the same way as by the built-in C{file()} function in python
    @type bufsize: int
    @return: the stdin, stdout, and stderr of the executing command
    @rtype: tuple(L{ChannelFile}, L{ChannelFile}, L{ChannelFile})
    @raise SSHException: if the server fails to execute the command
    """
    chan = self._transport.open_session()
    chan.exec_command(command)
    stdin = chan.makefile(`wb`, bufsize)
    stdout = chan.makefile(`rb`, bufsize)
    stderr = chan.makefile_stderr(`rb`, bufsize)
    return stdin, stdout, stderr

修改為:

def exec_command(self, command, bufsize=-1,timeout = None):
    """
    Execute a command on the SSH server.  A new L{Channel} is opened and
    the requested command is executed.  The command`s input and output
    streams are returned as python C{file}-like objects representing
    stdin, stdout, and stderr.
    @param command: the command to execute
    @type command: str
    @param bufsize: interpreted the same way as by the built-in C{file()} function in python
    @type bufsize: int
    @return: the stdin, stdout, and stderr of the executing command
    @rtype: tuple(L{ChannelFile}, L{ChannelFile}, L{ChannelFile})
    @raise SSHException: if the server fails to execute the command
    """
    chan = self._transport.open_session()
    if timeout is not None:
        chan.settimeout(timeout)
    chan.exec_command(command)
    stdin = chan.makefile(`wb`, bufsize)
    stdout = chan.makefile(`rb`, bufsize)
    stderr = chan.makefile_stderr(`rb`, bufsize)
    return stdin, stdout, stderr

主要就修改了兩個地方:

1、def exec_command(self, command, bufsize=-1,timeout = None)定義時加一個timeout = None;

2、在chan = self._transport.open_session()下面新增一個判斷

if timeout is not None:

   chan.settimeout(timeout)

那麼在使用paramiko模組執行命令時的程式碼如下:

stdin, stdout , stderr = s.exec_command(command, timeout=10)

這樣就有一個超時值,執行命令的超時時間為10s