Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to write a cross-platform tool that runs specific commands, expects certain output for verification, and sends certain output (like username/password) for authentication.

On Unix, I have been successful in programming a Python tool that uses the pexpect library (via pip install pexpect ). This code works perfectly and is exactly what I am trying to do. I've provided a small excerpt of my code for proof-of-concept below:

self.process = pexpect.spawn('/usr/bin/ctf', env={'HOME':expanduser('~')}, timeout=5)
self.process.expect(self.PROMPT)
self.process.sendline('connect to %s' % server)
sw = self.process.expect(['ERROR', 'Username:', 'Connected to (.*) as (.*)'])
if sw == 0:
elif sw == 1:
    asked_for_pw = self.process.expect([pexpect.TIMEOUT, 'Password:'])
    if not asked_for_pw:
        self.process.sendline(user)
        self.process.expect('Password:')
    self.process.sendline(passwd)
    success = self.process.expect(['Password:', self.PROMPT])
    if not success:
        self.process.close()
        raise CTFError('Invalid password')
elif sw == 2:
    self.server = self.process.match.groups()[0]
    self.user = self.process.match.groups()[1].strip()
else:
    info('Could not match any strings, trying to get server and user')
    self.server = self.process.match.groups()[0]
    self.user = self.process.match.groups()[1].strip()
info('Connected to %s as %s' % (self.server, self.user))

I tried running the same source on Windows (changing /usr/bin/ctf to c:/ctf.exe) and I receive an error message:

Traceback (most recent call last):
  File ".git/hooks/commit-msg", line 49, in <module> with pyctf.CTFClient() as c:
  File "C:\git-hooktest\.git\hooks\pyctf.py", line 49, in __init__
    self.process = pexpect.spawn('c:/ctf.exe', env={'HOME':expanduser('~')}, timeout=5)
  AttributeError: 'module' object has no attribute 'spawn'

According to the pexpect documentation:

pexpect.spawn and pexpect.run() are not available on Windows, as they rely on Unix pseudoterminals (ptys). Cross platform code must not use these.

That led me on my search for a Windows equivalent. I have tried the popular winpexpect project here and even a more recent (forked) version here, but neither of these projects seem to work. I use the method:

self.process = winpexpect.winspawn('c:/ctf.exe', env={'HOME':expanduser('~')}, timeout=5)

only to sit and watch the Command Prompt do nothing (it seems as though it's trapped inside the winspawn method). I was wondering what other means I could go about programming a Python script to interact with the command line to achieve the same effect as I have been able to in Unix? If a suitable working Windows-version pexpect script does not exist, what other means could I use to go about this?

I suspect this is the password prompt which causes your problems on Windows. I had a lot of trouble sending password to a PLINK (ssh) command, and finally gave it up. I'd personally use subprocess.Popen with line scanning (manual code) to do that. Can't you pass user/password to your command at least? – Jean-François Fabre Aug 16, 2016 at 14:00 winpexpect uses pipes for the standard handles. In this case most command-line programs switch to fully buffering stdout, so you'll only see output when the buffer fills up and flushes. Typically the buffer is 4 KiB. – Eryk Sun Aug 17, 2016 at 7:12 If you're attached to the same console as the child process, then you can use the Windows console API to directly write to its input buffer and read from the screen buffer. You can even create a new, empty screen buffer that can either be temporarily set as the active screen buffer or referenced by a file descriptor and passed as stdout to subprocess.Popen. – Eryk Sun Aug 17, 2016 at 7:16 There are actually two windows versions to pexpect - both are not (well) maintained or developed anymore - winpexpect and wexpect. neither of them worked for me (win 10, python 3.7.3). nor did the latest version of pexpect, which claims to have minor support for windows. – DarkLight Sep 16, 2019 at 12:01 @Leo Not really, with wexpect every time I run child.expect('anything') I get wexpect.wexpect_util.EOF: broken pipe, bye bye – IDK Jul 4, 2021 at 15:16 I can confirm that wexpect worked almost exactly on windows as pexpect did on linux. I had to port a linux/os x app to windows and found wexpect. The only minor difference is if doing child = wexpect.spawn(COMMAND) there is no child.logfile = fd attribute and so the workaround was to fd.write(str(child.after)) to get a logfile of the output and input. – bubonic Jan 11 at 6:23

Better solution is to move DOCKER. It will solve the entire Linux <-> Windows Dependecies in all kind of process. Very simple steps are there to convert a any .py code into a Docker-image. This will be the Futreistic an doptimised solution to use pexpect in windows.

The Example for Encapsulating Python in container: In Linux : Step 1: https://docs.docker.com/engine/install/centos/ After the installation ,one can get docker as a sytem command in linux. Step 2 : Create a directory , and copy the python in that directory and create a ne file called "Dockerfile" and also have the requirements.txt

root@host_name~#cd Demo_docker Demo_code.py DOckerfile requirements.txt

vi Demo_code.py
import pexpect
a=2+2
print(a)

vi requirements.txt pexpect==4.8.0

vi Dockerfile python:latest COPY . . COPY . reqitrements.txt RUN pip3 install -- requirement requirements.txt CMD ["python","Demo.py"]

Step 3: Use Docker build command to build and run and you can upload this to "dockerHUB" and then pull to any where in the world.

After you pushed the image to Docker-Hub , in windows one need to download "Docker Desktop Appliaction" and the use "Docker pull command to pull the repo which you pushed to Docker-hub

Could you provide an example of DockerFile or docker-compose.yml showing how someone can encapsulate a Python script in docker? Also could you mention what are required for docker to be able to run Linux container in Windows to provide a better, more complete answer to the question ? – Sylvaus Nov 22, 2020 at 21:02 The Example for Encapsulating Python in container: In Linux : Step 1: docs.docker.com/engine/install/centos After the installation ,one can get docker as a sytem command in linux. Step 2 : Create a directory , and copy the python in that directory and create a ne file called "Dockerfile" and also have the requirements.txt – katheravan arumugam Nov 24, 2020 at 1:54

Instead of using pexpect.spawn you can use pexpect.popen_spawn.PopenSpawn for windows.

child = pexpect.popen_spawn.PopenSpawn('cmd', timeout=1)
child.send('ipconfig')
child.expect('Wireless', timeout=None)
                Please note that PopenSpawn is not a direct replacement for spawn, and this solution may not work with interactive terminal programs.
– Mario Román
                Sep 4, 2018 at 19:51
                I had to do an extra import to get this working. See github.com/pexpect/pexpect/issues/328
– ChrisCantrell
                Sep 19, 2018 at 21:06
                no, it does not work. getting the same issue as in stackoverflow.com/questions/47582707/pexpect-telnet-on-windows
– etwas77
                May 21, 2019 at 10:59
                @etwas77 Telnet will not work with PopenSpawn in windows. You have to use plink.exe as mentioned in answer of stackoverflow.com/questions/47582707/pexpect-telnet-on-windows
– Hemang Bhimani
                May 22, 2019 at 9:47
                i actually tried ftp or ssh, same issue, no example of any pexpect tutorial work for me..
– etwas77
                May 22, 2019 at 9:56
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.