2020年4月

学习 Elisp 是如何处理变量的,以及如何在你的脚本与配置中使用它们。

GNU Emacs 是由 C 和 Emacs Lisp(Elisp,Lisp 编程语言的一种方言)写成,它是一个编辑器的同时,又碰巧是 Elisp 的沙盒。因此,理解 Elisp 中的一些基本编程概念会对你有一些帮助。

如果你是 Emacs 新手,请先阅读 Sacha Chua 的《给 Emacs 新手的资源》精品帖。本篇文章假定你熟悉常见的 Emacs 术语,并且能够阅读并求值 Elisp 代码的简单片段。最好你也听说过变量作用域的概念,知道它在其它编程语言中的作用。本篇文章中的示例假定你使用的是相对较新的 Emacs 版本(v.25 之后的版本)。

Elisp 手册 包含了 Elisp 的方方面面,但它是写给那些有明确查找目标的人们的(它在这方面也做得相当棒)。但是很多人想要能够在更高的层次上解释 Elisp 概念的材料,同时将信息压缩成最精华的部分。本篇文章也正是我回应这种呼声的一次尝试,为读者描绘基础的大体轮廓。使他们能在配置中用上这些技巧,也让他们在手册中查询细节变得更容易。

全局变量

defcustom 定义的用户设置和用 defvardefconst 定义的变量是全局的。使用 defcustomdefvar 声明变量的一个非常重要的原因是,当一个变量已经被 绑定 bind ,对它们进行重新求值不会覆盖掉已有的值。举个栗子,如果你在初始化文件中对 my-var 进行如下绑定:

(setq my-var nil)

对如下表达式求值不会将变量覆盖为 t

(defvar my-var t)

注意此处有一个例外:如果你用 C-M-x 快捷键对上述声明求值,它将调用 eval-defun 函数,并将变量覆盖为 t。通过此方式,你可以按需将变量强制覆盖。这种行为是刻意而为之的:你可能知道,Emacs 中的许多特性是按需加载的,也可以称为自动加载。如果那些文件中的声明将变量覆盖为它们的默认值,那它也就覆盖了你初始化文件中的设置。

用户选项

用户选项就是使用 defcustom 声明的全局变量。与使用 defvar 声明的变量不同,这些变量可以用 M-x customize 界面来配置。据我所知,大部分人因为觉得它开销较大而不经常使用。一旦你知道如何在你的初始化文件中设置变量,也就没有理由一定要去使用它了。许多用户没有意识到的一个细节是,通过 customize 的方式设置用户选项能够执行代码,有的时间可用来运行一些附加的配置说明:

(defcustom my-option t
  "My user option."
  :set (lambda (sym val)
         (set-default sym val)
         (message "Set %s to %s" sym val)))

若你对这段代码求值,并键入 M-x customize-option RET my-option RET 运行 customize 界面,lambda 匿名函数就会被调用,回显区域就会显示出该选项的符号名与值。

如果你在初始化文件中使用 setq 改变该选项的值,那么匿名函数不会运行。要想在 Elisp 中正确设置一个选项,你需要使用函数 customize-set-variable。或者,人们在他们的配置文件中使用了各种版本的 csetq 宏来自动处理(如你所愿,你可以通过 GitHub 的代码搜索发现更复杂的变体)。

