首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言獲取 Shell 命令執行結果:popen 管道實作詳解

     編輯:關於C語言

C 語言獲取 Shell 命令執行結果:popen 管道實作詳解

在 Linux 系統程式開發中,常需呼叫 Shell 命令或腳本。system() 雖簡單,但僅返回狀態碼(0 成功、-1 失敗),無法捕獲命令輸出。本文介紹兩種獲取輸出的方法,重點解析 popen() 管道機制的完整實作。

方法一:重定向到暫存檔

system("ls > result.txt");
FILE *fp = fopen("result.txt", "r");
// 讀取檔案內容...

缺點明顯:涉及磁碟 I/O、需管理暫存檔生命週期、效能較差。

方法二:popen() 管道直讀(推薦)

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;
}

關鍵點解析

  1. popen(cmd, "r"):以唯讀模式開啟管道,返回 FILE*,可用標準 I/O 函數讀取。
  2. fgets() 迴圈:逐行讀取命令輸出,累積至呼叫者提供的緩衝區,防止溢位。
  3. pclose(fp):關閉管道並回收子進程資源,返回命令結束狀態。
  4. 錯誤處理:檢查 popen 返回值,避免空指標解參考。

效能與架構建議

注意:C 語言調用 Shell 會 fork 新進程,開銷較大。高效能場景下,建議改用原生系統呼叫(如 opendir/readdir 替代 ls),或採用庫函數直接實現功能,避免 C/Shell 混合編程帶來的效能損耗與安全風險(命令注入)。

掌握 popen/pclose 模式,能靈活整合系統工具輸出,是 Linux C 開發的實用技能之一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved