2012-07-05 10 views
5

Sto cercando un'interfaccia C per shell bash. Cioè Mi piacerebbe avere una serie di funzioni che mi permettano di aprire una sessione, eseguire comandi, restituire l'output (STDOUT, STDERR) e infine chiudere la shell. Potrebbe essere una libreria o un codice sorgente C basato su librerie standard.C-Interface per bash interattivo

+0

Non sono a conoscenza di alcuna interfaccia di questo tipo. Qual è il tuo caso d'uso? Qualunque cosa in cui l'insieme dei comandi non è noto in anticipo probabilmente si rivelerebbe un brutto scherzo. –

+0

@highsciguy sembra essere alla ricerca di [expect] (http://expect.sourceforge.net/) come libreria C. – FooF

+0

Perché? In ogni caso, il modo più semplice (per ottenere un ambiente persistente) sarebbe scrivere uno script di shell in un file e poi eseguirlo usando 'system'. OK, una pipe sarebbe più veloce, ma non è necessario averla veloce altrimenti non si userebbe mai una shell. – cdarke

risposta

0

Stai cercando di ottenere qualcosa di simile:

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

uscita:

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

gets() e system chiamata può ottenere all'interno di un ciclo.

+0

Certo, ma questo non avrà un ambiente persistente. Molto probabilmente questo è ciò di cui l'OP è preoccupato. –

+0

Sì. Ad esempio tutte le variabili di shell dovrebbero essere conservate tra i comandi successivi. – highsciguy

1

Il problema di root generale sembra essere come eseguire a livello di programmazione programma terminale interattivo.

Ora, questa sarebbe in parte mia richiedere test vero e proprio, ma si sarebbe all'incirca necessario

  1. creare tre pipes corrispondente al processo figlio stdin, stdout, e stderr (la scrittura processo padre per stdin_pipe e la lettura stdout_pipe e stderr_pipe) utilizzando la chiamata di sistema pipe(2);
  2. fork e nel bambino close reindirizzare lo standard dentro, fuori e errore alle estremità corrette dei tubi precedenti chiamando dup2(2);
  3. exec (execve(2)/execv(3)) la shell interattiva;
  4. avvia i comandi writing a stdin_pipe e reading gli errori e le risposte degli altri due tubi.

(Se non è necessario fare la distinzione tra stdout e stderr si può solo semplificare la vita utilizzando popen(3) - probabilmente si potrebbe reindirizzare stderr a stdout da una corretta scelta di stringa di comando).

Per una soluzione correttamente funzionante, tuttavia, credo che probabilmente sarebbe necessario utilizzare pseudo tty (pty(7)) chiamando forkpty(3) anziché solo fork.

Mentre inizia a diventare sempre più complicato prendere in considerazione tutti i tipi di pseudo terminali, perché non cercare la libreria C che dovrebbe essere in grado di fare tutto questo per te. O emulare come viene implementato expect o un altro equivalente di lingua come pexpect. In realtà expect sembra fornire una libreria C denominata libexpect(3) per te in modo che non sia necessario scrivere tcl/tk per programmare l'interazione. Non conosco personalmente la biblioteca e potrebbero esserci altri migliori.

+1

Avresti bisogno di usare ptys, quasi certamente. –

+0

@JonathanLeffler - per scenari più complicati sì, certo. Ad esempio se i programmi da eseguire con shell richiedono informazioni sul terminale (come il numero di colonne per 'ls'). Penso che i comandi di shell semplici potrebbero forse ancora essere eseguiti con un banale approccio 'popen (3)' + 'pclose (3)' (impostazione delle variabili di ambiente, esecuzione di programmi a cui non interessano i terminali). In linea di principio, non riesco a capire perché shell come bash non dovrebbero consentire di usarli interattivamente senza tty (anche se sicuramente controllano se li stai usando usando tty e aggiustando di conseguenza il comportamento). – FooF