2012-07-05 12 views
5

Poszukuję interfejsu C dla powłok bash. To znaczy. Chciałbym mieć zestaw funkcji, które pozwolą mi otworzyć sesję, wykonać polecenia, zwrócić wyjście (STDOUT, STDERR) i wreszcie zamknąć powłokę. Może to być biblioteka lub kod źródłowy C oparty na standardowych bibliotekach.Interfejs C dla bashu interaktywnego

+0

Nie znam takiego interfejsu. Jaki jest twój przypadek użycia? Wszystko, co nie jest znane z góry, prawdopodobnie okazałoby się brzydkim kruchym hackerem. –

+0

@highsciguy wydaje się szukać niektórych [spodziewać] (http://expect.sourceforge.net/) jak biblioteka C. – FooF

+0

Dlaczego? W każdym razie, najprostszym sposobem (aby uzyskać trwałe środowisko) byłoby napisanie skryptu powłoki do pliku, a następnie wykonanie go za pomocą 'system'. OK, rura byłaby szybsza, ale nie można potrzebować szybko, w przeciwnym razie nie używałbyś w ogóle powłoki. – cdarke

Odpowiedz

0

Czy chcesz osiągnąć coś takiego:

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

wyjściowy:

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

gets() i system połączenie może dostać się do środka pętli.

+0

Oczywiście, ale to nie będzie miało trwałego środowiska. Najprawdopodobniej to dotyczy OP. –

+0

Tak. Na przykład wszystkie zmienne powłoki powinny zostać zachowane między kolejnymi poleceniami. – highsciguy

1

Ogólny problem główny to programowo uruchamiany interaktywny program terminalowy.

Teraz byłoby to w mojej części wymaga rzeczywistego badania, ale można z grubsza trzeba

  1. utworzyć trzy pipes odpowiadający procesu potomnego stdin, stdout i stderr (w piśmie procesowym z rodziców do stdin_pipe i czytanie stdout_pipe i stderr_pipe) przy użyciu wywołania systemowego pipe(2);
  2. i dla dziecka close przekieruj standardowe wejście, wyjście i błąd na właściwe końce powyższych rur, wywołując dup2(2);
  3. exec (execve(2)/execv(3)) Twoja interaktywna powłoka;
  4. Uruchomienie writing poleceń do stdin_pipe i reading błędów i odpowiedzi z dwóch pozostałych potoków.

(Jeśli nie trzeba dokonać rozróżnienia pomiędzy stdout i stderr można po prostu uprościć swoje życie za pomocą popen(3) - prawdopodobnie można przekierować stderr do stdout przez odpowiedni dobór ciąg poleceń).

Dla prawidłowo działającego rozwiązania uważam jednak, że prawdopodobnie będziesz musiał użyć pseudo ttys (pty(7)), dzwoniąc pod numer forkpty(3) zamiast po prostu fork.

Zaczynając coraz bardziej skomplikować się, aby wziąć pod uwagę wszystkie przypadki radzenia sobie z pseudo terminalami, dlaczego nie szukać C oczekiwać biblioteki, która powinna być w stanie zrobić to wszystko dla ciebie. Lub emulować, w jaki sposób zaimplementowany jest expect lub inny równoważny język, taki jak pexpect. Aktualnie wydaje się, że expect udostępnia bibliotekę C nazwaną libexpect(3), aby nie trzeba było pisać tcl/tk w celu programowania interakcji. Nie jestem osobiście zaznajomiony z biblioteką i mogą istnieć inne lepsze.

+1

Musisz użyć ptys, prawie na pewno. –

+0

@ JonathanLeffler - dla bardziej skomplikowanych scenariuszy tak, na pewno. Na przykład, jeśli programy uruchamiane z powłoką wymagają informacji o terminalu (np. Liczba kolumn dla 'ls'). Myślę, że proste polecenia powłoki mogą nadal działać z trywialnym podejściem opartym na 'popen (3)' + 'pclose (3)' (ustawianie zmiennych środowiskowych, uruchamianie programów, które nie dbają o terminale). Zasadniczo nie rozumiem, dlaczego powłoki takie jak bash nie pozwalają na interaktywne używanie ich bez tty (chociaż na pewno sprawdzają, czy używasz tty i odpowiednio dostosowujesz zachowanie). – FooF