I'm trying to get the script that asks for the input to work when stdin is redirected. It could be that this is not even possible, but I would like to understand why. Here is an example:

$ echo 'q = raw_input("question ?"); print "\ngot: ", q' | python -  < <(echo answer)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'answer' is not defined

I know I can get it to work with this:

$ python <(echo 'q = raw_input("question ?"); print "\ngot: ", q') < <(echo answer)
question ?
got:  answer

but this is a process substitution. Is it possible to get it to work only with redirection?

  • I'm not sure I get the main point here, is there some reason to not use python -c or a program saved in a file? Or does your script need to read something from stdin and prompt the user at the same time? Which would lead to the usual idea of giving the input from a file named at the script command line. Is there some reason you don't want that? – ilkkachu Mar 26 '17 at 20:19

Yes, maybe. One way is to open up the TTY and interact with that:

#!/usr/bin/env expect
package require Tcl 8.5

gets stdin line; puts "stdin: $line"

set tty [open /dev/tty r+]
chan configure $tty -buffering none

puts -nonewline $tty "nimi sina li seme? "
set name [gets $tty]

gets stdin line; puts "stdin: $line"
puts $tty "name: $name"

Which has results thusly given the above saved in ./prompt, chmod +x, installed expect, etc.

$ (echo foo; echo bar) | ./prompt
stdin: foo
nimi sina li seme? Bob
stdin: bar
name: Bob
$ echo 'q = ...' | python -  < <(echo answer)

This isn't going to work since you're redirecting to python's stdin twice. The (later) redirection of < <(echo answer) takes effect, and python gets only the word answer as the script to run.

Opening /dev/tty (or even /dev/stderr) can work even if stdin is redirected.

$ echo foo | python -c 'import sys; 
     s = sys.stdin.readline(); 
     print "from stdin:", s; 
     t = open("/dev/tty", "r"); 
     s = t.readline(); 
     print "from tty:", s;'

Of course this requires that the script is running with a tty, and not from cron or similar.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.