操作系统(OS)是一个广泛的主题。 几十年来,一种方法在这里占主导地位:Unix。 实际上,大多数现代系统,包括大多数GNU / Linux发行版,* BSD和macOS,都遵循Unix体系结构。 (没有Windows,但是在这个主题上几乎没有什么有趣的东西)。
在2000年,Rob Pike发表了关于为何
系统软件研究不相关的演讲。 由于对社区感到悲观或无视,他似乎完全忽略了许多Unix用户在
Unix-Haters Handbook (1994)中收集的抱怨。 该书刻意讽刺,但指出了Unix系统的一些关键问题-尚未解决。
2006年,Elko Dositra发表了他的论文
“全功能软件部署模型” ,它描述了功能性Nix软件包管理器。 在2008年,作者发布了
NixOS:一个功能齐全的Linux发行版 。 尽管NixOS为Unix系统重用了许多免费软件,但它与Unix的设计和哲学相去甚远,因此几乎不能称为“ Unix系统”。
Nix是系统工程领域的一次巨大飞跃。 该操作系统不仅解决了许多Unix问题(包括上述集合中的批评),而且还打开了许多其他功能和研究的道路,这些功能和研究在我们这个时代起着非常重要的作用,而可靠性和安全性已成为许多科学,公共和政治领域的主要话题。辩论。
派克错了。 这证明了另一个更普遍的观点:如果您不能证明进一步发展的可能性,那么不要宣布任何无关紧要的研究可能是更明智的选择。 所提到的报告几乎不能被视为数学证明。 他只是强调Unix是“足够好”的想法,您应该对它的功能和问题有所了解。
幸运的是,这种不必要的悲观主义是短视的,并不会持续很长时间:仅仅几年后,Nix系统证明了它是错误的。
Guix外观
Guix是Nix上的软件包管理器,而GuixSD是与NixOS类似的操作系统,其目标是成为“完全可编程的OS”。 实际上,这里几乎所有内容都是在
Guile Scheme中编写和配置的:从Guix程序包管理到
GNU Shepherd初始化系统。
Guix与Unix操作系统有很大不同。 您可以查看文档并评估更改程度:
Guix的好处
Guix的优势是革命性的,与其他操作系统相比,其余的OS看起来像旧系统。
我个人最喜欢的功能:
- 系统无漏洞:Guix保留了系统和用户级别的所有更改的历史记录。 如果更新中断了某些事情,您可以随时回滚。 这使得该系统几乎无懈可击 。
- 完整性:由于配置是声明性的,因此可以使用户或系统管理员完全控制。 在其他Unix变体中,当某些随机配置文件更改时,很难说出来。
- 完全可编程的OS:对系统配置进行编程并使用版本控制系统。 可以在Guile Scheme中配置许多系统服务:从udev规则到Xorg,PAM等。多亏了Guile,该配置可以取决于硬件甚至是主机名!
- 直接替代其他(不是很好)的软件包管理器:如果每个人都有一个界面,为什么还要分别管理Emacs,Python或TeXlive软件包(请参见下文 )! 编写和维护用户个人资料的声明更加容易。
- 指导包定义: 批量开发包定义要高效得多。 它可以很好地替代概念,例如Portage USE标志(请参阅下文 )。
- 发行包的几种方法:Guix包可能有几种“发行方式”,用于分隔各个组件(库,附加工具,文档等)。 在其他操作系统(通常是Debian)上,很难猜测哪些软件包可以组合在一起。
- 非乘法输入:在Guix术语中,“输入”是程序包依赖项。 用户配置文件和环境仅包含由用户显式安装的程序包,不一定包含其依赖项。 例如,请参阅用于报告系统信息的工具inxi :如果我仅对有关inxi系统/设备的报告感兴趣,则不必在
PATH
添加两到三打其他命令行工具。 Guix允许您仅在用户的个人资料中显示他真正需要的内容。
- Guix环境:当您运行
guix environment SOME-PACKAGES
Guix会建立一个临时环境,其中显示了SOME-PACKAGES
所有要求。 这可用于轻松配置项目的构建环境以及其他目的(请参见下文)。 一种优良的品质-它们使您无需在用户配置文件中安装程序即可运行程序。
- 部分更新:100%支持。 这可能是导致Arch Linux和Gentoo等浮动发行版崩溃的主要原因:由于一次仅支持多个版本(通常仅一个版本),因此必须对整个系统进行完全更新。 这意味着每次更新都会带来更多流量。 使用Guix,可以单独更新任何软件包。
- 持续集成或Guix无需软件包维护者的原因:由于可重现的程序集和对部分更新的支持,如果软件包在Guix上运行,它将“始终”运行,并且在下一次更新期间某些依赖项不会中断(更确切地说,如果依赖项破坏了软件包,则将其固定为使用正确版本的库)。 因此,可以将处理包的工作转移到“组装场”(一个在Nix项目的Hydra上 ,另一个在Cuirass上 )。 将此与大多数其他GNU / Linux社区进行比较,后者需要数十名维护人员来升级数千个软件包。 这种方法无法扩展:最后,这些分布停滞在数千个软件包上。 在Guix中,软件包数量可以安静地增长,而不必担心崩溃。 同时,可以更有效地使用贡献者。
在Guix中,从源代码进行构建同样容易。 实际上,这对于最终用户而言并不那么重要:如果没有完整的包装,那么Guix可以轻松地从源头返回装配体。
guix import
和guix refresh
:自动和递归地创建或更新程序包定义。 数百个定义被同时处理。 这些功能强调了在OS中使用真正的编程语言的好处。 在大多数操作系统上这是一项艰巨的任务,在Guix中相对容易实现。
- Guix频道:我最喜欢的功能之一! Arch Linux或Gentoo要求您创建本地存储库。 由于它们不支持部分更新,因此用户需要时常进行一些维护(即,确保依赖项更新不会破坏程序包)。 Guix渠道可替代Arch Linux和Gentoo的AUR覆盖层,从而从任何人那里分发其软件包定义(例如,来自Git存储库的软件包定义),从中获利。 同样,这保证了完全透明(回扣,历史记录等)。
- Emacs-Guix :据我所知,Guix是唯一具有最强大的Emacs用户界面的发行版!
- Guix包 :Docker等容器的真正替代品。 大多数容器系统都存在严重问题:它们无法播放,实际上它们是不透明的二进制文件,对于关心信任,安全性和隐私的用户来说绝对是不可接受的。 相反,Guix包装绝对清晰,可复制且透明。
guix system vm
和guix system disk-image
:Guix使在VM内部或在远程计算机上以实时USB的方式播放整个当前系统变得很简单。
Guix与竞争对手的比较
Debian,Arch Linux和大多数其他GNU / Linux发行版
GNU / Linux发行版通常没有Guix的上述优点。 最关键的缺点:
- 缺少对软件包的多个版本的支持或“依赖地狱”。 假设最新的mpv需要新的ffmpeg,但是更新ffmpeg会破坏大多数其他程序。 我们陷入了两难境地:要么破坏某些软件包,要么保存旧版本。 更糟糕的是,可能根本没有合适的软件包,或者没有操作系统支持。 在大多数不能保证完成其主要任务的发行版中,固有的问题是: 任何程序的软件包。
- 对维护者的严重依赖。 非功能性软件包管理意味着必须不断测试所有软件包的兼容性。 对于那些肩负这项任务的人来说,这是许多艰苦的工作。 实际上,这意味着包装管理的质量高度依赖于人员。 没有足够数量维护者的发行将不可避免地遭受痛苦甚至死亡。 通常对劳力的需求没有按比例缩放,并且随着数据包数量的增加,会导致复杂性的增加(在代码库和管理方面)。
Gentoo,* BSD
使用
Portage软件包管理器的
Gentoo和其他发行版具有一个著名的功能:
USE标志,用于在整个系统中激活功能(例如,静音,启用GUI支持等)。
USE标志使启用或禁用程序包作者的功能变得很简单(优点是已对它们进行了测试)。 另一方面,Portage不允许您配置事先未考虑的功能。 例如,如果一个包具有其他声音,但是作者没有设置相应的标志,则用户将无法对此做任何事情(创建新的包定义除外)。
相比之下,Guix允许您完全自定义所有内容,尽管使用了更多Scheme代码。 在伪代码中,它看起来像这样:
(loop-over (TARGET-PACKAGES) (package (inherit TARGET) (changes-here... including patches, build options, etc.))
这样的代码批处理随您的更改设置
TARGET-PACKAGES
的定义。 无需对程序包定义进行任何更改。 在任何时候,用户都可以完全控制对程序包所做的更改。
我爱Gentoo,但改用Guix后,Portage的局限性显而易见。
- USE标志系统不允许定制计划外的任意功能。
- 使用标志会增加一整套复杂性(请参阅相当复杂的原子语义 ),用于描述和管理包之间的功能关系。 Guix使用Guile Scheme编程关系完全消除了这种复杂性。
此外,由于缺乏对多个版本的适当支持,Portage遇到了同样的问题,并且标志大大增加了问题的严重性(经常抱怨Portage):当不兼容的USE标志应用于某些依赖项时,用户必须手动寻找解决方案。 有时,这意味着所需的功能不适用(至少在软件包定义方面不做大量工作)。
实际上,Guix提供了预编译的软件包-与Gentoo相比,它可以节省大量时间(尽管Portage支持二进制软件包分发)。
* BSD系统(例如FreeBSD)在
make config
遇到类似的问题。
尼克斯
Nix是操作系统研究的历史性突破,Guix从那里借鉴了几乎所有的想法。 今天,Nix仍然是最好的活动操作系统之一。 如果不是因为一个缺陷,Guix可能就不会存在。
在我看来,Guix解决了主要的Nix问题:这里使用的是成熟的基于Lisp的Guile Scheme编程语言,而不是它自己
的特定领域语言 (DSL)。
在软件开发中,“实施自己的编程语言”是一个非常普遍的误解。 这影响了许多项目,这些项目的配置或编程语言具有以下缺点:
- 有限的表现力和能力;
- 另一种学习语言(但不是非常有用和通用的语言),需要用户付出一些努力,因此会造成进入障碍。
- 可读性较低的代码(至少在最初);
- 通常表现不佳。
本地语言或语言限制的项目太多:
- XML,HTML(甚至更好的是: S-XML )
- Make,Autoconf,Automake,Cmake等
- Bash,Zsh,Fish(甚至更好:Eshell或scsh )
- JSON,TOML,YAML
- 移植到Nix Ebuild和OS软件包定义的许多其他语法规则
- 使用Firefox时使用XUL(此后Mozilla放弃了它)和大多数其他本地开发的语言来进行扩展
- 的SQL
- 八度,R,PARI / GP,大多数科学程序(例如Common Lisp,Racket和其他Scheme)
- 正则表达式( Emacs中的rx ,Racket中的PEG等)
- sed,AWK等
- 大多数初始化配置,包括systemd(甚至更好: GNU Shepherd )
- cron(甚至更好: mcron )
- conky(不是完全可编程的,尽管这应该是类似程序中最令人期待的功能)
- TeX,LaTeX(及所有衍生产品),渐近线(甚至更好: 涂鸦 , skribilo-仍在开发中;截至2019年1月,TeX / LaTeX仍用作准备PDF的中间步骤)
- 大多数程序的配置不使用通用编程语言。
重新发明轮子通常不是一个好主意。 当涉及到诸如编程语言之类的重要工具时,这将产生非常戏剧性的后果。 需要不必要的额外努力,会发生错误。 社区正在分散。 如果合并的社区能够改善现有的,完善的编程语言,则可以提高效率,并更好地利用自己的时间。
不只是台式机
Guix支持多种架构(截至2019年1月为i686,x86_64,ARMv7和AArch64),并计划支持Linux生态系统之外的更多内核(例如* BSD,
GNU Hurd或您自己的系统!)。
这使Guix成为部署(可重现)服务器和其他专用系统的出色工具。 我认为,在嵌入式系统中,Guix可以与
OpenWRT很好地竞争(尽管要移植到嵌入式系统需要一些工作)。
自复制实时USB
上面,我提到了
guix system disk-image
:例如,它允许您在USB闪存驱动器上重新创建当前系统。
因此,当前系统的克隆易于在任何地方连接并复制确切的当前环境(减去硬件)。 您可以在其中添加用户数据:PGP密钥,电子邮件。 下载后,所有内容均立即可用。
显然,克隆可以从安装克隆的计算机上进一步进行:代替成熟的Guix,可以部署完整的OS,随时可以使用。
替换其他程序包管理器
Emacs,Python,Ruby ...以及guix environment
的强大guix environment
Guix可以替换任何程序包管理器,包括编程语言的程序包管理器。 它具有几个优点:
- 无处不在的可重复性。
- 无处不在的回滚。
- 无需学习其他软件包管理器。
此时,您应该提到
guix environment
。 此命令仅使用一组特定的软件包来设置临时环境,例如
virtualenv
。 杀手级功能是它适用于所有语言及其组合。
Texlive
(免责声明:自2019年1月起,正在重新设计面向Guix的TeXlive构建系统)。
TeXlive特别受关注,因为它特别糟糕:),这再次证实了Guix的拯救作用!
大多数基于Unix的操作系统通常将TeXlive作为软件包套件的一部分进行分发。 例如,Arch Linux有许多此类。 如果您需要不同集合中的某些TeX软件包,那么Arch Linux别无选择,只能安装数千个(可能是不必要的)软件包,TeXlive会占用
大量空间:数百兆字节。
另外,您可以手动安装TeXlive,但让我们面对现实:
tlmgr
只是一个糟糕的软件包管理器,需要繁琐的额外工作。
使用Guix,TeXlive软件包与其他所有软件包一样单独安装,这可以帮助您维护自己的TeXlive软件包集,甚至可以创建用于编译特定文档的虚拟环境规范。
核心
许多操作系统仅对自定义内核提供有限的支持。 如果用户希望脱离默认内核,则必须手动维护非标准内核。
众所周知,Gentoo将“要求”用户内核作为推荐的(强制性)安装步骤。 但是,这几乎不是前提条件,用户本身必须支持内核配置。
在Guix中,内核是一个完全可自定义的常规软件包,与其他任何软件包一样。 您可以配置所有内容,并将内核配置文件传递给软件包定义。
例如,以下是使用
iwlwifi
驱动程序的非免费Linux内核的
iwlwifi
(警告:强烈建议您不要使用专有驱动程序,因为它们会对您的隐私和自由构成严重威胁):
(define-module (ambrevar linux-custom) #:use-module (guix gexp) #:use-module (guix packages) #:use-module (guix download) #:use-module (guix git-download) #:use-module (guix build-system trivial) #:use-module ((guix licenses) #:prefix license:) #:use-module (gnu packages linux) #:use-module (srfi srfi-1)) (define-public linux-nonfree (package (inherit linux-libre) (name "linux-nonfree") (version (package-version linux-libre)) (source (origin (method url-fetch) (uri (string-append "https://www.kernel.org/pub/linux/kernel/v4.x/" "linux-" version ".tar.xz")) (sha256 (base32 "1lm2s9yhzyqra1f16jrjwd66m3jl43n5k7av2r9hns8hdr1smmw4")))) (native-inputs `(("kconfig" ,(local-file "./linux-custom.conf")) ,@(alist-delete "kconfig" (package-native-inputs linux-libre)))))) (define (linux-firmware-version) "9d40a17beaf271e6ad47a5e714a296100eef4692") (define (linux-firmware-source version) (origin (method git-fetch) (uri (git-reference (url (string-append "https://git.kernel.org/pub/scm/linux/kernel" "/git/firmware/linux-firmware.git")) (commit version))) (file-name (string-append "linux-firmware-" version "-checkout")) (sha256 (base32 "099kll2n1zvps5qawnbm6c75khgn81j8ns0widiw0lnwm8s9q6ch")))) (define-public linux-firmware-iwlwifi (package (name "linux-firmware-iwlwifi") (version (linux-firmware-version)) (source (linux-firmware-source version)) (build-system trivial-build-system) (arguments `(#:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils)) (let ((source (assoc-ref %build-inputs "source")) (fw-dir (string-append %output "/lib/firmware/"))) (mkdir-p fw-dir) (for-each (lambda (file) (copy-file file (string-append fw-dir (basename file)))) (find-files source "iwlwifi-.*\\.ucode$|LICENSE\\.iwlwifi_firmware$")) #t)))) (home-page "https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi") (synopsis "Non-free firmware for Intel wifi chips") (description "Non-free iwlwifi firmware") (license (license:non-copyleft "https://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/tree/LICENCE.iwlwifi_firmware?id=HEAD"))))
自定义内核和固件可以有条件地包含在当前系统配置中(某些
config.scm
文件):
(define *lspci* (let* ((port (open-pipe* OPEN_READ "lspci")) (str (get-string-all port))) (close-pipe port) str)) (operating-system (host-name "...")
然后按照以下步骤安装新的系统配置:
sudo -E guix system reconfigure config.scm
您甚至无需安装新内核,就可以直接创建一个映像,准备从USB驱动器启动。
游戏
由于Guix软件包使用了先进的技术(例如,最新版本的Mesa)并允许进行完整的内核调整,因此,这是游戏(尤其是游戏
包装 )的理想平台!
不幸的是,游戏行业远非自由软件哲学,很少有游戏作为官方Guix项目的一部分打包。
尽管Guix代表自由软件,并且不接受其存储库中的任何所有权,但具有讽刺意味的是,许多高级功能使Guix成为非自由程序的理想软件包管理器。
一些好处:
guix environment
允许您在隔离的容器中运行任何应用程序,以限制对网络的访问,隐藏文件系统(不存在专有程序会窃取某些文件(例如,比特币钱包或PGP密钥)的风险),甚至是系统级信息,例如作为用户名。 这是运行任何不可靠的封闭源程序所必需的。
- 功能包管理:闭源程序通常无法经受时间的考验,并且在库依赖项更改其API时会中断。 由于Guix在任何依赖项的任何版本之上定义软件包(与当前系统没有冲突),因此Guix允许您为具有封闭源代码的游戏创建软件包,这些软件包将永远有效。
- 可重现的环境:闭源程序通常移植较差,在依赖关系稍有不同的系统上的行为可能有所不同。 Guix的可重现性属性表示,如果我们使Guix程序包工作一次,它将始终有效(硬件故障或硬件配置更改除外)。
由于这些原因,Guix是用于打包和分发封闭源游戏的理想工具。
但是,这是一个单独的大主题,最好留给另一篇文章。
技巧和窍门
Emacs-guix
Guix的惊人优势之一是
Emacs-Guix界面 ,该
界面使您可以安装和删除软件包,有选择地更新,搜索,进入软件包定义,管理世代,打印它们之间的“差异”等等。
它具有用于汇编和编程的开发模式,以及一个称为Scheme
REPL的特殊交互式环境。 这是操作系统的唯一用户界面。
还有一个
Helm System Packages界面,与Emacs-Guix部分重叠,但是对我来说,快速查找软件包和快速操作显得更加令人愉悦。
资料储存
由于Guix存储了几代系统配置(包括软件包的整个历史记录),因此与其他操作系统相比,它需要更多的磁盘空间。
以我的经验,在2018年,必须每月大约清洁25 GB的分区一次(考虑到我对软件包数量的要求很高),并且50 GB的分区可以整年无人看管。使用该命令清除存储空间很方便guix gc
,但是它可以删除“太多的软件包”,即在下次更新期间立即需要的软件包。Emacs-Guix有一个命令mx guix-store-dead-item
,可以按大小对死包进行排序,并允许您单独删除它们。如果需要分析依赖关系,请查看guix gc --references
和guix gc --requisites
。可以将其与输出结合guix build ...
以查看依赖关系图的不同元素。例如,要查看其中一个构建脚本的代码,请打开以下命令返回的文件: $ guix gc --references $(guix build -d coreutils) | grep builder /gnu/store/v02xky6f5rvjywd7ficzi5pyibbmk6cq-coreutils-8.29-guile-builder
清单生成
生成配置文件中安装的所有软件包的清单通常很有用。可以使用以下Guile脚本完成此操作: (use-modules (guix profiles) (ice-9 match) (ice-9 pretty-print)) (match (command-line) ((_ where) (pretty-print `(specifications->manifest ',(map manifest-entry-name (manifest-entries (profile-manifest where)))))) (_ (error "Please provide the path to a Guix profile.")))
例如,在您的个人资料上运行它~/.guix-profile
: $ guile -s manifest-to-manifest.scm ~/.guix-profile
我的点文件跟踪已安装软件包的历史记录。由于我还保留了Guix的版本,因此我可以在过去的任何时候返回系统的确切状态。参考文献
一些Web界面:文件:非官方套餐: