2012-03-09 44 views
3

方案:使用列表中execlp()系統調用在當前文件夾中的所有C文件:使用execlp與參數shell元字符用C系統調用

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

int main() 
{ 
    printf("Before Execl\n"); 
    execlp("ls","ls","*.c",NULL); // this should print all c files in the current folder. 
    return 0; 
} 

程序輸出:

Before Execl 
ls: cannot access *.c: No such file or directory 

每當我使用'*'在搜索模式中,我收到了類似的錯誤。請提出一些合適的解決方案

回答

2

如果你想shell元字符擴大,調用shell來擴展它們,從而:

execlp("sh", "sh", "-c", "ls *.c", (char *)0); 
fprintf(stderr, "Failed to exec /bin/sh (%d %s)\n", errno, strerror(errno)); 
exit(EXIT_FAILURE); 

注意,如果execl()或任何exec*函數返回的,它失敗。你不需要測試它的狀態;它失敗了。您不應該這樣做exit(0);(或return 0;main()函數),因爲這表明成功。包含一個錯誤信息是很有禮貌的,概述出錯的地方,並且信息應該寫入stderr,而不是stdout —,如圖所示。

你可以自己做元字符擴展;在POSIX庫中有幫助功能(如glob())。但是讓shell做到這一點更簡單了。

(我已經修訂上面的代碼中使用execlp()符合問題的要求。如果我做這個不受約束的,我可能會使用execl()並指定"/bin/sh"作爲第一個參數來代替。)

+0

請注意,如果你在調用'execlp'之前分叉了,那麼在孩子中使用'stdio'操作可能是錯誤的,除非你確定(1)程序是單線程的,(2)孩子的副本'stderr'(或者你正在使用的'FILE')有資格成爲「活動句柄」(參見POSIX XSH 2.5.1)。就我個人而言,我會避免在'fork'之後使用非異步信號安全函數,它也包含'exit';改用'_Exit'。 – 2012-03-09 07:40:33

+0

[XSH§2.5.1](http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05)是一種複雜的說法:「如果你編程正常,你會沒事的」。特別是,'stderr'通常是無緩衝的,並且在第三個項目符號上得到了「不需要採取任何操作」。 – 2012-03-09 15:02:31

+0

通常沒有緩衝的是一個實現細節。我記得,標準只是說它不應該被默認完全緩衝,所以'stderr'行默認緩衝可能符合實現,可能會顯着提高性能。如果你打算在分叉之後在父母和孩子中使用它,我會在分叉之前調用'fflush(stderr)',爲了安全起見...... – 2012-03-09 16:48:35

-1

它應該是:作爲外殼會爲你

execlp("ls", "*.c", NULL); 
+0

沒有;這並沒有幫助; shell執行元字符擴展,而不是'exec *'系統調用。 – 2012-03-09 06:14:17

1

Exec不處理「*」操作符。爲此,使用popen()glob_t。您可以通過 瞭解更多關於我在2012-03-08上詢問的question的詳細信息。

+0

爲什麼'popen()'?你不會寫'ls'命令,或者讀取它的輸出,那麼你爲什麼會從管道中受益呢?您提到的'glob_t'是與['glob()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html)函數關聯的類型。 – 2012-03-09 06:24:29

-1
execlp("ls", "*.c", NULL); 

應該工作

+0

對不起,這沒有幫助。 shell執行元字符擴展,而不是'exec *'系統調用。 – 2012-03-09 06:14:42