Subprocess module: running an interactive shell

  • Thread starter Roman Medina-Heigl Hernandez
  • Start date
R

Roman Medina-Heigl Hernandez

Hi,

I'm experimenting with Python and I need a little help with this. What I'd
like is to launch an interactive shell, having the chance to send first
several commands from python. I've written the following code:

=============

#!/usr/bin/env python

import sys, subprocess

exe = "/bin/sh"
params = "-i"

proc = subprocess.Popen([exe, params], stdin=subprocess.PIPE)

proc.stdin.write("id\n")

while True:
line = sys.stdin.readline()
if not line:
break
proc.stdin.write(line)

sys.exit()

=============

The problem is that when I launch it, python proggy is automatically
suspended. The output I got is:

roman@rslabs:~/pruebas$ ./shell.py
roman@rslabs:~/pruebas$ uid=1000(roman) gid=1000(roman) groups=1000(roman)
roman@rslabs:~/pruebas$

[2]+ Stopped ./shell.py
roman@rslabs:~/pruebas$

Why and how to fix it? Would you suggest a better and more elegant way to
do what I want?

Thank you.

--

Saludos,
-Roman

PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB 29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]
 
K

Karthik Gurusamy

Hi,

I'm experimenting with Python and I need a little help with this. What I'd
like is to launch an interactive shell, having the chance to send first
several commands from python. I've written the following code:

=============

#!/usr/bin/env python

import sys, subprocess

exe = "/bin/sh"
params = "-i"

-i says shell to be interactive. So looks like it is directly trying
to read from the terminal.
proc = subprocess.Popen([exe, params], stdin=subprocess.PIPE)

proc = subprocess.Popen([exe,], stdin=subprocess.PIPE)

works for me; but if there is an error 'sh' terminates.

If you want to simulate interactive, explore the pexpect module.
proc.stdin.write("id\n")

while True:
        line = sys.stdin.readline()
        if not line:

note that a simple enter terminates the shell which you may not want.
                break
        proc.stdin.write(line)

sys.exit()

=============

The problem is that when I launch it, python proggy is automatically
suspended. The output I got is:

roman@rslabs:~/pruebas$ ./shell.py
roman@rslabs:~/pruebas$ uid=1000(roman) gid=1000(roman) groups=1000(roman)
roman@rslabs:~/pruebas$

[2]+  Stopped                 ./shell.py
roman@rslabs:~/pruebas$

Why and how to fix it? Would you suggest a better and more elegant way to
do what I want?

As I see it, 'sh' is attempting to read from the keyboard and not from
stdin.

Karthik
Thank you.

--

Saludos,
-Roman

PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB  29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]
 
R

Roman Medina-Heigl Hernandez

Karthik Gurusamy escribió:
-i says shell to be interactive. So looks like it is directly trying
to read from the terminal.

Well, then the question will be: is there any way to tell python to
directly "map" the terminal to the subprocess?
proc = subprocess.Popen([exe, params], stdin=subprocess.PIPE)

proc = subprocess.Popen([exe,], stdin=subprocess.PIPE)

works for me; but if there is an error 'sh' terminates.

If you want to simulate interactive, explore the pexpect module.

I'll get it a try :)))
note that a simple enter terminates the shell which you may not want.

Test my code and you'll see that this is not true :) When you hit enter
line will contain '\n' so it's not empty.

Btw, another curiosity I have: is it possible to make a print not
automatically add \n (which is the normal case) neither " " (which happens
when you add a "," to the print sentence)? I found an alternative not
using print at all, eg: sys.stdout.write("KKKKK"). But it resulted strange
to me having to do that trick :)

Thank you for all your comments and comprenhension.

-r
sys.exit()

=============

The problem is that when I launch it, python proggy is automatically
suspended. The output I got is:

roman@rslabs:~/pruebas$ ./shell.py
roman@rslabs:~/pruebas$ uid=1000(roman) gid=1000(roman) groups=1000(roman)
roman@rslabs:~/pruebas$

[2]+ Stopped ./shell.py
roman@rslabs:~/pruebas$

Why and how to fix it? Would you suggest a better and more elegant way to
do what I want?

As I see it, 'sh' is attempting to read from the keyboard and not from
stdin.

Karthik
Thank you.

--

Saludos,
-Roman

PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB 29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]

--

Saludos,
-Roman

PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB 29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]
 
K

Karthik Gurusamy

Karthik Gurusamy escribió:





Well, then the question will be: is there any way to tell python to
directly "map" the terminal to the subprocess?

pexpect seems to be the solution for such problems :). [other
applications include ssh which asks for password from terminal (not
ssh's stdin)]

http://pexpect.sourceforge.net/pexpect.html
proc = subprocess.Popen([exe, params], stdin=subprocess.PIPE)
proc = subprocess.Popen([exe,], stdin=subprocess.PIPE)
works for me; but if there is an error 'sh' terminates.
If you want to simulate interactive, explore the pexpect module.

I'll get it a try :)))
note that a simple enter terminates the shell which you may not want.

Test my code and you'll see that this is not true :) When you hit enter
line will contain '\n' so it's not empty.

You are right. I thought readline() strips the trailing \n (It doesn't
and shouldn't as it's necessary for the case a file ends without a
newline).
Btw, another curiosity I have: is it possible to make a print not
automatically add \n (which is the normal case) neither " " (which happens
when you add a "," to the print sentence)?  I found an alternative not
using print at all, eg: sys.stdout.write("KKKKK"). But it resulted strange
to me having to do that trick :)

I am also aware of only the sys.stdout.write solution.

python3.0 has a way to do it.
Help on built-in function print in module builtins:

print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current
sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
hello>>>

Karthik


Thank you for all your comments and comprenhension.

-r


sys.exit()
=============
The problem is that when I launch it, python proggy is automatically
suspended. The output I got is:
roman@rslabs:~/pruebas$ ./shell.py
roman@rslabs:~/pruebas$ uid=1000(roman) gid=1000(roman) groups=1000(roman)
roman@rslabs:~/pruebas$
[2]+  Stopped                 ./shell.py
roman@rslabs:~/pruebas$
Why and how to fix it? Would you suggest a better and more elegant way to
do what I want?
As I see it, 'sh' is attempting to read from the keyboard and not from
stdin.
Thank you.
--
Saludos,
-Roman
PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB  29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]

--

Saludos,
-Roman

PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB  29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top