A Python module for controlling interactive programs in a pseudo-terminal

Related tags

pexpect
Overview
Build status

Pexpect is a Pure Python Expect-like module

Pexpect makes Python a better tool for controlling other applications.

Pexpect is a pure Python module for spawning child applications; controlling them; and responding to expected patterns in their output. Pexpect works like Don Libes' Expect. Pexpect allows your script to spawn a child application and control it as if a human were typing commands.

Pexpect can be used for automating interactive applications such as ssh, ftp, passwd, telnet, etc. It can be used to automate setup scripts for duplicating software package installations on different servers. It can be used for automated software testing. Pexpect is in the spirit of Don Libes' Expect, but Pexpect is pure Python.

The main features of Pexpect require the pty module in the Python standard library, which is only available on Unix-like systems. Some features—waiting for patterns from file descriptors or subprocesses—are also available on Windows.

If you want to work with the development version of the source code then please read the DEVELOPERS.rst document in the root of the source code tree.

Free, open source, and all that good stuff.

You can install Pexpect using pip:

pip install pexpect

Docs on ReadTheDocs

PEXPECT LICENSE:

http://opensource.org/licenses/isc-license.txt

Copyright (c) 2013-2016, Pexpect development team
Copyright (c) 2012, Noah Spurrier <[email protected]>

PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

This license is approved by the OSI and FSF as GPL-compatible.

