經常使用paramiko工具對幾百台裝置進行管理,但是由於伺服器本身或是網路原因,有時傳回值回不來,然後程式就看在那裡一直等待,這個時候後需要設定一個逾時值。paramiko模組中執行命令代碼如下:
stdin, stdout , stderr = s.exec_command(command)
這個地方在模組中只有一個參數,paramiko預設在這個是並不能設定逾時值。
其實paramiko本身是可以在這個地方設定逾時值的,只是預設情況下是沒有這個選項的,需要在paramiko的安裝目錄中修改他的原始碼,讓他支援,在代碼中是有這個介面的。之所以他沒有這個這個逾時值,我想是因為開發方考慮有些有些命令可能執行的時間比較長,比如大檔案的壓縮等,需要很長的時間才能執行完,逾時值如果設定的話,有可能會中斷命令的執行,索性留下介面,並不設定逾時值。但是我們用這個模組批量的去操作多台裝置的話,有時逾時值是很有必要的。
修改paramiko原始碼方法如下:
找到C:\Python27\Lib\site-packages\paramiko目錄,下面有個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
本文出自 “王偉” 部落格,請務必保留此出處http://wangwei007.blog.51cto.com/68019/1212492