exec族函數、system函數、popen函數、PATH

exec族函數函數的作用:
我們用fork函數創建新進程后,經常會在新進程中調用exec函數去執行另外一個程序。當進程調用exec函數時,該進程被完全替換為新程序(在exec都后面的代碼不會被得到執行)。因為調用exec函數并不創建新進程,所以前后進程的ID并沒有改變。

exec族函數功能:

在調用進程內部執行一個可執行文件。可執行文件既可以是二進制文件,也可以是任何Linux下可執行的腳本文件。

函數族:
exec函數族分別是:execl, execlp, execle, execv, execvp, execvpe

函數原型:

#include <unistd.h>
extern char **environ;int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);//使用較少
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);//使用較少

返回值:
exec函數族的函數執行成功后不會返回,調用失敗時,會設置errno并返回-1,然后從原程序的調用點接著往下執行。(errno這個值可以通過perror打印出來)

參數說明:

  • path:可執行文件的路徑名字
  • arg:可執行程序所帶的參數,第一個參數為可執行文件名字,沒有帶路徑且arg必須以NULL結束,例如:execl("./bin/echoarg",“echoarg”,“abc”,NULL) echoarg是可執行文件名,abc是第一個參數,最后必須以NULL結尾。
  • file:如果參數file中包含/,則就將其視為路徑名,否則就按 PATH環境變量,在它所指定的各目錄中搜尋可執行文件。

exec族函數參數極難記憶和分辨,函數名中的字符會給我們一些幫助:

  • l : 使用參數列表
  • p:使用文件名,并從PATH環境進行尋找可執行文件
  • v:應先構造一個指向各參數的指針數組,然后將該數組的地址作為這些函數的參數。
  • e:多了envp[]數組,使用新的環境變量代替調用進程的環境變量

字符串轉整型:

#include <stdlib.h>
int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);

示例代碼:

****execl代碼****
#include<stdio.h>
#include <unistd.h>
int main()
{printf("before execl");if(execl("./number","number","12","13",NULL)==-1){printf("execl fail\n");perror("because");}printf("after execl");//因為execl函數調用成功所以它之后的代碼就不再執行。return 0;
}****number可執行文件代碼:****
#include<stdio.h>
#include <stdlib.h>
int main(int agrc,char*argv[3])
{printf("參數和為:%d\n",atoi(argv[1])+atoi(argv[2]));return 0;
}可以通過whereis ls查看ls可執行程序的位置:
上述程序中就可以替換為下列代碼——執行ls即可
execl("ls路徑","ls",NULL);
想用ls -l就可以在ls后面加參數即可:
execl("ls路徑","ls","-l",NULL);獲取系統服務時間指令:date
同樣的道理可以用whereis date查看date可執行程序的路徑
上述程序中就可以替換為下列代碼——執行date即可
execl("date路徑","date",NULL);

execl和execlp的區別在于:

exaclp函數帶p,所以能通過環境變量PATH查找到可執行文件ps,當可執行文件的文件路徑中帶有 / 這種路徑符號,我們將其視為路徑名(就是按照這個路徑去找可執行文件),否則就將其視為環境變量(path變量的作用是可以讓我們在沒有這個應用的路徑下面打開我們需要打開的應用,前提是這個應用得在環境變量里面配置了路徑),在linux系統中可以用 echo $PATH 查看當前的環境變量,那些冒號是分隔符。如果用execlp就可以寫為execlp(“date”,“date”,NULL);直接寫date就好。

環境變量和pwd顯示的路徑不一樣,只有將當前路徑加入到環境變量的時候,環境變量里面才會出現當前路徑,也就意味著在任何路徑下都可以訪問該路徑下的可執行文件。

PATH是什么?

如何修改環境變量?
在linux環境中可以通過以下代碼將路徑加入到環境變量:

