2011-10-03 78 views
2

我試圖使用execve來運行ls命令。目前我使用以下參數運行它:使用execve的新路徑運行ls命令

execve(args[0], args, env_args) 
//args looks like {"ls", "-l", "-a", NULL} 
//env_args looks like {"PATH=/bin", "USER=me", NULL} 

我想到這做的是運行使用我的新env_args這意味着它會查找LS在我的道路ls命令。然而,這段代碼實際上並沒有做任何事情,當我運行代碼時,它只是返回到我的命令提示符而沒有輸出。

使用相同的參數[]我使用execvp和ls工作並搜索我當前的路徑。

你能告訴我我做錯了什麼嗎?

我想要做的是寫我自己的shell程序,我可以創建和導出我自己的環境,並讓exec使用我在char **中定義的環境。從本質上講,我正在編寫自己的函數來操作env_args來添加和刪除變量,並且當我調用exec時,我希望能夠對{「ls」,「-l」,NULL}調用exec,並讓它向下看我的新環境一個名爲ls的有效程序的路徑變量。我希望這能解釋我做得更好一點。在這種情況下,我不認爲extern environ var會適用於我。

回答

9

execve()不看PATH;爲此,您需要execvp()。你的程序未能執行ls,顯然你不會在execve()之後報告執行程序失敗。請注意,exec*()函數族的成員僅在錯誤時返回。

如果您使用/bin作爲當前目錄運行程序(因爲./ls - 又名ls - 會存在),您會得到預期的結果(或多或少)。

您需要在使用適當的PATH設置找到第一個參數到第一個參數execve()後提供可執行文件的路徑名。

或繼續使用execvp(),但將變量environ設置爲您的新環境。請注意,environ現在(POSIX 2008)在<unistd.h>中聲明,但以前未在任何地方聲明。

extern char **environ; 

environ = env_args; 
execvp(args[0], &args[0]); 

您不需要保存舊值並將其恢復;你在子進程中,切換它的環境不會影響主程序(shell)。


這看起來像我所期望的那樣工作 - 並證明原始代碼的行爲與我的預期相同。

#include <stdio.h> 
#include <unistd.h> 

extern char **environ; 

int main(void) 
{ 
    char *args[]  = { "ls", "-l", "-a", NULL }; 
    char *env_args[] = { "PATH=/bin", "USER=me", NULL }; 

    execve(args[0], args, env_args); 
    fprintf(stderr, "Oops!\n"); 

    environ = env_args; 
    execvp(args[0], &args[0]); 
    fprintf(stderr, "Oops again!\n"); 

    return -1; 
} 

我得到'哎呀!'接着列出我的目錄。當我在當前目錄下創建一個可執行ls

#!/bin/sh 
echo "Haha!" 

然後我沒有得到「糟糕!」並得到'哈哈!'。

+0

好的,但是說我想讓execvp看看不同於我的環境中定義的路徑嗎?那是我正在尋找的那種功能 – james

+0

關於第二個想法,我不認爲環境就是我想要的。我仍然不確定如何做到這一點。 – james

+0

你爲什麼認爲設置環境不是答案?你機器上的ls'在哪裏找到? –