2013-02-01 430 views
4

這是我正在學習的一個學校項目。如何執行shell腳本或可執行文件?

我在寫Web服務器。如果請求的資源具有擴展名'cgi',我需要fork和執行程序。如果CGI是編譯的可執行文件,這個工程:

execl(path, (char*) 0); 

但是,如果CGI程序是需要解釋的腳本,我需要做這樣的事情:

execl("/bin/sh", path, path, (char*) 0); 

我怎樣才能寫我的代碼,以便它可以處理任何一種情況?我的shell如何做到這一點?我是否應該使用file程序來確定它是可執行文件還是文本,以及它是否爲文本,然後假定它需要解釋?

回答

6

爲什麼你需要明確調用"/bin/sh"如果它是一個腳本?

只要腳本具有執行權限並在頂部有正確的shebang,就應該能夠執行它,就像它是可執行文件一樣。

+0

我也這麼認爲,但我得到「Exec格式錯誤」 –

+0

@TrevorDixon:當您從shell提示執行腳本時會發生什麼?腳本的第一行是什麼樣的? –

+0

達尼特,你說得對。我有一個錯字!我的測試腳本錯過了shebang的「爆炸」部分。我感到尷尬。謝謝! –

0

您可以讓shell使用-c選項爲您運行命令。

如果該命令是內置shell或shell腳本,shell將運行它;如果它是外部命令,那麼shell將執行二進制文件。

試試這個,看看它是否適合你:

execl("/bin/sh", "/bin/sh", "-c", path, (char*) 0); 

編輯:糾正上面的電話。這應該現在工作;我使用

execl("/bin/sh", "/bin/sh", "-c", "set", NULL); 

進行測試,我的測試程序回顯了默認的shell變量。然後我用

execl("/bin/sh", "/bin/sh", "-c", "/usr/bin/clear", NULL); 

和我的測試程序清除了終端仿真器的屏幕。

注意:這個答案的好處是它會運行任何你可以從shell運行的東西。因此,它將運行內置的shell命令,並且它將運行沒有合適的第一行的shell腳本。如果您想要運行的所有shell腳本具有正確的第一行#!,則不需要此操作。這提供了一個稍微更強大的解決方案,代價是可能不需要的shell。

+0

錯誤:「無法執行二進制文件」 –

+0

這不會奏效。請記住,任何程序的第一個參數(即'argv [0]')是實際的程序名... –

+0

對不起,我不習慣調用'execl()'。我會編輯答案。 – steveha

0

你應該檢查文件是否具有exec權限,如果不是警告你的用戶。 您可以使用GlibC的lstat函數來執行該操作。 然後使用glibC中的execve將其與路徑和參數列表一起提供給它(您也可以從main獲取env var,我建議您將環境提供給您的程序,而不是將(char *)0作爲NULL指針)