【前言】
寫這篇文章的原因,是因為我在工作中遇到重定向和fd的時候,被這廝折磨的夠嗆?,F(xiàn)在終于戰(zhàn)勝了他們,當然要奏一首凱歌,率土同慶啦!
在開啟正文之前,我們必須要先明白幾個關鍵點,這對于理解后面的文章頗有幫助。而且,在閱讀后面的文章時,我們也會加深對這些關鍵點的理解。
首先,我們要知道在linux中,一切皆文件。其實,在linux中不僅我們創(chuàng)建的txt,tar,sh是文件,其他的東西比如:目錄,設備(字符設備,塊設備),進程,線程,套接字,管道都是文件。我們所熟知的鍵盤和顯示器屬于字符設備,所以在linux中,鍵盤和顯示器也是文件。
第二,我們和計算機的交互,本質(zhì)上就是輸入和輸出。我們通過輸入命令告訴計算機要做哪些事情,然后計算機處理后,會通過打印在屏幕或者輸出文件的方式來告訴我們,它輸出了什么。所以,有了第一條關鍵點之后,我們不難理解,linux上所有命令的處理其實可以簡化為輸入文件 -> 命令 -> 輸出文件的形式。比如 ls,它的默認輸出文件其實就是屏幕。
第三,還有一個難啃的骨頭,它叫文件描述符fd(file descriptor)。fd有很多俗稱,有人叫它文件句柄,也有人叫它文件引用,甚至還有人叫它通道。我覺得都可以,其實fd本身不是文件,而是一個符號,它可以指向某個文件。由此看來,我們可以把上面的形式升級為[文件描述符]輸入文件->命令->[文件描述符]輸出文件的形式。而實際的情況,也大抵如此。
好了,啰里啰嗦了這么多,觀眾老爺們該不高興了,我們趕緊進入正文吧!
【正文】
1. linux標準
實際上,linux已經(jīng)規(guī)定好了一些fd的用處。如下:
| fd | 縮寫 | 描述 | 默認指向文件 |
|---|---|---|---|
| 0 | stdin | 標準輸入 | 鍵盤 |
| 1 | stdout | 標準輸出 | 屏幕 |
| 2 | stderr | 標準錯誤輸出 | 屏幕 |
在linux中,有一個exec命令可以改變文件描述符所指向的文件。我們可以嘗試一下,把標準輸出fd1指向的文件從屏幕文件改成一個普通文件,看看會有什么效果。
exec 1>1.txt
ls
執(zhí)行完上面的命令,我們會發(fā)現(xiàn)ls并沒有打印在屏幕上,這時候我們再打開一個終端,打開1.txt文件。是不是會出現(xiàn)剛才ls的內(nèi)容呢?
順便提一下一個知識點,有的時候我們會看到這樣的命令
exec 6<>1.txt
實際上這條命令不僅是讓fd6指向1.txt,而且還以讀寫的方式打開了1.txt文件。>表示只寫,<表示只讀,<>表示讀寫。
2. 重定向
關于重定向的話,我們主要理解> < >> << 就行。其中,<和<<屬于輸入重定向,>和>>屬于輸出重定向。
那我們?nèi)绾卫斫庵囟ㄏ蚰??基于我們總結(jié)的關鍵點[文件描述符]輸入文件->命令->[文件描述符]輸出文件,改變方向其實就是改變文件描述符(fd)所指向的文件。
我們來看一個常見的例子:
echo "xiaoma" > 1.txt
本來正常情況下echo后面的字符串是會打印到屏幕上,但是現(xiàn)在這些字符串跑到了1.txt文件中,這就是重定向。
現(xiàn)在我們來仔細分析一下這個過程,echo命令的輸出本來是標準輸出,也就是fd1(默認指向屏幕文件),后來經(jīng)過重定向,fd1就指向了1.txt文件??赡艽蠹視幸苫螅以趺礇]看到fd1從屏幕文件重定向到了1.txt。這是因為> 1.txt 就等于 1> 1.txt,fd1作為標準輸出可以省略不寫。不信大家可以試一下,肯定是一樣的效果:
echo "xiaoma" 1> 1.txt #注意1和>之間不能有空格,但是>和1.txt之間可以有
與它一樣的還有標準輸入0,當0在<左邊的時候也是可以省略不寫。
3. &的作用
有的時候,我們會看到這樣的命令
exec 3<>1.txt
echo "xiaoma" >&3
這里第一句話我們應該明白,就是讓fd3指向1.txt。對于后面一句話,他其實是把fd1重定向到了fd3,也就是最終fd1實際上指向了1.txt文件。
可能我們會有疑惑,為什么1不加&,而3要加&。實際上,這就是規(guī)定,在重定向符號左邊不用加&,數(shù)字表示的就是fd,但是重定向符號右邊如果不加&,3就變成了一個文件,而不再是fd3。你可以試試不加&,看看"xiaoma"是不是輸出到了一個名叫3的文件中。
4. 1>/dev/null
我們應該會經(jīng)??吹竭@樣的命令吧,
echo "xiaoma" 1>/dev/null 2>&1
如果大家是從上往下讀這篇文章,想必已經(jīng)知道了答案。如果跳著讀,可能就不清楚了。其實/dev/null,表示空設備文件,它會丟棄一切寫入它的文件。這句話的意思是說,我把fd1指向/dev/null,然后我再把fd2指向fd1,最終fd2也就指向了/dev/null。作用不言而喻:所有的輸出,不管是標準輸出還是錯誤輸出,我都不要啦。
【后記】
看到這,我相信觀眾老爺們對重定向和文件描述符有一個新的了解了吧。如果有的話,我當然幸甚樂哉。如果沒看懂的話,觀眾老爺們也可以隨時來騷擾,我當盡我所能。
最后,觀眾老爺們?nèi)绻吹倪€開心的話,臨走時不妨點個贊,點個關注,小弟在此多謝各位。