方法一:
export PATH=$PATH:當前路徑
$PATH表示當前環境變量
//配置完后可以通過echo $PATH查看配置結果。
生效方法:立即生效
有效期限:臨時改變,只能在當前的終端窗口中有效,當前窗口關閉后就會恢復原有的path配置
用戶局限:僅對當前用戶方法二:
通過修改.bashrc文件:
vim ~/.bashrc
//在最后一行添上:
export PATH=/usr/local/mongodb/bin:$PATH
生效方法:(有以下兩種)
1、關閉當前終端窗口,重新打開一個新終端窗口就能生效
2、輸入“source ~/.bashrc”命令,立即生效
有效期限:永久有效
用戶局限:僅對當前用戶方法三:
通過修改profile文件:
vim /etc/profile
/export PATH //找到設置PATH的行,添加
export PATH=/usr/local/mongodb/bin:$PATH
生效方法:系統重啟
有效期限:永久有效
用戶局限:對所有用戶方法四:
通過修改environment文件:
vim /etc/environment
在PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games”中加入“:/usr/local/mongodb/bin”
生效方法:系統重啟
有效期限:永久有效
用戶局限:對所有用戶

帶v不帶l的一類exec函數:

其實就是將execl可執行程序里面的餐數放到指針數組里面,然后用數組的首地址代替可執行程序名字和程序的參數。

示例:

char* canshu[]={"number","12","13","NULL"};
execv("./number",canshu)

exec配合fork使用:

實現功能當父進程檢測到輸入為1的時候后,創建子進程把配置文件的字段修改掉。

***********************
以下是存在父子進程的程序
通過調用現有的可執行程序
修改目標文件的內容,他這個
要修改文件要加上絕對路徑
************************
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include<stdlib.h>
#include <sys/wait.h>
int main()
{pid_t pid;pid_t fpid,returnpid;int status;int input=0;int execlreturn=0;while(1){printf("請輸入數字:\n");scanf("%d",&input);if(input==1){fpid=fork();if(fpid>0){returnpid=waitpid(fpid,&status,0);if(WIFEXITED(status)){printf("子進程正常退出,退出參數是:%d\n",WEXITSTATUS(status));}}if(fpid==0){execlreturn=execl("/home/fhn/linuxfile/changfile","changfile","/home/fhn/linuxfile/test.txt",NULL);            if(execlreturn==-1){printf("exec fail\n");perror("execfail");}}}else{printf("do nothing\n");}}return 0;
}

system函數:

#include <stdlib.h>
int system(const char *command);函數說明:
system()會調用fork()產生子進程,由子進程來調用/bin/sh-c string來執行參數string字符串所代表的命令
此命令執行完后隨即返回原調用的進程。在調用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被忽略。sh -c就相當于./  就是為了執行后面的指令string返回值:
如果fork()失敗 返回-1:出現錯誤如果exec()失敗,表示不能執行Shell,返回值相當于Shell執行了exit(127)如果執行成功則返回子Shell的終止狀態如果system()在調用/bin/sh時失敗則返回127,其他失敗原因返回-1。若參數string為空指針(NULL),則返回非零值。如果system()調用成功則最后會返回執行shell命令后的返回值,但是此返回值也有可能為 system()調用/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認執行成功。system調用結束后還會返回原程序繼續執行system下面的代碼,而exec族函數不會。我的理解:
在system函數調用成功時返回進程的狀態值
當因shell不能執行時也就是system()在調
用/bin/sh時失敗時返回127,其他失敗情況
返回-1,命令string為空指針(NULL)system
函數的返回值很簡單明了,只有01。返回1,
表明系統的命令處理程序,即/bin/sh是可用的。
相反,如果命令處理程序不可用,則返回0。 在
判斷返回值時最好能再檢查errno來確認執行成功使用例子:
system("/home/fhn/linuxfile/changfile /home/fhn/linuxfile/test.txt");

popen函數和system函數區別?

popen函數:

#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);

