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 :服務器
- <span style="font-size:18px">$cat test.txt
- just for test
- $cat test.txt >/dev/null
- $cat test.txt 1>/dev/null
- $cat test2.txt
- cat: test2.txt: 沒有那個文件或目錄
- $cat test2.txt >/dev/null
- cat: test2.txt: 沒有那個文件或目錄
- $cat test2.txt 2>/dev/null
- $
- </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 同樣的效果。
- <span style="font-size:18px">$cat test2.txt 2>/dev/null
- $cat test.txt 2>/dev/null >/dev/null
- $echo $?
- 0
- $cat test2.txt 2>/dev/null >/dev/null
- $echo $?
- 1
- $cat test.txt &>/dev/null
- $echo $?
- 0
- </span>
有時候,咱們須要刪除一些文件的內容而不刪除文件自己:(這個方法能夠用來刪除日誌文件,在個人Debian筆記本上我給 /var 盤配的空間有些太小,有時候就須要手動使用這個操做來清空日誌)
# cat /dev/null > /var/log/messages
# : > /var/log/messages 有一樣的效果,但不會產生新的進程。(由於:是內建的)
下面的實例中,使用/dev/null 來刪除cookie 而且再也不使用cookie
- <span style="font-size:18px"> if [ -f ~/.netscape/cookies ] # 若是存在則刪除,刪除後才能夠添加軟連接
- then
- rm -f ~/.netscape/cookies
- fi
-
- 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建立一個交換臨時文件
- <span style="font-size:18px">#!/bin/bash
- # 建立一個交換文件,參數爲建立的塊數量(不帶參數則爲默認),一塊爲1024B(1K)
-
- ROOT_UID=0 # Root 用戶的 $UID 是 0.
- E_WRONG_USER=65 # 不是 root?
-
- FILE=/swap
- BLOCKSIZE=1024
- MINBLOCKS=40
- SUCCESS=0
-
- # 這個腳本必須用root來運行,若是不是root做出提示並退出
- if [ "$UID" -ne "$ROOT_UID" ]
- then
- echo; echo "You must be root to run this script."; echo
- exit $E_WRONG_USER
- fi
-
-
- blocks=${1:-$MINBLOCKS} # 若是命令行沒有指定,則設置爲默認的40塊.
- # 上面這句等同如:
- # --------------------------------------------------
- # if [ -n "$1" ]
- # then
- # blocks=$1
- # else
- # blocks=$MINBLOCKS
- # fi
- # --------------------------------------------------
-
- if [ "$blocks" -lt $MINBLOCKS ]
- then
- blocks=$MINBLOCKS # 最少要有 40 個塊長,若是帶入參數比40小,將塊數仍設置成40
- fi
-
- echo "Creating swap file of size $blocks blocks (KB)."
- dd if=/dev/zero of=$FILE bs=$BLOCKSIZE count=$blocks # 把零寫入文件.
-
- mkswap $FILE $blocks # 將此文件建爲交換文件(或稱交換分區).
- swapon $FILE # 激活交換文件.
-
- echo "Swap file created and activated."
- exit $SUCCESS
- </span>
運行效果咱們能夠看到:
- <span style="font-size:18px">long@Raring:/tmp$ vim testswap.sh
- long@Raring:/tmp$ chmod +x testswap.sh
- long@Raring:/tmp$ sudo ./testswap.sh
- [sudo] password for long:
- long@Raring:/tmp$ ./testswap.sh
-
- You must be root to run this script.
-
- long@Raring:/tmp$ sudo ./testswap.sh
- [sudo] password for long:
- Creating swap file of size 40 blocks (KB).
- 記錄了40+0 的讀入
- 記錄了40+0 的寫出
- 40960字節(41 kB)已複製,0.000904021 秒,45.3 MB/秒
- 正在設置交換空間版本 1,大小 = 36 KiB
- 無標籤, UUID=3e59eddf-098f-454d-9507-aba55f434a8c
- Swap file created and activated.
- </span>
關於 /dev/zero 的另外一個應用是爲特定的目的而用零去填充一個指定大小的文件,如掛載一個文件系統到環回設備 (loopback device) 或"安全地" 刪除一個文件。
腳本實例2. 建立ramdisk
- <span style="font-size:18px">#!/bin/bash
- # ramdisk.sh
-
- # "ramdisk"是系統RAM內存的一段,它能夠被當成是一個文件系統來操做.
- # 優勢:存取速度很是快 (包括讀和寫).
- # 缺點: 易失性, 當計算機重啓或關機時會丟失數據.
- # 會減小系統可用的RAM.
- #
- # 那麼ramdisk有什麼做用呢?
- # 保存一個較大的數據集在ramdisk, 好比一張表或字典,這樣能夠加速數據查詢, 由於在內存裏查找比在磁盤裏查找快得多.
-
- E_NON_ROOT_USER=70 # 必須用root來運行.
- ROOTUSER_NAME=root
-
- MOUNTPT=/mnt/ramdisk
- SIZE=2000 # 2K 個塊 (能夠合適的作修改)
- BLOCKSIZE=1024 # 每塊有1K (1024 byte) 的大小
- DEVICE=/dev/ram0 # 第一個 ram 設備
-
- username=`id -nu`
- if [ "$username" != "$ROOTUSER_NAME" ]
- then
- echo "Must be root to run ""`basename $0`""."
- exit $E_NON_ROOT_USER
- fi
-
- if [ ! -d "$MOUNTPT" ] # 測試掛載點是否已經存在了,
- then #+ 若是這個腳本已經運行了好幾回了就不會再建這個目錄了
- mkdir $MOUNTPT #+ 由於前面已經創建了.
- fi
-
- dd if=/dev/zero of=$DEVICE count=$SIZE bs=$BLOCKSIZE # 把RAM設備的內容用零填充.
- # 爲什麼須要這麼作?
- mke2fs $DEVICE # 在RAM設備上建立一個ext2文件系統.
- mount $DEVICE $MOUNTPT # 掛載設備.
- chmod 777 $MOUNTPT # 使普通用戶也能夠存取這個ramdisk,可是, 只能由root來缷載它.
-
- echo """$MOUNTPT"" now available for use."
- # 如今 ramdisk 即便普通用戶也能夠用來存取文件了.
- # 注意, ramdisk是易失的, 因此當計算機系統重啓或關機時ramdisk裏的內容會消失.
- #
- # 重啓以後, 運行這個腳本再次創建起一個 ramdisk.
- # 僅從新加載 /mnt/ramdisk 而沒有其餘的步驟將不會正確工做.
-
- # 若是加以改進, 這個腳本能夠放在 /etc/rc.d/rc.local,以使系統啓動時能自動設立一個ramdisk。這樣很合適速度要求高的數據庫服務器.
- exit 0
- </span>
運行起來效果以下:
- <span style="font-size:18px">long@Raring:/tmp$ vim ramdisk.sh
- long@Raring:/tmp$ chmod +x ramdisk.sh
- long@Raring:/tmp$ ./ramdisk.sh
- Must be root to run ramdisk.sh.
- long@Raring:/tmp$ sudo ./ramdisk.sh
- 記錄了2000+0 的讀入
- 記錄了2000+0 的寫出
- 2048000字節(2.0 MB)已複製,0.0113732 秒,180 MB/秒
- mke2fs 1.42.8 (20-Jun-2013)
- Discarding device blocks: 完成
- 文件系統標籤=
- OS type: Linux
- 塊大小=1024 (log=0)
- 分塊大小=1024 (log=0)
- Stride=0 blocks, Stripe width=0 blocks
- 16384 inodes, 65536 blocks
- 3276 blocks (5.00%) reserved for the super user
- 第一個數據塊=1
- Maximum filesystem blocks=67108864
- 8 block groups
- 8192 blocks per group, 8192 fragments per group
- 2048 inodes per group
- Superblock backups stored on blocks:
- 8193, 24577, 40961, 57345
-
- Allocating group tables: 完成
- 正在寫入inode表: 完成
- Writing superblocks and filesystem accounting information: 完成
-
- /mnt/ramdisk now available for use.</span>
最後值得一提的是,ELF二進制文件利用了/dev/zero。