ZZ:Linux 下的兩個特殊的文件 -- /dev/null 和 /dev/zero 簡介及對比

http://blog.csdn.net/pi9nc/article/details/18257593node

 

 

一、概論 -- 來自維基的解釋

/dev/null  : 在類Unix系統中,/dev/null,或稱空設備,是一個特殊的設備文件,它丟棄一切寫入其中的數據(但報告寫入操做成功),讀取它則會當即獲得一個EOF。
在程序員行話,尤爲是Unix行話中,/dev/null 被稱爲位桶(bit bucket)或者黑洞(black hole)。空設備一般被用於丟棄不須要的輸出流,或做爲用於輸入流的空文件。這些操做一般由重定向完成。


程序員

/dev/zero  : 在類UNIX 操做系統中, /dev/zero 是一個特殊的文件,當你讀它的時候,它會提供無限的空字符(NULL, ASCII NUL, 0x00)。shell

其中的一個典型用法是用它提供的字符流來覆蓋信息,另外一個常見用法是產生一個特定大小的空白文件。BSD就是經過mmap把/dev/zero映射到虛地址空間實現共享內存的。可使用mmap將/dev/zero映射到一個虛擬的內存空間,這個操做的效果等同於使用一段匿名的內存(沒有和任何文件相關)。數據庫

 

二、 /dev/null 的平常使用

把/dev/null看做"黑洞"。它等價於一個只寫文件,而且全部寫入它的內容都會永遠丟失,而嘗試從它那兒讀取內容則什麼也讀不到。然而, /dev/null對命令行和腳本都很是的有用。

咱們都知道  cat $filename  會輸出filename對應的文件內容(輸出到標準輸出)
而使用         cat $filename >/dev/null 則不會獲得任何信息,由於咱們將原本該經過標準輸出顯示的文件信息重定向到了 /dev/null 中,so what will you get ?
使用  cat $filename 1>/dev/null 也會獲得一樣的效果,由於默認重定向的 1 就是標準輸出。  若是你對 shell 腳本或者重定向比較熟悉的話,應該會聯想到 2 ,也即標準錯誤輸出。vim

咱們使用 cat $filename  時若是filename對應的文件不存在,系統確定會報錯: 「 cat: filename: 沒有那個文件或目錄 」 。安全

若是咱們不想看到錯誤輸出呢?咱們能夠禁止標準錯誤:   cat $badname 2>/dev/nullbash

咱們能夠經過下面這個測試來更加深入的理解/dev/null :服務器

[plain]  view plain copy
 
 
  1. <span style="font-size:18px">$cat test.txt   
  2. just for test  
  3. $cat test.txt >/dev/null   
  4. $cat test.txt 1>/dev/null   
  5. $cat test2.txt   
  6. cat: test2.txt: 沒有那個文件或目錄  
  7. $cat test2.txt >/dev/null   
  8. cat: test2.txt: 沒有那個文件或目錄  
  9. $cat test2.txt 2>/dev/null   
  10. $  
  11. </span>  

 

有些時候,我並不想看道任何輸出,我只想看到這條命令運行是否是正常,那麼咱們能夠同時禁止標準輸出和標準錯誤的輸出:    cookie

       cat $filename 2>/dev/null >/dev/nullide

因此:

* 若是"$filename"不存在,將不會有任何錯誤信息提示,

* 若是"$filename"存在, 文件的內容不會打印到標準輸出。

* 所以, 上面的代碼根本不會輸出任何信息,當只想測試命令的退出碼而不想有任何輸出時很是有用。

 

下一步,咱們使用 echo $? 查看上條命令的退出碼:0爲命令正常執行,1-255爲有出錯。

固然,使用   cat $filename &>/dev/null   也能夠達到  cat $filename 2>/dev/null >/dev/null 同樣的效果。

 

[plain]  view plain copy
 
 
  1. <span style="font-size:18px">$cat test2.txt 2>/dev/null   
  2. $cat test.txt 2>/dev/null >/dev/null   
  3. $echo $?  
  4. 0  
  5. $cat test2.txt 2>/dev/null >/dev/null   
  6. $echo $?  
  7. 1  
  8. $cat test.txt &>/dev/null  
  9. $echo $?  
  10. 0  
  11. </span>  



 

有時候,咱們須要刪除一些文件的內容而不刪除文件自己:(這個方法能夠用來刪除日誌文件,在個人Debian筆記本上我給 /var 盤配的空間有些太小,有時候就須要手動使用這個操做來清空日誌)    

 # cat /dev/null > /var/log/messages
 # : > /var/log/messages   有一樣的效果,但不會產生新的進程。(由於:是內建的)

 

 
下面的實例中,使用/dev/null 來刪除cookie 而且再也不使用cookie

