• <tfoot id="ukgsw"><input id="ukgsw"></input></tfoot>
    
    • 久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
      分享

      Shell:管道與重定向

       520jefferson 2020-12-11

      轉自:TOMORROW

      鏈接:https:///A8vpQE

      對shell有一定了解的人都知道,管道和重定向是 Linux 中非常實用的 IPC 機制。
      在shell中,我們通常使用符合'|’來表示管道,符號'>’和'<’表示重定向。
      那么管道和重定向的真實含義(定義)又是什么呢?

      管道

      管道的定義

      管道就是一個進程與另一個進程之間通信的通道,它通常是用作把一個進程的輸出通過管道連接到另一個進程的輸入。

      它是半雙工運作的,想要同時雙向傳輸需要使用兩個管道。

      管道又可以分為匿名管道和命名管道,而shell中使用到的是匿名管道,所以本文僅描述匿名管道。

      例如命令ls | grep main.c,使用了管道來連接了兩條命令來執行,能夠快速地讓我們知道當前目錄下是否有 main.c 文件。

      管道的本質是內存中的緩沖區,可以看作是打開到內存中的文件。

      所以需要使用兩個文件描述符來索引它,一個表示讀端,一個表示寫端。

      并且規定,數據只能從讀端讀取、只能往寫端寫入。

      創建管道

      使用函數pipe()可以創建匿名管道,需要包含頭文件 unistd.h,示例代碼:

      int fd[2];
      pipe(fd);

      首先創建一個 2 個元素的整型數組,然后將該數組作為pipe()的參數,pipe()執行成功后,數組元素 fd[0]的值就會變成所創建的管道的讀端的文件描述符,fd[1]就會變成寫端的文件描述符。

      至此管道就算創建成功了。

      把管道作為標準輸入輸出

      管道創建成功后,就可以直接使用 read()和 write()函數對管道進行數據的讀寫。

      而因為shell中都是使用標準輸入輸出對管道進行讀寫的,例如ls | grep main.c就是將 ls 的標準輸出寫到了管道寫端,而 grep 的標準輸入則從管道讀端讀取,所以本文也只描述此方法。

      示例代碼如下:

      int fd[2];
      pipe(fd);
      pid=fork();

      if(0==pid) //execute next command in child process
      {
      dup2(fd[0],0);//redirect standard input to pipe(read)
      close(fd[0]);
      close(fd[1]);

      if(0!=execvp(cmd0[0],cmd0))
      printf('No such command!\n');
      exit(EXIT_SUCCESS);
      }
      else //execute current command in current process
      {
      dup2(fd[1],1);//redirect standard output to pipe(write)
      close(fd[0]);
      close(fd[1]);

      if(0!=execvp(cmd1[0],cmd1))
      printf('No such command!\n');

      exit(EXIT_SUCCESS);
      }
      • 首先是創建一個管道,然后創建子進程,子進程會繼承這一個管道,也就保證了父進程與子進程操作的是同一個管道(管道的繼承與普通變量不同)。

        如果我們希望在子進程中執行管道的讀端的程序例如ls | grep main.c中的grep main.c;在父進程中執行管道的寫端的程序,例如ls | grep main.c中的ls。

      • 在子進程中,先調用dup2(fd[0],0);此函數就是將標準輸入的文件描述符 0,指向了管道的讀端。

      文件描述符,本質是非負整數,通常是小整數;它是一個索引,通過該索引可以找到對應的文件。

      例如,標準輸入、標準輸出、標準錯誤的文件描述符默認是 0、1、2 。當進程需要從標準輸入中讀取數據時,就會通過 0 索引找到標準輸入所對應的內存緩沖區來讀取數據。

      • 假設此時管道讀端的文件描述符為 3、寫端文件描述符為 4 。

      • 調用dup2(fd[0],0),實際上就是將文件描述符 3 指向的文件表項賦值給了文件描述符 0,而文件描述符 0 正是進程默認的標準輸入。

        所以此時,當進程需要從標準輸入讀取數據時,進程就會通過文件描述符 0 來找到管道讀端所對應內存緩沖區。

      • 從而實現了通過標準輸入來讀取管道的數據,也可以說是,將管道的讀端重定向到了標準輸入。管道的寫端與標準輸入的關系也與此類似,此處不再贅述。

      • 調用dup2(fd[0],0)之后還需要調用close()函數將管道原有的文件描述符關閉,關閉的意思是文件描述符 3 和 4 不再索引到管道或者其他文件,也就是說此時使用 read 函數從文件描述符 3 中是讀取不到管道的數據的了,并不是說關閉管道的意思。

      • 完成管道的設置之后,就可以通過 exec 族函數來執行外部命令了。

        需要注意的是,調用 exec 族函數并不會把管道這種 IPC 資源覆蓋或者重新初始化。

      文件重定向

      文件重定向其實與上面管道重定向到標準輸入輸出很類似,甚至可以直接采用上面所說的方法來實現。但是此處將講述一種更加簡潔的方法實現。

      實例代碼如下:

      char fileName[20]='out.txt';
      freopen(fileName,'w',stdout);//redirect stdout to fileName

      以上兩行簡單的代碼就實現了,將該進程的標準輸出重定向到了文件 out.txt ,甚至一行就可以實現。

      執行以上代碼后,當前進程的所有標準輸出,也就是 printf()之類的輸出全都會被寫到文件 out.txt,顯示屏將不會有輸出。

      而將進程的標準輸入重定向到文件 in.txt 的代碼如下:

      char fileName[20]='in.txt';
      freopen(fileName,'r',stdin);//redirect stdin to fileName
      其中的核心函數就是freopen()

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發表

        請遵守用戶 評論公約

        類似文章 更多

        主站蜘蛛池模板: 一本大道久久东京热AV| 国产成人免费高清激情视频| 无码天堂亚洲国产AV| 天天日天天谢天天视2019天干| 中文字幕国产日韩精品| 国产综合有码无码中文字幕 | 夜夜爽一区二区三区精品| 女人张开腿让男人桶爽| 在线中文字幕有码中文| 超碰成人人人做人人爽| 无码人妻丝袜在线视频红杏| 国产成人精品午夜福利| 成人又黄又爽又色的视频| 日韩精品一区二区亚洲AV| 国产永久免费高清在线观看| 国产成人精品999在线观看| 女人18毛片水真多免费看| 2019亚洲午夜无码天堂| 亚洲AV午夜成人无码电影| 狠狠综合久久综合88亚洲| 欧美亚洲综合成人A∨在线| 99中文字幕国产精品| 亚洲综合色婷婷在线观看| 丁香婷婷色综合激情五月| 猫咪AV成人永久网站在线观看| 麻豆国产AV剧情偷闻女邻居内裤| 亚洲国产成人欧美在线观看| 国产JJZZJJZZ视频全部免费| 国产精品中文字幕在线| 成人免费看片又大又黄| 国产精品 自在自线| 国产不卡一区二区四区| 欧美亚洲一区二区三区 | 两个人看的视频WWW在线高清| 人妻少妇无码精品专区| 久久久亚洲AV波多野结衣| 欧美亚洲国产日韩一区二区| 一区二区三区激情都市| 凹凸在线无码免费视频| 欧美人与动牲交片免费| 国产成人A在线视频免费|