成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Shell的管道與重定向

系統 Linux
對shell有一定了解的人都知道,管道和重定向是 Linux 中非常實用的 IPC 機制。

對shell有一定了解的人都知道,管道和重定向是 Linux 中非常實用的 IPC 機制。

在shell中,我們通常使用符合‘|’來表示管道,符號‘>’和‘<’表示重定向。

那么管道和重定向的真實含義(定義)又是什么呢?

管道

管道的定義

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

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

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

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

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

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

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

創建管道

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

  1. int fd[2];  
  2. pipe(fd); 

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

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

把管道作為標準輸入輸出

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

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

示例代碼如下: 

  1. int fd[2];  
  2. pipe(fd);  
  3. pid=fork();  
  4. if(0==pid) //execute next command in child process  
  5.  
  6.  dup2(fd[0],0);//redirect standard input to pipe(read)  
  7.  close(fd[0]);  
  8.  close(fd[1]);  
  9.  if(0!=execvp(cmd0[0],cmd0))  
  10.   printf("No such command!\n");  
  11.  exit(EXIT_SUCCESS);  
  12.  
  13. else //execute current command in current process   
  14.  
  15.  dup2(fd[1],1);//redirect standard output to pipe(write)  
  16.  close(fd[0]);  
  17.  close(fd[1]);  
  18.  if(0!=execvp(cmd1[0],cmd1))  
  19.   printf("No such command!\n");  
  20.  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 資源覆蓋或者重新初始化。文件重定向

文件重定向

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

實例代碼如下: 

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

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

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

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

  1. char fileName[20]="in.txt";  
  2. freopen(fileName,"r",stdin);//redirect stdin to fileName 

其中的核心函數就是freopen():

 

 

責任編輯:龐桂玉 來源: 運維派
相關推薦

2022-11-14 15:07:09

Linux管道

2020-02-24 11:37:56

Linux重定向管道

2009-12-25 16:21:41

shell命令

2010-12-14 15:07:15

ICMP路由重定向

2009-06-17 09:11:24

Unix管道重定向

2009-06-17 17:13:40

UNIX

2021-03-28 08:32:58

Java

2010-06-23 16:14:52

Linux Bash

2017-08-08 09:17:41

301302重定向

2016-08-23 17:21:51

UnixLinux重定向

2017-01-19 19:14:20

Linux重定向命令

2010-03-09 16:11:59

Linux重定向

2009-11-23 18:39:17

PHP重定向

2010-07-13 14:10:44

ICMP協議

2022-09-02 08:03:44

IO程序網卡

2017-12-06 10:15:27

跳轉機制Chrome

2020-07-27 07:41:23

Linux重定向數據流

2010-12-31 13:35:25

文件夾重定向

2011-06-15 14:43:43

301重定向

2009-06-25 14:54:22

Servlet轉發Servlet重定向
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: av黄色国产 | 欧美激情视频一区二区三区在线播放 | 亚洲第一成年免费网站 | 成人午夜| 日韩精品久久久 | 亚洲成人免费视频在线 | 亚洲91| 人干人人 | 成人av在线播放 | 亚洲综合一区二区三区 | 一本一道久久a久久精品蜜桃 | 日韩欧美精品一区 | 亚洲综合二区 | 国产综合一区二区 | 中文字幕亚洲视频 | 久久久久九九九女人毛片 | 亚洲欧美日本国产 | 色一级 | 亚洲国产一区在线 | 91精品国产一区二区三区 | 午夜爱爱网 | 最新中文字幕久久 | 99久久国产综合精品麻豆 | 久久精点视频 | 国产成人高清视频 | 天天射美女 | 黄网站免费观看 | 911网站大全在线观看 | 欧美一区二区三区在线观看视频 | 久久亚洲二区 | 一区二区三区四区国产精品 | 中文字幕在线观看第一页 | 日韩欧美一级片 | 国产一区二区三区四区五区加勒比 | 午夜精品影院 | 午夜性色a√在线视频观看9 | 精品日韩一区二区三区av动图 | 日韩在线不卡 | 一区二区三区四区av | 国产成人精品免费视频大全最热 | 美女逼网站 |