2016-09-06 30 views
0

我在寫一個簡單的python腳本,通過SSH連接到SAN,運行一組命令。最終,每個命令都會記錄到單獨的日誌以及時間戳,然後退出。這是因爲我們連接的設備不支持證書ssh連接,並且在當前的固件版本上沒有合適的日誌記錄功能。如何設置pexpect ssh會話的列寬?

我似乎遇到的問題是,創建的SSH會話似乎限制爲78個字符寬。每個命令產生的結果顯着更寬 - 155個字符。這導致了一堆funkiness。

首先,其當前狀態下的結果顯然更難以解析。其次,由於緩衝區顯着較小,最終的卷命令將無法正確執行,因爲啓動SSH會話的實際提示「按任意鍵繼續」。

如何更改pexpect會話的列寬?

這裏是當前代碼(它的工作原理,但不完全):

#!/usr/bin/python 

import pexpect 
import os 

PASS='mypassword' 
HOST='1.2.3.4' 
LOGIN_COMMAND='ssh [email protected]'+HOST 
CTL_COMMAND='show controller-statistics' 
VDISK_COMMAND='show vdisk-statistics' 
VOL_COMMAND='show volume-statistics' 

VDISK_LOG='vdisk.log' 
VOLUME_LOG='volume.log' 
CONTROLLER_LOG='volume.log' 

DATE=os.system('date +%Y%m%d%H%M%S') 

child=pexpect.spawn(LOGIN_COMMAND) 
child.setecho(True) 
child.logfile = open('FetchSan.log','w+') 
child.expect('Password: ') 
child.sendline(PASS) 
child.expect('# ') 
child.sendline(CTL_COMMAND) 
print child.before 
child.expect('# ') 
child.sendline(VDISK_COMMAND) 
print child.before 
child.expect('# ') 
print "Sending "+VOL_COMMAND 
child.sendline(VOL_COMMAND) 
print child.before 
child.expect('# ') 
child.sendline('exit') 
child.expect(pexpect.EOF) 
print child.before 

輸出預期:

# show controller-statistics 
Durable ID  CPU Load Power On Time (Secs) Bytes per second IOPS    Number of Reads Number of Writes Data Read  Data Written  
--------------------------------------------------------------------------------------------------------------------------------------------------------- 
controller_A 0   45963169    1573.3KB   67    386769785  514179976  6687.8GB   5750.6GB 
controller_B 20   45963088    4627.4KB   421    3208370173  587661282  63.9TB   5211.2GB 
--------------------------------------------------------------------------------------------------------------------------------------------------------- 
Success: Command completed successfully. 

# show vdisk-statistics  
Name Serial Number     Bytes per second IOPS    Number of Reads Number of Writes Data Read  Data Written  
------------------------------------------------------------------------------------------------------------------------------------------------ 
CRS 00c0ff13349e000006d5c44f00000000 0B     0    45861   26756   3233.0MB   106.2MB 
DATA 00c0ff1311f300006dd7c44f00000000 2282.4KB   164    23229435   76509765   5506.7GB   1605.3GB 
DATA1 00c0ff1311f3000087d8c44f00000000 2286.5KB   167    23490851   78314374   5519.0GB   1603.8GB 
DATA2 00c0ff1311f30000c2f8ce5700000000 0B     0    26    4    1446.9KB   65.5KB 
FRA 00c0ff13349e000001d8c44f00000000 654.8KB   5    3049980   15317236   1187.3GB   1942.1GB 
FRA1 00c0ff13349e000007d9c44f00000000 778.7KB   6    3016569   15234734   1179.3GB   1940.4GB 
------------------------------------------------------------------------------------------------------------------------------------------------ 
Success: Command completed successfully. 

# show volume-statistics  
Name  Serial Number     Bytes per second IOPS    Number of Reads Number of Writes Data Read  Data Written  
----------------------------------------------------------------------------------------------------------------------------------------------------- 
CRS_v001 00c0ff13349e0000fdd6c44f01000000 14.8KB    5    239611146  107147564  1321.1GB   110.5GB   
DATA1_v001 00c0ff1311f30000d0d8c44f01000000 2402.8KB   218    1701488316  336678620  33.9TB   3184.6GB   
DATA2_v001 00c0ff1311f3000040f9ce5701000000 0B     0    921    15    2273.7KB   2114.0KB   
DATA_v001 00c0ff1311f30000bdd7c44f01000000 2303.4KB   209    1506883611  250984824  30.0TB   2026.6GB   
FRA1_v001 00c0ff13349e00001ed9c44f01000000 709.1KB   28    25123082   161710495  1891.0GB   2230.0GB   
FRA_v001 00c0ff13349e00001fd8c44f01000000 793.0KB   34    122052720  245322281  3475.7GB   3410.0GB   
----------------------------------------------------------------------------------------------------------------------------------------------------- 
Success: Command completed successfully. 

作爲打印到終端(如所提到的,第三命令贏得的輸出在當前狀態下執行):

show controller-statistics 
Durable ID  CPU Load Power On Time (Secs) Bytes per second 
    IOPS    Number of Reads Number of Writes Data Read   
    Data Written  
---------------------------------------------------------------------- 
controller_A 3   45962495    3803.1KB   
    73    386765821  514137947  6687.8GB   
    5748.9GB 
controller_B 20   45962413    5000.7KB   
    415    3208317860  587434274  63.9TB   
    5208.8GB 
---------------------------------------------------------------------- 
Success: Command completed successfully. 


Sending show volume-statistics 
show vdisk-statistics 
Name Serial Number     Bytes per second IOPS    
    Number of Reads Number of Writes Data Read  Data Written  
---------------------------------------------------------------------------- 
CRS 00c0ff13349e000006d5c44f00000000 0B     0     
    45861   26756   3233.0MB   106.2MB 
DATA 00c0ff1311f300006dd7c44f00000000 2187.2KB   152    
    23220764   76411017   5506.3GB   1604.1GB 
DATA1 00c0ff1311f3000087d8c44f00000000 2295.2KB   154    
    23481442   78215540   5518.5GB   1602.6GB 
DATA2 00c0ff1311f30000c2f8ce5700000000 0B     0     
    26    4    1446.9KB   65.5KB 
FRA 00c0ff13349e000001d8c44f00000000 1829.3KB   14    
    3049951   15310681   1187.3GB   1941.2GB 
FRA1 00c0ff13349e000007d9c44f00000000 1872.8KB   14    
    3016521   15228157   1179.3GB   1939.5GB 
---------------------------------------------------------------------------- 
Success: Command completed successfully. 
Traceback (most recent call last): 
    File "./fetchSAN.py", line 34, in <module> 
    child.expect('# ') 
    File "/Library/Python/2.7/site-packages/pexpect-4.2.1-py2.7.egg/pexpect/spawnbase.py", line 321, in expect 
    timeout, searchwindowsize, async) 
    File "/Library/Python/2.7/site-packages/pexpect-4.2.1-py2.7.egg/pexpect/spawnbase.py", line 345, in expect_list 
    return exp.expect_loop(timeout) 
    File "/Library/Python/2.7/site-packages/pexpect-4.2.1-py2.7.egg/pexpect/expect.py", line 107, in expect_loop 
    return self.timeout(e) 
    File "/Library/Python/2.7/site-packages/pexpect-4.2.1-py2.7.egg/pexpect/expect.py", line 70, in timeout 
    raise TIMEOUT(msg) 
pexpect.exceptions.TIMEOUT: Timeout exceeded. 
<pexpect.pty_spawn.spawn object at 0x105333910> 
command: /usr/bin/ssh 
args: ['/usr/bin/ssh', '[email protected]'] 
buffer (last 100 chars): '-------------------------------------------------------------\r\nPress any key to continue (Q to quit)' 
before (last 100 chars): '-------------------------------------------------------------\r\nPress any key to continue (Q to quit)' 
after: <class 'pexpect.exceptions.TIMEOUT'> 
match: None 
match_index: None 
exitstatus: None 
flag_eof: False 
pid: 19519 
child_fd: 5 
closed: False 
timeout: 30 
delimiter: <class 'pexpect.exceptions.EOF'> 
logfile: <open file 'FetchSan.log', mode 'w+' at 0x1053321e0> 
logfile_read: None 
logfile_send: None 
maxread: 2000 
ignorecase: False 
searchwindowsize: None 
delaybeforesend: 0.05 
delayafterclose: 0.1 
delayafterterminate: 0.1 
searcher: searcher_re: 
    0: re.compile("# ") 

這裏是什麼被捕獲在日誌中:

Password: mypassword 


HP StorageWorks MSA Storage P2000 G3 FC 
System Name: Uninitialized Name 
System Location:Uninitialized Location 
Version:TS230P008 
# show controller-statistics 
show controller-statistics 
Durable ID  CPU Load Power On Time (Secs) Bytes per second 
    IOPS    Number of Reads Number of Writes Data Read   
    Data Written  