函數說明:

  • popen()會調用fork()產生子進程,然后從子進程中調用/bin/sh -c來執行參數command的指令。
  • 參數type可使用“r”代表讀取,“w”代表寫入。依照此type值,popen()會建立管道連到子進程的標準輸出設備(比如說:ps指令,所以可以用“”r“”根據返回的指針讀取子進程的標準輸出內容)或標準輸入設備,然后返回一個文件指針。隨后進程便可利用此文件指針來讀取子進程的輸出設備或是寫入到子進程的標準輸入設備中。
  • 此外,所有使用文件指針(FILE*)操作的函數也都可以使用,除了fclose()以外。
  • 如果 type 為 r,那么調用進程讀進 command 的標準輸出。如果 type 為 w,那么調用進程寫到 command 的標準輸入。
  • popen比sysytem的好處是可以通過管道獲取運行結果

返回值:
若成功則返回文件指針,否則返回NULL,錯誤原因存于errno中。
注意:
popen()會繼承環境變量,通過環境變量可能會造成系統安全的問題。

為什么要用popen函數:

#include<stdio.h>
#include <stdlib.h>
int main()
{system("ps");return 0;
}這幾行代碼的運行結果如下:
fhn@ubuntu:~/jincheng$ ./popen PID TTY          TIME CMD20157 pts/3    00:00:03 bash24755 pts/3    00:00:00 popen24756 pts/3    00:00:00 sh24757 pts/3    00:00:00 ps如果想要把它運行的結果放到文件或者字符串中去
就要用到popen函數將結果流入到文件中去,如下面代碼:
#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{char* buf;FILE* fd;int n_read;buf=(char*)malloc(1024);fd=popen("ps","r");n_read=fread(buf,1,1024,fd);pclose(fd);printf("管道輸出:%s",buf);return 0;
}
以下是輸出結果:fhn@ubuntu:~/jincheng$ ./popen 
管道輸出:   PID TTY          TIME CMD20157 pts/3    00:00:03 bash24865 pts/3    00:00:00 popen24866 pts/3    00:00:00 sh24867 pts/3    00:00:00 ps如果有將信息流入到內存而不打印則屏幕上面沒有顯示。

注意popen用的是fread、fwrite而不是read和write,因為read返回的是文件描述符不符合,fread返回的是文件指針

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272217.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272217.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272217.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jquery.validate.unobtrusive的使用

應用 一、引入 <script src"Scripts/jquery-1.7.1.min.js"></script> <script src"Scripts/jquery.validate.js"></script> <script src"Scripts/jquery.validate.unobtrusive.js"></script> 二、1&#xf…

Linux操作系統六大優點

??作者主頁&#xff1a;IT技術分享社區 ??作者簡介&#xff1a;大家好,我是IT技術分享社區的博主&#xff0c;從事C#、Java開發九年&#xff0c;對數據庫、C#、Java、前端、運維、電腦技巧等經驗豐富。 ??個人榮譽&#xff1a; 數據庫領域優質創作者&#x1f3c6;&#x…

[webview] 放大縮小的問題

http://www.cocoachina.com/bbs/read.php?tid33249轉載于:https://www.cnblogs.com/zxykit/p/5274831.html

進程間通信IPC(一)(半雙工管道和消息隊列)

引言&#xff1a; 之前學習的進程之間交換信息的方法只能由fork或exec傳送打開文件&#xff0c;或者文件系統。但是這種通訊方式有局限性&#xff0c;接下來將說明進程之間相互通信的其他技術——IPC(InterProcessCommunication)&#xff0c;過去UNIX系統IPC是各種進程間通信方…

Seata相關概念

相關概念 XID&#xff1a;一個全局事務的唯一標識 Transaction Coordinator (TC)&#xff1a; 事務協調器&#xff0c;維護全局事務的運行狀態&#xff0c;負責協調并驅動全局事務的提交或回滾&#xff08;可以理解為事務的協調者&#xff09;。 Transaction Manager (TM)&…

VSS配置

http://www.cnblogs.com/FreeDong/articles/2193151.html轉載于:https://www.cnblogs.com/lacey/p/5275514.html

Program terminated with signal SIGSEGV, Segmentation fault.

問題&#xff1a; 在程序運行時出現了&#xff1a;Segmentation fault (core dumped)&#xff0c;分段故障(堆芯轉儲)也就是段錯誤。 我首先在一篇博客上面找到如何使用gdb調試&#xff1a; 1、首先使用ulimit -a查看你的core file size是否為0.如果不是的話就請跳到步驟3&am…

