2015-11-19 50 views
0

我試圖編寫一個基本的外殼,可以解釋簡單的命令,如日期,LS在語言C。沒有這樣的文件或目錄時使用execv()

我首先得到這樣的PATH變量,以便稍後將它傳遞給execv()函數。

const char *name = "PATH"; 
char *value; 
value = getenv(name) 

,我打印出來的價值,我得到這個:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games 

請注意,我用virutalbox運行Ubuntu Linux系統。這是我用來嘗試一個簡單的ls命令的代碼。在變線下面的代碼是用戶寫了實際的命令,在我們的情況下,它是「LS」

pid_t pid, wpid; 
    int status; 

    pid = fork(); 
    if (pid == 0) { 
     // Child process 
     if (execv(value, line) == -1) { 
      perror("lsh"); 
     } 
     exit(EXIT_FAILURE); 
    } 
    else if (pid < 0) { 
     // Error forking 
     perror("lsh"); 
    } 
    else { 
     // Parent process 
     do { 
      wpid = waitpid(pid, &status, WUNTRACED); 
     } 
     while (!WIFEXITED(status) && !WIFSIGNALED(status)); 
    } 

而結果我得到的是:

lsh: no such file or directory 

什麼想法?

+2

你確定它是'lsh'嗎? –

+0

林不知道你的意思? @EugeneSh。 –

+0

我的意思是,根據Wiki,你選擇運行一些「開源SSH協議實現項目」,這看起來很奇怪。 –

回答

1

系統調用execv()使用您在第一個參數中指定的名稱作爲可執行文件的文件名;它不會執行基於PATH的搜索。

這意味着如果您指定"lsh"作爲第一個參數,那麼在當前目錄中必須有一個可執行文件lsh

如果您想要基於PATH的搜索,請用execvp()替換execv()。否則,請在第一個參數中指定命令的路徑名 - 絕對或相對,但絕對更正常。

請注意,如果exec*()函數中的任何函數返回,則它失敗。沒有必要測試返回值;它將始終爲-1。

valueline的內容必須是沿着線:

char *value = "ls"; 
char *line[] = { "ls", "-l", 0 }; 

execvp(value, line); 

,或者更常規:

execvp(line[0], line); 

如果是自己分析路徑,你需要有line[0]指向您從PATH創建的完整文件名,然後使用execv()而不是execvp()

+0

我試着將它改爲execvp(),但我得到了相同的響應。 getenv()應該工作得到正確的路徑名? –

+0

@TimoCengiz:'getenv()'在很大程度上不重要。如果這是你要求的,它將得到'PATH'的當前值,但'execv()'不會使用它。在幕後,如果第一個參數中的名稱沒有斜線,'execvp()'將使用'PATH'。然後它會在命令前加上PATH的每個元素並嘗試執行它。如果你將''ls「'轉換爲''/ bin/ls''等,你必須自己進行連接。如果使用'execvp()',如果第一個參數包含'「ls」',那麼'execvp()'將查找並執行PATH目錄中的第一個'ls'可執行文件。 –

0

execv的第一個參數是要運行的命令。這意味着你試圖運行/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games作爲命令。

假設line數組中的第一個值是你要調用的程序,則應該這樣做:

execv(line[0], line); 

如果要執行基於路徑的查詢,用execvp代替(無需要手動提取PATH變量):

execvp(line[0], line); 

編輯:

例如,假設你想運行ls -l /usr/bin /var/log,你的陣列看起來像這樣:

char *line[] = { "ls", "-l", "/usr/bin", "/var/log", NULL}; 
+0

好吧,所以我得到該行[0]等於「ls」,但是您描述的execvp()函數中的第二個參數行是什麼? –

+0

@TimoCengiz第二個參數是一個'char *'數組,它們是命令行參數。此數組的索引0包含命令的名稱,它出現在'ps'列表中。其餘的是命令行參數,數組中的最後一個元素是NULL。 – dbush

+0

好吧,我試着用你提到的方式使用execvp。它的工作我現在沒有得到任何錯誤消息,但我沒有得到答案。基本沒有發生。我可以編寫另一個命令,並且不管我寫什麼。我嘗試寫「sdfsdf」,但它沒有給我任何錯誤? –

相關問題