2012-07-05 58 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