-1

Need help, so what I am trying to do is :-

I wanna setup a python program, that will open command prompt in background, and I will be able to give commands as input to python program, it will then forward that commands to command prompt and gives me output, I want this connection to be established for the time I want,

I have been through some python codes, what happens in them is, when I enter command, it displays me results at once then it exits, I don't want that instance of command prompt to exit till I want, so I can make changes, change directories, etc.

I have tried, but no such result :( .

So if any ideas do help me out.

Thnx folks.

icedwater
  • 4,701
  • 3
  • 35
  • 50
  • 5
    Don't just say "i have tried", tell us _what_ you've tried, and what the result is. Meanwhile: The way to open a command prompt, or any other program, is the `subprocess` module. If you want to control input and output instead of having it just mix in with your own input and output, the key is `subprocess.PIPE`. The way to do something in the background is the `threading` module. That should be all you need here. Just show us where you got stuck. – abarnert Jul 16 '13 at 00:43
  • ohk sure dude, well basic logic is, i want to create a python program, then will connects or binds with command prompt, so i can give commands to it, subprocess works, but command prompt exits after entering one command or so, i want that same instance to work for the time i want. i am planning for something like following import subprocess commands prompts starts while 1: a = enter commands process.stdin.write(a+"\n") communicate() if a == ' ': exit the command prompt Thanks – user2585427 Jul 16 '13 at 00:58
  • 1
    Yes, `communicate` just sends one hunk of input and gets back one hunk out output. You need to actually use read and write the `PIPE`s yourself. – abarnert Jul 16 '13 at 01:37

2 Answers2

1

If you want to do this with subprocess, here's what you do:

p = subprocess.Popen(['sh'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

Now, every time you want to send a command, you have to p.stdin.write() the command. And you have to p.stdout.read() the result.

But those are blocking calls. So, what you probably want is:

  • A reader thread that loops on p.stdout.read() and posts to a queue.Queue
  • A writer thread that loops on a different queue.Queue and does p.stdin.write().
  • A main thread that deals with user input and output via the queues.
  • Possibly a fourth thread to wait on the Popen object itself.

This isn't easy, but the source code to communicate will show you how to do it. (Make sure to read the 3.2 or later version, because earlier versions didn't actually do it right.)

If you want something simpler, use a higher-level library like pexpect or any of the dozen or so shell wrappers on PyPI.

abarnert
  • 354,177
  • 51
  • 601
  • 671
0

Ok, now I remember. The way to keep the subprocess shell open is to keep the stdin PIPE open

from subprocess import Popen, PIPE

process = Popen(['whatever'], stdin=PIPE, stdout=PIPE,shell=True)
process.stdin.write('Hello\n')
print repr(process.stdout.readline()) 
process.stdin.write('World\n')
print repr(process.stdout.readline()) 

#close
process.stdin.close()
process.wait()

But it isn't recomended and it is unreliable. Use pexpect (non-Windows) and for windows use winpexpect.

In reference to this thread, Keeping a pipe to a process open

Take a look at this question as well, Using module 'subprocess' with timeout

Also take a look at this code from activestate, http://code.activestate.com/recipes/576911-keep-a-process-up-and-running/

Community
  • 1
  • 1
  • This only works if you only need a single line of response (or, alternatively, know exactly how many lines you should need) from `process.stdout`. Otherwise, you have to just keep calling `read` until you block… at which point you're blocked, and your whole program is stuck. You can't work around this with `select` in a portable way, so the only real option is threads. Which is why, in Python 3.2+, `communicate` uses threads. – abarnert Jul 16 '13 at 01:43
  • Thnx buddy for your help – user2585427 Jul 16 '13 at 01:44
  • In particular, if `'whatever'` is `'sh'` or `'cmd'`, and what's you're writing to it is arbitrary commands, there's no way you can possibly know how much to read in response. – abarnert Jul 16 '13 at 01:45