Wie öffnet man eine Datei mit relativen Pfad unter Linux?
Ich habe ein Programm öffnet eine Datei mit einem relativen Pfad (z.B. '..').
Nun das problem ist, wenn ich führen Sie das Programm aus einem anderen Verzeichnis, der relative Pfad ist nicht in Bezug auf das Programm, sondern relativ zum Arbeitsverzeichnis. So, wenn ich starten Sie das Programm mit '/Pfad/zum/Programm/myprog' es schlägt fehl, um die Datei zu suchen.
Gibt es eine Möglichkeit, das Programm auszuführen, das unabhängig von der Arbeits-Verzeichnis? Id est, als Wenn die Arbeits-Verzeichnis das Verzeichnis, wo das Programm liegt? Oder bin ich einfach nur zu denken in einer viel zu komplizierten Weg und es gibt einen viel einfacheren Weg, der zum verweisen auf eine Datei, die Lage ist nur bekannt durch Ihren Pfad relativ zum Pfad der Datei des Programms?
- mögliche Duplikate von Verzeichnis der ausgeführten Programm unter Linux?
- Dies sollte erreichbar sein jedoch, sind Sie sicher, dass Sie das wollen ? Auf Linux, jeder Dateityp hat seine eigene Verzeichnisse : Konfiguration in der Regel gehen Sie zu
/etc/
oder ` ~/.my_program, images and documentations to
/usr/share`, und so weiter. Auch, die meisten Nutzer werden erwarten, dass Ihr Programm im aktuellen Verzeichnis. - Siehe auch dreamincode.net/forums/topic/98402-directory-of-running-program
- Ich verstehe nicht, warum es ein Duplikat ist. Vielleicht war die Frage nicht klar genug. Mein Programm ist immer in './Release/bin'. Der code steht in der". /tools/etwas". Da ich manchmal bin in das tools-Verzeichnis und manchmal in das root-Verzeichnis, kann das Programm nicht ausgeführt, wenn ich den relativen Pfad in das Programm.
- Sobald Sie das Programm auf den absoluten Pfad, ändern das aktuelle Verzeichnis ist trivial (
chdir
) also, was Sie Fragen, ist im Grunde gleich: "Wie bekomme ich den absoluten Pfad meines executable ?". - Ich hatte nicht gedacht, dass. Sie haben Recht: von diesem Punkt ist es trivial.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn das Programm nicht tut es von selbst, es ist ein schlechtes Programm. Schlechte Programme sollten eingewickelt werden, mit ein bisschen Bash-scripting:
Dem Skript oben legt das Verzeichnis fest, in dem es liegt, dann ändert das aktuelle Arbeitsverzeichnis auf das Verzeichnis und führt das Programm
myprog
von dort aus, vorbei sind alle Parameter transparent. Damit Sie dieses Skript in das selbe Verzeichnis, wo das Programm liegt, und führen Sie es statt in Ihrem Programm.Vorausgesetzt, dass Sie Zugriff auf den Quellcode und können Update das Programm, dann verwenden Sie proc-fs zu bestimmen, wird der Speicherort des Programms und verwenden Sie dann den absoluten Pfad.
Beispielsweise
/proc/self/exe
wird immer ein symlink zeigt auf die Binär-Datei des aktuellen Prozesses. Verwendenreadlink
Lesen seinen Wert, dann schneiden Sie die ausführbare Namen und du hast das Verzeichnis.chdir
wie ich bereits erwähnte)?"$@"
eher als$*
openat
öffnet eine Datei relativ zu einem bestimmten Verzeichnis-Datei-Deskriptor übergeben Sie es, aber ich glaube nicht, dass es wirklich das ist, was Sie wollen (genau).Müssen Sie das Verzeichnis finden, wo die aktuelle ausführbare Datei, und erstellen Sie dann eine offene call-relative (mit string-Operatoren zu bauen, den Pfad
openat
oder ändern Sie das aktuelle Verzeichnis auf das Verzeichnis).Finden Sie die ausführbare Datei kann
readlink
/proc/self/exe
.readlink
liest den Pfad, den ein symbolischer link zeigt, und/proc/self
ist ein symbolischer link zu/proc/<PID>
wo<PID>
ist die Prozess-ID des aktuellen Prozesses (behandelt besonders in den kernel), und dieexe
unter, das einen symbolischen link auf die ausführbare Datei für diesen Prozess. Dann müssen Sie die Fische aus den Pfad zu dieser ausführbaren Datei und verwenden.Alle, dass gesagt wird, Sie sollten in der Regel vermeiden Sie das schreiben von Programmen in der Weise, dass Sie erwarten, Dinge zu finden, die relativ zu Ihrer ausführbaren Datei.
es wurde eine Frage vor einer Weile, wie zu finden der Speicherort der ausführbaren Datei in den C
Sie könnten auf diesem Weg öffnen Sie Ihre Konfiguration, Ressource, etc ..
Eine Möglichkeit ist die Verwendung von argv[0] - es gibt den relativen Pfad des Programms (zum Beispiel
./programs/test/a.out
). Wenn Sie schneiden den Namen des Programms und fügen Sie den relativen Pfad zur Datei, erhalten Sie ein monster (zum Beispiel./programs/test/../../input_data
) aber es sollte funktionieren.execve
nennen, aber es ist in der Regel korrekt und sollte gut genug sein für diesen Einsatz.c++
ich denke, wir können davon ausgehen, dass er die volle Kontrolle über das Programm.exec
- und-pass "Clowns Angriff der Welt", wieargv[0]
und die ganze Sache schlägt fehl.Die einfachste Möglichkeit wäre entweder setzen Sie Ihr Programm in einem pre-bekannten Ort (/bin, /usr/bin, etc.). Wenn nicht, können Sie den argv[0], entfernen Sie die Programm-name (der Letzte Teil), und verwenden Sie diese als Ihre working directory-Präfix alle relativen Pfade (wenn Sie möchten, dass relative Pfade relativ zu denen Ihr Programm ist).
Können, können Sie auch bestimmen den Pfad zu Ihrem Programm mit der oben beschriebenen Methode (verwenden
argv[0]
), und rufen Sie dann einechdir()
mit diesem Verzeichnis. Alle relativen Pfade, die von da an sein würde, relativ zu dem das Programm ist. Beachten Sie jedoch, dass in diesem Fall müssen Sie, um festzustellen, obargv[0]
hält einen absoluten Pfad. Wenn nicht, haben Sie, um den aktuellen Arbeits-Verzeichnis (getcwd()
) und fügen Sie den Verzeichnis-Teil desargv[0]
. Beachten Sie jedoch, dass eine änderung der derzeitigen Arbeit von dir. ist es nicht eine gute Idee, in der Regel, wie wenn ein Benutzer Ihnen eine Datei-Pfad als argument an, es werden relativ zur aktuellen Arbeit von dir, nicht relativ zu dem das Programm gespeichert ist.Einige Beispiele: stellen Sie sich Ihr Programm lebt in
/usr/bin
. Sie können nennen Sie Ihr Programm:(das wäre
argv[0]
. Beschneiden Sie den Namen der ausführbaren Datei und Sie haben Ihre dir.) Oder, als, sagen wir, in/usr
:Nun
argv[0]
ist ein relativer Pfad. Sie haben voranstellen aktuellen Arbeits-Verzeichnis (/usr
) in derargv[0]
:/usr/./bin/myprog
, und dann wieder beschneiden Sie den Namen der ausführbaren Datei. Das Verzeichnis wäre wieder/usr/bin
.Gut, wenn Ihr Programm braucht, um öffnen Sie eine Datei von einem Standort, hängt davon ab, wo das Programm installiert ist, sollten Sie wahrscheinlich machen dies zu einem compile-time-option. Haben Sie Ihre build-system setzen einige CPP-makro angibt, das Verzeichnis, wo die Daten-Dateien in Frage gefunden werden kann. Dies ist, was der --datadir-option zu konfigurieren, die in einem standard - "configure, make, make install"-Programm gebaut oft tut.
Natürlich, wenn Sie wirklich wollen, Sie programmgesteuert ändern können, die arbeiten dir mit der
chdir
POSIX-Funktionen. Aber wie ich schon sagte, wenn ein Programm muss wissen wo es sich befindet, dies sollte zur Verfügung gestellt werden zur compile-Zeit. Dann brauchen Sie nicht zu überschreiben, wird die Auswahl des Benutzers zu arbeiten, dir.Nicht relative Pfade verwenden. Absolute Pfade verwenden. Haben Sie vielleicht eine Konstante definiert, die in einer config.h header-Datei, die angibt, wo sich die ausführbare Datei installiert ist. Dann voranstellen, dass die string-Konstante zu jedem relativen Pfad im code angeben.
Bestimmen Sie den Ausführungspfad von der
argv[0]
parameter, aber seien Sie vorsichtig, wenn dies zu tun.Was Sie beschrieben, ist eine gut bekannte und erwartete semantische. Die Benutzer werden erwarten, dass dieses Verhalten.
Hier ist etwas code, den Sie verwenden können, finden Sie Ihre install-Pfad von innerhalb Ihrem Programm ein (ersetzen Sie "test0002" mit dem Namen des Programms):