NFS簡介

NFS 是Network File System的縮寫&#xff0c;即網絡文件系統。一種使用于分散式文件系統的協定&#xff0c;由Sun公司開發&#xff0c;于1984年向外公布。功能是通過網絡讓不同的機器、不同的操作系統能夠彼此分享個別的數據&#xff0c;讓應用程序在客戶端通過網絡訪問位于服…

Php Laravel框架 多表關系處理 之 Eloquent一對多關系處理

Php Laravel框架 多表關系處理 之 Eloquent一對多關系處理 本博文主要介紹 Laravel 框架中 Eloquent 對一對多關系的處理以及在 Laravel Administrator(后臺擴展包)中的應用。 您的數據庫可能是彼此相關的。比方&#xff0c;一篇博客文章可能有很多評論&#xff0c;或者一個訂…

進程間通信IPC(二)(共享內存、信號、信號量)

共享內存&#xff1a; 共享內存就是允許兩個或多個進程共享一定的存儲區。就如同 malloc() 函數向不同進程返回了指向同一個物理內存區域的指針。當一個進程改變了這塊地址中的內容的時候&#xff0c;其它進程都會察覺到這個更改。因為數據不需要在客戶機和服務器端之間復制&am…

分布式理論CAP定理

CAP原則又稱CAP定理&#xff0c;指的是在一個分布式系統中&#xff0c; Consistency&#xff08;一致性&#xff09;、 Availability&#xff08;可用性&#xff09;、Partition tolerance&#xff08;分區容錯性&#xff09;&#xff0c;三者不可兼得。 998年&#xff0c;加州…

xmlWriter 以UTF-8格式寫xml問題

dom4j中的XMLWriter提供以下幾種構造方法&#xff1a; XMLWriter() XMLWriter(OutputFormat format) XMLWriter(OutputStream out) XMLWriter(OutputStream out, OutputFormat format) XMLWriter(Writer writer) XMLWriter(Writer writer, OutputFormat format) 最簡單常…

linux線程(互斥鎖、條件)

線程概念&#xff1a; 典型的UNIX/Linux進程可以看成只有一個控制線程&#xff1a;一個進程在同一時刻只做一件事情。有了多個控制線程后&#xff0c;在程序設計時可以把進程設計成在同一時刻做不止一件事&#xff0c;每個線程各自處理獨立的任務。 進程是程序執行時的一個實例…

centos下防火墻設置

1、開啟防火墻 systemctl start firewalld2、開放指定端口firewall-cmd --zonepublic --add-port8888/tcp --permanent命令含義&#xff1a; --zone #作用域 --add-port1935/tcp #添加端口&#xff0c;格式為&#xff1a;端口/通訊協議 --permanent #永久生效&#xff0c;沒有…

linux網絡編程、socket編程

進程間通信&#xff1a; 特點&#xff1a;依賴于內核&#xff0c;造成缺陷——無法實現多機通信。 網絡&#xff1a; 地址&#xff1a;由IP地址&#xff08;IP地址是IP協議提供的一種統一的地址格式&#xff0c;它為互聯網上的每一個網絡和每一臺主機分配一個邏輯地址&#xf…

【Python】Python Mako模板使用

參考資料&#xff1a; Mako Templates for Python官網&#xff1a;http://www.makotemplates.org/ Python模板庫Mako的用法&#xff1a;http://my.oschina.net/u/877170/blog/290438 Mako 1.0.4 Documentation&#xff1a;http://docs.makotemplates.org/en/latest/usage.html#…

簡單的ftp服務器(客戶端、服務器端、socket)

查看本機IP地址&#xff1a; 127.0.0.1 服務器功能&#xff1a; 可以獲取服務器文件使用get指令可以展示服務器有哪些文件使用ls指令進入服務器某個文件夾使用指令cd文件夾名稱上傳本地文件到服務器&#xff0c;使用指令putpwd可以查看客戶端在當前服務器的位置 客戶端本地…