如何管理交互式shell的输入和输出?

时间:2013-05-11 22:04:19

标签: shell stdout stdin interactive irb

我正在尝试构建一个应用程序,使用户能够与命令行交互式shell(如IRB或Python)进行交互。这意味着我需要将用户输入传递到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解释为脚本文件,并且它不会管理任何交互式界面,例如“&gt;&gt;&gt;”在行的开头。它也在第一行失败并出现错误,因为我们在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 个答案:

答案 0 :(得分:2)

从技术上讲,你的第一个样本没有将输入传递给Python;它来自一个文件 - 是的,文件输入的处理方式不同。

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

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