2013-05-11 48 views
1

我正在尝试构建一个应用程序,使用户能够与命令行交互式shell(如IRB或Python)进行交互。这意味着我需要将用户输入输入到shell中,并将shell的输出返回给用户。如何管理交互式shell的输入和输出?

我希望这会像管道STDIN,STDOUT和STDERR一样简单,但大多数shell似乎对STDIN输入的反应不同,而不是直接键盘输入。

例如,这里是我管STDIN到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 

看来,Python是解释STDIN为一个脚本文件,它不会管任何的人机交互界面,就像行开头的“>>>”一样。它也在第一行失败,因为我们在outfile中看不到“再见”。

这里是irb(交互式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比Python的反应不同:即,它继续执行命令,即使有错误。但是,它仍然缺少shell界面。

应用程序如何与交互式shell环境交互?

回答

1

从技术上讲,您的第一个示例不是将输入传送给Python;它来自一个文件 - 是的,文件输入的处理方式不同。

说服程序输入来自终端的方式是使用伪tty。有一个主方和一个奴隶方;你会将shell(Python,Ruby)挂接到从属端,并让你的控制程序写入并从主端读取。

设置起来相当困难。使用expect或其中一个克隆来管理伪tty可能会更好。在其他相关问题中,请参阅How to perform automated Unix input?

+0

感谢您的信息。我不知道应用程序能够判断他们的STDIN是来自键盘(tty)还是来自管道/文件。在我的情况下,我很幸运,我使用的shell有一个选项来强制它进入“交互模式”,这使得它跳过了tty测试。 [IRB示例](http://www.ruby-forum.com/topic/126906)。如果你使用shell XYZ,快速搜索“XYZ强制交互模式”应该告诉你这个选项是否已经存在。 – sffc 2013-05-13 02:02:00