How do you pipe input and output to and from an interactive shell?

别说谁变了你拦得住时间么 提交于 2021-02-08 03:31:13

问题


I am trying to build an application that enables the user to interact with a command-line interactive shell, like IRB or Python. This means that I need to pipe user input into the shell and the shell's output back to the user.

I was hoping this was going to be as easy as piping STDIN, STDOUT, and STDERR, but most shells seem to respond differently to STDIN input as opposed to direct keyboard input.

For example, here is what happens when I pipe STDIN into python:

$ python 1> py.out 2> py.err <<EOI
> print 'hello'
> hello
> print 'goodbye'
> EOI
$ cat py.out
hello
$ cat py.err
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: name 'hello' is not defined

It seems that Python is interpreting the STDIN as a script file, and it doesn't pipe any of the interactive interface, like the ">>>" at the beginning of the line. It also fails at the first line with an error, because we do not see "goodbye" in the outfile.

Here is what happens with irb (Interactive Ruby):

$ irb 1> irb.out 2> irb.err <<EOI
> puts 'hello'
> hello
> puts 'goodbye'
> EOI
$ cat irb.out
Switch to inspect mode.
puts 'hello'
hello
nil
hello
NameError: undefined local variable or method `hello' for main:Object
    from (irb):2
    from /path/to/irb:16:in `<main>'
puts 'goodbye'
goodbye
nil

$ cat irb.err

IRB responds differently than Python: namely, it continues executing commands even when there is an error. However, it still lacks the shell interface.

How can an application interact with an interactive shell environment?


回答1:


Technically, your first sample is not piping the input to Python; it is coming from a file — and yes, file input is treated differently.

The way to persuade a program that its input is coming from a terminal is using a pseudo-tty. There's a master side and a slave side; you'll hook the shell (Python, Ruby) to the slave side, and have your controlling program write to and read from the master side.

That's fairly tricky to set up. You may do better using expect or one of its clones to manage the pseudo-tty. Amongst other related questions, see How to perform automated Unix input?



来源:https://stackoverflow.com/questions/16502170/how-do-you-pipe-input-and-output-to-and-from-an-interactive-shell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!