2#include3#include4#include5#include67#defineMSGSIZE208#defineREAD09#defineWRITE11011intmain(intargc,charconst*argv[])12{13intp[2],bytes,res,c;14charinbuf[10240" />

日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Linux系統(tǒng)編程:dup2()重定向

系統(tǒng) 2221 0

對于 Dup2 的理解:

源代碼:

?

      
         1
      
       #include <unistd.h>

      
         2
      
       #include <stdio.h>

      
         3
      
       #include <stdlib.h>

      
         4
      
       #include <
      
        string
      
      .h>

      
         5
      
       #include <time.h>

      
         6
      
      
         7
      
      
        #define
      
       MSGSIZE 20

      
         8
      
      
        #define
      
       READ 0 

      
         9
      
      
        #define
      
       WRITE 1

      
        10
      
      
        11
      
      
        int
      
       main(
      
        int
      
       argc, 
      
        char
      
      
        const
      
       *
      
        argv[])

      
      
        12
      
      
        {

      
      
        13
      
      
        int
      
       p[
      
        2
      
      
        ], bytes, res, c;

      
      
        14
      
      
        char
      
       inbuf[
      
        10240
      
      
        ];

      
      
        15
      
      
        int
      
      
         pid;

      
      
        16
      
           printf(
      
        "
      
      
        %c
      
      
        "
      
      , 
      
        11
      
      
        );

      
      
        17
      
      
        if
      
      (pipe(p) == -
      
        1
      
      ){
      
        //
      
      
         creat the pipe , if pipe is built failed , exit .
      
      
        18
      
               perror(
      
        "
      
      
        pip call
      
      
        "
      
      
        );

      
      
        19
      
               exit(
      
        1
      
      
        );

      
      
        20
      
      
            }

      
      
        21
      
           pid =
      
         fork();

      
      
        22
      
      
        if
      
      (pid != 
      
        0
      
      ){
      
        //
      
      
         creat parent pid and child pid.
      
      
        23
      
               close(p[READ]);
      
        //
      
      
        close parent pipe read 
      
      
        24
      
               dup2(p[WRITE], 
      
        1
      
      
        );

      
      
        25
      
               close(p[WRITE]);
      
        //
      
      
        close parent pipe write
      
      
        26
      
               execlp(argv[
      
        1
      
      ], argv[
      
        1
      
      
        ], NULL);

      
      
        27
      
      
            }

      
      
        28
      
      
        else
      
      
        {

      
      
        29
      
      
        30
      
               close(p[WRITE]);
      
        //
      
      
        close child pipe write
      
      
        31
      
      
        32
      
               dup2(p[READ],
      
        0
      
      
        );

      
      
        33
      
      
        34
      
               close(p[READ]);
      
        //
      
      
        close child pipe read
      
      
        35
      
      
        36
      
               execlp(argv[
      
        2
      
      ], argv[
      
        2
      
      
        ], NULL);

      
      
        37
      
      
            }

      
      
        38
      
      
        return
      
      
        0
      
      
        ;

      
      
        39
      
       }
    

?

通過命令行輸出:

./a.out “l(fā)s” “ps”

僅僅在終端執(zhí)行了 ps 的命令, 而沒有看到 ls 命令的結(jié)果。

因此,開始走入了第一個(gè)誤區(qū):父進(jìn)程沒有執(zhí)行

通過調(diào)試 在父進(jìn)程執(zhí)行 if 條件中加入以下代碼:

if(pid != 0){

printf("4556\n");

close(p[READ]);

dup2(p[WRITE], 1);

close(p[WRITE]);

printf("4556\n");

execlp(argv[1], argv[1], NULL);

}


加入了 2 個(gè) printf , 但是只有 dup2 上面的 printf 結(jié)果輸出到屏幕上,因此我注釋了 dup2(p[WRITE], 1); 結(jié)果在父進(jìn)程 if 語句中的 dup2 后面的命令都執(zhí)行并且輸出到屏幕上了。通過查找 dup2 命令發(fā)現(xiàn)了重定向的強(qiáng)大之處。


先解釋下 dup2 命令,

int dup2(int filedes, int filedes2);

說明:

dup2 則可以用 filedes2 參數(shù)指定新描述符的數(shù)值。如果 filedes2 已經(jīng)打開,則先將其關(guān)閉。如若 filedes 等于 filedes2 ,則返回 filedes2 ,而不關(guān)閉它。

