源代碼:
問題:
首先,執行 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 第二版P188頁8.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,所以程序能正確運行。