經常使用paramiko工具對幾百台設備進行管理,但是由於服務器本身或是網絡原因,有時返回值回不來,然後程序就看在那裡一直等待,這個時候後需要設置一個超時值。paramiko模塊中執行命令代碼如下:
stdin, stdout , stderr = s.exec_command(command)
這個地方在模塊中只有一個參數,paramiko默認在這個是並不能設置超時值。
其實paramiko本身是可以在這個地方設置超時值的,只是默認情況下是沒有這個選項的,需要在paramiko的安裝目錄中修改他的源代碼,讓他支持,在代碼中是有這個接口的。之所以他沒有這個這個超時值,我想是因為開發方考慮有些有些命令可能執行的時間比較長,比如大文件的壓縮等,需要很長的時間才能執行完,超時值如果設置的話,有可能會中斷命令的執行,索性留下接口,並不設置超時值。但是我們用這個模塊批量的去操作多台設備的話,有時超時值是很有必要的。
修改paramiko源代碼方法如下:
找到C:\Python27\Lib\site-packages\paramiko目錄,下面有個client.py文件,文件中找到這段代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20def
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
修改為:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22def
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