system函式的原理和呼叫方法

2021-06-25 09:06:25 字數 3450 閱讀 3776

#include

int system(const char *command);

返回值:

通常:shell命令執行成功返回0,失敗返回非0.

1. 若引數string為空指標(null),則返回非零值

2. 若system()在呼叫/bin/sh時失敗則返回127

返回127的例子:

#include

#include

#include

int main(int argc, char **argv)

const char* cmd = "ll /home/wipan";

int status = system(cmd);

printf("returned code: %d\n", wexitstatus(status));

輸入結果為:

[wipan@bjlinc1229 ~/src]$ ./system

sh: ll: command not found

returned code: 127

3. 若fork不成功返回-1.

4. 若system()呼叫成功則最後會返回執行shell命令後的返回值(此值也可能是127,若shell命令執行的最後有返回值,則需注意其返回值的判斷方法)

例子:while ( !hddready ) }

else  //呼叫失敗 }

原理:當system接受的命令為null時直接返回,否則fork出乙個子程序,因為fork在兩個程序:父程序和子程序中都返回,這裡要檢查返回的pid,fork在子程序中返回0,在父程序中返回子程序的pid,父程序使用waitpid等待子程序結束,子程序則是呼叫execl來啟動乙個程式代替自己,execl("/bin/sh", "sh", "-c", cmdstring, (char*)0)是呼叫shell,這個shell的路徑是/bin/sh,後面的字串都是引數,然後子程序就變成了乙個shell程序,這個shell的引數是cmdstring,就是system接受的引數。在windows中的shell是command,想必大家很熟悉shell接受命令之後做的事了。

3.1  

背景 exit的名字就能看出,這個系統呼叫是用來終止乙個程序的。無論在程式中的什麼位置,只要執行到exit系統呼叫,程序就會停止剩下的所有操作,清除包括pcb在內的各種資料結構,並終止本程序的執行。

exit系統呼叫帶有乙個整數型別的引數status,我們可以利用這個引數傳遞程序結束時的狀態,比如說,該程序是正常結束的,還是出現某種意外而結束的,一般來說,0表示沒有意外的正常結束;其他的數值表示出現了錯誤,程序非正常結束。我們在實際程式設計時,可以用wait系統呼叫接收子程序的返回值,從而針對不同的情況進行不同的處理。關於wait的詳細情況,我們將在以後的篇幅中進行介紹。

在乙個程序呼叫了exit之後,該程序並非馬上就消失掉,而是留下乙個稱為殭屍程序(zombie)的資料結構。在linux程序的5種狀態中,殭屍程序是非常特殊的一種,它已經放棄了幾乎所有記憶體空間,沒有任何可執行**,也不能被排程,僅僅在程序列表中保留乙個位置,記載該程序的退出狀態等資訊供其他程序收集。

先來了解一下殭屍程序的來由,我們知道,linux和unix總有著剪不斷理還亂的親緣關係,殭屍程序的概念也是從unix上繼承來的,而unix的先驅們設計這個東西並非是因為閒來無聊想煩煩其他的程式設計師。殭屍程序中儲存著很多對程式設計師和系統管理員非常重要的資訊,首先,這個程序是怎麼死亡的?是正常退出呢,還是出現了錯誤,還是被其它程序強迫退出的?其次,這個程序占用的總系統cpu時間和總使用者cpu時間分別是多少?發生頁錯誤的數目和收到訊號的數目。這些資訊都被儲存在殭屍程序中,試想如果沒有殭屍程序,程序一退出,所有與之相關的資訊都立刻歸於無形,而此時程式設計師或系統管理員需要用到,就只好乾瞪眼了。

waitpid呼叫和wait呼叫。這兩者的作用都是收集殭屍程序留下的資訊,同時使這個程序徹底消失。程序一旦呼叫了wait,就立即阻塞自己,由wait自動分析是否當前程序的某個子程序已經退出,如果讓它找到了這樣乙個已經變成殭屍的子程序,wait就會收集這個子程序的資訊,並把它徹底銷毀後返回;如果沒有找到這樣乙個子程序,wait就會一直阻塞在這裡,直到有乙個出現為止。

3.2  

判斷返回值的巨集

如果引數status的值不是null,wait就會把子程序退出時的狀態取出並存入其中,這是乙個整數值(int),指出了子程序是正常退出還是被非正常結束的,或被哪乙個訊號結束的等資訊。由於這些資訊被存放在乙個整數的不同二進位制位中,所以用常規的方法讀取會非常麻煩,人們就設計了一套專門的巨集(macro)來完成這項工作,下面我們來學習一下其中最常用的兩個:

1)  wifexited(status) 這個巨集用來指出子程序是否為正常退出的,如果是,它會返回乙個非零值。

2)  wexitstatus(status) 當wifexited返回非零值時,我們可以用這個巨集來提取子程序的返回值,如果子程序呼叫exit(5)退出,wexitstatus(status)就會返回5;如果子程序呼叫exit(7),wexitstatus(status)就會返回7。請注意,如果程序不是正常退出的,也就是說,wifexited返回0,這個值就毫無意義。

例子如下:

#include

#include

#include

main()

int status;

pid_t pc,pr;

pc=fork();

if(pc<0) 

printf("error ocurred!\n");

else if(pc==0)

elseelse 

printf("the child process %d exit abnormally.\n",pr);

}結果如下:

$ cc wait2.c -o wait2

$ ./wait2

this is child process with pid of 1538.

the child process 1538 exit normally.

the return code is 3.

3.3 

判斷system呼叫的返回值

#inlucde

...sprintf(szcommand, "compress -fc %s > %s.z", szfilepath, szfilepath);

istatus = system(szcommand);

if (wifexited(istatus) && wexitstatus(istatus) == 0)

else

system()函式功能強大,很多人用卻對它的原理知之甚少。看下簡單的linux版system函式的原始碼:

#include

#include

#include

#include

int system(const char * cmdstring)

if((pid = fork())<0)

else if(pid = 0)

else}}

return status;

}

system函式呼叫

相關函式 fork,execve,waitpid,popen 表頭檔案 include 定義函式 int system const char string 函式說明 system 會呼叫fork 產生子程序,由子程序來呼叫 bin sh c string來執行引數string字串所代表的命令,此命 ...

system 可以呼叫的 DOS 函式 總結

system 函式 是可以呼叫一些dos命令,比如 system cls 清屏,等於在dos上使用cls命令 下面列出常用的dos命令,都可以用system函式呼叫 assoc 顯示或修改副檔名關聯。at 計畫在計算機上執行的命令和程式。attrib 顯示或更改檔案屬性。break 設定或清除擴充套...

使用system()函式呼叫Linux指令碼

system 函式在函式庫中,通過他可以呼叫linux中的指令碼。具體使用可以用 man system來看。這個函式就乙個引數,就是你要執行的命令的字串。比如,呼叫的指令碼位於 home usr joker test.sh,那麼就可以這樣在c c 中呼叫system home usr joker t...