2016-07-13 4 views
0

Ich fange gerade an, mit der Kombination von ncurses und C herumzuspielen, um eine sehr minimale TUI zu entwickeln. Der Zweck der TUI ist es, Benutzer mit einem einfachen Anmelde-/Begrüßungsbildschirm zu begrüßen. Das Ziel wäre, grundlegende Systeminformationen wie das Betriebssystem, den verfügbaren Speicher, die IP-Adresse usw. anzuzeigen. Nichts außer schreibgeschützt.Einfache Text-GUI (TUI) Verwendung von NCurses und C zur Anzeige von Systeminformationen

Was wäre der beste Weg, dies zu tun? Der Teil, mit dem ich zu kämpfen habe, ist die Schnittstelle der Shell-Befehle wie df, ls, ifconfig usw. mit Variablen, die ich dann in ncurses und C anzeigen oder drucken kann. Ich weiß, sowas kann getan werden, ebenso wie das Aufrufen des Systembefehls mit einer Schnur, aber dies scheint etwas sperrig:

#include <ncurses.h> 
#include <stdlib.h> 
#include <stdio.h> 

int main(void) { 
    FILE *pp; 

    initscr(); 
    cbreak(); 
    if ((pp = popen("df", "r")) != 0) { 
     char buffer[BUFSIZ]; 
     while (fgets(buffer, sizeof(buffer), pp) != 0) { 
      addstr(buffer); 
     } 
     pclose(pp); 
    } 
    getch(); 
    return EXIT_SUCCESS; 
} 

gibt es Methoden, um einen Befehl in der Befehlszeile aus einem C-Programm auszuführen und dann Zugriff selektiv die Ausgabe dieses Befehls für eine spätere Anzeige? Oder werden diese Informationen in der Regel irgendwo in einer analysierbaren Datei auf dem Computer gespeichert? Ich bin neu zu versuchen, Systeminformationen zu ziehen/verwenden Sie die Befehlszeile im Sinne von "TUI" und jede Hilfe wäre willkommen. Vielen Dank im Voraus!

Antwort

1

Die Idee mit der Pfeife ist gut und einfach, alles andere würde mindestens eines von "gut und einfach", am wahrscheinlichsten beide fehlen. Aber Ihre andere Frage betrifft die Verfügbarkeit bestimmter Systeminformationen. Nun, diese Informationen sind wild verteilt und der genaue Ort hängt von dem Betriebssystem ab, das tatsächlich verwendet wird.

Für das übliche, nicht spezialisierte Linux-System: Für das Dateisystem ist es /etc/mtab (und verwenden Sie statfs() für die Details) und viele Systeminformationen sind in /proc. Wenn Sie mehr brauchen, wird es kompliziert.

Es ist bereits ziemlich kompliziert, auch wenn Sie zum Beispiel eine vereinfachte Version von df erstellen möchten (Originalcode df in $COREUTILS/src/df.c). Anstatt nur df und lesen aus einem Rohr läuft, müssen Sie

  • lesen /etc/mtab und finden Sie die Mount-Punkte (System möglicherweise nicht /etc/mtab obwohl es sollte) tun
  • laufen statfs() auf jedem einhängepunkt und drucken Sie das Ergebnis

Sie werden über 100 fehleranfällige Zeilen von C-Code dafür benötigen, auch wenn Sie alles auslassen. Und das zum Drucken des Dateisystems allein.

Nein, lesen Sie einfach die Ausgabe der alten und gut getesteten Programme von einer Pipe, es ist der einfachste Weg.

EDIT:

Sie verwenden die Vollschale, wenn Sie das Rohr verwenden. Das bedeutet, dass Sie auch alle anderen Tools verwenden können.

Um es einfacher zu testen, hier ist eine vereinfachte Version ohne ncurses (wodurch es viel komplizierter ;-)), nur für das Abspielen in der Kommandozeile.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define BUF_SIZE 256 

// ALL CHECKS OMMITTED! 

