pythonpexpectpxssh

Pexpect+pxssh handling of long strings


I am using pexpect+pxssh to communicate with a remote server. Somme commands can be a bit long and the following code does not work:

import pxssh

channel = pxssh.pxssh()
channel.login('192.168.93.129', 'tester', 'tester', 22, auto_prompt_reset=False, quiet=False)
channel.PROMPT = 'tester' + "@[^#$]+[#$]"
channel.sendline('echo 1234567890abcdefghojklmnopqrstuvwxyzmyveryverylongaworkspaceaoneamoreafolder >log.txt 2>&1')
print channel
index = channel.expect(['echo 1234567890abcdefghojklmnopqrstuvwxyzmyveryverylongaworkspaceaoneamoreafolder >log.txt 2>&1'], timeout=10, )
print channel

It creates a timeout because of the expect function. The command 'echo 1234567890 >log.txt 2>&1' creates no problem at all. The problem also happens with a short command in a long path place e.g.

sendline('cd folder1')
sendline('cd folder2')
...
sendline('cd foldern')
pexpect('cd foldern')

If the length of folder1/folder2/.../folder is too long, expect will not work either because of the length of the 'prompt' that displays your current path.

Here is the output produced by the code:

/usr/bin/python2.7 /data/eskenazi/stash/alb-tools/testing_framework/tests/build/remote_build_test.py
<pexpect.pxssh.pxssh object at 0x7f6402096990>
version: 3.1
command: /usr/bin/ssh
args: ['/usr/bin/ssh', '-l', 'tester', '192.168.93.129']
searcher: <pexpect.searcher_re object at 0x7f6402096a50>
buffer (last 100 chars): ' '
before (last 100 chars): ": \r\nWelcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-30-generic x86_64)\r\n\r\n * Documentation:  https://help.ubuntu.com/\r\n\r\n517 packages can be updated.\r\n296 updates are security updates.\r\n\r\nNew release '16.04.1 LTS' available.\r\nRun 'do-release-upgrade' to upgrade to it.\r\n\r\nLast login: Mon Feb  6 16:56:30 2017 from 192.168.93.130\r\r\ntester@ubuntu:~"
after: '$'
match: <_sre.SRE_Match object at 0x7f640209a850>
match_index: 1
exitstatus: None
flag_eof: False
pid: 7004
child_fd: 3
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
Traceback (most recent call last):
  File "/data/eskenazi/stash/alb-tools/testing_framework/tests/build/remote_build_test.py", line 23, in <module>
    index = channel.expect(['echo 1234567890abcdefghojklmnopqrstuvwxyzmyveryverylongaworkspaceaoneamoreafolder >log.txt 2>&1'], timeout=10, )
  File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1417, in expect
    timeout, searchwindowsize)
  File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1431, in expect_list
    timeout, searchwindowsize)
  File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1542, in expect_loop
    raise TIMEOUT(str(err) + '\n' + str(self))
pexpect.TIMEOUT: Timeout exceeded.
<pexpect.pxssh.pxssh object at 0x7f6402096990>
version: 3.1
command: /usr/bin/ssh
args: ['/usr/bin/ssh', '-l', 'tester', '192.168.93.129']
searcher: <pexpect.searcher_re object at 0x7f6402096a10>
buffer (last 100 chars): 'eaoneamoreafolder >log.                         \x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08txt 2>&1\r\ntester@ubuntu:~$ '
before (last 100 chars): ' echo 1234567890abcdefghojklmnopqrstuvwxyzmyveryverylongawork\r<67890abcdefghojklmnopqrstuvwxyzmyveryverylongaworks                         \x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08paceaoneamoreafolder >log\r\r<vwxyzmyveryverylongaworkspaceaoneamoreafolder >log.                         \x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08txt 2>&1\r\ntester@ubuntu:~$ '
after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 7004
child_fd: 3
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1

Process finished with exit code 1

Any help would be greatly appreciated to solve this issue.

SebE


Solution

  • Found the answer myself. As I thought this is related to the length of the command line window opened by pexpect. The default is 80 characters. You can configure it right after its creation with channel.setwinsize(24, channel.maxread)

    import pxssh
    
    channel = pxssh.pxssh()
    channel.setwinsize(24, channel.maxread)
    channel.login('192.168.93.129', 'tester', 'tester', 22, auto_prompt_reset=False, quiet=False)
    channel.PROMPT = 'tester' + "@[^#$]+[#$]"
    channel.sendline('echo 1234567890abcdefghojklmnopqrstuvwxyzmyveryverylongaworkspaceaoneamoreafolder >log.txt 2>&1')
    print channel
    index = channel.expect(['echo 1234567890abcdefghojklmnopqrstuvwxyzmyveryverylongaworkspaceaoneamoreafolder >log.txt 2>&1'], timeout=10, )
    print channel