shell-komandos in programmen ?



  • hi,
    ich frag mich gerade ob ich in einem c++ programm auf shell komandos zugreifen kann,vor allem ls,df und so was. das müßte doch gehen das ich z.b. ls aufrufe und das ergebnis in verwertbarer form in eine text-datei schreibe...oder ?

    oder muss ich da den quellcode hernehmen ?



  • Gibt einige Möglichkeiten.

    z.B.

    System(xxxx);

    oder ein Script schreiben, dieses ausführbar machen und dann mit

    system("scriptdatei &"); starten.
    Der Vorteil bei 2terem ist, daß dein Programm nicht auf die Beendigung der Befehle im Script wartet und der Befehl system zurückkehrt.



  • Wenn du es auch noch SICHER programmieren möchtest (zumindest sicherer als mit system()) dann mach einen fork(), execl() im Kind Prozess und lass dir mit einer Pipe den Output vom Kind Prozess an den Vater Prozess leiten.

    Beispiel:

    /* fork.c
     *
     * Aufrunf von list() erzeugt ein Pfadliste analog zu "ls -1".
     *
     * Hierzu wird per fork() ein Sohn Prozess erzeugt und
     * mit execl() ein externes Programm (hier: ls) aufgerufen.
     *
     * Die Ausgabe des Kind Prozess wird mit einer Pipe an
     * den Vater Prozess weitergeleitet der das ganze auf der
     * Konsole ausgibt.
     */
    
    #include <stdio.h> /* printf() fprintf() */
    
    #include <unistd.h> /* fork() pipe() close() */
    
    #include <sys/types.h>
    #include <sys/wait.h>  /* wait() */
    
    #define PIPE_IN   1
    #define PIPE_OUT  2
    
    void list(char* path);
    
    int main()
    {
      printf("--- Programm gestartet\n");
    
      printf("--- TEST 1 ---\n");
      list("/tmp; echo \"=== Security Hole ===\" ");  /* Fehlermeldung */
    
      printf("--- TEST 2 ---\n");
      list("/tmp");                                   /* OK */
    
      printf("--- Programm beendet\n");
      return 0;
    }
    
    void list(char* path)
    {
      int   fd[2];
    
      if(pipe(fd) != 0)
        {
          fprintf(stderr, "Fehler beim Einrichten einer Pipe\n");
          exit(1);
        }
      else
        {
          switch(fork())
            {
              case -1 :
                {
                  fprintf(stderr, "Fehler beim Fork-Aufruf\n");
                  exit(1);
                }
              case  0 : /* Sohn Prozess */
                {
                  close(fd[PIPE_IN]); /* Leseseite der Pipe schliessen */
    
                  execl("/bin/ls", "ls", "-1" , path, NULL); /* externes Programm aufrufen */
    
                  close(fd[PIPE_OUT]); /* Schreibseite der Pipe schliessen,   */
                                       /* um Ende der Uebertragung anzuzeigen */
                  exit(0);
                }
              default : /* Vater Prozess */
                {
                  const int len=200;
                  char buffer[len];
                  int i=1;
                  int status;
    
                  close(fd[PIPE_OUT]);  /* Schreibseite der Pipe schliessen */
    
                  while(read(fd[PIPE_IN], &buffer, len) > 0)
                    {
                      printf(" %c", buffer);
                      if(++i>len)
                        {
                          printf("\n");
                          i=1;
                        }
                    }
                  wait(&status); /* auf Beendigung des Sohn Prozess warten */
                }
            }
        }
    }
    

    [ Dieser Beitrag wurde am 05.01.2003 um 04:10 Uhr von Descartes editiert. ]



  • Original erstellt von Descartes:
    *```cpp
    list("/tmp; echo "=== Security Hole ===" "); /
    Fehlermeldung */

    Nicht zwingend. Es spricht, zumindest technisch, nichts dagegen, Dateien im Root-Verzeichnis 'tmp; echo \"=== Security Hole ===\" ' zu nennen.

    execl("/bin/ls", "ls", "-1" , path, NULL); /* externes Programm aufrufen */
    

    NULL muss man leider auf char* casten, weil man hier mit va_args hantiert. Z.B.: NULL kann zu 0 evaluieren, was in diesem Kontext dann ein int und kein char-Nullzeiger ist ... Das wird vorsichtshalber in 99% aller Fälle falsch gemacht und meistens geht's gut, aber ... :).



  • Es ist vielleicht fast ein philosophischer Einwand, aber ich verwende
    für einfach Probleme (wie das Einlesen eines Verzeichnisses) höchst selten
    "system" oder ähnliches. Das ist langsam (2. Prozess wird erzeugt) und die
    Fehlerbehandlung höchst unhandlich (was, wenn nicht das erwartete zurückgegeben
    wird... wie z.B. "kein Zugriff auf...").

    Und die fork/exec Möglichkeit erscheint mir irgendwie mit Kanonen auf Spatzen
    geschossen...
    Wie wärs wenn einfach die OS-Funktionen genutzt werden?
    In C++ kann man da ne schöne Klasse drumherum schreiben, oder in C einfach in ne Library werfen..

    Ich sitze nicht gerade an einem Unix (wo ich den Quellcode hätte), aber vermutlich würde sich das mit
    http://www.rt.com/man/readdir.3.html
    oder sowas lösen lassen...





  • danke,damit sollte es gehen.


Anmelden zum Antworten