區分execl與system 應用程式中執行命令

2021-09-22 22:19:09 字數 2823 閱讀 7722

execl:

相關函式:fork, execle, execlp, execv, execve, execvp

表頭檔案:#include

函式定義:int execl(const char *path, const char *arg, ...);

函式說明:execl()用來執行引數path字串所代表的檔案路徑, 接下來的引數代表執行該檔案時傳遞的ar**[0],ar**[1].....是後乙個引數必須用空指標null作結束

返回值    :成功則不返回值, 失敗返回-1, 失敗原因存於errno中

錯誤**:參execve()

範例:/*   執行 /bin/ls   -al   /ect/passwd */

#include

/**

* file: execl.c**/

main()

或#include

/**

* file: execl.c *

*/int main()

[cnscn@test c]$ make execl

cc     execl.c   -o execl

[cnscn@test c]$ ./execl   

-rw-r--r-- 1 root root 2218 jan 13 11:36 /etc/passwd

system:

相關函式

fork,execve,waitpid,popen

表頭檔案

#i nclude

定義函式

int system(const char * string);

函式說明

system()會呼叫fork()產生子程序,由子程序來呼叫/bin/sh-c string來執行引數string字串所代表的命令,此命》令執行完後隨即返回原呼叫的程序。在呼叫system()期間sigchld 訊號會被暫時擱置,sigint和sigquit 訊號則會被忽略。

返回值=-1:出現錯誤   

=0:呼叫成功但是沒有出現子程序   

>0:成功退出的子程序的id

如果system()在呼叫/bin/sh時失敗則返回127,其他失敗原因返回-1。若引數string為空指標(null),則返回非零值》。 如果system()呼叫成功則最後會返回執行shell命令後的返回值,但是此返回值也有可能為 system()呼叫/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認執行成功。

附加說明

在編寫具有suid/sgid許可權的程式時請勿使用system(),system()會繼承環境變數,通過環境變數可能會造成系統安全的問題。

範例#i nclude

main()

執行結果:

-rw-r--r-- 1 root root 705 sep 3 13 :52 /etc/passwd

-r--------- 1 root root 572 sep 2 15 :34 /etc/shado

例2:char tmp;

sprintf(tmp,"/bin/mount -t vfat %s /mnt/usb",dev);

system(tmp);

其中dev是/dev/sda1。

system原始碼

#include 

#include 

#include 

#include 

int system(const char * cmdstring)

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

else if(pid == 0)

else}}

return status;

}當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接受命令之後做的事了。

如果上面的你沒有看懂,那我再解釋下fork的原理:當乙個程序a呼叫fork時,系統核心建立乙個新的程序b,並將a的記憶體映像複製到b的程序空間中,因為a和b是一樣的,那麼他們怎麼知道自己是父程序還是子程序呢,看fork的返回值就知道,上面也說了fork在子程序中返回0,在父程序中返回子程序的pid。

execl是編譯器的函式(在一定程度上隱藏具體系統實現),在linux中它會接著產生乙個linux系統的呼叫execve, 原型見下:

int execve(const char * file,const char **ar**,const char **envp);

看到這裡你就會明白為什麼system()會接受父程序的環境變數,但是用system改變環境變數後,system一返回主函式還是沒變,原因從system的實現可以看到,它是通過產生新程序實現的,從我的分析中可以看到父程序和子程序間沒有程序通訊,子程序自然改變不了父程序的環境變數。

注意 :execl與system的乙個區別是:使用execl時最好在之前先呼叫fork,在子程序中執行execl,否則execl會返回。而system則不用,因為從它的實現原始碼來看,實際上已經呼叫了fork。

linux下system和execl函式的區別

今天學到了execl函式族,發現函式功能就是呼叫系統的二進位制程式或者一些指令碼檔案,此函式族函式一大堆,可是仔細想想實現的功能和前面的system函式沒什麼區別,感覺system函式方便多了,為何還要exec弄一大堆呢?肯定是有原因的啦!小結兩點區別關係 1.system會新起乙個子程序來呼叫要執...

exec 與system 的區別

這應該算是老生長談的問題了,在此做乙個記錄。執行exec 後,老的程序上下文將被exec出來的新的程序上下文覆蓋,新程序代替原程序執行。執行system 後則相當於fork 出乙個子程序,並等待此子程序執行完畢。請看如下程式以加深理解。rt.c int main gcc rt.c o rt test...

exec 與system 的區別

這應該算是老生長談的問題了,在此做乙個記錄。執行exec 後,老的程序上下文將被exec出來的新的程序上下文覆蓋,新程序代替原程序執行。執行system 後則相當於fork 出乙個子程序,並等待此子程序執行完畢。請看如下程式以加深理解。cpp view plain copy rt.c intmain...