1

I am trying to pipe 2 python scripts using the shell pipe operator "|", like this:

python s1.py | python s2.py

In the simpliest case, s1.py and s2.py do nothing but print some strings:

in s1.py:

print 'from s1.'

in s2.py:

import sys
for line in sys.stdin.readlines():
    print 'from s2: '+line

I would like to enter interactive mode after executing s2.py. I have tried to put the -i flag in front of s1.py, s2.py and both. But none of them give the desired result. Putting import pdb;pdb.set_trace() at the end of s2.py doesn't help either.

Could anyone give some clue? Btw, my python version is 2.5.2

Jason
  • 2,950
  • 2
  • 30
  • 50

2 Answers2

1

You'll need to reset stdin to come from the terminal, rather than the pipe. That is, before asking for input from the user (and assuming you're on a Unix-y environment) invoke sys.stdin = open("/dev/tty"). For example:

import sys
for line in sys.stdin.readlines():
    print 'from s2: ' + line

sys.stdin = open("/dev/tty")

raw_input()
jme
  • 19,895
  • 6
  • 41
  • 39
  • Thanks for answering so quickly. I think a combination of your suggestion and [this one](http://stackoverflow.com/questions/5597836/how-can-i-embedcreate-an-interactive-python-shell-in-my-python-program) solves my problem. I tried to redirect the sys.stdin and also used `code` module and now it seems to be working. – Jason Nov 25 '14 at 16:43
  • @Jason could you post your final solution? I'd like to do the same (get a shell where I can read the piped-in data from stdin) but somehow don't manage to combine both solutions. – Holger Brandl Apr 26 '16 at 12:38
  • @HolgerBrandl sorry for late reply. I've added my solution, basically I'm checking if a script is receiving the inputs from *atty* or not, and if it is not re-directing to another script, it enters an interactive session, where the variables etc. are retained following [this post](https://stackoverflow.com/questions/5597836/embed-create-an-interactive-python-shell-inside-a-python-program). Hope it helps. – Jason May 08 '16 at 15:02
1

To give a more clear answer based on suggestions by jme and the discussion:

As a minimal working example, in s1.py:

print "from s1.py"

In s2.py:

import sys
import readline # optional, will allow Up/Down/History in the console
import code

red_out=not sys.stdout.isatty()   # check if re-directing out
red_in=not sys.stdin.isatty()   # chech if re-directed in

#------Print out the re-directed in messages------
if red_in:
    for line in sys.stdin.readlines():
        print line.strip()

#--- Enter interactive session if not re-directing out---
if not red_out:
    sys.stdin = open("/dev/tty")
    shell=code.InteractiveConsole(vars)
    shell.interact()

And finally to launch it, python s1.py | python s2.py

Jason
  • 2,950
  • 2
  • 30
  • 50