簡體   English   中英

C ++ system()函數 - 如何收集已發出命令的輸出?

[英]C++ system() function — How to collect the output of the issued command?

我正在使用C ++ system()函數運行一些命令:

int system ( const char * command );

如何從發出的命令中收集標准輸出?

具體來說,我想收集已發出命令的輸出(例如,發出dir命令的目錄列表輸出)。

您是在尋找已執行命令的返回值(如“退出狀態”),還是其輸出(如“打印的內容”)?

如果是后者,請改用popen()pclose()

如果是前者,請查看system()的返回值(並使用來自waitpid()信息的信息來解釋它)。

system()返回一個int ,所以只需抓住它: int rvalue = system(command);

我相信system()返回的確切細節是系統特定的。

系統程序通常有兩種方式“返回”一個值:寫入stdout,並在程序結束時返回一個狀態整數。 (通常有更多的方法可以返回結果,例如通過寫入文件或數據庫,但我認為這些方法超出了范圍)。

要接收狀態代碼,只需檢查system功能的返回值。

要接收輸出,請將其重定向到文件中,然后讀取文件,或使用popen

system的返回值(具有諷刺意味)依賴於系統,但在POSIX系統(包括Linux等)中,它與等待相同 - 低8位或16位是孩子的退出狀態(可能是你的意思) “返回的值”),更高的位表示什么樣的信號終止了孩子,如果有的話。 我給出的聯機幫助頁的URL提供了可用於撬開該返回值的預處理器宏!

沒有程序的“返回字符串”這樣的東西,因為你現在在評論中澄清了你想要的東西; 作為已經提到的另一個答案,如果你想要由其他程序輸出的文本,你應該使用popen而不是system

受bmorin嘗試的啟發,但是經過工作和測試,這個片段將采用char *命令並返回包含執行該命令的結果的char * ...

// Calling function must free the returned result.
char* exec(const char* command) {
  FILE* fp;
  char* line = NULL;
  // Following initialization is equivalent to char* result = ""; and just
  // initializes result to an empty string, only it works with
  // -Werror=write-strings and is so much less clear.
  char* result = (char*) calloc(1, 1);
  size_t len = 0;

  fflush(NULL);
  fp = popen(command, "r");
  if (fp == NULL) {
    printf("Cannot execute command:\n%s\n", command);
    return NULL;
  }

  while(getline(&line, &len, fp) != -1) {
    // +1 below to allow room for null terminator.
    result = (char*) realloc(result, strlen(result) + strlen(line) + 1);
    // +1 below so we copy the final null terminator.
    strncpy(result + strlen(result), line, strlen(line) + 1);
    free(line);
    line = NULL;
  }

  fflush(fp);
  if (pclose(fp) != 0) {
    perror("Cannot close stream.\n");
  }
  return result;
}

我調查了只是編輯bmorin的代碼,但是必須改變大多數行,所以單獨的答案似乎更合適。 如果沒有道歉。 (在其他問題中,bmorin的代碼實際上沒有累積行;它將它們打印到stdout,我認為它們不會被通緝,因為system()會這樣做;並且它在一個錯誤路徑中返回void,當函數必須返回一個char *,所以代碼不會編譯。也許最令人震驚的是,它在返回之前釋放了結果。)

system()libc中聲明和定義。 您可以讀取我提供的第一個鏈接,也可以在shell中的命令提示符下執行man system

我建議使用popen()函數,正如其他人所說,但這個問題是特定於平台的。 popen()函數在使用POSIX API的操作系統上可用。 我不確定這個命令是否適用於WIN32等其他API

這是一個代碼片段(在簡單的C中)用popen執行命令並返回其輸出:

char* exec(const char* command) {
    FILE* fp;
    char* result = NULL;
    size_t len = 0;

    fflush(NULL);
    fp = popen(command, "r");
    if (fp == NULL) {
        printf("Cannot execute command:\n%s\n", command);
        return;
    }

    while(getline(&result, &len, fp) != -1) {
        fputs(result, stdout);
    }

    free(result);
    fflush(fp);
    if (pclose(fp) != 0) {
        perror("Cannot close stream.\n");
    }
    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM