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 的生态系统的流行,如果它迅速成为流行的操作系统,我不会感到惊讶。 你怎么看待这件事? 在评论中告诉我。