(defmacro csetq (sym val)
  `(funcall (or (get ',sym 'custom-set) 'set-default) ',sym ,val))

若你正在使用 use-package 宏,:custom 关键字会替你处理好以上这些。

在你将以上代码放入到你的初始化文件中之后,你便可以使用 csetq 宏在设置变量的同时运行任何现存的 setter 函数。要证明这点,你可以使用此宏来改变上面定义的选项,并观察回显区域的消息输出。

(csetq my-option nil)

动态绑定与词法绑定

当你在使用其它编程语言时,你可能不会意识到动态绑定与词法绑定的区别。当今的大部分编程语言使用词法绑定,并且在学习变量作用域与变量查找时也没有必要去了解它们之间的区别。

如此看来,Emacs Lisp 比较特殊因为动态绑定是默认选项,词法绑定需要显式启用。这里有一些历史遗留原因,但在实际使用中,你应该时刻启用词法绑定,因为它更快并且不容易出错。要启用词法绑定,只需将如下的注释行作为你的 Emacs Lisp 文件的第一行:

;;; -*- lexical-binding: t; -*-

另一种方式,你可以调用 add-file-local-variable-prop-line,在你选择将变量 lexical-binding 置为 t 后,会自动插入如上的注释行。

在加载包含如上特殊格式行的文件时,Emacs 会相应地设置变量,这意味着该缓冲区中的代码加载时启用了词法绑定。若要采用交互式的方式,你可以调用 M-x eval-buffer 命令,它会将词法绑定考虑在内。

既然你已经知道了如何启用词法绑定,那么了解这些术语的含义就很明智了。对于动态绑定,在程序执行期间建立的最后一个绑定将用于变量查找。你可以通过将以下代码放入空缓冲区并执行 M-x eval buffer,以对此进行测试:

(defun a-exists-only-in-my-body (a)
  (other-function))

(defun other-function ()
  (message "I see `a', its value is %s" a))

(a-exists-only-in-my-body t)

你可能会很惊讶地发现,在 other-function 中查找变量 a 竟然成功了。

若你在顶部添加了特殊的词法绑定注释后,重新运行前面的示例,这段代码将抛出 variable is void 错误,因为 other-functioin 无法识别变量 a。如果你使用的是其它编程语言,这才是你所期望的行为。

启用词法绑定后,作用域会由周围的代码所定义。这并不单单是性能原因,时间也已经表明了词法绑定才是更受喜爱的。

特殊变量与动态绑定

如你所知,let 用于临时建立局部绑定:

(let ((a "I'm a")
      (b "I'm b"))
  (message "Hello, %s. Hello %s" a b))

接下来有趣的是——使用 defcustomdefvar 以及 defconst 定义的变量被称为特殊变量,不论词法绑定是否启用,它们都将使用动态绑定:

;;; -*- lexical-binding: t; -*-

(defun some-other-function ()
  (message "I see `c', its value is: %s" c))

(defvar c t)

(let ((a "I'm lexically bound")
      (c "I'm special and therefore dynamically bound"))
  (some-other-function)
  (message "I see `a', its values is: %s" a))

通过 C-h e 切换至 Messages 缓冲区,查看上述示例输出的消息。

使用 let 或者函数参数绑定的局部变量会遵循由 lexical-binding 变量定义的查找规则,但使用 defvardefconstdefcustom 定义的全局变量,能够沿着调用栈在 let 表达式中被修改。

这种技巧允许方便地进行特殊定制,并且经常在 Emacs 中被使用。这并不奇怪,毕竟 Emacs Lisp 最开始只提供动态绑定作为唯一选择。下面是一个常见的示例,说明如何向只读缓冲区临时写入数据:

(let ((inhibit-read-only t))
  (insert ...))

这是另一个常见的示例,如何进行大小写敏感的搜索:

(let ((case-fold-search nil))
  (some-function-which-uses-search ...))

动态绑定允许你采用作者未曾预料的方式对函数进行修改。对于像 Emacs 这样设计使用的程序来说,这是个强大的工具与特性。

有一点需要注意:你可能会意外地使用局部变量名,该变量在其他地方被声明为特殊变量。防止这种冲突的一个技巧是避免在局部变量名中使用下划线。在我当前的 Emacs 会话中,以下代码只留下少数潜在冲突的候选:

(let ((vars ()))
  (mapatoms
   (lambda (cand)
     (when (and (boundp cand)
                (not (keywordp cand))
                (special-variable-p cand)
                (not (string-match "-"
                                   (symbol-name cand))))
       (push cand vars))))
  vars) ;; => (t obarray noninteractive debugger nil)

缓冲区局部变量

每个缓冲区都能够拥有变量的一个局部绑定。这就意味着对于任何变量,都会首先在当前缓冲区中查找缓冲区局部变量取代默认值。局部变量是 Emacs 中一个非常重要的特性,比如它们被主模式用来建立缓冲区范围内的行为与设置。

事实上你已经在本文中见过缓冲区局部变量——也就是将 lexical-binding 在缓冲区范围内设置为 t 的特殊注释行。在 Emacs 中,在特殊注释行中定义的缓冲区局部变量也被称为文件局部变量

任何的全局变量都可以用缓冲区局部变量来遮掩,比如上面定义的变量 my-var,你可用如下方式设置局部变量:

(setq-local my-var t)
;; or (set (make-local-variable 'my-var) t)

此时 my-var 对于你在对上述代码进行求值时对应的缓冲区来说就是局部变量。若你对它调用 describe-variable,文档会同时告诉你局部与全局的值。从编程的角度来讲,你可以分别用 buffer-local-value 获取局部值,用 default-value 获取全局值。若要移除局部值,你可以调用 kill-local-variable

另一个需要注意的重要性质就是,一旦一个变量成为缓冲区局部变量,后续在该缓冲区中使用的 setq 都将只能设置局部的值。要想设置默认值,你需要使用 setq-default

因为局部变量意味着对缓冲区的定制,它们也就经常被用于模式钩子中。一个典型的例子如下所示:

(add-hook 'go-mode-hook
          (defun go-setup+ ()
            (setq-local compile-command
              (if (string-suffix-p "_test.go" buffer-file-name)
                  "go test -v"
                (format "go run %s"
                        (shell-quote-argument
                         (file-name-nondirectory buffer-file-name)))))))

这将设置 go-mode 缓冲区中 M-x compile 使用的编译命令。

另一个重要的方面就是一些变量会自动成为缓冲区局部变量。这也就意味着当你使用 setq 设置这样一个变量时,它会针对当前缓冲区设置局部绑定。这个特性不应该被经常使用,因为这种隐式的行为并不好。不过如果你想的话,你可以使用如下方法创建自动局部变量:

(defvar-local my-automatical-local-var t)
;; or (make-variable-buffer-local 'my-automatical-local-var)

变量 indent-tabs-mode 就是 Emacs 内建的一个例子。如果你在初始化文件中使用 setq 改变变量的值,根本不会影响默认值。只有在你加载初始化文件时正处在当前的缓冲区的局部值会被改变。因此,你需要使用 setq-default 来改变 indent-tabs-mode 的默认值。

结语

Emacs 是一个强大的编辑器,并且随着你的定制它将变得更加强大。现在,你知道了 Elisp 是如何处理变量的,以及你应如何在你自己的脚本与配置中使用它们。

本篇文章此前采用 CC BY-NC-SA 4.0 许可证发布在 With-Emacs 上,经过修改(带有合并请求)并在作者允许的情况下重新发布。


via: https://opensource.com/article/20/3/variables-emacs

作者:Clemens Radermacher 选题:lujun9972 译者:cycoe 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

你觉得 Linux 终端里只有无趣的工作吗?那你一定不知道下面这些有趣的 Linux 命令吧。

Linux 终端是用来完成复杂的工作的,我们有很多有用的 linux 命令奇技淫巧来帮助你。

但是,你知道你还可以用终端来做很多有趣的事吗?如果你不知道,没关系,大多数 Linux 用户也都只把终端视为一个用来管理系统和开发工作的交互界面。

然而,如果你知道这里有些你可以在终端玩的基于终端的游戏ASCII 码游戏,你一定会大吃一惊。

在这篇文章中,我将会探索一些有趣的、可笑的、荒谬的命令来让你可以在终端中找点乐子!

用这些命令在 Linux 终端中找点乐子

你可能会觉得这些命令荒谬或没用,但是有一些还是可以被好好利用的。

我已经放上了 Ubuntu/Debian 的安装指令,如果你使用基于 Ubuntu 的发行版,请确保启用 universe 仓库,因为大多数命令不在主仓库中。

如果你使用 Arch、Fedora、SUSE、Solus 或者其他非 Ubuntu 的发行版,请使用你的发行版包管理工具去安装这些有趣的 Linux 命令。

1、在终端开一辆火车

让我们坐上火车,来一场说走就走的旅行的,没错,就是字面意思!

sl 命令可以让你在终端运行一辆火车。

安装方法:

sudo apt install sl

完成后,你只要在终端输入下面的命令就可以开始:

sl

很精彩,对吧?但等等,我们还没结束!你还可以让你的火车飞起来,只要加上参数 -F,波特先生,请飞吧:

sl -F

这样会让火车长出翅膀飞出终端窗口!

2、给你的 Linux 终端加上黑客帝国效果

还记得科幻电影黑客帝国吗?终端里掉落的绿色字符成为了黑客帝国的标志形象。

你也可以在你的 Linux 电脑里有这样的黑客帝国数字雨!你只需要安装 cmatric 然后在终端输入它就行。

在 Debian/Ubuntu Linux 上安装 cmatrix:

sudo apt install cmatrix

现在,你要做的就是输入下面的命令,在终端就会有黑客帝国屏幕了:

cmatrix

按下 Ctrl+C 来停止它,黑客先生。

3、燃起来

拿好灭火器,因为接下来你要在你的终端里点火了!

想安装它,你要输入:

sudo apt install libaa-bin

完成后,你输入下面的命令,你的终端就会燃起一团火焰:

aafire

按下 Ctrl+C 来停止它。

4、幸运饼干命令

想知道你的运气怎样但身边没有幸运饼干?

别担心,你只需在终端打出 fortune 然后按下回车。终端将会随机显示出一个幸运语,就像你从幸运饼干里得到的一样。

安装它:

sudo apt install fortune

完成后,只要在命令行打出下面的内容,你就会知道你的运气怎样:

fortune

这是一个你可以实际使用的命令。你可以用它作为每日消息,这样在多用户环境下,每个用户登录后都会得到一个“幸运饼干”。

你也可以把它添加到 bashrc 文件,这样当你登进终端你就会看到了。

5、宠物爱好者?这是给你准备的

oneko 是一个有趣的命令,可以把你的光标变成一只老鼠,然后创造一只好奇的猫,一旦你移动光标,就会来追你。这不仅局限于终端。当猫追逐光标时,你可以继续工作。

如果你家里有孩子这一定很有趣。

用下面的命令安装 oneko

sudo apt install oneko

用下面的命令运行它:

oneko

如果你不喜欢猫,喜欢狗,输入:

oneko -dog

它有很多种小宠物,你可以用 oneko -help 获取信息。按下 Ctrl+C 终止它。

6、有个小兄弟在看着你

xeyes 是一个很小的 GUI 程序,它可以绘制出一双眼睛一直盯着你!它会不断跟随你的鼠标光标,运行命令自己看看!

你可以用下面命令安装:

sudo apt install xeyes

然后这样用它:

xeyes

按下 Ctrl+C 终止它。

7、让终端帮你讲话

打开你的扬声器,你来试试这个命令,eSpeak 是一个有趣的命令,它可以让你的终端说话。是的,你没听错。

先安装这个包:

sudo apt install espeak

接下来,你只需要输入在命令行中输入你想听到的话:

espeak "Type what your computer says"

无论你在双引号里面填什么,你的电脑都会复述出来!它就像在 Linux 中的 echo 命令,但不是打印出来,而是说出来。

8、Toilet(但与洗手间无关)

这听起来有点奇怪,是的。但是,这只是一个命令,用来将文本转换成大的 ASCII 字符。

用这个命令安装 toilet

sudo apt install toilet

完成后,你只需输入:

toilet sample text you want

我也不知道为啥这个小程序叫 Toilet。

9、那个牛说什么?

cowsay 是一个在终端中用 ASCII 字符展示出一头牛的命令。通过这个命令,你可以控制牛说出你想说的话。

别纠结声音,它只展示文本(就是你看漫画书一样)。

Cowsay Cowthink

安装 cowsay

sudo apt install cowsay

安装完成后,你只要输入:

cowsay "your text"

无论你在双引号里填什么,你的牛都会说!我看到一些系统管理员用它来展示每天的消息。你也可以这样,你甚至可以把它和 fortune 命令结合。

10、旗帜

banner 命令与 toilet 命令相似,但它限制最多只能打印 10 个字符。

你可以这样安装 banner 命令:

sudo apt install sysvbanner

然后这样运行:

banner "Welcome"

替换双引号里的内容,你将会得到你想要的展示内容。

11、Yes

yes 命令帮助你在循环中自动响应直到终止命令。这个命令将会一直打印相同的内容。如果你想快速生成大量垃圾文本,那么此命令将像超级按钮一样工作。

你也可以使用它为命令提供 yes 应答(如果提示应答时)。例如,apt upgrade 命令会要求你确认,你可以像这样使用它:

yes | sudo apt upgrade

你不需要安装任何包,yes 命令已经存在了。

想要终止 yes 命令循环,只需按下 CTRL+C

12、得到一个新的身份

要生成一个随机的假身份吗?我推荐你用 rig 命令。你在终端运行它,就会生成一个假的身份。

用这个命令安装 rig

sudo apt install rig

只需像这样输入:

rig

它可能被用在脚本或者 web 应用中展示随机信息,但我自己还没做过什么。

结尾

我希望你会喜欢这个有趣的 Linux 命令列表。你最喜欢哪个命令呢?你还知道其他有趣的命令吗?请在评论部分与我们分享。


via: https://itsfoss.com/funny-linux-commands/

作者:Srimanta Koley 选题:lujun9972 译者:Zioyi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Ubuntu 20.04 LTS Focal Fossa 终于发布了。以下是 Ubuntu 20.04 的新功能和下载链接,以及Ubuntu 20.04的官方风味版。

等待终于结束了。Ubuntu 20.04 LTS 终于来了,可以下载了!

如果你已经在使用 Ubuntu 19.10,你可能发现没有太多明显的差异 —— 但我所看到的改进清单确实令人印象深刻。

如果你想知道有什么新的东西,我将会提到这个版本的几个主要亮点。

Ubuntu 20.04 有什么新特性?

与之前的 18.04 LTS 版本相比,Ubuntu 20.04 LTS 有很多视觉上的改变,同时也包括了一些底层的改进。

当然,随着 GNOME 3.36 的加入,视觉上的重大升级和性能上的提升是相当明显的。以下是一段视频,重点介绍了 Ubuntu 20.04 中的新功能。

如果你有兴趣的话,你也可以深入到我们的文章中去看看,重点介绍 Ubuntu 20.04 的新功能

不管是哪种情况,让我来给你介绍一些亮点。

  • GNOME 3.36 是默认的桌面系统
  • 性能提高了很多
  • 新的 Yaru 主题很华丽,也有黑暗模式。
  • 你不会再看到亚马逊应用程序,它已经永远消失了!
  • 改进的 ZFS 支持
  • 你可以获得最新的 Linux 内核 5.4(LTS)
  • 增加了对 exFAT 的支持
  • 改进硬件和图形支持
  • 更新软件 Python 3.8.2
  • Wireguard 已被移植到 Linux 内核5.4,可以在 Ubuntu 20.04 上使用。

如果你想看详细的功能介绍,请观看这段视频,重点介绍 20.04 LTS 的最佳功能。

如果你是 Ubuntu 的新手,对 Ubuntu 20.04 有疑问,我们也为你提供了一篇快速的 Ubuntu 20.04 FAQ 文章。

从 18.04 和 19.10 升级到 Ubuntu 20.04

如果你已经在使用 Ubuntu 18.04 或 19.10,你可以从系统中轻松升级到 Ubuntu 20.04。

这样一来,当你开始使用新版本的时候,你的文件和大部分的应用程序设置都会保持原样,而无需从 ISO 中重新安装。

你可以阅读此详细教程来学习如何将 Ubuntu 升级到新版本

请注意,如果你使用的是 Lubuntu 18.04,请不要升级到 Lubuntu 20.04。Lubuntu 18.04 使用的是 Lxde 桌面,而后面的版本使用的是 LXQt 桌面。这样升级可能会导致冲突和系统崩溃。

下载 Ubuntu 20.04 LTS

你可以抓取 ISO 或 torrent 文件,这取决于你喜欢什么。

请按照本教程学习如何安装 Ubuntu

下载Ubuntu 20.04 LTS官方版下载

如果你想在不同的桌面环境下得到 Ubuntu 的官方版本,请按照下面的链接进行操作。

如果你没有在各自的官方网站上找到最新的 ISO/torrent 文件,只需前往 cdimages.ubuntu.com 找到所有的版本。

接下来,导航到“发行版名称” -> “releases” -> “20.04” -> “release”,然后你应该可以找到列出的 ISO 和 torrent 文件的链接。

如果你有问题,请参考这篇文章,它回答了关于 Ubuntu 20.04 的常见问题。如果你要安装,请查看我们推荐的安装 Ubuntu 20.04 之后要做的事情

享受 Ubuntu 20.04 LTS Focal Fossa!


via: https://itsfoss.com/download-ubuntu-20-04/

作者:Ankush Das 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

了解如何使用 dh\_virtualenv 来让你的 Python 应用可作为 .deb 包安装。

在基于 Debian 的操作系统(例如 Debian 或 Elementary OS)上安装 Python 应用的一种方法是使用 dh\_virtualenv 工具。它可以构建一个 .deb 包,在应用之外封装了一个 Python 虚拟环境,并在安装时进行部署。

在本文中,我将以构建一个包含 HTTPie 工具的包为例来解释如何使用它,以便在无需激活虚拟环境的情况下从命令行测试 HTTP API。

使用 dh\_virtualenv 打包

首先,你需要安装 dh_virtualenv 所需的工具。dh_virtualenv文档提供了所有安装选项。在基于 Debian 的系统上,我输入:

apt-get install dh-virtualenv devscripts

尽管不需要 devscripts 包,但它可以简化后续操作。

现在,创建一个目录来保存源码。由于这是一个本地的、非官方的 HTTPie 打包,因此我将其称为 myhttp。接下来,让我们在 myhttp 内创建一些文件,向 Debian 构建系统提供元数据。

首先,创建 debian/control 文件:

Source: myhttp
Section: python
Priority: extra
Maintainer: Jan Doe <[email protected]>
Build-Depends: debhelper (>= 9), python3.7, dh-virtualenv (>= 0.8)
Standards-Version: 3.9.5

Package: myhttp
Architecture: any
Pre-Depends: dpkg (>= 1.16.1), python3.7, ${misc:Pre-Depends}
Depends: ${misc:Depends}
Description: http client
 Useful for doing stuff

那么这些是什么信息呢?正如 Debian 文档指出的:

“第 1–7 行是源码包的控制信息。第 9–13 行是二进制包的控制信息。”

以下是我使用的:

  • Section 的值对于我们来说大多没有意义,但需要存在。它对给引导式 UI 安装程序提供信息是有意义的,但对于这个包来说,没有意义。
  • Priority 对像这样的第三方包的正确值是 extra
  • 强烈建议在 Maintainer 字段中填写正确的联系人信息。但不一定非得是你的个人电子邮件,如果包由团队维护,并且你希望将问题发送到团队的邮件别名,例如 Infrastructure Team <[email protected]>
  • Build-Depends 字段标识你需要 debhelperpythondh-virtualenv 来构建包:包构建过程中将确保这些依赖项在包构建时已安装。
  • Standards-Version 字段主要给人看。它表明你遵循的指南。本指南基于 dh-virtualenv 的官方文档,它是基于 Debian 的 3.9.5 指南。最好一直将源码包和二进制包命名相同。
  • Architecture 字段应为 Any,因为除非虚拟环境可能包含一些特定于体系结构的文件。否则,最好选择该字段为 any
  • 保持 Pre-Depends 列表不变:它是一种非常严格的依赖关系形式,你很少会需要比这里建议的最小依赖更多的依赖项。依赖项通常由构建系统准确计算,因此没有理由手动指定它们。
  • 如果你的包主要用于内部,那么 Description 字段可能只需要最少的信息或者指向公司 wiki 的链接,不然更多的信息会更有用。

然后创建 debian/compat 文件,它主要出于历史目的而存在

$ echo "9" > debian/compat

接下来,创建更新日志以告知包用户自上次发布以来发生了什么变化。最简单的方法是使用 dch --create 创建模板,然后填写值。

填写后,它看起来像:

myhttp (2.0.0-1) stable; urgency=medium

  * Initial release.

 -- Jan Doe <[email protected]>  Fri, 27 Mar 2020 01:09:22 +0000

现在你需要告诉工具安装 HTTPie,但是哪个版本?

创建一个宽松版本的 requirements.in 文件:

httpie

通常,宽松的需求文件将仅包含项目的直接依赖项,并在需要时指定最低版本。不一定总是需要指定最低版本:这些工具通常偏向于将依赖关系转化为“可能的最新版本”。如果你的 Debian 包与一个内部 Python 包相对应,这是内部应用中的一种常见情况,那么宽松的需求文件看起来将很相似:仅包含包名的一行。

然后使用 pip-compile(可通过安装 PyPI 包 pip-tools 获得):

$ pip-compile requirements.in > requirements.txt

这会生成一个严格的依赖文件,名为 requirements.txt

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile requirements.in
#
certifi==2019.11.28       # via requests
chardet==3.0.4            # via requests
httpie==2.0.0             # via -r requirements.in
idna==2.9                 # via requests
pygments==2.6.1           # via httpie
requests==2.23.0          # via httpie
urllib3==1.25.8           # via requests

最后,写一个 debian/rules 文件来创建包。因为 dh_virtualenv 会处理所有困难的事,因此规则文件很简单:

#!/usr/bin/make -f

%:
        dh $@ --with python-virtualenv --python /usr/bin/python3.7

确保指定 Python 解释器。默认它会使用 /usr/bin/python,这是 Python2,但是你应该使用一个受支持的 Python 版本

完成了,接下来就是构建包:

$ debuild -b -us -uc

这会在父目录生成一个类似 myhttp_2.0.0-1_amd64.deb 的文件。该文件可在任何兼容的系统上安装。

通常,最好在同一平台上构建用于特定平台(例如 Debian 10.0)的 Debian 包。

你可以将此 Debian 包保存在软件仓库中,并使用例如 Ansible 的工具将其安装在所有相关系统上。

总结

给基于 Debian 的系统的打包应用是一个有着多个步骤的过程。使用 dh_virtualenv 将使过程变得简单明了。


via: https://opensource.com/article/20/4/package-python-applications-linux

作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

一级互联网服务提供商(ISP)将其高速光纤网络连接在一起,形成互联网的骨干网,实现在不同地理区域之间高效地传输流量。

互联网会产生大量的计算机到计算机的流量,要确保所有流量都可以在世界上任何地方之间传输,就需要大量汇聚的高速网络,这些网络统称为互联网骨干网,但是它是如何工作的呢?

互联网的骨干网是什么?

像任何其他网络一样,互联网由接入链路组成,这些接入链路将流量传输到高带宽路由器,路由器又将流量从源地址通过最佳可用路径传输到目的地址。其核心是由相互连接的、彼此对等的各个高速光纤网络而构成的互联网骨干网。

单个独立的核心网络由一级互联网服务提供商(ISP)所拥有。他们的网络连接在一起。这些提供商包括 AT&T、CenturyLink、Cogent Communications,、Deutsche Telekom、Global Telecom and Technology (GTT)、NTT Communications、Sprint、Tata Communications,、Telecom Italia Sparkle、Telia Carrier和 Verizon。

通过将这些长途网连接在一起,一级 ISP 们创建了一个他们可以访问整个路由表的单一的全球性网络,因此他们可以通过逐步层次化地增加本地 ISP 网络来有效地将流量传输到其目的地。

除了物理连接之外,这些骨干网提供商还通过一致的网络协议 TCP/IP 融合在一起,这实际上是两个协议, 传输控制协议 transport control protocol 互联网协议 internet protocol ,它们在计算机之间建立连接,以确保连接可靠,并将消息格式化为数据包。

互联网交接点(IXP)将骨干网连接在一起

骨干网 ISP 在中立位置的对等点通过高速交换机和路由器连接其网络。这些通常由第三方(有时是非营利组织)提供,以促进骨干网的统一。

参与的一级 ISP 会帮助资助 IXP,但不向其他一级 ISP 收取流量传输费用,这种关系称为无结算对等。这种协议消除了可能导致互联网性能下降的潜在财务纠纷。

骨干网有多快?

互联网骨干网由最快的路由器组成,可以提供 100Gbps 的线路速度。这些路由器由包括 Cisco、Extreme、华为、Juniper 和 Nokia 在内的供应商制造,使用边界网关协议(BGP)在彼此之间路由流量。

流量是如何进入骨干网的

在 1 级 ISP 之下是规模较小的 2 级和 3 级 ISP。

3 级 ISP 为企业和消费者提供了互联网接入服务。这些提供商自己没有接入互联网骨干网,因此,他们自己无法将其客户连接到数十亿台互联网上的计算机。

购买一级 ISP 提供商的接入非常昂贵。通常 3 级 ISP 与拥有自己网络的 2 级(区域)ISP 签订合同,利用 2 级 ISP 的网络将流量传输到有限的地理区域,但不能传输到所有互联网上的设备。

为此,2 级 ISP 与 1 级 ISP 签约以访问全球骨干网,并以这种方式使客户可以访问整个互联网。

这种方式使得来自世界一侧的计算机的流量能够连接到另一侧的计算机。流量从源计算机流向 3 级 ISP,再路由到 2 级 ISP,再路由到 1 级骨干网提供商,再路由到正确的 2 级 ISP,最后路由到提供该数据的 3 级接入提供商连接的目标计算机。


via: https://www.networkworld.com/article/3532318/what-is-the-internet-backbone-and-how-it-works.html

作者:Tim Greene 选题:lujun9972 译者:messon007 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

通过这个简单的工作流程创建的研讨会幻灯片,可以在任何浏览器、设备和平台上获得一致的查看效果。

无论你是学习者还是教师,你可能都会认识到采用幻灯片放映来传播知识的在线 研讨会 workshop 的价值。如果你曾经偶然看到过这样一个逐页、逐章设置的井井有条的教程,你可能会想知道创建这样的一个网站有多难。

好吧,让我在这里向你展示,使用全自动化的流程来生成这样的教程是多么容易。

介绍

当我开始将学习内容放到网上置时,体验并不是很好。我想要的是一种可重复的、一致的、易于维护的东西,因为我的内容会随着我教学的技术发展而变化。

我尝试了许多交付模型,从 Asciidoctor 这样的低级代码生成器到在单个 PDF 文件中放置教程。全都不能让我满意。当我举办现场的在座研讨会时,我喜欢使用幻灯片放映,因此我想知道我是否可以为我自己的在线的,自定进度的研讨会体验做同样的事情。

经过一番挖掘,我为创建无痛的研讨会网站打下了基础。当时我已经在使用一个演示文稿生成框架,这对我来说是很有帮助的,因为这个框架可以产生对网站友好的格式(HTML)。

设置

这里是这个项目所需要的基本组件。

  • 研讨会的想法(这是你的问题,我帮不了你)
  • 用于研讨会幻灯片的 Reveal.js
  • GitLab 项目仓库
  • 你常用的 HTML 代码编辑器
  • Web 浏览器
  • 在你的机器上安装好 Git

如果这个列表看起来令人望而生畏,那么有一个快速入门的方法,不需要把所有的东西一个个都拉到一起。你可以用我的模板项目来给你提供幻灯片和项目设置的入门教程。

本文假设你熟悉 Git 和在 Git 平台(如 GitLab)上托管项目。如果你需要指导或教程,请查看我们的Git 入门系列

首先,将模板项目克隆到本地机器上。

$ git clone https://gitlab.com/eschabell/beginners-guide-automated-workshops.git

为此设置一个新的 GitLab 项目,导入模板项目作为初始导入。

研讨会网站有一些重要的文件。在根目录下,你会发现一个名为 .gitlab-ci.yml 的文件,当你向主分支提交修改时(即将拉取请求合并到 master 分支),这个文件会作为触发器。它可以触发将 slides 目录的全部内容复制到 GitLab 项目的 website 文件夹中。

我把它托管在我的 GitLab 账户中,名为 beginners-guide-automated-workshops。当它部署完毕后,你可以在浏览器中通过导航到下列地址查看 slides 目录的内容:

https://eschabell.gitlab.io/beginners-guide-automated-workshops

对于你的用户帐户和项目,URL 如下所示:

https://[YOUR_USERNAME].gitlab.io/[YOUR_PROJECT_NAME]

这些是你开始创建网站内容所需要的基本素材。当你推送修改后,它们会自动生成更新过的研讨会网站。请注意,默认模板包含了几个示例幻灯片,这将是你完成对存储库的完整签入后的第一个研讨会网站。

研讨会模板生成的结果是一个 receive.js 幻灯片,可以在任何浏览器中运行,并可以自动调整大小,几乎可以让任何人在任何地方、任何设备上观看。

这样创建一个方便、易访问的研讨会怎么样?

它是如何工作的

有了这些背景信息,你就可以开始探索研讨会的这些素材,并开始把你的内容放在一起了。你需要的一切都可以在项目的 slides 目录中找到;这里是使用 reveal.js 在浏览器中创建研讨会幻灯片的地方。

你将用来制作研讨会的文件和目录是:

  • default.css文件
  • images 目录
  • index.html文件

在你常用的 HTML/CSS 编辑器中打开每一个文件,然后进行下面描述的修改。你用哪个编辑器并不重要,我更喜欢 RubyMine IDE,因为它能在本地浏览器中提供页面预览。这对我在将内容推送到研讨会网站之前测试内容时很有帮助。

default.css 文件

文件 css/theme/default.css 是一个基础文件,你将在这里为你的研讨会幻灯片设置重要的全局设置。其中值得注意的两个主要的项目是所有幻灯片的默认字体和背景图片。

default.css 中,看一下标有 GLOBAL STYLES 的部分。当前的默认字体在这一行中列出了。

font-family: "Red Hat Display", "Overpass", san-serif;

如果你使用的是非标准字体类型,则必须在以下行中将其导入(Overpass 字体类型就是这样做的):

@import url('SOME_URL');

background 是你创建的每张幻灯片的默认图像。它存储在 images 目录下(见下面),并在下面这一行中设置(重点是图像路径)。

background: url("…/…/images/backgrounds/basic.png")

要设置一个默认背景,只需将这一行指向你要使用的图片。

images 目录

顾名思义,images 目录是用来存储你想在研讨会幻灯片上使用的图片。例如,我通常会把展示研讨会主题进展的截图放在我的个人幻灯片上。

现在,你只需要知道你需要将背景图片存储在一个子目录(backgrounds)中,并将你计划在幻灯片中使用的图片存储在 images 目录中。

index.html 文件

现在你已经把这两个文件整理好了,剩下的时间你就可以在 HTML 文件中创建幻灯片了,从 index.html 开始。为了让你的研讨会网站开始成形,请注意这个文件中的以下三个部分。

  • head部分,在这里你可以设置标题、作者和描述。
  • body 部分,你可以在这里找到要设计的单个幻灯片。
  • 你可以在每个 section 中定义各个幻灯片的内容。

head 部分开始,因为它在顶部。模板项目有三个占位符行供你更新。

<title>INSERT-YOUR-TITLE-HERE</title>
<meta name="description" content="YOUR DESCIPTION HERE.">
<meta name="author" content="YOUR NAME">

title 标签包含文件打开时显示在浏览器选项卡中的文字。请将其改为与你的研讨会的标题相关的内容(或研讨会的某个部分),但记得要简短,因为标签页的标题空间有限。description 元标签包含了对你的工作坊的简短描述,而 author 元标签是你应该把你的名字(如果你是为别人写的,则是工作坊创建者的名字)。

现在继续到 body 部分。你会注意到它被分成了许多 section 标签。body 的开头包含了一个注释,说明你正在为每个标有 section 的打开和关闭的标签创建幻灯片。

<body>
        <div class="reveal">

        <!-- Any section element inside of this container is displayed as a slide -->
        <div class="slides">

接下来,创建你的各个幻灯片,每张幻灯片都用 section 标签封装起来。这个模板包括了一些幻灯片来帮助你开始制作。例如,这里是第一张幻灯片。

<section>
      <div style="width: 1056px; height: 300px">
            <h1>Beginners guide</h1>
            <h2>to automated workshops</h2>
      </div>
      <div style="width: 1056px; height: 200px; text-align: left">
            Brought to you by,<br/>
            YOUR-NAME<br/>
      </div>
      <aside class="notes">Here are notes: Welcome to the workshop!</aside>
</section>

这张幻灯片有两个区域,用 div 标签分隔。用空格隔开了标题和作者。

如果你有一定的 HTML 使用知识,可以尝试各种东西来开发你的研讨会。使用浏览器预览结果的时候真的很方便。有些 IDE 提供了本地查看修改,但你也可以打开 index.html 文件查看你的修改,然后再推送到资源库中。

一旦你对你的研讨会感到满意,推送你的修改,然后等待它们通过持续集成管道。它们将像模板项目一样被托管在 https://eschabell.gitlab.io/beginners-guide-automated-workshops

了解更多

要了解更多关于这个工作流程可以做什么,请查看下面的示例研讨会和托管了研讨会集合的网站。所有这些都是基于本文中描述的工作流程。

研讨会例子:

研讨会集合:

我希望这本新手指南和模板研讨会项目能让你看到,在开发和维护研讨会网站的过程中,可以轻松、无痛地完成。我也希望这个工作流程能让你的研讨会受众几乎在任何设备上都能完全访问你的内容,这样他们就能从你分享的知识中学习到你的知识。


via: https://opensource.com/article/20/4/create-web-tutorial-git

作者:Eric D. Schabell 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出