2017-10-20 102 views
0

我從目錄中執行一個簡單的shell程序執行的程序,我可以運行與我的shell可執行文件在同一文件夾中的文件,但無法運行諸如ls.exe之類的程序。的execve(......)不,儘管傳遞PATH變量

令牌容器在下列元素中包含文件名作爲第一個元素和任何後續標記(例如輸入「ls.exe -l」中的「-l」)。

if (fork()) 
{ 
    int status; 
    wait(&status); 
} 
else 
{ 
std::vector<const char*> exeArgs; 
std::vector<const char*> envArgs; 

std::for_each(tokens.begin(), tokens.end(), 
[&exeArgs](const string& elem){ exeArgs.push_back(elem.c_str()); } 
      ); 

exeArgs.push_back(nullptr); 

string path = "PATH="; 
path.append(getenv("PATH")); 

envArgs.push_back(path.c_str()); 
envArgs.push_back(nullptr); 

if (execve(exeArgs[0], const_cast<char *const *>(&exeArgs[0]), 
         const_cast<char *const *>(&envArgs[0]))) 
{ 
    std::cout << word << ": command not found" << std::endl; 
    exit(0); 
} 
} 

我花了無數的時間只是谷歌搜索,並一遍又一遍地閱讀手冊頁,但似乎無法得到一個線索,爲什麼這個代碼不工作。

這個想法是,我的shell程序應該允許用戶設置PATH變量,然後用該PATH變量執行程序,這就是爲什麼我必須使execve()正常工作而不是使用execvp()。

我在文件的一個單獨的部分有一個shell變量的地圖,但由於我甚至無法得到這個工作,我認爲這將是毫無意義的,包括。

回答

2

知道exec家庭的功能取代當前進程與新節目的圖像?這就是爲什麼在exec之前使用fork這麼常見。

武裝與知識,很容易找到一個解決方案適合你,你怎麼可以使用execvp(你需要使用,execve並沒有真正使用你傳遞的環境,它只是將它傳遞給新程序):在調用execvp之前,您使用fork並使用setenv來設置PATH新的過程。

+0

我編輯的帖子,包括我的功能的其餘部分。 我只想澄清一下,如果execve()在加載新程序後沒有使用傳入的環境變量來設置進程的環境變量,那麼什麼是環境變量數組參數? – ozma

+1

@ozma正如我所說的,它將環境傳遞給執行'exec'的* new *程序。如果你不知道,在POSIX系統(如Linux或macOS,其中'exec'是標準化的)中,'main'函數可以有一個* third *參數,通常命名爲'env'並且被聲明並且類似於' argv'數組。這是'execve'傳遞的環境(並且可以通過新程序中的'getenv'獲得)。 –

+0

哦,對!我一直認爲自從傳遞環境變量以來,他們也會參與執行程序。這也是我第一次聽說關於main的第三個參數。萬分感謝。 – ozma