char *sub_exec(const char *command) 
{ 
    char buf[BUF_SIZE]; 
    char *ret; 
    size_t mem_alloc, mem_needed; 

    ret = malloc(4 * BUF_SIZE * sizeof(char)); 
    // or use calloc or set \0 manually 
    memset(ret, '\0', 4 * BUF_SIZE); 
    // memory allocated 
    mem_alloc = 4 * BUF_SIZE; 
    // memory needed 
    mem_needed = 0; 
    // open the pipe read-only 
    FILE *out_pipe = popen(command, "r"); 
    // until end of the output of the pipe (EOF) 
    while (!feof(out_pipe)) { 
    // read a chunk of the output 
    if (fgets(buf, BUF_SIZE, out_pipe) != NULL) { 
     mem_needed += BUF_SIZE; 
     if (mem_alloc < mem_needed) { 
    // no fancy algorithms 
    ret = realloc(ret, mem_needed + 4 * BUF_SIZE); 
    mem_alloc = mem_needed * 2; 
     } 
     // and conatenate it to the result 
     strncat(ret, buf, BUF_SIZE); 
    } 
    } 
    pclose(out_pipe); 
    // You may or may not readjust the memory used 
    // ret = realloc(ret, strlen(ret) + 1); 
    return ret; 
} 

int main(int argc, char **argv) 
{ 
    char *str_from_pipe; 
    if (argc < 2) 
    fprintf(stderr, "Usage: %s command\n", argv[0]); 

    str_from_pipe = sub_exec(argv[1]); 
    printf("%s\n", str_from_pipe); 

    free(str_from_pipe); 

    exit(EXIT_SUCCESS); 
} 

Sie können hier einfache Dinge tun, wie

./readpipe "cat win*c | tr -d '\015' | perl -0777 -pe 's{/\*.*?\*/}{}gs' | indent -" 

(verketten alle C-Dateien, entfernen die \r s, die meisten Kommentare Streifen und führen Sie es durch indent(1))

Oder mit df . Sagen Sie bitte die Dateisysteme mit aktuellen Daten in es wollen, nicht tempfs oder gleich, so:

./readpipe "df -P -h -t ext4" 

die Drucke hier:

Filesystem  Size Used Avail Use% Mounted on 
/dev/sda2  48G 33G 14G 71%/
/dev/sda3  861G 761G 56G 94% /home 

Sie (ganz voll ist, wie es scheint) verwenden kann, wie es ist oder massieren sie es weiter:

./readpipe "df -h -t ext4 --output=target,fstype,size,used,avail|awk '{if(NR>1)print}'" 

Drucke:

/   ext4 48G 33G 14G 
/home  ext4 861G 761G 56G 

Caveat:

./readpipe "df -h -t ext4 --output=target,fstype,size,used,avail| sed -n '1!p'" 

nicht funktioniert, müssen Sie die Art von Zitaten austauschen (aber es ist nicht immer so einfach)

./readpipe 'df -h -t ext4 --output=target,fstype,size,used,avail | sed -n "1!p"' 

Um das spalten Einträge mit zB: strtok(3) ersetzen Sie alle Leerzeichen mit einzelnen Tabs

(ja, es gibt viel elegantere Möglichkeiten, es zu tun, aber es ist gut genug)

Weitere nützliche Informationen in den Dateien/Verzeichnisse über die CPU (s)

/sys/devices/system/cpu/cpu*/cpufreq/ 
/sys/devices/system/cpu/cpu*/cache/ 

Oder von lscpu. Es gibt viele ls* Programme, die nützlich sind, wie lspci, lsusb, lskat & hellip; nein, warten Sie, das ist etwas anderes, und nicht zu vergessen lsblk (listet die Block-Geräte inkl. Partitionen, wenn sie verfügbar sind.). Eine recht vollständige Liste der installierten Hardware (einige Informationen benötigen Root-Rechte, aber es ist bereits ziemlich umfangreich ohne) ist mit Hilfe von lshw und uname ist für Informationen über das OS, auch verfügbar: free für den Speicherverbrauch, und viele, viel mehr. Die meisten, wenn nicht alle, erlauben eine Formatierung, siehe die entsprechenden Manpages für die blutigen Details.

Wenn Sie mir sagen, was Sie brauchen, kann ich Ihnen sagen, wo Sie es finden (er sagt kühn ;-)). Fragen Sie einfach in einem Kommentar unten, ich werde es hinzufügen.

Verwandte Themen