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) 2079 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 命令的結果。

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

通過調試 在父進程執(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 printf , 但是只有 dup2 上面的 printf 結果輸出到屏幕上,因此我注釋了 dup2(p[WRITE], 1); 結果在父進程 if 語句中的 dup2 后面的命令都執(zhí)行并且輸出到屏幕上了。通過查找 dup2 命令發(fā)現(xiàn)了重定向的強大之處。


先解釋下 dup2 命令,

int dup2(int filedes, int filedes2);

說明:

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

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

?

?

?

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

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

代碼 :

?

      
         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)結果果然是 p[READ] 的內容,猜疑沒錯。


為了更清楚的理解 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 文件里面的內容。

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

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

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

第二個輸出是 dup(0, fd) 輸出了 Levi 文件的內容。即是 通過文件重定向到標準輸入的內容。

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

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

并且不會被后面的代碼所修改。

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

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

而是進入了一種交互模式。

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

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

所以,這里直接輸出了該文本的內容。

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

dup2(0,fd) 不是表示 fd 所指的文件接收來自終端的輸入,因為, fd 已經不再指向原來的那個文件了。

它和文件描述符 0 已經在共享同一個文件表項(即指向終端標準輸入的那個表項)了。

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

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


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


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美中文字幕在线观看 | 视频在线欧美 | 色播综合 | 一区二区三区欧美日韩国产 | 日韩欧美在线综合网高清 | 在线精品亚洲欧洲第一页 | 97视频在线观看视频最新 | 国产精品九九久久精品女同 | 日韩欧美在线观看视频一区二区 | 日本免费成人网 | 在线a亚洲视频播放在线观看 | 牛牛影视午夜免费福利 | 操美女国产 | 亚洲人成绝费网站色ww | 狠狠色狠狠色综合婷婷tag | 日本a视频在线 | 天天干天天草天天射 | 国产欧美一区二区三区视频 | 国产亚洲欧美在线视频 | 亚洲一区欧美日韩 | 在线观看福利网站 | 精品中文字幕不卡在线视频 | 欧美一区在线观看视频 | 99久久免费精品国产免费高清 | 亚洲国产精品第一区二区三区 | 国产午夜精品一区二区三区 | 日本操比 | 精品福利视频第一 | 日韩在线第三页 | 亚洲综合伊人 | 日韩欧美一区二区三区久久 | xxxwww欧美| 久久七国产精品 | 91亚色视频在线观看 | 国产精品久久久一区二区三区 | 欧美一级久久久久久久大 | 国产97色在线 | 亚洲 | 91视频地址| 久草欧美视频 | 一区二区三区欧美在线 | 亚洲精品国产精品国自产观看 |