Issues
  • Windows support

    Windows support

    There are at least two ports of pexpect to Windows APIs:

    We could look at integrating this support into pexpect. Both Chris and Geert have said they'd be willing to help out with some initial work, but I think this would need someone committed to maintaining it and fixing the inevitable problems. I don't really use Windows myself, so I can't give it much support.

    enhancement needs-code 
    opened by takluyver 42
  • select.select() cannot handle more than 1024 open files

    select.select() cannot handle more than 1024 open files

    I have been using pexpect for many months with no problem. However, I recently this line:

    1680 return select.select(iwtd, owtd, ewtd, timeout)

    Has been creating a few problems. The select system call cannot handle more than 1024 file descriptors. On the other hand, the select.poll() system call does not have such limitations.

    I understand that not all platforms support poll() but it would be nice to incorporate this system call as an option.

    enhancement needs-code 
    opened by rediate 23
  • pexpect on Solaris via cron (/dev/tty issue)

    pexpect on Solaris via cron (/dev/tty issue)

    I am using the pexpect (version 3.1, installed via pip) on OmniOS (Solaris fork), and it works fine on the interactive shell. But when I try to use it via cron it has issues with /dev/tty. I thought this was an issue for Solaris but had been fixed? Specifically, the error is:

    OSError: [Errno 6] No such device or address: '/dev/tty'
    

    Rest of the trace:

    p=pexpect.spawn('ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no %[email protected]%s' % ('root', host), timeout=60)
      File "/usr/lib/python2.6/site-packages/pexpect/__init__.py", line 485, in __init__
        self._spawn(command, args)
      File "/usr/lib/python2.6/site-packages/pexpect/__init__.py", line 607, in _spawn
        self.pid, self.child_fd = self.__fork_pty()
      File "/usr/lib/python2.6/site-packages/pexpect/__init__.py", line 668, in __fork_pty
        self.__pty_make_controlling_tty(child_fd)
      File "/usr/lib/python2.6/site-packages/pexpect/__init__.py", line 722, in __pty_make_controlling_tty
        fd = os.open("/dev/tty", os.O_WRONLY)
    OSError: [Errno 6] No such device or address: '/dev/tty'
    Traceback (most recent call last):
      File "/root/nologify.py", line 25, in <module>
        p.expect('\r\n.+]# ')
      File "/usr/lib/python2.6/site-packages/pexpect/__init__.py", line 1418, in expect
        timeout, searchwindowsize)
      File "/usr/lib/python2.6/site-packages/pexpect/__init__.py", line 1433, in expect_list
        timeout, searchwindowsize)
      File "/usr/lib/python2.6/site-packages/pexpect/__init__.py", line 1521, in expect_loop
        raise EOF(str(err) + '\n' + str(self))
    pexpect.EOF: End of File (EOF). Very slow platform.
    <pexpect.spawn object at 0x8181d6c>
    version: 3.1
    command: /usr/bin/ssh
    args: ['/usr/bin/ssh', '-oUserKnownHostsFile=/dev/null', '-oStrictHostKeyChecking=no', '[email protected]']
    searcher: <pexpect.searcher_re object at 0x8181dec>
    buffer (last 100 chars): ''
    
    bug 
    opened by ksalman 22
  • ANSI and screen don't support Unicode

    ANSI and screen don't support Unicode

    It would be nice if the ANSI and screen packages supported Unicode strings, or there were additional packages/classes that did. I only had to change str() to unicode() and add u in front of the quoted strings (and perhaps even some of that wasn't necessary) in screen.pretty() and put_abs() in 345eb58 to get this working quickly for me, but I didn't test all methods.

    If you could suggest your preferred solution, I might be able to implement it and submit a pull request.

    opened by dcoshea 22
  • Some update broke pexpect

    Some update broke pexpect

    Up until a few weeks ago pexpect worked just fine.

    My setup: A Raspberry Pi 3B+ updated with the latest Raspbain: 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv7l GNU/Linux

    Latest python included with Raspbain: python3/oldstable,now 3.5.3-1 armhf [installed,automatic] Latest pexpect included with Raspbain: python3-pexpect/oldstable,now 4.2.1-1 all [installed]

    Simplified and sanitized version of my code:

    import pexpect

    child = pexpect.spawn('ssh -i /home/pi/.ssh/remote_box -o StrictHostKeyChecking=no -p 22 [email protected]_box ifconfig') child.expect("remote_box': ") child.sendline('secretpassword') child.expect(pexpect.EOF, timeout=20) print (child.before)

    What happens is it sends the ssh command, it then gets two identical prompt lines for the passphrase instead of just one. However pexpect never sends the secretpassword. It just times out.

    Tried many things including: Tried the ssh command line outside of python. - That works fine. The prompt comes back to enter the passphrase for the key. Enter that and you get the ifconfig output and it exits from the remote box. Changed timeout=None - just hangs there forever Changed the child.expect("remote_box': ") line with shorter and longer prompt strings - no change Replaced the child.expect("remote_box': ") line entirely with time.sleep(5) - no change

    What can I try next?

    opened by T-2 22
  • Add tests into source tarball

    Add tests into source tarball

    Please also add the tests into the source tarball, so it can be also tested downstream, when building the package.

    opened by tomspur 21
  • Restore POSIX support to fdpexpect.

    Restore POSIX support to fdpexpect.

    Factor out uninterruptible select and put the code in utils as select_ignore_interrupts. Modify fdpexpect to use select_ignore_interrupts if os.name is posix. This should restore POSIX support without affecting Windows support.

    needs-changelog 
    opened by MountainRider 19
  • Issue #84: Unicode support in screen and ANSI.

    Issue #84: Unicode support in screen and ANSI.

    Please see the commit message for details.

    I'm not sure if I'm on the right track at all, so I didn't spend a huge amount of time trying to tidy the code, get the comments exactly right, etc. I'm happy to fix that stuff up if I'm on the right track. Apologies if I'm on the completely wrong track!

    The screen and ANSI unit tests pass on Python 2.6, 2.7 and 3.3.

    Some issues I'm aware of which I think are fairly minor:

    It's not 100% clear to me which methods are meant to be public and which are only meant for internal use, so I've tried to perform decoding in all methods that accept input.

    There are some cases (e.g. screen.fill(), fill_region(), put(), insert_abs(), insert()) where decoding is performed by a method that then invokes another method that also potentially performs decoding. I thought that this was safer as it meant that future refactoring wouldn't inadvertently result in decoding not being performed in some code path.

    Use of the incremental decoder from ANSI.write_ch() and screen.put_abs() technically doesn't make sense, since those methods expect to receive exactly one character, and if the caller actually needs an incremental decoder to be used because they don't know where the character boundaries are in the byte stream, they shouldn't be calling those methods. However, I've just used the same incremental decoder in those methods as in all the other ones. I assume those methods probably wouldn't typically be called directly by outside code, and if they were, the user would have to have more of an idea of what they were doing with regards to multi-byte encodings.

    With an incremental decoder, we're meant to call it once at the end with final=True so that any incomplete byte sequence at the end of the stream can be detected. I don't know of a sensible way to do that - perhaps screen() should have a close() method added to it that does this?

    opened by dcoshea 18
  • Read more bytes

    Read more bytes

    Optimize read_nonblocking() in two ways:

    1. When a lot of data is available to read, return all of it. This speeds up callers of read_nonblocking() such as expect_loop() because there are a lot less iterations in the loop.
    2. Only call is_alive() if there is no data ready to read. This avoids a lot of pointless calls to is_alive().

    Downstream: http://trac.sagemath.org/ticket/10295

    enhancement needs-changelog needs-decision 
    opened by jdemeyer 17
  • pexpect.spawn(logfile=sys.stdout) fails on python3.4, clarify documentation to use sys.stdout.buffer.

    pexpect.spawn(logfile=sys.stdout) fails on python3.4, clarify documentation to use sys.stdout.buffer.

    File "/usr/lib/python3.4/site-packages/pexpect/init.py", line 904, in _log self.logfile.write(s) TypeError: must be str, not bytes

    This contradicts the doc.

    enhancement needs-changelog needs-tests WIP 
    opened by rich-pixley 17
Releases(4.8.0)
  • 4.8.0(Jan 17, 2020)

    • Returned behavior of searchwindowsize to that in 4.3 and earlier (searches are only done within the search window) (#579).
    • Fixed a bug truncating before attribute after a timeout (#579).
    • Fixed a bug where a search could be less than searchwindowsize if it was increased between calls (#579).
    • Minor test cleanups to improve portability (#580) (#581) (#582) (#583) (#584) (#585).
    • Disable chaining of timeout and EOF exceptions (#606).
    • Allow traceback included snippet length to be configured via str_last_chars rather than always 100 (#598).
    • Python 3 warning added to interact.py (#537).
    • Several doc updates.
    Source code(tar.gz)
    Source code(zip)
  • 4.2(Jul 2, 2016)

    • Change: When an env parameter is specified to the spawn() or run() family of calls containing a value for PATH, its value is used to discover the target executable from a relative path, rather than the current process's environment PATH. This mirrors the behavior of subprocess.Popen in the standard library (PR #348).
    • Regression: Re-introduce capability for method read_nonblocking() in class fdspawn as previously supported in version 3.3 (PR #359).
    Source code(tar.gz)
    Source code(zip)
  • 3.2(Apr 15, 2014)

    • Fix exception handling from select.select() on Python 2 (PR #38). This was accidentally broken in the previous release when it was fixed for Python 3.
    • Removed a workaround for TIOCSWINSZ on very old systems, which was causing issues on some BSD systems (PR #40).
    • Fixed an issue with exception handling in pxssh (PR #43)

    The documentation for pxssh was improved.

    Source code(tar.gz)
    Source code(zip)
    pexpect-3.2.tar.gz(127.99 KB)
  • 3.1(Jan 22, 2014)

    • Fix an issue that prevented importing pexpect on Python 3 when sys.stdout was reassigned (#30).
    • Improve prompt synchronisation in pxssh (PR #28).
    • Fix pickling exception instances (PR #34).
    • Fix handling exceptions from select.select() on Python 3 (PR #33).

    The examples have also been cleaned up somewhat - this will continue in future releases.

    Source code(tar.gz)
    Source code(zip)
    pexpect-3.1.tar.gz(127.33 KB)
  • 3.0(Nov 11, 2013)

    The new major version number doesn't indicate any deliberate API incompatibility. We have endeavoured to avoid breaking existing APIs. However, pexpect is under new maintenance after a long dormancy, so some caution is warranted.

    • A new unicode API was introduced.
    • Python 3 is now supported, using a single codebase.
    • Pexpect now requires at least Python 2.6 or 3.2.
    • The modules other than pexpect, such as pexpect.fdpexpect and pexpect.pxssh, were moved into the pexpect package. For now, wrapper modules are installed to the old locations for backwards compatibility (e.g. import pxssh will still work), but these will be removed at some point in the future.
    • Ignoring SIGHUP is now optional - thanks to Kimmo Parviainen-Jalanko for the patch.

    We also now have docs on ReadTheDocs, and continuous integration on Travis CI.

    Source code(tar.gz)
    Source code(zip)
    pexpect-3.0.tar.gz(143.24 KB)
  • 3.0b1(Oct 2, 2013)

    The new major version number doesn’t indicate any deliberate API incompatibility. We have endeavoured to avoid breaking existing APIs. However, pexpect is under new maintenance after a long dormancy, so some caution is warranted.

    • A new unicode API was introduced.
    • Python 3 is now supported, using a single codebase.
    • Pexpect now requires at least Python 2.6 or 3.2.

    We also now have docs on ReadTheDocs, and continuous integration on Travis CI.

    Source code(tar.gz)
    Source code(zip)
    pexpect-3.0b1.tar.gz(740.67 KB)
Jurigged lets you update your code while it runs.

jurigged Jurigged lets you update your code while it runs. Using it is trivial: python -m jurigged your_script.py Change some function or method with

Olivier Breuleux 515 Oct 17, 2021
Python process launching

sh is a full-fledged subprocess replacement for Python 2.6 - 3.8, PyPy and PyPy3 that allows you to call any program as if it were a function: from sh

Andrew Moffat 5.9k Oct 18, 2021
Supervisor process control system for UNIX

Supervisor Supervisor is a client/server system that allows its users to control a number of processes on UNIX-like operating systems. Supported Platf

Supervisor 7k Oct 17, 2021