2012-07-05 56 views
5

我正在寻找一个C接口的bash炮弹。即我希望有一组函数允许我打开会话,执行命令,返回输出(STDOUT,STDERR),最后关闭shell。它可以是基于标准库的库或C源代码。C-接口交互的bash

+0

我不知道有任何这样的接口。你的用例是什么?任何事先未知的命令集可能会变成一个丑陋的脆弱黑客。 – 2012-07-05 11:22:54

+0

@highsciguy似乎正在寻找像C库一样的[expect](http://expect.sourceforge.net/)。 – FooF 2012-07-05 12:00:59

+0

为什么?无论如何,最简单的方法(获得持久化环境)将写出一个shell脚本到一个文件,然后使用'system'执行它。好吧,管道会更快,但你不需要快速,否则你根本不会使用外壳。 – cdarke 2012-07-05 12:09:57

回答

0

你希望获得这样的事情:

#include<stdio.h> 
    int main() 
    { 
     char a[1000]; 
     gets(a); 
     system(a); 
     return 0; 
    } 

输出:

./a.out 
cat testing.c 
#include<stdio.h> 
int main() 
{ 
    char a[1000]; 
    gets(a); 
    system(a); 
    return 0; 
} 

gets()system呼叫可以在一个循环中获得。

+0

当然,但这不会有持久的环境。 OP最关心的可能是这个。 – 2012-07-05 11:21:16

+0

是的。例如,所有的shell变量都应该在后续命令之间保留。 – highsciguy 2012-07-05 16:27:53

1

一般根本的问题似乎是如何以编程方式运行交互式终端程序

现在,这会在我的部分需要实际测试,但你大概需要

  1. 创建对应于子进程stdinstdout,并stderr(父进程写入和阅读stdout_pipestderr_pipe)使用pipe(2)系统调用;
  2. fork和子女close通过调用dup2(2)将标准输入,输出和错误重定向到上述管道的适当端;
  3. EXEC(execve(2)/execv(3))你的交互shell;
  4. 从其他两个管开始writing命令stdin_pipereading错误和响应。

(如果你不需要做stdoutstderr之间的区别,你可以只用popen(3)简化你的生活 - 你很可能通过命令字符串的正确选择重定向到stderrstdout)。

但是,对于正常工作的解决方案,我相信你可能需要使用伪ttys(pty(7))通过调用forkpty(3)而不是fork。

当它开始变得越来越复杂,考虑到处理伪终端的所有nyances,为什么不搜索对于C期望库,应该能够做到这一切为您服务。或者模拟expect或其他一些与pexpect等效的语言是如何实现的。实际上expect似乎为您提供了一个名为libexpect(3)的C库,因此您不需要编写tcl/tk来编程交互。我对图书馆并不熟悉,可能还有其他更好的图书馆。

+1

你几乎可以肯定需要使用ptys。 – 2012-07-06 02:50:03

+0

@JonathanLeffler - 对于更复杂的场景是的,当然。例如,如果用shell运行的程序需要关于终端的信息(比如'ls'的列数)。我认为简单的shell命令可能仍然可以通过基于普通的'popen(3)'+'pclose(3)'方法(设置环境变量,运行不关心终端的程序)来运行。原则上,我不明白为什么像bash这样的shell不应该允许在没有tty的情况下交互地使用它们(尽管它们确实检查是否使用tty运行它们并相应地调整行为)。 – FooF 2012-07-06 03:09:12