dup2(p[WRITE], 1); 這句話可以理解為將標(biāo)準(zhǔn)輸出重定向到 p[WRITE], 因此在這句話后面的所有 printf 語句打印或者 exec 執(zhí)行的內(nèi)容都輸入到了 p[WRITE] 中。剛開始有個(gè)迷惑,就是既然已經(jīng) close 1 )了,為什么還能輸入到 p[WRITE] 中,通過自己的直覺判斷,應(yīng)當(dāng)是 close(1) 關(guān)閉了屏幕的輸出,但是它有緩沖區(qū)保存 printf 打印出的內(nèi)容,并且由于重定向的關(guān)系,輸進(jìn)了 p[WRITE] 中。

?

代碼:

?

      
         1
      
       #include <unistd.h>

      
         2
      
       #include <stdio.h>

      
         3
      
       #include <stdlib.h>

      
         4
      
       #include <
      
        string
      
      .h>

      
         5
      
       #include <time.h>

      
         6
      
      
         7
      
      
        #define
      
       MSGSIZE 20

      
         8
      
      
        #define
      
       READ 0 

      
         9
      
      
        #define
      
       WRITE 1

      
        10
      
      
        11
      
      
        int
      
       main(
      
        int
      
       argc, 
      
        char
      
      
        const
      
       *
      
        argv[])

      
      
        12
      
      
        {

      
      
        13
      
      
        int
      
       p[
      
        2
      
      
        ], bytes, res, c;

      
      
        14
      
      
        char
      
       inbuf[
      
        10240
      
      
        ];

      
      
        15
      
      
        int
      
      
         pid;

      
      
        16
      
           printf(
      
        "
      
      
        %c
      
      
        "
      
      , 
      
        11
      
      
        );

      
      
        17
      
      
        if
      
      (pipe(p) == -
      
        1
      
      ){
      
        //
      
      
         creat the pipe , if pipe is built failed , exit .
      
      
        18
      
               perror(
      
        "
      
      
        pip call
      
      
        "
      
      
        );

      
      
        19
      
               exit(
      
        1
      
      
        );

      
      
        20
      
      
            }

      
      
        21
      
           pid =
      
         fork();

      
      
        22
      
      
        if
      
      (pid != 
      
        0
      
      ){
      
        //
      
      
         creat parent pid and child pid.
      
      
        23
      
               close(p[READ]);
      
        //
      
      
        close parent pipe read 
      
      
        24
      
               dup2(p[WRITE], 
      
        1
      
      
        );

      
      
        25
      
               close(p[WRITE]);
      
        //
      
      
        close parent pipe write
      
      
        26
      
               printf(
      
        "
      
      
        123!\n
      
      
        "
      
      
        );

      
      
        27
      
               execlp(argv[
      
        1
      
      ], argv[
      
        1
      
      
        ], NULL);

      
      
        28
      
               perror(
      
        "
      
      
        execlp
      
      
        "
      
      );
      
        //
      
      
        error output
      
      
        29
      
      
            }

      
      
        30
      
      
        else
      
      
        {

      
      
        31
      
      
        while
      
      (
      
        1
      
      
        ){

      
      
        32
      
                   res = read(p[READ], inbuf, 
      
        10240
      
      
        );

      
      
        33
      
      
        if
      
      (res>
      
        0
      
      
        )

      
      
        34
      
                           printf(
      
        "
      
      
        %s\n
      
      
        "
      
      
        , inbuf);

      
      
        35
      
      
        break
      
      
        ;

      
      
        36
      
      
                }

      
      
        37
      
      
        38
      
               close(p[WRITE]);
      
        //
      
      
        close child pipe write
      
      
        39
      
      
        40
      
               dup2(p[READ],
      
        0
      
      
        );

      
      
        41
      
      
        42
      
               close(p[READ]);
      
        //
      
      
        close child pipe read
      
      
        43
      
      
        44
      
               execlp(argv[
      
        2
      
      ], argv[
      
        2
      
      
        ], NULL);

      
      
        45
      
      
            }

      
      
        46
      
      
        return
      
      
        0
      
      
        ;

      
      
        47
      
       }
    

?

?

?

通過在子進(jìn)程中用 while(1) 循環(huán)讀取 p[READ] 內(nèi)容,發(fā)現(xiàn)讀出了父進(jìn)程本應(yīng)在屏幕上打印的內(nèi)容,因此父進(jìn)程是執(zhí)行了所有命令行,只是通過重定向命令存到了 p[WRITE] 管道中。

由于有 dup2(p[READ], 0) 命令,因此猜測標(biāo)準(zhǔn)輸入的文件描述符定向到了 p[READ] , 因此如果猜測沒錯(cuò),通過 getchar() 讀取文件標(biāo)準(zhǔn)輸入并把 P[READ] 的內(nèi)容輸出到屏幕上則證明我猜想沒錯(cuò)。

代碼 :