[plain]  view plain copy
 
 
  1. <span style="font-size:18px">    if [ -f ~/.netscape/cookies ]       # 若是存在則刪除,刪除後才能夠添加軟連接  
  2.      then  
  3.        rm -f ~/.netscape/cookies  
  4.      fi  
  5.        
  6.      ln -s /dev/null ~/.netscape/cookies     </span>  


其中,cookies的目錄是能夠變換的,好比說我本身電腦上的firefox的cookie目錄爲: ~/.mozilla/firefox/nah4b6di.default/cookies*

三、/dev/zero 的平常使用

像/dev/null同樣,/dev/zero也是一個僞文件,但它實際上產生接二連三的null的流(二進制的零流,而不是ASCII型的)。寫入它的輸出會丟失不見,/dev/zero主要的用處是用來建立一個指定長度用於初始化的空文件,像臨時交換文件。

好比說,在個人前一篇博客中(《嘗試安裝Chrome OS的新版本 Vanilla & 安裝以後U盤遇到的問題解決》),提到我使用dd 製做的U盤系統,而個人U盤有16G,而製做好後,系統盤只佔了2.5G,而其餘的空間(將近12G)都無發使用。我只能使用  dd if=/dev/zero of=/dev/sdb bs=4M 來從新給我整個U盤清零。

腳本實例 1. 用/dev/zero建立一個交換臨時文件

[plain]  view plain copy
 
 
  1. <span style="font-size:18px">#!/bin/bash  
  2. # 建立一個交換文件,參數爲建立的塊數量(不帶參數則爲默認),一塊爲1024B(1K)  
  3.   
  4. ROOT_UID=0         # Root 用戶的 $UID 是 0.  
  5. E_WRONG_USER=65    # 不是 root?  
  6.   
  7. FILE=/swap  
  8. BLOCKSIZE=1024  
  9. MINBLOCKS=40  
  10. SUCCESS=0  
  11.   
  12. # 這個腳本必須用root來運行,若是不是root做出提示並退出  
  13. if [ "$UID" -ne "$ROOT_UID" ]  
  14. then  
  15.   echo; echo "You must be root to run this script."; echo  
  16.   exit $E_WRONG_USER  
  17. fi   
  18.     
  19.   
  20. blocks=${1:-$MINBLOCKS}          # 若是命令行沒有指定,則設置爲默認的40塊.  
  21. # 上面這句等同如:  
  22. # --------------------------------------------------  
  23. # if [ -n "$1" ]  
  24. # then  
  25. #   blocks=$1  
  26. # else  
  27. #   blocks=$MINBLOCKS  
  28. # fi  
  29. # --------------------------------------------------  
  30.   
  31. if [ "$blocks" -lt $MINBLOCKS ]  
  32. then  
  33.   blocks=$MINBLOCKS              # 最少要有 40 個塊長,若是帶入參數比40小,將塊數仍設置成40  
  34. fi   
  35.   
  36. echo "Creating swap file of size $blocks blocks (KB)."  
  37. dd if=/dev/zero of=$FILE bs=$BLOCKSIZE count=$blocks # 把零寫入文件.  
  38.   
  39. mkswap $FILE $blocks             # 將此文件建爲交換文件(或稱交換分區).  
  40. swapon $FILE                     # 激活交換文件.  
  41.   
  42. echo "Swap file created and activated."  
  43. exit $SUCCESS  
  44. </span>  

 

運行效果咱們能夠看到: 

 

[plain]  view plain copy
 
 
  1. <span style="font-size:18px">long@Raring:/tmp$ vim testswap.sh  
  2. long@Raring:/tmp$ chmod +x testswap.sh             
  3. long@Raring:/tmp$ sudo ./testswap.sh             
  4. [sudo] password for long:    
  5. long@Raring:/tmp$ ./testswap.sh             
  6.   
  7. You must be root to run this script.  
  8.   
  9. long@Raring:/tmp$ sudo ./testswap.sh             
  10. [sudo] password for long:       
  11. Creating swap file of size 40 blocks (KB).  
  12. 記錄了40+0 的讀入  
  13. 記錄了40+0 的寫出  
  14. 40960字節(41 kB)已複製,0.000904021 秒,45.3 MB/秒  
  15. 正在設置交換空間版本 1,大小 = 36 KiB  
  16. 無標籤, UUID=3e59eddf-098f-454d-9507-aba55f434a8c  
  17. Swap file created and activated.  
  18. </span>  

 


關於 /dev/zero 的另外一個應用是爲特定的目的而用零去填充一個指定大小的文件,如掛載一個文件系統到環回設備 (loopback device) 或"安全地" 刪除一個文件。
腳本實例2. 建立ramdisk

