NodeOS:基於 JavaScript 的操作系統
已發表: 2022-03-11我相信大多數程序員都聽說過 Node.js,但是 NodeOS 呢? 是的,NodeOS,一個用 Node.js 編寫的操作系統。 嗯,有點。 NodeOS 將 Linux 內核用於大多數性能關鍵的事情,例如硬件交互,但對於其他所有事情,它都使用 Node.js。 NodeOS 的開發始於兩年前,由一群共享一個簡單但有趣的想法的人創建: “是否可以僅使用 Node.js 創建操作系統?”
有什麼大不了的?
首先,想想 Node.js 在它出現的短時間內所取得的進步。 現在,想想操作系統發生的同樣的事情。 然後,讓我們添加一些很酷的東西。
每個用戶獨立和隔離的根文件系統
NodeOS 引入了一個有趣的範例:如果所有用戶都有一個獨立的文件系統,它會給他們一個簡單的文件系統層次結構來使用。 由於他們的“主文件夾”實際上是他們自己的文件系統層次結構的根目錄,因此他們可以在不需要特殊權限的情況下全局安裝包,也不需要配置任何東西,因為它們默認安裝在他們的主目錄中。 此外,它還提供了很好的安全性; 如果黑客找到了進入操作系統中特定帳戶的方法,那麼他/她可以訪問的唯一分區就是該用戶的分區。 最終結果是黑客無法破壞整個系統。
Node.js 和 NPM
如果您考慮一下,使用 Node.js 的操作系統意味著 NPM 中可用的任何包同時也是 NodeOS 包。 在撰寫本文時,有 210,735 個包; 由於 NPM 包的數量每分鐘都在增長,如果幾年後 NodeOS 擁有一百萬個應用程序也就不足為奇了。
它基於Linux內核
這似乎沒什麼大不了的,但 Linux 是最常用的服務器操作系統。 由於 NodeOS 基於 Linux 內核,您可以運行為其他 Linux 發行版編寫的每個應用程序,只需進行極少的更改。
缺點
儘管我想要一個完整的 NodeOS,但它還沒有。 它仍然缺少服務器操作系統的許多關鍵功能。 例如,缺少整個 BASH 工具集,包括 ps、tail、nano 和 grep。 此外,您不能將其作為桌面操作系統運行,因為它沒有 GUI。 當然,您可以使用一些 JavaScript 相當輕鬆地實現一些缺失的功能,但事實上所有提到的功能在默認情況下都不可用,這並不好。
那麼,我該如何試用 NodeOS?
使用 Docker
試用 NodeOS 最簡單快捷的方法是使用以下方法:
- 一台裝有 Mac OSX 或 Linux 的計算機。 它可能適用於 Windows,但我沒有嘗試過。
- 碼頭工人。
安裝 Docker 後,運行 NodeOS 實例就很容易了。 您需要做的就是執行以下命令,Docker 會做所有的事情:
sudo docker run -t -i nodeos/nodeos
當您運行上述命令時,Docker 會自動從存儲庫下載 NodeOS 的磁盤映像,並在虛擬機中執行 NodeOS 的安裝。 安裝完成後,它會打開一個到 NodeOS shell 的 SSH 會話。
沒有碼頭工人
有一些原因可以避免使用 Docker,其中一個是最新的 NodeOS 版本。 在撰寫本文時,NodeOS 的 Docker 映像的最後一次更改是在兩個月前進行的,而開發版本是在六天前更新的。 因此,如果您想使用最新版本,您絕對應該獲取源代碼。 這不是太難,但需要很長時間。 你會需要:
- 一台裝有 Linux 的計算機。 你可以在 OS X 上編譯它,但它需要更長的時間,因為它必須進行交叉編譯。 Windows 也是如此。
- Linux 構建實用程序(make、g++、gcc、autoconf)。
- 奇木。
- 時間。 說真的,很多。
一旦你擁有了一切,你可以繼續進行源代碼編譯:
- 下載項目源代碼:
bash git clone [email protected]:NodeOS/NodeOS.git
。 - 通過運行以下命令編譯它:
cd NodeOS
和npm install
。 - 我將逐字引用官方文檔: “挑選一些微波爆米花去看電影。 不,真的,去做吧。” . 是的,這需要很多時間,所以在此期間做一些有趣的事情。
- 運行
bash npm start
在 Qemu 中運行 NodeOS。
它在工作嗎?
安裝完成後,我們可以通過在 NodeOS shell 中執行命令ls
來檢查它是否正常工作。 應該出現這樣的輸出:
[ 'etc', 'lib', 'lib64', 'root', 'bin', 'sys', 'usr', 'share', 'proc' ]
如果是這樣,則意味著一些基本命令正在運行。 但是,如果我們想顯示網卡的 IP 地址呢? 在 Linux 下,有一個名為ifconfig
的命令可以做到這一點。 讓我們嘗試一下:
command not found: ifconfig
似乎缺少ifconfig
命令。 那是因為 NodeOS 沒有默認的ifconfig
命令。 怎麼辦? 嗯,很簡單; NodeOS 有一個集成的包管理器(如apt
或yum
),稱為npkg
,它基於 Node 的 NPM 並且易於使用。 安裝ifconfig
就像運行以下命令一樣簡單:
npkg install bin-ifconfig
如果一切順利,命令ifconfig
現在應該在 shell 中可用。 如果我們再次嘗試執行它,就會出現這樣的輸出(出於顯而易見的原因,我放了一個隨機的 MAC 地址和 IP 地址):
eth0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 ether 01:23:45:67:89:ab inet6 f0cd::ef01:0203:0405:181%en1 prefixlen 64 scopeid 0x5 inet 192.168.0.21 netmask 0xffffff00 broadcast 192.168.0.21 nd6 options=1<PERFORMNUD> media: autoselect status: active
如果您的輸出看起來像那樣,那麼它正在工作。 您已經成功安裝了您的第一個 NodeOS 應用程序: ifconfig
。
這是工作。 但是,我們現在如何處理操作系統?
如果您可以在 Ubuntu 或任何其他 Linux 發行版上做同樣的事情(甚至更少的事情),那麼擁有一個用 Node.js 編寫的操作系統有什麼意義呢? 嗯,重點是一切都是通過使用 Node.js 開發的。 這也意味著我們可以只使用 Node.js 來開發我們的應用程序。 例如,NodeOS 沒有命令man
的默認實現,該命令在 Linux 上用於顯示其他命令的手冊頁。 不要害怕,實現它很容易。 怎麼樣,我聽到你問了? 簡單的。
首先,讓我們安裝一個名為 Hipster 的文本編輯器,這樣我們就可以通過執行以下命令來創建和編輯文件: npm install -g [email protected]
。 這個文件編輯器很簡單,絕對不是我會用作其他任何東西的編輯器,但在這種情況下它已經足夠好了。 使用 Hipster 創建文件非常簡單,只需運行hip filename
,例如hip package.json
; 保存按Ctrl + s
並退出按Ctrl + q
。 對於這個示例,我將使用由主要 NodeOS 開發人員之一開發的代碼,我自己並沒有真正實現它。 我們示例的原始代碼可以在 node-bin-man Git 存儲庫中找到。

