NodeOS:基於 JavaScript 的操作系統

已發表: 2022-03-11

我相信大多數程序員都聽說過 Node.js,但是 NodeOS 呢? 是的,NodeOS,一個用 Node.js 編寫的操作系統。 嗯,有點。 NodeOS 將 Linux 內核用於大多數性能關鍵的事情,例如硬件交互,但對於其他所有事情,它都使用 Node.js。 NodeOS 的開發始於兩年前,由一群共享一個簡單但有趣的想法的人創建: “是否可以僅使用 Node.js 創建操作系統?”

達爾文進化圖

是否可以僅使用 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 最簡單快捷的方法是使用以下方法:

  1. 一台裝有 Mac OSX 或 Linux 的計算機。 它可能適用於 Windows,但我沒有嘗試過。
  2. 碼頭工人。

安裝 Docker 後,運行 NodeOS 實例就很容易了。 您需要做的就是執行以下命令,Docker 會做所有的事情:

 sudo docker run -t -i nodeos/nodeos 

試用 NodeOS 最簡單快捷的方法是使用 Docker

試用 NodeOS 最簡單、最快捷的方法是使用 Docker。
鳴叫

當您運行上述命令時,Docker 會自動從存儲庫下載 NodeOS 的磁盤映像,並在虛擬機中執行 NodeOS 的安裝。 安裝完成後,它會打開一個到 NodeOS shell 的 SSH 會話。

沒有碼頭工人

有一些原因可以避免使用 Docker,其中一個是最新的 NodeOS 版本。 在撰寫本文時,NodeOS 的 Docker 映像的最後一次更改是在兩個月前進行的,而開發版本是在六天前更新的。 因此,如果您想使用最新版本,您絕對應該獲取源代碼。 這不是太難,但需要很長時間。 你會需要:

  1. 一台裝有 Linux 的計算機。 你可以在 OS X 上編譯它,但它需要更長的時間,因為它必須進行交叉編譯。 Windows 也是如此。
  2. Linux 構建實用程序(make、g++、gcc、autoconf)。
  3. 奇木。
  4. 時間。 說真的,很多。

一旦你擁有了一切,你可以繼續進行源代碼編譯:

  1. 下載項目源代碼: bash git clone [email protected]:NodeOS/NodeOS.git
  2. 通過運行以下命令編譯它: cd NodeOSnpm install
  3. 我將逐字引用官方文檔: “挑選一些微波爆米花去看電影。 不,真的,去做吧。” . 是的,這需要很多時間,所以在此期間做一些有趣的事情。
  4. 運行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 有一個集成的包管理器(如aptyum ),稱為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 上用於顯示其他命令的手冊頁。 不要害怕,實現它很容易。 怎麼樣,我聽到你問了? 簡單的。

使用 Node.js 構建 NodeOS 應用程序

首先,讓我們安裝一個名為 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" } }

參數nameversionauthorrepositorylicensedescription是不言自明的。 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應用程序的方法。 我們組合鍵escapeq或 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(); });

我們使用方向鍵向上或向下滾動一行,使用spacefjn鍵向下滾動一頁(與屏幕上的行數一樣多)。 使用bkp做相反的事情。

 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 的生態系統的流行,如果它迅速成為流行的操作系統,我不會感到驚訝。 你怎麼看待這件事? 在評論中告訴我。