關於exec系列函數的文件路徑問題及延伸

源代碼:

  

 

  

問題:

首先,執行 gcc -o echoall prog8-9.c

這樣,echoall就在prog8-9.c的目錄/home/user01/apue_exercise下。

然後執行gcc prog8-8.c

./a.out

發現在exec處報錯:No such file or directory

          No such file or directory

兩次調用exec函數都找不到可執行文件!!

 

解決方法:

其一、

發現APUE 第二版P1888.10exec函數一節寫到:

execlp execvp)當指定filename作爲參數時:

如果filename中包含/,則將其視爲路徑名。

否則就按PATH環境變量,在它所指定的各目錄中搜尋可執行文件。

 

於是查看當前的PATH環境變量echo $PATH, 很明顯,echoall所在的目錄不在PATH環境變量中,只好在執行程序前先手動將當前目錄(即/home/user01/apue_exercise加上。

$export PATH=$PATH:$PWD

這樣,再執行./a.out

$./a.out

輸出結果:

No such file or directory

argv[0]: echoall

argv[1]: only 1 arg

 

說明execlp的調用執行正確了。那第一次調用execle爲什麼會出錯呢?

 

其二、

if (execle("~/apue_exercise/echoall", "echoall", "myarg1", /

               "MY ARG2", (char*)0, env_init) < 0)

 

試着將這句代碼中引用的路徑改爲:

/home/user01/apue_exercise/echoll

if (execle("/home/user01/apue_exercise/echoall ", "echoall", "myarg1", /

               "MY ARG2", (char*)0, env_init) < 0)

再次執行:

$export PATH=$PATH:$PWD

$./a.out

輸出結果:

argv[0]: echoall

argv[1]: myarg1

argv[2]: MY ARG2

argv[0]: echoall

argv[1]: only 1 arg

 執行正確!

那麼,爲什麼不能在此處使用~呢?

原因是由於~只是shell$home的引用,在系統函數中是不會對此進行相同的擴展的。

系統函數如何解釋路徑呢?

$man path_resolution

可得到相關的信息。大致意思如下:

某些unix/linux系統調用有文件名參數。文件名(或路徑名)按下列方式解析:

如果路徑名以/開頭,則從當前進程的root目錄開始查找路徑。此所謂絕對路徑。

如果路徑名不以/開頭,則從該進程的當前工作目錄開始查找。此所謂相對路徑。

一般情況下,每個目錄都有一個”. “ “..”, 用於表示當前目錄和父目錄。這也是能被正確解析的。

 

據此來看,系統調用並不能解析~

 

試驗:

因爲echoall在當前工作目錄下,

所以將

if (execle("/home/user01/apue_exercise/echoall ", "echoall", "myarg1", /

               "MY ARG2", (char*)0, env_init) < 0)

改爲

if (execle("echoall ", "echoall", "myarg1",  "MY ARG2", (char*)0, env_init) < 0)

或者

if (execle("./echoall ", "echoall", "myarg1", /

               "MY ARG2", (char*)0, env_init) < 0)

兩個路徑都能被正確解析,並且能夠在進程的當前目錄中找到echoall,所以程序能正確運行。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章