system()
和 popen()
是 C 語言中用于執行外部命令的兩個函數,它們的功能類似,但在使用方式和特性上有一些區別。
system()
system()
函數允許您在程序中執行外部命令,并等待該命令執行完成后繼續執行程序。其基本語法如下:
int system(const char *command);
-
command
是一個字符串,包含您要執行的命令。這可以是任何有效的命令,就像您在命令行中輸入的一樣。 -
system()
函數將返回執行結果。如果成功執行了命令,則返回值為命令的退出狀態碼。如果無法執行命令,則返回 -1。 -
system()
函數會阻塞當前進程,直到執行的命令完成。
示例:
#include <stdio.h>
#include <stdlib.h>int main() {int status = system("ls -l");if (status == -1) {printf("Failed to execute command\n");} else {printf("Command executed successfully with exit status: %d\n", status);}return 0;
}
?執行結果:
popen()
popen()
函數允許您在程序中執行外部命令,并建立一個到該命令的管道,可以通過管道進行輸入和輸出。其基本語法如下:
-
command
和mode
參數分別與system()
函數的參數相同,用于指定要執行的命令和管道的打開模式。 -
popen()
函數返回一個指向 FILE 結構的指針,您可以使用該指針來讀取或寫入命令的輸入和輸出。 -
popen()
函數允許并發執行多個命令,并且可以通過管道進行通信。
示例:
#include <stdio.h>int main() {FILE *fp;char buffer[1024];fp = popen("ls -l", "r");if (fp == NULL) {printf("Failed to execute command\n");return 1;}while (fgets(buffer, sizeof(buffer), fp) != NULL) {printf("%s", buffer);}pclose(fp);return 0;
}
執行結果:
這段代碼的作用是執行一個外部命令 ls -l
(列出當前目錄下的文件和文件夾,并顯示詳細信息),并將命令的輸出逐行打印到標準輸出(終端)上。
讓我們逐行解釋代碼:
-
#include <stdio.h>
:包含了標準輸入輸出的頭文件。 -
int main()
:主函數的定義。 -
FILE *fp;
:聲明了一個指向FILE
結構的指針fp
,它將被用作popen()
返回的管道。 -
char buffer[1024];
:聲明了一個用于存儲命令輸出的緩沖區。 -
fp = popen("ls -l", "r");
:調用popen()
函數執行外部命令ls -l
,并將其輸出連接到管道上。模式"r"
表示只讀模式,因此fp
將用于從管道讀取命令的輸出。 -
if (fp == NULL)
:檢查popen()
函數的返回值,如果返回空指針,則表示執行命令失敗。 -
printf("Failed to execute command\n");
:打印錯誤信息。 -
return 1;
:退出程序,返回錯誤代碼。 -
while (fgets(buffer, sizeof(buffer), fp) != NULL)
:使用fgets()
函數從管道中讀取命令的輸出,并將其逐行存儲到buffer
緩沖區中。循環會繼續,直到fgets()
函數返回NULL
,表示已經讀取完全部輸出。 -
printf("%s", buffer);
:打印緩沖區中的內容,即命令的輸出。 -
pclose(fp);
:關閉由popen()
打開的管道,并等待命令執行完畢。 -
return 0;
:退出程序,返回成功代碼。
system 和 popen的區別:
-
返回類型:
system()
返回命令的退出狀態碼。popen()
返回一個文件指針,用于讀取或寫入命令的輸入和輸出。
-
阻塞特性:
system()
函數會阻塞當前進程,直到執行的命令完成。popen()
函數允許并發執行多個命令,并且您可以在不等待命令完成的情況下繼續執行程序。
-
輸入輸出:
system()
函數只能捕獲命令的退出狀態碼,無法直接獲取命令的輸入和輸出。popen()
函數可以通過管道進行輸入和輸出,允許更靈活的交互。
綜上所述,如果您只需要執行簡單的命令并等待其完成,可以使用 system()
函數。如果您需要與命令進行交互,或者需要同時執行多個命令,可以使用 popen()
函數。
問:是不是雖然沒有ls -l的運行結果沒在終端顯示,但是它已經執行了?
????????是的,即使沒有使用 printf
或其他輸出函數將 popen()
命令的輸出顯示在終端上,該命令仍然會在后臺執行,并將結果寫入到管道中。
????????即便沒有讀取管道中的輸出,popen()
也會執行給定的命令,并等待命令執行完成。只是程序沒有處理這些輸出而已。