讓我們回到創建我們的第一個 NodeOS 應用程序。 與每個 Node.js 應用程序(或 NPM 包)一樣,我們首先創建一個package.json
文件,如下例所示:
{ "name": "bin-man", "version": "0.0.1", "description": "Format and display manual pages", "bin": { "man": "man.js" }, "repository": "https://github.com/groundwater/node-bin-man", "author": "groundwater", "license": "MIT", "dependencies": { "blessed": "~0.0.22" } }
參數name
、 version
、 author
、 repository
、 license
和description
是不言自明的。 bin
集合是一個 JSON 鍵/值對象,其中包含命令名稱和關聯的 JavaScript 文件。 在我們的示例中, man
命令與文件man.js
相關聯。 集合dependencies
包含使用此應用程序所需的 NPM 包列表。 在我們的示例中,代碼的作者包括 Blessed,這是一個類似於 curses 的庫,具有用於 Node.js 的高級終端接口 API。
現在讓我們進入主要部分,實際代碼。
#!/usr/bin/env node
這部分稱為“shebang”。 NodeOS 實際上並不需要它,但它告訴操作系統如何執行以下代碼。 在我們的例子中,它告訴解釋器一切都需要使用命令/usr/bin/env node
來執行。
var fs = require('fs'); var blessed = require('blessed');
就像在 Node.js 中一樣,函數require()
將選定的包加載到內存中並將其保存到指定的變量中。
var arg = process.argv[2] || 'bin-man';
如果沒有指定其他命令, man
命令的標準行為是告訴手冊它自己。 我們的代碼示例也是這樣做的:如果沒有為第二個參數指定參數(第一個是 man 本身),則默認為 bin-man。
var path = process.env.HOME + "/lib/node_modules/" + arg + "/README.md"; try{ var readme = fs.readFileSync(path, 'utf-8'); }catch(e){ console.log('No README.md for Package ',arg); process.exit(-1); }
此時,程序會檢查給定應用程序是否存在自述文件。 在 NodeOS 中,每個應用程序的安裝路徑是主目錄(或/
),後跟目錄lib/node_modules
。 如果文件README.md
存在,它將其內容保存在變量readme
中。 否則,它會顯示錯誤並退出該過程。
// Create a screen object. var screen = blessed.screen(); var box = blessed.box({ content: readme, alwaysScroll:true, scrollable: true, }); // Append our box to the screen. screen.append(box);
Blessed 有一個非常簡單的 API; 顯示文件的內容就像告訴它創建一個box
並加載內容一樣簡單。
screen.key(['escape', 'q', 'C-c'], function(ch, key) { return process.exit(0); });
現在,讓我們創建一種退出man
應用程序的方法。 我們組合鍵escape
、 q
或 emacs 風格的組合Cc
來退出進程。
screen.key(['space','f','j','n'], function(ch, key) { box.scroll(box.height); screen.render(); }); screen.key(['down'], function(ch, key) { box.scroll(1); screen.render(); }); screen.key(['up'], function(ch, key) { box.scroll(-1); screen.render(); }); screen.key(['b','k','p'], function(ch, key) { box.scroll(-box.height); screen.render(); });
我們使用方向鍵向上或向下滾動一行,使用space
、 f
、 j
或n
鍵向下滾動一頁(與屏幕上的行數一樣多)。 使用b
, k
或p
做相反的事情。
box.focus(); screen.render();
最後,我們告訴應用程序專注於我們創建的box
並渲染整個東西。 讓我們將這些文件放在目錄/lib/node_modules/bin-man
,然後添加一個簡單的README.md
,如下所示:
# Man Author: @groundwater ## Install npkg install bin-man ## Usage ``` Usage: man PKGNAME Display a packages README.md file ```
我們幾乎完成了我們的第一個 NodeOS 自定義應用程序。 只剩下最後一小步了; 我們需要創建一個配置文件,因為它是 NodeOS 應用程序的要求。 就像在路徑/etc/bin-man/config.json
中創建一個包含以下內容的文件一樣簡單: {}
,一個空的 JSON 對象。 現在,我們可以嘗試我們的新應用程序。 在 NodeOS shell 中運行man
應該會顯示我們之前創建的自述文件。
結論
正如您在我們的簡單代碼示例中所看到的,在 NodeOS 中實現任何東西都是一件容易的事,您只需要了解 Node.js。
NodeOS 有很大的潛力,我認為一旦實現了附加功能,它可能會成為一個很棒的操作系統。 它仍然需要改進,但由於整個基於 Node.js 的生態系統的流行,如果它迅速成為流行的操作系統,我不會感到驚訝。 你怎麼看待這件事? 在評論中告訴我。