[plain]  view plain copy
 
 
  1. <span style="font-size:18px">#!/bin/bash  
  2. # ramdisk.sh  
  3.   
  4. # "ramdisk"是系統RAM內存的一段,它能夠被當成是一個文件系統來操做.  
  5. # 優勢:存取速度很是快 (包括讀和寫).  
  6. # 缺點: 易失性, 當計算機重啓或關機時會丟失數據.  
  7. #       會減小系統可用的RAM.  
  8. #  
  9. # 那麼ramdisk有什麼做用呢?  
  10. # 保存一個較大的數據集在ramdisk, 好比一張表或字典,這樣能夠加速數據查詢, 由於在內存裏查找比在磁盤裏查找快得多.  
  11.   
  12. E_NON_ROOT_USER=70             # 必須用root來運行.  
  13. ROOTUSER_NAME=root  
  14.   
  15. MOUNTPT=/mnt/ramdisk  
  16. SIZE=2000                      # 2K 個塊 (能夠合適的作修改)  
  17. BLOCKSIZE=1024                 # 每塊有1K (1024 byte) 的大小  
  18. DEVICE=/dev/ram0               # 第一個 ram 設備  
  19.   
  20. username=`id -nu`  
  21. if [ "$username" != "$ROOTUSER_NAME" ]  
  22. then  
  23.   echo "Must be root to run ""`basename $0`""."  
  24.   exit $E_NON_ROOT_USER  
  25. fi  
  26.   
  27. if [ ! -d "$MOUNTPT" ]         # 測試掛載點是否已經存在了,  
  28. then                           #+ 若是這個腳本已經運行了好幾回了就不會再建這個目錄了  
  29.   mkdir $MOUNTPT               #+ 由於前面已經創建了.  
  30. fi  
  31.   
  32. dd if=/dev/zero of=$DEVICE count=$SIZE bs=$BLOCKSIZE # 把RAM設備的內容用零填充.  
  33.                                                       # 爲什麼須要這麼作?  
  34. mke2fs $DEVICE                 # 在RAM設備上建立一個ext2文件系統.  
  35. mount $DEVICE $MOUNTPT         # 掛載設備.  
  36. chmod 777 $MOUNTPT             # 使普通用戶也能夠存取這個ramdisk,可是, 只能由root來缷載它.  
  37.   
  38. echo """$MOUNTPT"" now available for use."  
  39. # 如今 ramdisk 即便普通用戶也能夠用來存取文件了.  
  40. # 注意, ramdisk是易失的, 因此當計算機系統重啓或關機時ramdisk裏的內容會消失.  
  41. #  
  42. # 重啓以後, 運行這個腳本再次創建起一個 ramdisk.  
  43. # 僅從新加載 /mnt/ramdisk 而沒有其餘的步驟將不會正確工做.  
  44.   
  45. # 若是加以改進, 這個腳本能夠放在 /etc/rc.d/rc.local,以使系統啓動時能自動設立一個ramdisk。這樣很合適速度要求高的數據庫服務器.  
  46. exit 0  
  47. </span>  

運行起來效果以下:

 

[plain]  view plain copy
 
 
  1. <span style="font-size:18px">long@Raring:/tmp$ vim ramdisk.sh  
  2. long@Raring:/tmp$ chmod +x ramdisk.sh  
  3. long@Raring:/tmp$ ./ramdisk.sh  
  4. Must be root to run ramdisk.sh.  
  5. long@Raring:/tmp$ sudo ./ramdisk.sh  
  6. 記錄了2000+0 的讀入  
  7. 記錄了2000+0 的寫出  
  8. 2048000字節(2.0 MB)已複製,0.0113732 秒,180 MB/秒  
  9. mke2fs 1.42.8 (20-Jun-2013)  
  10. Discarding device blocks: 完成  
  11. 文件系統標籤=  
  12. OS type: Linux  
  13. 塊大小=1024 (log=0)  
  14. 分塊大小=1024 (log=0)  
  15. Stride=0 blocks, Stripe width=0 blocks  
  16. 16384 inodes, 65536 blocks  
  17. 3276 blocks (5.00%) reserved for the super user  
  18. 第一個數據塊=1  
  19. Maximum filesystem blocks=67108864  
  20. 8 block groups  
  21. 8192 blocks per group, 8192 fragments per group  
  22. 2048 inodes per group  
  23. Superblock backups stored on blocks:  
  24.     8193, 24577, 40961, 57345  
  25.   
  26. Allocating group tables: 完成  
  27. 正在寫入inode表: 完成  
  28. Writing superblocks and filesystem accounting information: 完成  
  29.   
  30. /mnt/ramdisk now available for use.</span>  



 

最後值得一提的是,ELF二進制文件利用了/dev/zero。

相關文章
相關標籤/搜索