1. 程式人生 > >淺談dup和dup2的用法

淺談dup和dup2的用法

https://blog.csdn.net/u012058778/article/details/78705536

一、dup和dup2函式 
這兩個函式都可以來複制一個現有的檔案描述符,他們的宣告如下:

 #include <unistd.h>
 int  dup(int fd);
 int dup2(int fd, int fd 2);
  • 1
  • 2
  • 3

關於dup函式,當我們呼叫它的時候,dup會返回一個新的描述符,這個描述一定是當前可用檔案描述符中的最小值。我們知道,一般的0,1,2描述符分別被標準輸入、輸出、錯誤佔用,所以在程式中如果close掉標準輸出1後,呼叫dup函式,此時返回的描述符就是1。 
對於dup2,可以用fd2指定新描述符的值,如果fd2本身已經打開了,則會先將其關閉。如果fd等於fd2,則返回fd2,並不關閉它。 
這兩個函式返回的描述符與fd描述符所指向的檔案共享同一檔案表項。如下圖所示: 
這裡寫圖片描述

 
也就是fd與fd2可對同一個檔案進行讀寫操作。且其是一種原子操作。 
二、重定向示例 
1. dup

  8 #include <stdio.h>
  9 #include <unistd.h>
 10 #include <stdlib.h>
 11 #include <sys/stat.h>
 12 #include <fcntl.h>
 13 
 14 int main(int argc, char* argv[])
 15 {
 16     int i_fd = open("hello.txt", O_CREAT|O_APPEND|O_RDWR, 0666
); 17 18 if(i_fd < 0) 19 { 20 printf("open error!\n"); 21 return 0; 22 } 23 24 if(write(i_fd, "hello fd\n", 9) != 9) 25 { 26 printf("write fd error\n"); 27 28 } 29 30 int i_dup_fd = dup(i_fd); 31 if(i_dup_fd < 0) 32 { 33
printf("dup error!\n"); 34 return 0; 35 } 36 37 printf("i_dup_fd = %d \t i_fd = %d\n", i_dup_fd, i_fd); 38 close(i_fd); 39 40 char c_buffer[100]; 41 int n = 0; 42 while((n = read(STDIN_FILENO, c_buffer, 1000)) != 0) 43 { 44 if(write(i_dup_fd, c_buffer, n) != n) 45 { 46 printf("write dup fd error!\n"); 47 return 0; 48 } 49 } 50 return 0; 51 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

如上開啟一個檔案,我們先寫入檔案內容“hello fd”,然後將fd的描述符拷貝到dup_fd 的檔案描述符上,然後將標準輸入的內容寫入到dup_fd 的檔案中。 
執行程式如下: 
這裡寫圖片描述 
檢視檔案可以看到檔案內容如下: 
這裡寫圖片描述

  1. dup2 
    如下關於dup2的使用:
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <string.h>
 11 #include <unistd.h>
 12 #include <sys/stat.h>
 13 #include <fcntl.h>
 14 
 15 int main(int argc, char* argv[])
 16 {
 17     int i_fd = open("hello_dup2.txt", O_CREAT|O_APPEND|O_RDWR, 0666);
 18 
 19 
 20     if(i_fd < 0)
 21     {
 22         printf("open error!\n");
 23         return 0;
 24     }
 25 
 26     if(write(i_fd, "hello i_fd\n", 11) != 11)
 27     {
 28         printf("write dup2 error\n");
 29     }
 30 
 31 
 32     int i_dup2_fd = dup2(i_fd, STDOUT_FILENO);
 33 
 34     if(i_dup2_fd != STDOUT_FILENO)
 35     {
 36         printf("error dup2!\n");
 37         return 0;
 38     }
 39     close(i_fd);
 40 
 41     char c_buf[1024];
 42     int i_read_n = 0;
 43     while((i_read_n = read(STDIN_FILENO, c_buf, 1024)) != 0)
 44     {
 45         i_read_n = read(STDIN_FILENO, c_buf + i_read_n, sizeof(c_buf) - 1 - i_read_n);
 46 
 47         if(i_read_n < 0)
 48         {
 49             printf("read error!\n");
 50             return 0;
 51         }
 52 
 53         printf("%s", c_buf);
 54         fflush(stdout);
 55         sleep(1);
 56     }
 57     close(i_dup2_fd);
 58 
 59     return 0;
 60 
 61 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

如上,這裡沒有像使用dup的時候顯示的呼叫write函式將標準輸入的內容寫入到指定檔案中,而是將標準輸出重定向到指定檔案中,然後呼叫printf函式將標準輸出的內容重定向到指定檔案中。我們在寫簡單的日誌時就可以將printf的內容重定向到日誌中,使用printf作為寫日誌的介面。 
如上執行程式如下: 
這裡寫圖片描述

檢視hello_dup2.txt可以看到如下: 
這裡寫圖片描述


相關推薦

dupdup2用法

https://blog.csdn.net/u012058778/article/details/78705536一、dup和dup2函式 這兩個函式都可以來複制一個現有的檔案描述符,他們的宣告如下: #include <unistd.h> int dup(i

【APUE學習筆記】dupdup2用法

在瞭解dup用法之前,需要對linux的檔案節點有一個認識。 核心有3個數據結構來表示程序開啟的檔案,dup是系統提供的一個API可以直接操作這三個資料結構之間的關係。 (1)每個程序在程序表當中都有一個記錄項,記錄項中包含一張表格,記錄了所有當前程序開啟的檔案,可以將其想

mmap()ioremap()的用法與區別

12只 設備 gpa 我們 之間 mmap ioremap shared set 一、mmap()mmap()函數是用來將設備內存線性地址映射到用戶地址空間。(1)首先映射基地址,再通過偏移地址尋址;(2)unsigned char *map_cru_base=(unsig

Invoke BegionInvoke的用法

很多人對Invoke和BeginInvoke理解不深刻,不知道該怎麼應用,在這篇博文裡將詳細闡述Invoke和BeginInvoke的用法: 首先說下Invoke和BeginInvoke有兩種用法: 1.Control中Invoke,BeginInvoke 2.Delegate中Invokke,Begi

NaNundefined--------與君共勉

單詞 類型 賦值 使用 數值 數字類型 fin 類型轉換 bsp NaN不是一個數字,但卻是數字類型; undefined是聲明未賦值; typeof不能顯示NaN,因為NaN雖然不是number但是他的數據類型卻是number。 提示: 使用 isNaN() 來判斷一

【轉】Linux系統編程---dupdup2詳解

系統 強調 操作 attach bsp ads 正常的 註意 tdi 正常的文件描述符: 在linux下,通過open打開以文件後,會返回一個文件描述符,文件描述符會指向一個文件表,文件表中的節點指針會指向節點表。看下圖: 打開文件的內核數據結構 dup和dup2兩

HiveHBase區別

但是 hql 應該 hdf 目前 http 返回 最重要的 hadoop基礎 出處: http://www.cnblogs.com/zlslch/p/5659641.html . 兩者分別是什麽?   Apache Hive是一個構建在Hadoop基礎設施之上的數

FineBI學習系列之FineBITableau對比異同(從產品理念功能對比)(圖文詳解)

研究 簡單 nio 比較 管理 post 企業it 獨立 圖片   不多說,直接上 幹貨!   FineBI和Tableau是比較好的自助式商業智能軟件,功能都很強大,是企業數據可視化不可或缺的利器,但兩款產品還是有非常大的區別的

RHEL7RHEL6的主要變化

linux淺談RHEL7和RHEL6的主要變化RHEL7RHEL6文件系統XFSEXT4內核版本3.10.x-x系列2.6.x-x系列內核名稱MaipoSantiago發布時間2014-06-09(3.10.0-123)2010-11-09(2.6.32-71)進程名稱systemdinit運行級別runle

3A進程

linux3A安全認證服務: AAA 認證(Authentication)含義:1驗證(Authentication)用戶的身份與可使用的網絡服務;2授權(Authorization):依據認證結果開放網絡服務給用戶;3計帳(Accounting):記錄用戶對各種網絡服務的用量,並提供給計費系統。整個系統在網

Log4jLog4j2的區別

淺談Log4j和Log4j2的區別1、配置文件類型 log4j是通過一個.properties的文件作為主配置文件的,而現在的log4j 2則已經棄用了這種方式,采用的是.xml,.json或者.jsn這種方式來做,可能這也是技術發展的一個必然性,畢竟properties文件的可閱讀性真的是有點差。 2、核心

Jquery常用框架Vue變化

v-on items method NPU his new jquer ID 常用 區別 數據與視圖的分離 數據驅動視圖 Vue 簡單示例: <div id="example-1"> <input v-model="tit

thisstatic

當前 多個 技術 代碼 三種 ati 成員 聲明 語法 一.this關鍵字 一個比較經典的使用: 輸出的結果是:12 1.this關鍵字只能在方法的內部使用,表示對“調用方法的那個對象”的引用,this的用法和其他對象引用並無不同。註意一點:在方法的內部調用同一個類的其他

memcacheredis區別

寫到 應對 狀態 rdb lis lte 而在 mage 內存池 memcache和redis區別 memcach簡介 Memcache時一個內存對象緩存系統,用於加速動態web應用程序,減輕數據庫負載。它可以應對任意多個連接,使用非阻塞的網絡I/O,工作機制:在內存中開辟

查詢演算法 演算法資料結構: 七 二叉查詢樹 演算法資料結構: 十一 雜湊表

閱讀目錄 1. 順序查詢 2. 二分查詢 3. 插值查詢 4. 斐波那契查詢 5. 樹表查詢 6. 分塊查詢 7. 雜湊查詢   查詢是在大量的資訊中尋找一個特定的資訊元素,在計算機應用中,查詢是常用的基本運算,例如編譯程式中符號表的查詢。本文

演算法資料結構: 五 優先順序佇列與堆排序

在很多應用中,我們通常需要按照優先順序情況對待處理物件進行處理,比如首先處理優先順序最高的物件,然後處理次高的物件。最簡單的一個例子就是,在手機上玩遊戲的時候,如果有來電,那麼系統應該優先處理打進來的電話。 在這種情況下,我們的資料結構應該提供兩個最基本的操作,一個是返回最高優先

Python2Python3區別

1.首先編碼;   Python2 :   (1).預設編碼是ASCII碼型別,如果發現其他編碼非ASCII編碼是通常會報錯 UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in ran

static final

Static Static系統快取作用,只會初始化一次,無須多次new。 Static不能修飾區域性變數。 靜態變數被全域性物件共有,當且僅當類被初次載入時初始化,在記憶體中只有一個副本。 靜態方法無法呼叫非靜態的成員和方法。 Static 程式碼塊用於優化效能,把只需要初始化一次的程式碼放入sta

dupdup2函式的小理解

int dup(int fd); int dup2(int fd, int fd 2); dup的引數是一個檔案描述符,指向一個檔案(stdin,stdout等也是特殊的檔案)。返回的也是一個檔案描述符(當前還未被使用的最小的描述符編號),這個描述符和fd指向同一個檔案。也就