我正在尝试找到一种方法来调用交互式命令行程序,以便它既可以直接从键盘输入,也可以从命名管道输入。我的目标是让这个与MATLAB一起工作,但我认为Bash和一个例子一样好用。因此,我们的想法是启动Bash,一旦它运行,我就可以输入命令,使用箭头表示历史记录等,并将命令发送到命名管道。我一直在四处寻找并摆弄这几天,但到目前为止我没有尝试过的任何事情都做得很好。
例如,https://serverfault.com/questions/171095/how-do-i-join-two-named-pipes-into-single-input-stream-in-linux处有一个有用的帖子,建议做这样的事情:
mkfifo alt_in
(tail -f alt_in & cat) | bash
这几乎正是我正在寻找的,除非你尝试使用退格键或箭头键,它不能正常工作。 (我想这是因为cat
拦截击键,通常由bash中的readline库处理?)有人有其他建议吗?
最终,我想有一种方法来启动MATLAB过程,以便我可以从TextMate向它发送命令,但也可以在终端中与它进行交互。我使用MATLAB进行工作,但不是它的GUI或编辑器的忠实粉丝。
编辑2010年12月19日
感谢所有非常有用的建议!我想对任何有兴趣的人总结一下这个结果。我查看了rlwrap
,但由于我的目标是让任何人都可以使用的TextMate包中的这个工作,我对依赖非标准实用程序(我应该首先提到)非常犹豫。我还简要地查看了expect
和unbuffer
,但是,它们看起来相当复杂,我只是没有勇气深入研究它。
screen
工作得很好 - 如下所示,我可以打开终端,启动screen
,启动matlab -nodesktop
,然后就可以发送TextMate,例如发送在TextMate命令中使用screen -X ...
将所选文本添加到Matlab。我注意到这种方法的缺点是:
当我在玩screen
时,我想到虽然我问过的问题是关于连接管道和STDIN等等,但实际上我只关心这个问题是一个非常具体的案例:从中获取文本TextMate到终端。这促使我尝试用AppleScript做到这一点,令人惊讶的是,结果比我试过的任何其他东西更简单,更强大。创建一个TextMate命令,将选定的文本或当前行作为输入,并包含
#!/usr/bin/env osascript
set input_command to do shell script "cat"
tell application "Terminal"
do script input_command in window 1
end tell
只要MATLAB位于最前面的终端窗口,这就很有效。 (也可以搜索运行MATLAB的终端选项卡,为了清楚起见,我将其排除在外。)
这个故事的寓意是我应该提出更具体的问题。再次感谢所有的帮助;我从摔跤中学到了很多东西!
答案 0 :(得分:1)
尝试通过unbuffer
管道化数据。
答案 1 :(得分:1)
尝试一下:
mkfifo alt_in
(tail -f alt_in & rlwrap cat) | bash
您将不会收到提示,但您可以输入命令并使用箭头键等,包括历史记录检索。您可以echo
从另一个终端命令进入命名管道,它们将在接收端执行,但它们不会在其历史记录中。
其他一些需要调查的事项:
对于后者,在一个终端开始screen
。你可以像往常那样与Bash进行交互。现在在另一个终端上,做
screen -ls
确定您开始的screen
会话的PID。它将是一行开头的数字,如下所示:
31544.pts-2.hostname (01/01/2010 01:01:01 PM) (Attached)
现在你可以这样做:
screen -S 31544 -X stuff $'echo Your ad here.\n'
将导致echo
命令在另一个终端上执行。 $''
导致转义内的转义序列被解释,在这种情况下为我们提供换行符,因此我们可以“按” Enter 。
假设我们这样做了:
screen -S 31544 -X stuff $'top\n'
现在top
正在运行。我们可以去那个终点站并按 q 退出,但那里的乐趣在哪里?
screen -S 31544 -X stuff 'q'
请注意,这次我们不需要换行符。
答案 2 :(得分:0)
键盘输入有不同的风格,称为“原始模式”,“cbreak模式”和“熟食模式”。
原始模式是操作系统在您向程序输入时传递每次击键的地方(例如bash)。
熟化模式是操作系统缓冲一行并允许您进行简单编辑(如删除字符)的位置。当你按RETURN或EOF(通常是 Ctrl-D )时,它会向程序发送一行。
stty命令允许您定义一些解释为行尾(RETURN),EOF(Ctrl-D)和其他一些键码的键码。
Cbreak-mode是一个中途,其中许多控制字符保留其常用功能,但操作系统仍然一次向应用程序发送一个字符。像bash,vi和less这样的程序通常使用这种模式。
如果您将终端设置为原始模式,那么除非您正在运行的程序合作,否则您无法再使用键盘“突破”它。
期望(here或here)可以为Bash提供一个终端界面,这样它仍然认为它是从普通键盘运行的,并且仍然会执行所有酷bash命令行编辑,我们'习惯了。
Expect可以在原始模式和管道中读取键盘输入并无缝传递。