?

      
         1
      
       #include <unistd.h>

      
         2
      
       #include <stdio.h>

      
         3
      
       #include <stdlib.h>

      
         4
      
       #include <
      
        string
      
      .h>

      
         5
      
       #include <time.h>

      
         6
      
      
         7
      
      
        #define
      
       MSGSIZE 20

      
         8
      
      
        #define
      
       READ 0 

      
         9
      
      
        #define
      
       WRITE 1

      
        10
      
      
        11
      
      
        int
      
       main(
      
        int
      
       argc, 
      
        char
      
      
        const
      
       *
      
        argv[])

      
      
        12
      
      
        {

      
      
        13
      
      
        int
      
       p[
      
        2
      
      
        ], bytes, res, c;

      
      
        14
      
      
        char
      
       inbuf[
      
        10240
      
      
        ];

      
      
        15
      
      
        int
      
      
         pid;

      
      
        16
      
           printf(
      
        "
      
      
        %c
      
      
        "
      
      , 
      
        11
      
      
        );

      
      
        17
      
      
        if
      
      (pipe(p) == -
      
        1
      
      ){
      
        //
      
      
         creat the pipe , if pipe is built failed , exit .
      
      
        18
      
               perror(
      
        "
      
      
        pip call
      
      
        "
      
      
        );

      
      
        19
      
               exit(
      
        1
      
      
        );

      
      
        20
      
      
            }

      
      
        21
      
           pid =
      
         fork();

      
      
        22
      
      
        if
      
      (pid != 
      
        0
      
      ){
      
        //
      
      
         creat parent pid and child pid.
      
      
        23
      
               close(p[READ]);
      
        //
      
      
        close parent pipe read 
      
      
        24
      
               dup2(p[WRITE], 
      
        1
      
      
        );

      
      
        25
      
               close(p[WRITE]);
      
        //
      
      
        close parent pipe write
      
      
        26
      
               printf(
      
        "
      
      
        123!\n
      
      
        "
      
      
        );

      
      
        27
      
               execlp(argv[
      
        1
      
      ], argv[
      
        1
      
      
        ], NULL);

      
      
        28
      
               perror(
      
        "
      
      
        execlp
      
      
        "
      
      );
      
        //
      
      
        error output
      
      
        29
      
      
            }

      
      
        30
      
      
        else
      
      
        {

      
      
        31
      
      
        //
      
      
         while(1){

      
      
        32
      
      
        //
      
      
             res = read(p[READ], inbuf, 10240);

      
      
        33
      
      
        //
      
      
                 if(res>0)

      
      
        34
      
      
        //
      
      
                     printf("%s\n", inbuf);

      
      
        35
      
      
        //
      
      
             break;

      
      
        36
      
      
        //
      
      
         }
      
      
        37
      
      
        38
      
               close(p[WRITE]);
      
        //
      
      
        close child pipe write
      
      
        39
      
      
        40
      
               dup2(p[READ],
      
        0
      
      
        );

      
      
        41
      
      
        while
      
      ((c=getchar()) != -
      
        1
      
      
        ){

      
      
        42
      
                   printf(
      
        "
      
      
        %c
      
      
        "
      
      
        , c);

      
      
        43
      
      
                }

      
      
        44
      
               close(p[READ]);
      
        //
      
      
        close child pipe read
      
      
        45
      
      
        46
      
               execlp(argv[
      
        2
      
      ], argv[
      
        2
      
      
        ], NULL);

      
      
        47
      
      
            }

      
      
        48
      
      
        return
      
      
        0
      
      
        ;

      
      
        49
      
       }
    

?


通過在 dup2(p[READ], 0) 后面 while 循環(huán)讀入輸入流輸入的字符并且打印出來, 發(fā)現(xiàn)結(jié)果果然是 p[READ] 的內(nèi)容,猜疑沒錯(cuò)。


為了更清楚的理解 dup2 的重定向含義,想理解 dup2(fd,0) dup2(0,fd) 功能相同嗎?

為了得到答案,找些資料發(fā)現(xiàn),答案是不同。

?

