5 Stimmen

Unix-Pfadsuchfunktion in C

Ich programmiere eine UNIX-Shell und muss den execv()-Systemaufruf verwenden, um einen Prozess zu erstellen. Einer der Parameter für execv() ist der Dateipfad für das ausführbare Programm. Wenn also jemand /bin/ls eingibt, wird das ausführbare Programm ls ausgeführt. Aber was ich brauche, ist eine Funktion, damit beim Eingeben von ls nach dem Dateipfad von ls gesucht wird (ähnlich wie beim which-Befehl). Gibt es eine Funktion, die mir das ermöglicht?

Leider handelt es sich um ein Schulprojekt, und ich darf execvp() nicht verwenden. Ich muss eine Funktion zur Pfadsuche implementieren und dann diesen Dateipfad dem Parameter von execv() hinzufügen.

2voto

mhawke Punkte 79590

Einige Leute haben vorgeschlagen, dass Sie access() oder stat() aufrufen, bevor Sie versuchen, das Programm mit execv() auszuführen. Das ist nicht notwendig. execv() gibt einen Fehler zurück, wenn es die angeforderte Datei nicht ausführen konnte.

0 Stimmen

Richtig. Und Sie müssen möglicherweise zwischen ENOENT (Datei existiert nicht) und ENOEXEC (Datei ist nicht ausführbar) unterscheiden, um zu entscheiden, ob es sich lohnt, zu versuchen, das "Programm" über die Shell als Skript auszuführen.

0 Stimmen

Nicht wirklich. Wenn die Datei existiert, aber nicht ausführbar ist, können Sie sie sowieso nicht ausführen (es sei denn, als Argument für /bin/sh - aber nun raten Sie, dass es ein Skript ist). Wenn es ein Skript (Shell oder sonstiges) mit dem richtigen "Shebang" oben ist, wird es wie erwartet ausgeführt.

0 Stimmen

@mhawke: Obwohl ich zustimme, dass deine Meinung objektiv besser und näher an dem liegt, was Benutzer moderner Unix-Systeme erwarten, berücksichtigt POSIX streng genommen nicht den "shebang"-Trick und erwartet, dass nicht-binäre Dateien ausgeführt werden, indem der Standard-Shell-Interpreter aufgerufen wird. execvp ist tatsächlich so spezifiziert, dass es sich auf diese Weise verhält, wenn das zugrunde liegende execve einen ENOEXEC-Fehler zurückgeben würde.

0voto

Chris Jester-Young Punkte 212385

execvp :-)

Bearbeitung: Okay. Hier ist eine Perl-Version, die als Pseudocode für Ihr Problem dienen kann.

use List::Util qw(erstes);

my @pfad = split /:/, $ENV{PATH};
my $verz = erstes {$_ ||= '.'; -x "$_/$name"} @pfad
    or die "Kann Programm $name nicht finden\n";
exec "$verz/$name", @args;

split teilt einen String anhand des angegebenen Trennzeichens in ein Array von Strings auf. erstes findet das erste Element, das einem Kriterium entspricht; hier, dass die Verkettung des Verzeichnisses und des gesuchten Namens ausführbar ist (-x). Danach wird das Programm ausgeführt.

Hoffentlich hilft es!

0 Stimmen

Ein hinterlistiger Trick, der nicht berücksichtigt wurde, als ich dies eingetippt habe - ein leeres Feld in PATH muss wie ein Punkt (aktueller Verzeichnis) behandelt werden.

0voto

mhawke Punkte 79590

Vom execvp-Mann-Seite:

   Die Funktionen execlp() und execvp() duplizieren die Aktionen der
   Shell bei der Suche nach einer ausführbaren Datei, wenn der angegebene Dateiname
   kein Schrägstrich (/) Zeichen enthält. Der Suchpfad ist der in der Umgebung
   durch die PATH Variable angegebene Pfad. Wenn diese Variable
   nicht angegeben wird, wird der Standardpfad ‘‘:/bin:/usr/bin’’ verwendet. Darüber hinaus werden bestimmte Fehler speziell behandelt.

Vielleicht dürfen Sie execlp() verwenden? Wenn Sie execv verwenden müssen, müssen Sie den Wert der PATH-Umgebungsvariable erhalten, dies mit strtok() analysieren, um die einzelnen Pfade zu erhalten, Ihren Dateinamen an jeden Pfad anhängen und versuchen, ihn mit execv() auszuführen.

Ich würde Code bereitstellen, aber ich mache Ihre Hausaufgaben nicht für Sie.

0voto

Andrew Stein Punkte 12272

Oh, ein Schulprojekt...

Wenn du etwas "ähnliches" willst, warum führst du nicht einfach "which" selbst aus (/usr/bin/which unter Linux, nicht das Bash-Alias oder das tcsh-Builtin), um den Pfad zu dem zu erhalten, wonach du suchst...

-)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X