UNIX/Linux最偉大的技術是什麼?
本人學習linux不久,好奇有此一問,下面是本人覺得很屌的幾個概念
- 一切都是文件:
- IO重定向:
- 管道:連接各種程序的功能
不知有沒有高手為我解答一翻
在知乎問關於 Unix 文化的問題,最好先去讀《 The Art of UNIX Programming 》。如果你不是專吃快餐的,這本書寫的比這裡所有答案都全都有深度。看完了,細節我們可以討論。
Linux不偉大,他只是好用而已。
就像很多國家不偉大,只是其百姓的日子好過而已。你說的那些概念,都不是牛逼,而是樸實無華,是事物原本的樣子。
Linux 真正的優點是樸實,謙恭。它知道多少告訴你多少,它知道自己是僕人你是主人,不會替你思考替你做判斷替你做決策。UNIX is very simple, it just needs a genius to understand its simplicity. -- Dennis Ritchie
最偉大的技術。。。
我覺得是proc。。。。。。本來proc只是提供進程相關的信息和介面,但是內核通過這樣的方式來提供更多的東西,使得很多設計都得以簡化,堪稱是創舉了吧。。。當然devfs,sysfs,tmpfs什麼的腦洞也是大得很。其他內核確實也提供了很多不同的介面,但是linux這樣僅僅通過文件操作就可以獲得內核當前狀態和控制內核的運行,腦洞確實是不一般得大。
還有個腦洞叫做control groups,這是lxc所依賴的技術。
同樣大的腦洞還有kvm,什麼esx啊hv server啊,和這個相比,腦洞就缺在這個k字上了,當然這個k字本身可能並無卵用,而且大多數情況kvm還是配qemu的。。。但是腦洞大啊。netfilter,不用解釋的黑科技。
LSM,雖然大多數人似乎不需要這東西不過還是一個黑科技啊。
還有一個nohz_full特性,也是腦洞巨大的存在。我覺得不管是「一切都是文件」還是「一個工具只做好一件事」,其背後共通的邏輯就是「工程實踐大於理論完美」,或者說「解決問題先於完善架構」。
我們知道 UNIX 有很多缺陷。
首先就是 C 語言,天生缺乏類型系統,沒有安全的內存分配機制,指針導致 segfault 滿天飛。然而它簡單又高效,及時地滿足了內核開發的需求,有一些缺陷也無傷大雅。
其次是「一切皆文件」,或者說基於 raw byte stream 的程序間信息交換和信息存儲。缺點是沒有 metadata,沒有類型系統。然而它的普適性很強,只要程序間定好了協議,定好了文件格式,就可以做各種事情。這樣的設計可以快速地解決問題。而如果要設計一套類型系統,不花大量人力和時間是做不出來的。而且即使做出來了,也可能會存在滿足不了快速變化的需求的問題。比如要求所有 IPC 都使用同一套帶 metadata 的結構化的協議,可能並不適合所有情況,不同類型的服務用不同的協議才更有針對性,更高效。又比如用一套資料庫系統代替文件系統,可是有了新的文件類型怎麼辦?文件的 metadata 欄位不完善又怎麼辦?又比如用統一的配置系統代替每個程序各有各的語法各不相同的配置文件,又怎麼保證能滿足所有程序的配置需求?
要設計一套非常完美的系統是很難的,只有 M$ 這種級別的大公司才能做得出來。但即使是 M$ 也因為背著沉重的歷史包袱,無法完成這種宏大的工作。M$ 曾試圖把 Windows 設計成一套完美的架構,那就是當年的 Longhorn 計劃,可是到最後卻失敗了,留下了一套先進的 .NET Framework 和仍然必須不斷向後兼容的 Win32 API。這就好像 C++ 一樣,既要保持對 C 的兼容又要引進現代語言特性,最終變成了一個極其複雜的語言。這並不是說 Windows 或 C++ 不好,而是它們雖然好,卻又沒有做到完美,結果反而對使用者造成了困難。
而不管是 UNIX 還是 C,它們雖然簡陋,卻是完善的,這就足夠了。即使我們需要更複雜的東西,也可以在它們上面增加抽象層。對程序員來說,UNIX 的架構、層級是簡單的、清晰的。而至於後來 *nix 的上層架構發展沒有 Windows 那麼快,則是因為用戶數量始終上不來,因而也缺乏大公司的支持,我覺得這跟技術本身並沒有關係。
我個人認為,真正的新一代操作系統,應該具有以下特點:
具有系統級別的類型系統;具有系統級別的資源管理機制;所有數據交換都是帶有 metadata 的結構化數據;資料庫代替文件系統;
對開發者而言內存與硬碟之間是透明的,不再有變數和文件的區別,只有臨時數據和永久數據的區別;由於開發語言的特性以及系統的資源管理,很可能我們不再需要進程,只需要線程就夠了,因為語言本身不再可能產生 segfault。(這點有爭議)這究竟有沒有可能實現呢?我對此保留意見。現實世界是很複雜的,真的那麼容易做出抽象嗎?一個個人淺見,請各位輕噴。
無論是一切都是文件、管道還是別的什麼東西,*nix底下都有一樣是基礎的,就是所有程序都儘力遵循一個統一的規範來傳遞消息,這個規範就是「文本」。現在我們看會覺得很自然,但是這僅僅是因為這個開創性的設計已經成為了後來幾乎所有信息交換協議的基礎了,比如xml,比如json。但是最初的unix的設計者意識到了,只有所有程序都統一地選擇接受來自文本的輸入並且產生文本的輸出,才能組合各種各樣的目的單一的工具,來實現複雜的功能,這就是管道的基礎。unix底下所有的配置也都是以文本的方式存儲的,所以沒有註冊表這種奇怪的東西。可以說文本以最簡單的方式實現了一個操作系統內部溝通和與人交流的統一。舉一個例子,vim。據說早期的vim實際上完全是在利用ed進行文本編輯,也是通過管道傳遞命令。而如果你用過vim的導入其他文件的命令更能感受到這點。它可以很輕鬆地導入文件的內容或者其他應用程序的輸出。恰恰是因為對vim和其他任何一個unix程序而言,其他程序所產生的都是文本輸出,和文件是一樣的。真要說無可炫耀,是因為它們最偉大的技術,大家都學過去了,恰恰因為這些這些技術偉大。至於Windows,一個個程序都是圖形界面,對用戶來說很簡單,但要想組合起來就很蛋疼了,所以設計了COM這套東西。不過後來的Windows學了蠻多其他系統的好東西,比如到NT的時候就在API層面兼容了POSIX。Windows的優勢是它是微軟一家開發的,所以微軟可以獨立地決定Windows應該如何發展,就很容易從其他系統學習。我倒是很好奇 @vczh 說的 「Windows 內核」是 1985 年的 Windows 1.0x 呢,還是 1993 的 NT 呢?
順便管道的概念是道格拉斯·麥克羅伊發明,然後在 Unix 上實現,後來才被 Windows 學去的:「它的想法在1973年被實現,Ken Thompson將管道添加到了UNIX操作系統。這個點子最終被移植到了其他的操作系統,比如DOS、OS/2、Microsoft Windows和BeOS,而且常常使用相同的記號(垂直線)。」
——維基百科:管道 (Unix)
至於 Windows 里的一切皆文件和 IO 重定向,我懶得去查了,不過 UNIX 是 1971 年發布的,比 Windows 1.0x 早了 10 多年,誰先誰後就不用我說了吧
另外 Windows 的確有不少可以用來跟 *NIX 炫耀的呢,藍屏比 Kernel Panic 好看多了這些是古老的os中流傳下來的設計。
作為現在的開發者,了解這些設計的工作機制就可以了。更進一步,去理解嘗試當初的開發者為何會選擇這樣的設計方向(而放棄了其他可能的選擇),取捨之間他們當時是如何考慮的。
把這些來源久遠的設計選擇當作段子掛嘴邊毫無意義。比如說:
- ms powershell管道傳的是.net object,比parse raw text高多了
- 現今的基於http + json的RESTful,比起曾經的XML RPC風格怎麼樣?
- c++弄出來的那些classic design pattern,對大python來說很多是多餘的,so what? C++性能秒翻你,為了性能搞點複雜的pattern無所謂的,總比被一個大lock鎖住好
所以呢,看人家的設計最最要緊的是知道背景,理解做出設計決策的過程和思路。
最後加一句對問題的回答:unix裡面最nb的技術應該是和os結合非常緊密的的c語言了,其他的相對更加細枝末節一些。
linux成功算歷史的選擇吧。最偉大的技術是GPL,讓所有意圖霸佔它代碼的人都必須退步。
linux初期所有的概念在bsd 里都有了,而且當年bsd 比linux 高得可不是一星半點啊。它們之所以有現在這樣不同的命運,主要是它們個人的選擇決定的: BSD 對 GPL
linux 的發展離不開 反MS聯盟的支持,如果沒有微軟在當時如此強勢,就不會有java linux 今天的地位,而GPL 和BSD 的差異,導致了如果你不想給別人做嫁衣,重新培養一個微軟出來,那麼你必須選擇GPL,所以 Linux被 大家選中了。
所以linux的出現,挑了一個好時候,也挑了一個好協議。這個協議 讓所有的貪慾都止步了,這是它最偉大的地方。 而BSD協議,你今天的努力 隨時會變為別人的武器。真可惜啊
補充
根本不是這樣,雖然法律官司讓bsd暫停了3年,但是和linux還是不可同日而語。一個是精英寫的,一個只是一個玩具。但是反微軟聯盟不可能選擇bsd作為自己資助的對手。bsd協議導致可能有一家商業公司瞬間摘走勝利果實。比如apple的osx。人性的貪婪是無法抵禦的。bsd理想主義思想太濃了,導致一定會被拋棄。想想看沒有ibm redhat intel那些輸入,只靠一些志願者,linux怎麼可能快速反超bsd,並做出真正的os?
linux 這是一個理想主義加反微軟聯盟各懷鬼胎的一個妥協產物。現在已經成為一個怪獸,可以真正抗衡微軟的怪物。有段時間曾在linux上練習編程,雖然是淺嘗輒止,但是linux系統「一切皆文件」的哲學讓我印象非常深刻。
從編程的角度來看,linux系統中很多功能對象都實現了文件介面,都能用一個普通整數——文件描述符來標識,都可以看做是文件。這樣一來,很多能夠操作普通文件的函數都可以應用到這些對象上去,產生非常豐富有趣的效果。
並且這些實現了文件介面的功能對象很多時候都會關聯上文件系統中一個可見的虛擬文件,這使得普通用戶可以很方面的通過一些常用的、用於操作普通文件的命令行實用工具程序去直接訪問這些虛擬文件,從而不用編程就能很方面的使用一些系統功能,以及在應用程序進程之間通信。
舉兩個「一切皆文件」的實際例子:- proc文件系統就通過文件的方式向程序員和普通用戶提供了查詢甚至修改系統狀態的介面。
- 對於每個虛擬終端窗口中的shell進程,都有一個文件/dev/pts/&
被分配為其標準輸入、標準輸出和標準錯誤輸出。如果將一個窗口中shell進程的標準輸入重定向到另一個窗口中shell進程對應的文件/dev/pts/& 上,就會造成一種「在這個窗口中遙控另一個窗口執行命令」的有趣效果。
現在回想起來,「一切皆文件」是初嘗linux給我最大的驚喜之一。
但是隨著後來慢慢了解更多以後,開始發現「一切皆文件」本身並不是什麼過分偉大的思想,與之相似的也有很多,比如說windows裡面無處不在的句柄。而在面向對象的世界裡,「一切皆文件」就更加普通了,甚至還有不少缺點——因為這個介面太過於泛化了。我只想評論一下題目中說的管道,重點不是傳遞是組合。
Unix Philosophy裡面我認為最重要的是:每個程序只完成一個獨立的小功能,通過管道組合變強大。這個概念造就了和Windows最大的區別,也一樣有不少的麻煩。目標用戶不同而已,沒有優劣,但是(作為開發者)我更喜歡這種簡單而優美的理念,所以在自己做的項目中,盡量模仿和學習。開源
「一切皆是文件」
UNIX的歷史價值在於開創了一種最簡化設計(Minimal Design)但是又非常實用的操作系統風格,因此成為經典
遠沒有資格談論*nix「偉大」之處,但就*nix哲學拋磚引玉一下。個人感覺*nix哲學的核心是
- 純文本是數據的基本形式
為什麼這麼說?
- 因為*nix通過內置很多文本處理工具的方式來強調這一哲學,比如cat, grep, sed, awk, 等等等等。
- *nix的很多軟體甚至系統也都用文本的配置文件來配置,而不是二進位的註冊表。
這樣做有什麼好處?
- 可讀性:不僅電腦能看懂,人也能看懂
- 溝通性:不同程序之間有一個公用的協議 來溝通,大家說一樣的語言才能允許「每個人干好自己的事,用管道連起來就行了」這樣的工程實踐。
這樣做的壞處:主要是效率。parse文本其實還挺費時間的。。
擴展閱讀:The art of UNIX programming吐槽:RMS寫的Emacs真是高大全的代表,完全不符合大家干好自己的事,用管道連起來的*nix哲學。。不曉得他怎麼想的。。利益相關:軟狗UNIX編程藝術 -- By E.S. RaymondLinux/Unix設計思想 -- By Mike GancarzThe UNIX Hater"s Handbook -- By Simson L. Garfinkel
逃脫360騰訊百度以及微軟等流氓公司的魔掌
Everything (including hardware) is a file所有的事物(甚至硬體本身)都是一個的文件。 Configuration data stored in text以文本形式儲存配置數據。 Small, single-purpose program程序盡量朝向小而單一的目標設計 Avoid captive user interfaces盡量避免令人困惑的用戶介面 Ability to chain program together to perform complex tasks將幾個程序連結起來,處理大而複雜的工作。
Linux第一版也是一團漿糊而已
關鍵Linus把握住了歷史機遇現在即便再來一個一樣的系統,甚至更好的,也不可能得到這麼大範圍的使用了,因為生態系統沒建立起來要知道,Linux在2005年的時候,連wifi都驅動不了,這麼多年來,寫了多少配套的驅動!微軟投入了極其巨大的人力物力為各類硬體寫驅動程序能被稱得上偉大,只有頭頂的星空。http://web.mit.edu/~simsong/www/ugh.pdf
推薦閱讀:
※Linux上有哪些操作是原子操作?
※怎樣評價《無根的根:無名師的 Unix 心傳》?
※Linux 上有哪些工具軟體堪稱精美?
※有哪些在線 Linux 環境可以 ssh 登錄來玩?
※監控程序如何編寫單元測試?