測試代碼:

      
         1
      
       #include <stdio.h>

      
         2
      
       #include <unistd.h>

      
         3
      
       #include <fcntl.h>

      
         4
      
      
         5
      
      
        #define
      
       BUFMAXSIZE 4096

      
         6
      
      
         7
      
      
        int
      
       main(
      
        int
      
       argc, 
      
        char
      
       *
      
        argv[])

      
      
         8
      
      
        {

      
      
         9
      
      
        int
      
      
         fd;

      
      
        10
      
      
        int
      
      
         n;

      
      
        11
      
      
        char
      
      
         buf[BUFMAXSIZE];

      
      
        12
      
      
        int
      
      
         fs;

      
      
        13
      
           fs = open(
      
        "
      
      
        test
      
      
        "
      
      
        , O_RDWR);   

      
      
        14
      
      
        if
      
      ((fd = open(
      
        "
      
      
        duan
      
      
        "
      
      , O_RDWR )) == -
      
        1
      
      
        )

      
      
        15
      
      
            {

      
      
        16
      
               perror(
      
        "
      
      
        open error!
      
      
        "
      
      
        );

      
      
        17
      
      
        return
      
      (
      
        1
      
      
        );

      
      
        18
      
      
            }

      
      
        19
      
      
        20
      
           dup2(fd, 
      
        1
      
      );       
      
        //
      
      
         dup2(0,fd);
      
      
        21
      
      
        22
      
      
        while
      
      ((n = read(fs, buf, BUFMAXSIZE)) > 
      
        0
      
      
        )

      
      
        23
      
      
            {

      
      
        24
      
               printf(
      
        "
      
      
        begin to read...\n
      
      
        "
      
      
        );

      
      
        25
      
      
        if
      
      (write(STDOUT_FILENO, buf, n) !=
      
         n)

      
      
        26
      
      
                {

      
      
        27
      
                   perror(
      
        "
      
      
        write error!
      
      
        "
      
      
        );

      
      
        28
      
      
        return
      
      (
      
        1
      
      
        );

      
      
        29
      
      
                }

      
      
        30
      
               printf(
      
        "
      
      
        end to write...\n
      
      
        "
      
      
        );   

      
      
        31
      
      
            }

      
      
        32
      
      
        if
      
      (n < 
      
        0
      
      
        )

      
      
        33
      
      
            {

      
      
        34
      
               perror(
      
        "
      
      
        read error
      
      
        "
      
      
        );

      
      
        35
      
      
        return
      
      (
      
        1
      
      
        );

      
      
        36
      
      
            }

      
      
        37
      
      
        38
      
      
        return
      
      
        0
      
      
        ;

      
      
        39
      
       } 
    

?

?

dup(fd, 0) 這段代碼測試, 打印出了 duan 文件里面的內(nèi)容。

之后創(chuàng)建個(gè)文件 Levi 里面寫和 duan 文件不同的內(nèi)容。

通過 ./a. out < Levi 輸出:

第一個(gè)輸出是 dup(fd, 0) 輸出了 Duan 文件的內(nèi)容。即是 fd 的內(nèi)容

第二個(gè)輸出是 dup(0, fd) 輸出了 Levi 文件的內(nèi)容。即是 通過文件重定向到標(biāo)準(zhǔn)輸入的內(nèi)容。

從圖中的輸出結(jié)果已經(jīng)可以看到兩者的區(qū)別了。

第一種 dup2(fd,0) 之前已經(jīng)將 fd 初始化指向到文本 Duan 了,

并且不會(huì)被后面的代碼所修改。

第二種 dup2(0,fd) 則將 fd 重新指向到文件描述符 0 所代表的文件(即終端標(biāo)準(zhǔn)輸入)了。

那么可以看到,程序的執(zhí)行中不會(huì)再讀取 Duan 文件了。

而是進(jìn)入了一種交互模式。

另外,這時(shí)“輸入重定向”也可以生效了。

文件描述符 0 被 “ <” 重定向到 Duan

所以,這里直接輸出了該文本的內(nèi)容。

dup2(fd,0) 相當(dāng)于“輸入重定向”的功能,

dup2(0,fd) 不是表示 fd 所指的文件接收來自終端的輸入,因?yàn)椋? fd 已經(jīng)不再指向原來的那個(gè)文件了。

它和文件描述符 0 已經(jīng)在共享同一個(gè)文件表項(xiàng)(即指向終端標(biāo)準(zhǔn)輸入的那個(gè)表項(xiàng))了。

輸出重定向”的功能可以用 dup2(fd ,1) 替代。

dup2(fd,1) dup2(1,fd) 也是大同小異。


Linux系統(tǒng)編程:dup2()重定向


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 广东省| 平原县| 丹东市| 福鼎市| 澎湖县| 昆山市| 安西县| 喀喇| 临沂市| 广宁县| 时尚| 棋牌| 肃北| 白朗县| 游戏| 清原| 义马市| 民县| 博客| 海兴县| 靖安县| 贵南县| 东乌珠穆沁旗| 兴和县| 屏南县| 紫阳县| 清徐县| 化隆| 白玉县| 托克逊县| 惠东县| 淳安县| 阿鲁科尔沁旗| 龙游县| 保山市| 仙桃市| 延寿县| 历史| 济阳县| 古交市| 仙居县|