使用exec函數將當前的信息輸入到文件中

先來看看exec函數: shell

exec函數族     函數

fork建立子進程後執行的是和父進程相同的程序(但有可能執行不一樣的代碼分支),子進程每每要調用一種exec函數以執行另外一個程序。當進程調用一種exec函數時,該進程的用戶空間代碼和數據徹底被新程序替換,重新程序的啓動例程開始執行。調用exec並不建立新進程,因此調用exec先後該進程的id並未改變。 google

將當前進程的.text、.data替換爲所要加載的程序的.text、.data,而後讓進程重新的.text第一條指令開始執行,但進程ID不變,換核不換殼。 spa

其實有六種以exec開頭的函數,統稱exec函數: orm

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[]); it

int execv(const char *path, char *const argv[]); io

int execvp(const char *file, char *const argv[]); form

int execve(const char *path, char *const argv[], char *const envp[]);

execlp函數

加載一個進程,藉助PATH環境變量    

int execlp(const char *file, const char *arg, ...);        成功:無返回;失敗:-1

參數1:要加載的程序的名字。該函數須要配合PATH環境變量來使用,當PATH中全部目錄搜索後沒有參數1則出錯返回。

該函數一般用來調用系統程序。如:ls、date、cp、cat等命令。

 

如你所見,exec函數實際上時一族函數:有6個。解決標題的問題這幾個均可以用,可是我使用execlp函數。

先來看看它的用法:

它的原型:int execlp(const char *file, const char *arg, …);

這是一個變參函數。第一個參數是可執行文件的名稱,能夠不用指定文件目錄,他會自動在當前的環境變量中查找,適用於使用系統可執行文件來建立一個進程這樣的場合。相信知道exec函數的人應該知道它是用來幹嗎的吧?若是不知道,請自行www.baidu.com或www.google.com。一個示例:execlp("ls", "ls", "-l", "-f", NULL);        使用程序名在PATH中搜索。用NULL做爲哨兵

因此,咱們能夠利用它在使程序執行自己的過程當中執行其餘可執行文件。查看當前進程的命令:ps   aux    而後要將它輸入到文件中去,怎麼辦呢?重定向! ps  aux > out.txt    可是咱們能直接在程序中這麼寫麼?答案是不能。爲何?由於>是轉義字符。(別嫌我囉嗦,大部分人基礎都不咋地,我也是。基礎好的話也不會來寫這個來增強記憶了。)因此,咱們實際上要這樣作:execlp("ps","ps","aux","\>","o_ret",NULL);  o_ret是一個自定義文件描述符。

懂了嗎?可是,我要說可是!這不行!爲何?來,咱們來看看,execlp("ps","ps","aux","\>","o_ret",NULL);若是咱們是在shell環境中執行這個函數所作的事,那咱們是這樣執行的:ps  aux > o_ret   請問,請問,o_ret是什麼?shell環境知道麼?他不知道!因此,命令執行失敗。

那麼怎麼辦?沒事,有辦法,知道dup2函數麼?(不能讀成dup2(er),應該是dup(to))他將一個文件描述符複製給另外一個文件描述符。你們應該知道一句話,在Linux中,一切皆文件。那麼標準輸入輸出流,標準錯誤流是否是文件?是,而且他們三一直佔用這文件描述符的前三。我不是說他們的使用頻率,我是說他們的地位,咱們用戶自定義的文件描述符最牛逼也就只能排在3號位置,前面的0,1,2是他們的天下。

若是,若是咱們用dup2函數將o_ret複製給stdout,會發生什麼?是的,原先默認輸出到屏幕上的東西都會輸出到o_ret指向的文件中去。咱們還用去重定向麼?不用,還要去使用轉義字符麼?不用。

說了這麼些,若是認真看,應該是會有一些明悟的。接下來上代碼:

#include <cstdio>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

 

int main()

{

    int o_ret, e_ret, c_ret;

    o_ret = open("process_information.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);//建立文件,若存在,截斷;權限644

    if (-1 == o_ret)

    {

        perror("file ");

        exit(1);

    }

    dup2(o_ret, STDOUT_FILENO);

 

    e_ret = execlp("ps", "ps", "aux", nullptr);

    //第一個ps是讓函數去找這個可執行文件,第二個ps是argv[0]參數,這裏我是這麼理解的,函數找到ps文件後,開闢一個shell空間,而後使用後面的參數來執行。

    //可參考:https://baike.baidu.com/item/execlp

    if (-1 == e_ret)

    {

        perror("execlp() ");

        //exit(1); 執行到這兒了,若是退出,打開的文件怎麼辦?

    }

 

    c_ret = close(o_ret);

    if (-1 == c_ret)

    {

        puts("close file failure");

    }

    printf("c_ret = %d\n", c_ret);

 

    printf("hello from processInformation_printf_file!\n");

    return 0;

}

相關文章
相關標籤/搜索