---------------------------------------------------------------------- 
controller_A 3   45962495    3803.1KB   
    73    386765821  514137947  6687.8GB   
    5748.9GB 
controller_B 20   45962413    5000.7KB   
    415    3208317860  587434274  63.9TB   
    5208.8GB 
---------------------------------------------------------------------- 
Success: Command completed successfully. 

# show vdisk-statistics 
show vdisk-statistics 
Name Serial Number     Bytes per second IOPS    
    Number of Reads Number of Writes Data Read  Data Written  
---------------------------------------------------------------------------- 
CRS 00c0ff13349e000006d5c44f00000000 0B     0     
    45861   26756   3233.0MB   106.2MB 
DATA 00c0ff1311f300006dd7c44f00000000 2187.2KB   152    
    23220764   76411017   5506.3GB   1604.1GB 
DATA1 00c0ff1311f3000087d8c44f00000000 2295.2KB   154    
    23481442   78215540   5518.5GB   1602.6GB 
DATA2 00c0ff1311f30000c2f8ce5700000000 0B     0     
    26    4    1446.9KB   65.5KB 
FRA 00c0ff13349e000001d8c44f00000000 1829.3KB   14    
    3049951   15310681   1187.3GB   1941.2GB 
FRA1 00c0ff13349e000007d9c44f00000000 1872.8KB   14    
    3016521   15228157   1179.3GB   1939.5GB 
---------------------------------------------------------------------------- 
Success: Command completed successfully. 

# show volume-statistics 
show volume-statistics 
Name  Serial Number     Bytes per second 
    IOPS    Number of Reads Number of Writes Data Read   
    Data Written  
---------------------------------------------------------------------- 
CRS_v001 00c0ff13349e0000fdd6c44f01000000 11.7KB    
    5    239609039  107145979  1321.0GB   
    110.5GB   
DATA1_v001 00c0ff1311f30000d0d8c44f01000000 2604.5KB   
    209    1701459941  336563041  33.9TB   
    3183.3GB   
DATA2_v001 00c0ff1311f3000040f9ce5701000000 0B     
    0    921    15    2273.7KB   
    2114.0KB   
DATA_v001 00c0ff1311f30000bdd7c44f01000000 2382.8KB   
    194    1506859273  250871273  30.0TB   
    2025.4GB   
FRA1_v001 00c0ff13349e00001ed9c44f01000000 1923.5KB   
    31    25123006   161690520  1891.0GB   
    2229.1GB   
FRA_v001 00c0ff13349e00001fd8c44f01000000 2008.5KB   
    37    122050872  245301514  3475.7GB   
    3409.1GB   
---------------------------------------------------------------------- 
Press any key to continue (Q to quit)% 

回答

1

作爲起點:According to the manual,SAN有一個禁用尋呼機的命令。請參閱set cli-parameters pager off的文檔。執行該命令可能就足夠了。它也可能有一個命令來設置它用於格式化輸出的終端行和列,儘管我無法找到它。

回到問題:當ssh客戶端連接到服務器並請求交互式會話時,它可以選擇請求會話服務器端的PTY(僞tty)。當它這樣做時,它會通知服務器服務器應該用於TTY的線路,列和終端類型。您的SAN可能會遵守PTY請求並使用行和列值來格式化其輸出。或者它可能不會。

ssh客戶端從TTY的PTY標準輸入中獲取PTY請求的行和列。這是peshpect用來與ssh通信的PTY。 this question討論瞭如何設置pexpect會話的終端大小。據我所知,Ssh並不尊重LINES或COLUMNS環境變量,所以我懷疑這會起作用。然而,calling child.setwinsize()產卵SSH之後應該工作:

child = pexpect.spawn(cmd) 
child.setwinsize(400,400) 

如果你有這樣的煩惱,你可以嘗試通過SSH之前調用stty本地設置終端大小:

child=pexpect.spawn('stty rows x cols y; ssh [email protected]') 

最後,你需要確保ssh實際上請求會話的PTY。它在某些情況下默認是這樣做的,這應該包括您運行它的方式。但它有一個命令行選項-tt來強制它分配一個PTY。您可以將該選項添加到ssh命令行以確保:

child=pexpect.spawn('ssh -tt [email protected]') 
or 
child=pexpect.spawn('stty rows x cols y; ssh -tt [email protected]') 
+0

這些建議非常有效。該劇本現在嗡嗡作響,沒有問題。非常感謝! – Matthew