在 Linux 系統程式開發中,常需呼叫 Shell 命令或腳本。system() 雖簡單,但僅返回狀態碼(0 成功、-1 失敗),無法捕獲命令輸出。本文介紹兩種獲取輸出的方法,重點解析 popen() 管道機制的完整實作。
system("ls > result.txt");
FILE *fp = fopen("result.txt", "r");
// 讀取檔案內容...
缺點明顯:涉及磁碟 I/O、需管理暫存檔生命週期、效能較差。
popen() 建立單向管道,將命令標準輸出連接到檔案流,避免磁碟落地,效率更高。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
char* shellcmd(char* cmd, char* buff, int size) {
char temp[256];
FILE* fp = NULL;
int offset = 0, len;
fp = popen(cmd, "r");
if (fp == NULL) return NULL;
while (fgets(temp, sizeof(temp), fp) != NULL) {
len = strlen(temp);
if (offset + len < size) {
strcpy(buff + offset, temp);
offset += len;
} else {
buff[offset] = '\0';
break;
}
}
if (fp != NULL) pclose(fp);
return buff;
}
int main(void) {
char buff[1024];
memset(buff, 0, sizeof(buff));
printf("%s", shellcmd("ls", buff, sizeof(buff)));
return 0;
}
FILE*,可用標準 I/O 函數讀取。popen 返回值,避免空指標解參考。注意:C 語言調用 Shell 會 fork 新進程,開銷較大。高效能場景下,建議改用原生系統呼叫(如
opendir/readdir替代ls),或採用庫函數直接實現功能,避免 C/Shell 混合編程帶來的效能損耗與安全風險(命令注入)。
掌握 popen/pclose 模式,能靈活整合系統工具輸出,是 Linux C 開發的實用技能之一。