UNIX再学习 -- 函数 system
生活随笔
收集整理的這篇文章主要介紹了
UNIX再学习 -- 函数 system
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、system 函數
#include <stdlib.h> int system(const char *command);1、參數解析
command:shell 命令行字符串2、函數解析
system 函數執行 command 參數表示的命令行,并返回命令進程的終止狀態。若 command 參數是一個空指針 (NULL),則僅當命令處理程序可用時,system 返回非 0 值,這一特征可以確定在一個給定的操作系統上是否支持 system 函數。在 UNIX 中,system 總是可用的。3、返回值
因為 system 在其實現中調用了 fork、exec 和 waitpid,因此有 3 種返回值。 (1)fork 失敗或者 waitpid 返回除 EINTR 之外的出錯,則 system 返回 -1,并且設置 errno 以指示錯誤類型。 (2)如果 exec 失敗(表示不能執行 shell),則其返回值如同 shell 執行了 exit (127) 一樣。 (3)否則所有 3 個函數(fork、exec 和 waitpid)都成功,那么 system 的返回值是 shell 的終止狀態,其格式已在 waitpid 中說明。參看:UNIX再學習 -- exit 和 wait 系列函數4、函數功能
主要用于執行指定的shell命令,以及shell腳本。shell 編程我們也講了,參看:UNIX再學習 -- shell編程5、示例說明
//system函數的使用 #include <stdio.h> #include <stdlib.h>int main(void) {int status;if ((status = system (NULL)) == -1)perror ("system"), exit (1);if (!status)printf ("shell 不可用\n");else{if ((status = system ("ls -l")) == -1) // if ((status = system ("lss -l")) == -1) // if ((status = system ("/home/tarena/project/c_test/shell.sh")) == -1)perror ("system"), exit (1);printf ("WEXITSTATUS (status) = %d\n", WEXITSTATUS (status));}return 0; }輸出結果: 總用量 16 -rwxr-xr-x 1 root root 7308 Apr 27 10:35 a.out -rwxrwxrwx 1 root root 19 Apr 27 10:21 shell.sh -rw-r--r-- 1 root root 450 Apr 27 10:35 test.c WEXITSTATUS (status) = 0如果將shell命令錯誤則,終止狀態為 exit(127) 輸出結果: sh: 1: lss: not found WEXITSTATUS (status) = 1276、示例解析
若 command 參數是一個空指針 (NULL),則僅當命令處理程序可用時,system 返回非 0 值。 通過?if (!status)?判斷系統是否支持 system 函數。 如果成功,那么 system 的返回值是 shell 的終止狀態,WEXITSTATUS (status) 得到 exit或_exit 參數、return返回值。再有參數可以是 shell 腳本,也可以是 shell 命令。 如果將shell命令錯誤則,終止狀態為 exit(127).
二、system 進階
1、system 函數實現
#include <sys/wait.h> #include <errno.h> #include <unistd.h> #include <stdlib.h>int system_my(const char *cmdstring) /* version without signal handling */ {pid_t pid;int status;if (cmdstring == NULL)return(1); /* always a command processor with UNIX */if ((pid = fork()) < 0) {status = -1; /* probably out of processes */} else if (pid == 0) { /* child */execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);_exit(127); /* execl error */} else { /* parent */while (waitpid(pid, &status, 0) < 0) {if (errno != EINTR) {status = -1; /* error other than EINTR from waitpid() */break;}}}return(status); }int main (void) {int status;if ((status = system_my ("date")) < 0)perror ("system_my"), exit (1);if ((status = system_my ("ls -l")) < 0)perror ("system_my"), exit (1);return 0; } 輸出結果: Thu Apr 27 11:06:08 CST 2017 總用量 16 -rwxr-xr-x 1 root root 7419 Apr 27 11:06 a.out -rw-r--r-- 1 root root 862 Apr 27 11:06 test.c -rw-r--r-- 1 root root 575 Apr 27 11:03 test.c~ root@ubuntu:/home/tarena/project/c_test# gedit test.c2、示例解析
上例說明了 system 實現中調用了 fork、exec 和 waitpid。其中 shell 的 -c 選項告訴 shell 程序去下一個命令行參數(在這里是 cmdstring)作為命令輸入(而不是從標準輸入或從一個給定的文件中讀命令)。shell 對以 null 字節終止的命令字符串進行語法分析,將它們分成命令行參數。傳遞給 shell 的實際命令字符串可以包含任一有效的 shell 命令。 如果不使用 shell 執行此命令,而是試圖由我們自己執行它,那將相當困難。首先,我們必須用 execlp 而不是 execl,像 shell 那樣使用 PATH 變量。我們必須將 null 字節終止的命令字符串分成各個命令行參數,以便調用 execlp。最后,我們也不能使用任何一個 shell 元字符。 注意,我們調用 _exit 而不是 exit。這是為了防止任一標準 I/O 緩沖(這些緩沖會在 fork 中由父進程復制到子進程)在子進程中被沖洗。3、system 和 fork+exec 比較
使用 system 函數而不直接使用 fork+exec 的好處是,syetem函數針對各種錯誤和信號都做了必要的處理,而且 system 是標準庫函數,可跨平臺使用。與exec的區別
(1)system()和exec()都可以執行進程外的命令,system是在原進程上開辟了一個新的進程,但是exec是用新進程(命令)覆蓋了原有的進程
(2)system()和exec()都有能產生返回值,system的返回值并不影響原有進程,但是exec的返回值影響了原進程
三、system 與信號
參看:system函數的總結 后續講到信號部分再來補充!總結
以上是生活随笔為你收集整理的UNIX再学习 -- 函数 system的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UNIX再学习 -- exec 函数族
- 下一篇: 2022年中国政企采购数字化转型白皮书