2009-06-01 119 views
131

在C/C++中有找到當前執行程序的位置(完整路徑)的方法嗎?如何在C中找到可執行文件的位置?

(與argv[0]的問題是,它沒有給出完整路徑。)

+11

哪個操作系統? – 2009-06-01 07:38:12

+6

這裏也有很好的答案:http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe/1024937#1024937 – ergosys 2011-09-10 19:32:54

+0

這個問題(「我怎樣才能找到我的位置程序在設置X?「)可以*真的*使用標籤;很難搜索使用關鍵字! – SamB 2012-02-12 22:32:19

回答

178

總結:

  • 在Unix系統與/proc真直度和realiable的方法是:

    • readlink("/proc/self/exe", buf, bufsize)(Linux)的

    • readlink("/proc/curproc/file", buf, bufsize)(FreeBSD的)

    • readlink("/proc/self/path/a.out", buf, bufsize)(Solaris)上

  • 在Unix系統而不/proc(即如果以上失敗):

    • 如果argv [0]以「/」(絕對路徑)開頭,則爲路徑。否則,如果argv [0]包含「/」(相對路徑),則將它追加到cwd (假設它尚未更改)。

    • 否則搜索目錄$PATH中的可執行文件argv[0]

    之後,檢查可執行文件是否實際上不是符號鏈接可能是合理的。 如果它解析它相對於symlink目錄。

    此步驟在/ proc方法中是不必要的(至少對於Linux)。 有proc符號鏈接直接指向可執行文件。

    請注意,由調用進程正確設置argv[0]。 這是正確的大多數時候,但有時,調用過程不能被信任(例如setuid可執行文件)。

  • 在Windows上:使用GetModuleFileName(NULL, buf, bufsize)

6

在許多POSIX系統中,你可以檢查位於下的/ proc/PID/EXE一個simlink。幾個例子:

# file /proc/*/exe 
/proc/1001/exe: symbolic link to /usr/bin/distccd 
/proc/1023/exe: symbolic link to /usr/sbin/sendmail.sendmail 
/proc/1043/exe: symbolic link to /usr/sbin/crond 
15

請注意,以下評論僅限unix。

這個問題的迂迴的答案是,沒有一般方式來正確回答這個問題在所有情況下。正如你發現的那樣,argv [0]可以由父進程設置爲任何東西,因此與程序的實際名稱或其在文件系統中的位置無關。

但是,下面的啓發式經常工作:

  1. 如果argv的[0]是一個絕對路徑,假設這是對可執行文件的完整路徑。
  2. 如果argv [0]是相對路徑,即它包含/,則使用getcwd()確定當前工作目錄,然後向其附加argv [0]。
  3. 如果argv的[0]是一個普通的詞,搜索$ PATH尋找的argv [0],並追加的argv [0]到任何目錄,你發現它英寸

注意,所有的這些都可以被調用該程序的過程繞過。最後,您可以使用特定於linux的技術,例如emg-2中提到的技術。其他操作系統上可能有相同的技術。

即使假定上述步驟給你一個有效的路徑名,你仍然可能沒有你真正想要的(因爲我懷疑你真正想要做的是想找個地方一個配置文件)的路徑名。硬鏈接的存在意味着你可以有以下情況:

-- assume /app/bin/foo is the actual program 
$ mkdir /some/where/else 
$ ln /app/bin/foo /some/where/else/foo  # create a hard link to foo 
$ /some/where/else/foo 

現在,上面的方法(包括我懷疑的/ proc/$ PID/exe文件)會給/some/where/else/foo作爲給程序的實際路徑。而且,實際上,它是a程序的真正路徑,而不是你想要的。請注意,在實踐中比硬鏈接更常見的符號鏈接不會出現此問題。

儘管這種方法原則上不可靠,但它在大多數情況下在實踐中運作良好。

3

請記住,在Unix系統自啓動以來可能已被刪除的二進制文件。在Unix上它是完全合法和安全的。最後我檢查Windows不會允許您刪除正在運行的二進制文件。

/proc/self/exe仍然是可讀的,但它確實不是一個可用的符號鏈接。這將是...奇怪。

9

實際上並不是一個答案,而只是一個要記住的記錄。

正如我們所看到的,找到運行可執行文件的位置的問題在Linux和Unix中非常棘手和特定於平臺。在做這件事之前,你應該三思。

如果您需要可執行文件的位置,用於發現一些配置或資源文件,也許你應該遵循將文件放置到系統的Unix的方式:把CONFIGS到/etc/usr/local/etc或在當前用戶的主目錄,並/usr/share是一個很好的放置你的資源文件。

0

我會

1)使用基本名()函數:http://linux.die.net/man/3/basename
2)的chdir()到該目錄
3)使用getpwd()來獲得當前目錄

這樣,你將以整潔,完整的形式獲取目錄,而不是./或../bin/。

也許你會想保存和恢復當前目錄,如果這對你的程序很重要。

相關問題