Linux: Pipe into Python (Ncurses) Script, Stdin and Termios

Linux: Pipe into Python (ncurses) script, stdin and termios

This can't be done without getting the parent process involved. Fortunately, there's a way to get bash involved using I/O redirection :

$ (echo "foo" | ./pipe.py) 3<&0

That will pipe foo to pipe.py in a subshell with stdin duplicated into file descriptor 3. Now all we need to do is use that extra help from our parent process in the python script (since we'll inherit fd 3):

#!/usr/bin/env python

import sys, os
import curses

output = sys.stdin.readline(100)

# We're finished with stdin. Duplicate inherited fd 3,
# which contains a duplicate of the parent process' stdin,
# into our stdin, at the OS level (assigning os.fdopen(3)
# to sys.stdin or sys.__stdin__ does not work).
os.dup2(3, 0)

# Now curses can initialize.
screen = curses.initscr()
screen.border(0)
screen.addstr(12, 25, output)
screen.refresh()
screen.getch()
curses.endwin()

Finally, you can work around the ugly syntax on the command line by running the subshell first:

$ exec 3<&0  # spawn subshell
$ echo "foo" | ./pipe.py # works
$ echo "bar" | ./pipe.py # still works

That solves your problem, if you have bash.

Bad pipe filedescriptor when reading from stdin in python

It seems that stdin/stdout redirect does not work when starting from a file association.
This is not specific to python, but a problem caused by win32 cmd.exe.

See: http://mail.python.org/pipermail/python-bugs-list/2004-August/024920.html

openmpi, termios and stdin

In Open MPI, stdin is read by the mpirun process.

Then the data read is forwarded to one MPI task (task 0 unless explicitly requested otherwise), and that could involve the orted daemon(s).

Bottom line, and from the point of view of the MPI task that is forwarded stdin, file descriptor zero is a pipe to the local daemon (mpirun or orted), and that is why tcgetattr() and friends fail.

Note all other MPI tasks have file descriptor zero pointing to /dev/null.

IIRC, SLURM provides a srun option (e.g. direct-run) in which stdin is a pseudo-terminal.

Pipe stdin into a shell script through php

Using xenon's answer with popen seems to do the trick.

// Open the process handle
$ph = popen("./script.sh","w");
// This puts it into the file line by line.
while(($line = fgets(STDIN)) !== false){
// Put in line from STDIN. (Note that you may have to use `$line . '\n'`. I don't know
fputs($ph,$line);
}
pclose($ph);

The difference between bash and python pipes

When python opens stdin and stdout, it detects what encoding to use and uses text I/O to give you unicode strings.

But subprocess does not (and can not) detect the encoding of the subprocess you start, so it'll return bytes. You can use a io.TextIOWrapper() instance to wrap the child.stdout pipe to provide unicode data:

sys.stdin = io.TextIOWrapper(child.stdout, encoding='utf8')


Related Topics



Leave a reply



Submit