2014-01-23 26 views
0

我想編寫一個生成gz文件的函數。該功能只能在Linux上運行,所以我想使用gzip命令(只需執行外部命令)。
到目前爲止,我有這樣的:C++ - 在執行之前知道Linux命令是否存在的方法

bool generate_gz(const String& path) 
{ 
    bool res = false; 

    // LINUX 
#ifndef __WXMSW__ 

    if(!gzip_command_exists()) 
    cout << "cannot compress file. 'gzip' command is not available.\n"; 
    else 
    res = (0 == execute_command(String::Format("gzip %s", path.c_str()))); 

    // WINDOWS 
#else 

    // do nothing - result will be false 

#endif 

    return res; 
} 

bool gzip_command_exists() 
{ 
    // TBD 
} 

問題

是否有實現的方法嗎?如果是這樣,是否需要運行(或試圖運行)命令gzip

+3

有一種方法,但沒有必要。無論如何,你必須檢查運行的結果。試着運行命令並報告任何失敗。 –

+0

運行命令的退出代碼告訴我它在進程中是否存在並失敗,或根本不存在?我想區分這些失敗。 – idanshmu

+0

試試'man execve'並查看errno描述。 (你可能應該使用'exec'系列之一而不是'system')。 –

回答

3

最簡單的是通過system()執行:"which gzip"並查看系統調用的退出代碼:

返回值 返回的值是1的錯誤(例如,叉(2)失敗),和否則返回該命令的狀態。後者返回狀態 是 等待(2)中指定的格式。因此,該命令的退出代碼將爲WEXITSTATUS(狀態)。如果/ bin/sh不能執行 , 退出狀態將是退出命令的狀態(127)。

如何查找:

:~$ which gzip 
/bin/gzip 
:~$ echo $? 
0 
:~$ which gzip11 
:~$ echo $? 
1 
3

你可以使用popen(3)閱讀的/usr/bin/which gzip輸出(你也可以用它來壓縮在飛行中通過直寫popen -ing一個gzip > file.gz命令) 。你也可以有:FILE* pgzipv = popen("gzip --version", "r");fgets第一行,pclose ....

你可以考慮使用getenv("PATH")然後在其上進行循環利用access測試,通過附加/gzip在每個元素獲得的每個構建路徑PATH,等等......你也fork然後execvp可以用gzip--versionstdoutstderr適當重定向等。

注意兩個popen(3)和當被要求執行一個不存在的程序時,會失敗(因爲它們都是fork(2) a /bin/sh shell與-c)。因此,您不需要測試gzip的存在,並且您始終需要測試systempopen(可能因多種原因失敗,請參閱下面的fork失敗以及其他失敗的文檔)的成功。

要挑剔,檢查gzip是否存在是沒用的:它[文件/bin/gzip]可能(不太可能)已經在您的檢查之間被刪除 - 例如。其中access如上所述或者與popen如上相同,並且您稍後調用systempopen;所以你第一次檢查gzip不帶任何東西。

在大多數Linux系統上,gzip一般在/bin/gzip(實際上總是安裝gzip); 這是file system hierarchy standard(它表示如果安裝了gzip,它應該在該文件路徑中)。那麼你可以只使用access(2)與像

#define GZIP_PATH "/bin/gzip" /* per FSH, see www.pathname.com/fhs */ 
if (access(GZIP_PATH, X_OK)) { perror(GZIP_PATH); exit(EXIT_FAILURE); }; 

代碼最後,你並不需要在所有fork一個gzip過程的gzip -compress的文件。你可以(並且你應該)簡單地使用使用像zlib這樣的庫(根據Linux Standard Base要求爲libz.so.1);你想要它的gzopen,gzwrite,gzprintf,gzputs,gzclose等....功能!這將是更快(無需fork(2)任何外部過程)和更可靠的(像gzip一些外部程序不依賴;將工作,即使因爲限制已經達到fork是不可能的 - 看到setrlimit(2)RLIMIT_NPROCulimit內置的bash(1)

Advanced Linux Programming

+0

的成功感謝您的建議。好像我通過使用'zlib'來代替實現增加了複雜性。我想了解通過使用'zlib'而不是激活外部命令可以獲得什麼?99%的時間可用? – idanshmu

+0

使用* zlib *(在我聽說的每個Linux系統上都可用並安裝),您不需要依賴外部資源。所以通過使用* zlib *可以降低軟件的複雜度! –

4

看到,如果你不想產卵外部命令,你可以使用stat函數來檢查文件是否存在,如果它是一個POSIX的系統上執行。

它你不想硬編碼gzip的路徑,它稍微複雜一點。您必須獲取PATH環境變量,將其拆分爲冒號,然後檢查每個路徑的gzip。再次,路徑變量的名稱和格式是POSIX特定的。檢查getenv函數來讀取路徑,並且可以使用strtok來分割它。

這是值得商榷的,但是,只是試圖運行它並處理任何錯誤。

相關問題