Quantcast
Channel: Linux 中国◆开源社区
Viewing all 9060 articles
Browse latest View live

浅析 Bash 中的 {花括号}

$
0
0

让我们继续我们的 Bash 基础之旅,来近距离观察一下花括号,了解一下如何和何时使用它们。

在前面的 Bash 基础系列文章中,我们或多或少地使用了一些还没有讲到的符号。在之前文章的很多例子中,我们都使用到了括号,但并没有重点讲解关于括号的内容。

这个系列接下来的文章中,我们会研究括号们的用法:如何使用这些括号?将它们放在不同的位置会有什么不同的效果?除了圆括号、方括号、花括号以外,我们还会接触另外的将一些内容“包裹”起来的符号,例如单引号、双引号和反引号。

在这周,我们先来看看花括号 {}

构造序列

花括号在之前的《点的含义》这篇文章中已经出现过了,当时我们只对点号 . 的用法作了介绍。但在构建一个序列的过程中,同样不可以缺少花括号。

我们使用

echo {0..10}

来顺序输出 0 到 10 这 11 个数。使用

echo {10..0}

可以将这 11 个数倒序输出。更进一步,可以使用

echo {10..0..2}

来跳过其中的奇数。

echo {z..a..2}

则从倒序输出字母表,并跳过其中的第奇数个字母。

以此类推。

还可以将两个序列进行组合:

echo {a..z}{a..z}

这个命令会将从 aa 到 zz 的所有双字母组合依次输出。

这是很有用的。在 Bash 中,定义一个数组的方法是在圆括号 () 中放置各个元素并使用空格隔开,就像这样:

month=("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")

如果需要获取数组中的元素,就要使用方括号 [] 并在其中填入元素的索引:

$ echo ${month[3]} # 数组索引从 0 开始,因此 [3] 对应第 4 个元素
Apr

先不要过分关注这里用到的三种括号,我们等下会讲到。

注意,像上面这样,我们可以定义这样一个数组:

letter_combos=({a..z}{a..z})

其中 letter_combos 变量指向的数组依次包含了从 aa 到 zz 的所有双字母组合。

因此,还可以这样定义一个数组:

dec2bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})

在这里,dec2bin 变量指向的数组按照升序依次包含了所有 8 位的二进制数,也就是 00000000、00000001、00000010,……,11111111。这个数组可以作为一个十进制数到 8 位二进制数的转换器。例如将十进制数 25 转换为二进制数,可以这样执行:

$ echo ${dec2bin[25]}
00011001

对于进制转换,确实还有更好的方法,但这不失为一个有趣的方法。

参数展开

再看回前面的

echo ${month[3]}

在这里,花括号的作用就不是构造序列了,而是用于参数展开parameter expansion。顾名思义,参数展开就是将花括号中的变量展开为这个变量实际的内容。

我们继续使用上面的 month 数组来举例:

month=("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")

注意,Bash 中的数组索引从 0 开始,因此 3 代表第 4 个元素 "Apr"。因此 echo ${month[3]} 在经过参数展开之后,相当于 echo "Apr"

像上面这样将一个数组展开成它所有的元素,只是参数展开的其中一种用法。另外,还可以通过参数展开的方式读取一个字符串变量,并对其进行处理。

例如对于以下这个变量:

a="Too longgg"

如果执行:

echo ${a%gg}

可以输出 “too long”,也就是去掉了最后的两个 g。

在这里,

  • ${...} 告诉 shell 展开花括号里的内容
  • a 就是需要操作的变量
  • % 告诉 shell 需要在展开字符串之后从字符串的末尾去掉某些内容
  • gg 是被去掉的内容

这个特性在转换文件格式的时候会比较有用,我来举个例子:

ImageMagick 是一套可以用于操作图像文件的命令行工具,它有一个 convert 命令。这个 convert 命令的作用是可以为某个格式的图像文件制作一个另一格式的副本。

下面这个命令就是使用 convert 为 JPEG 格式图像 image.jpg 制作一个 PNG 格式的图像副本 image.png

convert image.jpg image.png

在很多 Linux 发行版中都预装了 ImageMagick,如果没有预装,一般可以在发行版对应的软件管理器中找到。

继续来看,在对变量进行展开之后,就可以批量执行相类似的操作了:

i=image.jpg
convert $i ${i%jpg}png

这实际上是将变量 i 末尾的 "jpg" 去掉,然后加上 "png",最终将整个命令拼接成 convert image.jpg image.png

如果你觉得并不怎么样,可以想象一下有成百上千个图像文件需要进行这个操作,而仅仅运行:

for i in *.jpg; do convert $i ${i%jpg}png; done

就瞬间完成任务了。

如果需要去掉字符串开头的部分,就要将上面的 % 改成 # 了:

$ a="Hello World!"
$ echo Goodbye${a#Hello}
Goodbye World!

参数展开还有很多用法,但一般在写脚本的时候才会需要用到。在这个系列以后的文章中就继续提到。

合并输出

最后介绍一个花括号的用法,这个用法很简单,就是可以将多个命令的输出合并在一起。首先看下面这个命令:

echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls > PNGs.txt

以分号分隔开的几条命令都会执行,但只有最后的 ls 命令的结果输出会被重定向到 PNGs.txt 文件中。如果将这几条命令用花括号包裹起来,就像这样:

{ echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls; } > PNGs.txt

执行完毕后,可以看到 PNGs.txt 文件中会包含两次 echo 的内容、find 命令查找到的 PNG 文件以及最后的 ls 命令结果。

需要注意的是,花括号与命令之间需要有空格隔开。因为这里的花括号 {} 是作为 shell 中的保留字,shell 会将这两个符号之间的输出内容组合到一起。

另外,各个命令之间要用分号 ; 分隔,否则命令无法正常运行。

下期预告

在后续的文章中,我会介绍其它“包裹”类符号的用法,敬请关注。


via: https://www.linux.com/blog/learn/2019/2/all-about-curly-braces-bash

作者:Paul Brown 选题:lujun9972 译者:HankChow 校对:wxy

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


降低 Emacs 启动时间的高级技术

$
0
0

Emacs Start Up Profiler》 的作者教你六项减少 Emacs 启动时间的技术。

简而言之:做下面几个步骤:

  1. 使用 Esup 进行性能检测。
  2. 调整垃圾回收的阀值。
  3. 使用 use-package 来自动(延迟)加载所有东西。
  4. 不要使用会引起立即加载的辅助函数。
  5. 参考我的 配置

从 .emacs.d 的失败到现在

我最近宣布了 .emacs.d 的第三次失败,并完成了第四次 Emacs 配置的迭代。演化过程为:

  1. 拷贝并粘贴 elisp 片段到 ~/.emacs 中,希望它能工作。
  2. 借助 el-get 来以更结构化的方式来管理依赖关系。
  3. 放弃自己从零配置,以 Spacemacs 为基础。
  4. 厌倦了 Spacemacs 的复杂性,基于 use-package 重写配置。

本文汇聚了三次重写和创建 《Emacs Start Up Profiler》过程中的技巧。非常感谢 Spacemacs、use-package 等背后的团队。没有这些无私的志愿者,这项任务将会困难得多。

不过守护进程模式又如何呢

在我们开始之前,让我反驳一下优化 Emacs 时的常见观念:“Emacs 旨在作为守护进程来运行的,因此你只需要运行一次而已。”

这个观点很好,只不过:

  • 速度总是越快越好。
  • 配置 Emacs 时,可能会有不得不通过重启 Emacs 的情况。例如,你可能为 post-command-hook 添加了一个运行缓慢的 lambda 函数,很难删掉它。
  • 重启 Emacs 能帮你验证不同会话之间是否还能保留配置。

1、估算当前以及最佳的启动时间

第一步是测量当前的启动时间。最简单的方法就是在启动时显示后续步骤进度的信息。

;; Use a hook so the message doesn't get clobbered by other messages.
(add-hook 'emacs-startup-hook
    (lambda ()
        (message "Emacs ready in %s with %d garbage collections."
            (format "%.2f seconds"
                (float-time
                    (time-subtract after-init-time before-init-time)))
        gcs-done)))

第二步、测量最佳的启动速度,以便了解可能的情况。我的是 0.3 秒。

# -q ignores personal Emacs files but loads the site files.
emacs -q --eval='(message "%s" (emacs-init-time))' 

;; For macOS users:
open -n /Applications/Emacs.app --args -q --eval='(message "%s" (emacs-init-time))'  

2、检测 Emacs 启动指标对你大有帮助

Emacs StartUp Profiler》(ESUP)将会给你顶层语句执行的详细指标。

esup.png

图 1: Emacs Start Up Profiler 截图

警告:Spacemacs 用户需要注意,ESUP 目前与 Spacemacs 的 init.el 文件有冲突。遵照 https://github.com/jschaf/esup/issues/48 上说的进行升级。

3、调高启动时垃圾回收的阀值

这为我节省了 0.3 秒

Emacs 默认值是 760kB,这在现代机器看来极其保守。真正的诀窍在于初始化完成后再把它降到合理的水平。这为我节省了 0.3 秒。

;; Make startup faster by reducing the frequency of garbage
;; collection.  The default is 800 kilobytes.  Measured in bytes.
(setq gc-cons-threshold (* 50 1000 1000))

;; The rest of the init file.

;; Make gc pauses faster by decreasing the threshold.
(setq gc-cons-threshold (* 2 1000 1000))

~/.emacs.d/init.el

4、不要 require 任何东西,而是使用 use-package 来自动加载

让 Emacs 变坏的最好方法就是减少要做的事情。require 会立即加载源文件,但是很少会出现需要在启动阶段就立即需要这些功能的。

use-package 中你只需要声明好需要哪个包中的哪个功能,use-package 就会帮你完成正确的事情。它看起来是这样的:

(use-package evil-lisp-state ; the Melpa package name

  :defer t ; autoload this package

  :init ; Code to run immediately.
  (setq evil-lisp-state-global nil)

  :config ; Code to run after the package is loaded.
  (abn/define-leader-keys "k" evil-lisp-state-map))

可以通过查看 features 变量来查看 Emacs 现在加载了那些包。想要更好看的输出可以使用 lpkg explorer 或者我在 abn-funcs-benchmark.el 中的变体。输出看起来类似这样的:

479 features currently loaded
  - abn-funcs-benchmark: /Users/jschaf/.dotfiles/emacs/funcs/abn-funcs-benchmark.el
  - evil-surround: /Users/jschaf/.emacs.d/elpa/evil-surround-20170910.1952/evil-surround.elc
  - misearch: /Applications/Emacs.app/Contents/Resources/lisp/misearch.elc
  - multi-isearch: nil
  - <many more>

5、不要使用辅助函数来设置模式

通常,Emacs 包会建议通过运行一个辅助函数来设置键绑定。下面是一些例子:

  • (evil-escape-mode)
  • (windmove-default-keybindings) ; 设置快捷键。
  • (yas-global-mode 1) ; 复杂的片段配置。

可以通过 use-package 来对此进行重构以提高启动速度。这些辅助函数只会让你立即加载那些尚用不到的包。

下面这个例子告诉你如何自动加载 evil-escape-mode

;; The definition of evil-escape-mode.
(define-minor-mode evil-escape-mode
  (if evil-escape-mode
      (add-hook 'pre-command-hook 'evil-escape-pre-command-hook)
    (remove-hook 'pre-command-hook 'evil-escape-pre-command-hook)))

;; Before:
(evil-escape-mode)

;; After:
(use-package evil-escape
  :defer t
  ;; Only needed for functions without an autoload comment (;;;###autoload).
  :commands (evil-escape-pre-command-hook) 

  ;; Adding to a hook won't load the function until we invoke it.
  ;; With pre-command-hook, that means the first command we run will
  ;; load evil-escape.
  :init (add-hook 'pre-command-hook 'evil-escape-pre-command-hook))

下面来看一个关于 org-babel 的例子,这个例子更为复杂。我们通常的配置时这样的:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((shell . t)
   (emacs-lisp . nil)))

这不是个好的配置,因为 org-babel-do-load-languages 定义在 org.el 中,而该文件有超过 2 万 4 千行的代码,需要花 0.2 秒来加载。通过查看源代码可以看到 org-babel-do-load-languages 仅仅只是加载 ob-<lang> 包而已,像这样:

;; From org.el in the org-babel-do-load-languages function.
(require (intern (concat "ob-" lang)))

而在 ob-<lang>.el 文件中,我们只关心其中的两个方法 org-babel-execute:<lang>org-babel-expand-body:<lang>。我们可以延时加载 org-babel 相关功能而无需调用 org-babel-do-load-languages,像这样:

;; Avoid `org-babel-do-load-languages' since it does an eager require.
(use-package ob-python
  :defer t
  :ensure org-plus-contrib
  :commands (org-babel-execute:python))

(use-package ob-shell
  :defer t
  :ensure org-plus-contrib
  :commands
  (org-babel-execute:sh
   org-babel-expand-body:sh

   org-babel-execute:bash
   org-babel-expand-body:bash))

6、使用惰性定时器来推迟加载非立即需要的包

我推迟加载了 9 个包,这帮我节省了 0.4 秒

有些包特别有用,你希望可以很快就能使用它们,但是它们本身在 Emacs 启动过程中又不是必须的。这些软件包包括:

  • recentf:保存最近的编辑过的那些文件。
  • saveplace:保存访问过文件的光标位置。
  • server:开启 Emacs 守护进程。
  • autorevert:自动重载被修改过的文件。
  • paren:高亮匹配的括号。
  • projectile:项目管理工具。
  • whitespace:高亮行尾的空格。

不要 require 这些软件包,而是等到空闲 N 秒后再加载它们。我在 1 秒后加载那些比较重要的包,在 2 秒后加载其他所有的包。

(use-package recentf
  ;; Loads after 1 second of idle time.
  :defer 1)

(use-package uniquify
  ;; Less important than recentf.
  :defer 2)

不值得的优化

不要费力把你的 Emacs 配置文件编译成字节码了。这只节省了大约 0.05 秒。把配置文件编译成字节码还可能导致源文件与编译后的文件不一致从而难以重现错误进行调试。


via: https://blog.d46.us/advanced-emacs-startup/

作者:Joe Schafer 选题:lujun9972 译者:lujun9972 校对:wxy

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

在 Linux 中如何删除文件中的空行

$
0
0

有时你可能需要在 Linux 中删除某个文件中的空行。如果是的,你可以使用下面方法中的其中一个。有很多方法可以做到,但我在这里只是列举一些简单的方法。

你可能已经知道 grepawksed 命令是专门用来处理文本数据的工具。

如果你想了解更多关于这些命令的文章,请访问这几个 URL:在 Linux 中创建指定大小的文件的几种方法在 Linux 中创建一个文件的几种方法 以及 在 Linux 中删除一个文件中的匹配的字符串

这些属于高级命令,它们可用在大多数 shell 脚本中执行所需的操作。

下列 5 种方法可以做到。

  • sed:过滤和替换文本的流编辑器。
  • grep:输出匹配到的行。
  • cat:合并文件并打印内容到标准输出。
  • tr:替换或删除字符。
  • awk:awk 工具用于执行 awk 语言编写的程序,专门用于文本处理。
  • perl:Perl 是一种用于处理文本的编程语言。

我创建了一个 2daygeek.txt 文件来测试这些命令。下面是文件的内容。

$ cat 2daygeek.txt
2daygeek.com is a best Linux blog to learn Linux.

It's FIVE years old blog.

This website is maintained by Magesh M, it's licensed under CC BY-NC 4.0.

He got two GIRL babys.

Her names are Tanisha & Renusha.

现在一切就绪,我们准备开始用多种方法来验证。

使用 sed 命令

sed 是一个流编辑器stream editor。流编辑器是用来编辑输入流(文件或管道)中的文本的。

$ sed '/^$/d' 2daygeek.txt
2daygeek.com is a best Linux blog to learn Linux.
It's FIVE years old blog.
This website is maintained by Magesh M, it's licensed under CC BY-NC 4.0.
He got two GIRL babes.
Her names are Tanisha & Renusha.

以下是命令展开的细节:

  • sed: 该命令本身。
  • //: 标记匹配范围。
  • ^: 匹配字符串开头。
  • $: 匹配字符串结尾。
  • d: 删除匹配的字符串。
  • 2daygeek.txt: 源文件名。

使用 grep 命令

grep 可以通过正则表达式在文件中搜索。该表达式可以是一行或多行空行分割的字符,grep 会打印所有匹配的内容。

$ grep . 2daygeek.txt
or
$ grep -Ev "^$" 2daygeek.txt
or
$ grep -v -e '^$' 2daygeek.txt
2daygeek.com is a best Linux blog to learn Linux.
It's FIVE years old blog.
This website is maintained by Magesh M, it's licensed under CC BY-NC 4.0.
He got two GIRL babes.
Her names are Tanisha & Renusha.

以下是命令展开的细节:

  • grep: 该命令本身。
  • .: 替换任意字符。
  • ^: 匹配字符串开头。
  • $: 匹配字符串结尾。
  • E: 使用扩展正则匹配模式。
  • e: 使用常规正则匹配模式。
  • v: 反向匹配。
  • 2daygeek.txt: 源文件名。

使用 awk 命令

awk 可以执行使用 awk 语言写的脚本,大多是专用于处理文本的。awk 脚本是一系列 awk 命令和正则的组合。

$ awk NF 2daygeek.txt
or
$ awk '!/^$/' 2daygeek.txt
or
$ awk '/./' 2daygeek.txt
2daygeek.com is a best Linux blog to learn Linux.
It's FIVE years old blog.
This website is maintained by Magesh M, it's licensed under CC BY-NC 4.0.
He got two GIRL babes.
Her names are Tanisha & Renusha.

以下是命令展开的细节:

  • awk: 该命令本身。
  • //: 标记匹配范围。
  • ^: 匹配字符串开头。
  • $: 匹配字符串结尾。
  • .: 匹配任意字符。
  • !: 删除匹配的字符串。
  • 2daygeek.txt: 源文件名。

使用 cat 和 tr 命令 组合

cat串联(拼接)concatenate的简写。经常用于在 Linux 中读取一个文件的内容。

cat 是在类 Unix 系统中使用频率最高的命令之一。它提供了常用的三个处理文本文件的功能:显示文件内容、将多个文件拼接成一个,以及创建一个新文件。

tr 可以将标准输入中的字符转换,压缩或删除,然后重定向到标准输出。

$ cat 2daygeek.txt | tr -s '\n'
2daygeek.com is a best Linux blog to learn Linux.
It's FIVE years old blog.
This website is maintained by Magesh M, it's licensed under CC BY-NC 4.0.
He got two GIRL babes.
Her names are Tanisha & Renusha.

以下是命令展开的细节:

  • cat: cat 命令本身。
  • tr: tr 命令本身。
  • |: 管道符号。它可以将前面的命令的标准输出作为下一个命令的标准输入。
  • s: 替换标数据集中任意多个重复字符为一个。
  • \n: 添加一个新的换行。
  • 2daygeek.txt: 源文件名。

使用 perl 命令

Perl 表示实用的提取和报告语言Practical Extraction and Reporting Language。Perl 在初期被设计为一个专用于文本处理的编程语言,现在已扩展应用到 Linux 系统管理,网络编程和网站开发等多个领域。

$ perl -ne 'print if /\S/' 2daygeek.txt
2daygeek.com is a best Linux blog to learn Linux.
It's FIVE years old blog.
This website is maintained by Magesh M, it's licensed under CC BY-NC 4.0.
He got two GIRL babes.
Her names are Tanisha & Renusha.

以下是命令展开的细节:

  • perl: perl 命令。
  • n: 逐行读入数据。
  • e: 执行某个命令。
  • print: 打印信息。
  • if: if 条件分支。
  • //: 标记匹配范围。
  • \S: 匹配任意非空白字符。
  • 2daygeek.txt: 源文件名。

via: https://www.2daygeek.com/remove-delete-empty-lines-in-a-file-in-linux/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:pityonline 校对:wxy

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

Emoji-Log:编写 Git 提交信息的新方法

$
0
0

使用 Emoji-Log 为你的提交添加上下文。

我是一名全职的开源开发人员,我喜欢称自己为“开源者”。我从事开源软件工作已经超过十年,并构建了数以百计的开源软件应用程序。

同时我也是“避免重复工作Don’t Repeat Yourself”(DRY)哲学的忠实粉丝,并且我相信编写更好的 Git 提交消息是 DRY 的一个重要组成部分。它们具有足够的上下文关联,可以作为你开源软件的变更日志。我编写的众多工作流之一是 Emoji-Log,它是一个简单易用的开源 Git 提交日志标准。它通过使用表情符号来创建更好的 Git 提交消息,从而改善了开发人员的体验(DX)。

我使用 Emoji-Log 构建了 VSCode Tips & Tricks 仓库 和我的 🦄 紫色 VSCode 主题仓库,以及一个看起来很漂亮的自动变更日志

Emoji-Log 的哲学

我喜欢(很多)表情符号,我很喜欢它们。编程、代码、极客/书呆子、开源……所有这一切本质上都很枯燥,有时甚至很无聊。表情符号帮助我添加颜色和情感。想要将感受添加到这个 2D 的、平板的、基于文本的代码世界并没有错。

相比于数百个表情符号,我学会的更好办法是让类别较小和普遍性。以下是指导使用 Emoji-Log 编写提交信息的原则:

  • 必要的
    • Git 提交信息是必要的。
    • 像下订单一样编写提交信息。
      • 例如,使用 ✅ Add 而不是 ❌ Added
      • 例如,使用 ✅ Create 而不是 ❌ Creating
  • 规则
    • 少数类别易于记忆。
    • 不多也不少
      • 例如 📦 NEW👌 IMPROVE🐛 FIX📖 DOC🚀 RELEASE✅ TEST
  • 行为
    • 让 Git 的提交基于你所采取的操作
    • 使用像 VSCode 这样的编辑器来提交带有提交信息的正确文件。

编写提交信息

仅使用以下 Git 提交信息。简单而小巧的占地面积是 Emoji-Log 的核心。

  • 📦 NEW: 必要的信息
    • 当你添加一些全新的东西时使用。
      • 例如 📦 NEW: 添加 Git 忽略的文件
  • 👌 IMPROVE: 必要的信息
    • 用于改进/增强代码段,如重构等。
      • 例如 👌 IMPROVE: 远程 IP API 函数
  • 🐛 FIX: 必要的信息
    • 修复 bug 时使用,不用解释了吧?
      • 例如 🐛 FIX: Case converter
  • 📖 DOC: 必要的信息
    • 添加文档时使用,比如 README.md 甚至是内联文档。
      • 例如 📖 DOC: API 接口教程
  • 🚀 RELEASE: 必要的信息
    • 发布新版本时使用。例如, 🚀 RELEASE: Version 2.0.0
  • ✅ TEST: 必要的信息
    • 发布新版本时使用。
      • 例如 ✅ TEST: 模拟用户登录/注销

就这些了,不多不少。

Emoji-Log 函数

为了快速构建原型,我写了以下函数,你可以将它们添加到 .bashrc 或者 .zshrc 文件中以快速使用 Emoji-Log。

#.# Better Git Logs.

### Using EMOJI-LOG (https://github.com/ahmadawais/Emoji-Log).

# Git Commit, Add all and Push — in one step.

function gcap() {
    git add . && git commit -m "$*" && git push
}

# NEW.
function gnew() {
    gcap "📦 NEW: $@"
}

# IMPROVE.
function gimp() {
    gcap "👌 IMPROVE: $@"
}

# FIX.
function gfix() {
    gcap "🐛 FIX: $@"
}

# RELEASE.
function grlz() {
    gcap "🚀 RELEASE: $@"
}

# DOC.
function gdoc() {
    gcap "📖 DOC: $@"
}

# TEST.
function gtst() {
    gcap "✅ TEST: $@"
}

要为 fish shell 安装这些函数,运行以下命令:

function gcap; git add .; and git commit -m "$argv"; and git push; end;
function gnew; gcap "📦 NEW: $argv"; end
function gimp; gcap "👌 IMPROVE: $argv"; end;
function gfix; gcap "🐛 FIX: $argv"; end;
function grlz; gcap "🚀 RELEASE: $argv"; end;
function gdoc; gcap "📖 DOC: $argv"; end;
function gtst; gcap "✅ TEST: $argv"; end;
funcsave gcap
funcsave gnew
funcsave gimp
funcsave gfix
funcsave grlz
funcsave gdoc
funcsave gtst

如果你愿意,可以将这些别名直接粘贴到 ~/.gitconfig 文件:

# Git Commit, Add all and Push — in one step.
cap = "!f() { git add .; git commit -m \"$@\"; git push; }; f"

# NEW.
new = "!f() { git cap \"📦 NEW: $@\"; }; f"
# IMPROVE.
imp = "!f() { git cap \"👌 IMPROVE: $@\"; }; f"
# FIX.
fix = "!f() { git cap \"🐛 FIX: $@\"; }; f"
# RELEASE.
rlz = "!f() { git cap \"🚀 RELEASE: $@\"; }; f"
# DOC.
doc = "!f() { git cap \"📖 DOC: $@\"; }; f"
# TEST.
tst = "!f() { git cap \"✅ TEST: $@\"; }; f"

Emoji-Log 例子

这里列出了一些使用 Emoji-Log 的仓库:

你呢?如果你的仓库使用 Emoji-Log,请将这个 Emoji-Log 徽章放到你的 README 中,并给我发送一个拉取请求,以让我可以将你的仓库列在这里。


via: https://opensource.com/article/19/2/emoji-log-git-commit-messages

作者:Ahmad Awais 选题:lujun9972 译者:MjSeven 校对:wxy

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

给大家安利一下 PowerShell

$
0
0

代码更简洁、脚本更清晰、跨平台一致性等好处是让 Linux 和 OS X 用户喜爱 PowerShell 的原因。

今年(2018)早些时候,Powershell CoreMIT 开源协议发布了正式可用版(GA)。PowerShell 算不上是新技术。自 2006 年为 Windows 发布了第一版 PowerShell 以来,PowerShell 的创建者在结合了 Unⅸ shell 的强大和灵活的同时也在弥补他们所意识到的缺点,特别是从组合命令中获取值时所要进行的文本操作。

在发布了 5 个主要版本之后,PowerShell 已经可以在所有主流操作系统上(包括 OS X 和 Linux)本地运行同样创新的 shell 和命令行环境。一些人(应该说是大多数人)可能依旧在嘲弄这位诞生于 Windows 的闯入者的大胆和冒失:为那些远古以来(从千禧年开始算不算?)便存在着强大的 shell 环境的平台引荐自己。在本帖中,我希望可以将 PowerShell 的优势介绍给大家,甚至是那些经验老道的用户。

跨平台一致性

如果你计划将脚本从一个执行环境迁移到另一个平台时,你需要确保只使用了那些在两个平台下都起作用的命令和语法。比如在 GNU 系统中,你可以通过以下方式获取昨天的日期:

date --date="1 day ago"

在 BSD 系统中(比如 OS X),上述语法将没办法工作,因为 BSD 的 date 工具需要以下语法:

date -v -1d

因为 PowerShell 具有宽松的许可证,并且在所有的平台都有构建,所以你可以把 PowerShell 和你的应用一起打包。因此,当你的脚本运行在目标系统中时,它们会运行在一样的 shell 环境中,使用与你的测试环境中同样的命令实现。

对象和结构化数据

*nix 命令和工具依赖于你使用和操控非结构化数据的能力。对于那些长期活在 sedgrepawk 环境下的人们来说,这可能是小菜一碟,但现在有更好的选择。

让我们使用 PowerShell 重写那个获取昨天日期的实例。为了获取当前日期,使用 Get-Date cmdlet(读作 “commandlet”):

> Get-Date                        

Sunday, January 21, 2018 8:12:41 PM

你所看到的输出实际上并不是一个文本字符串。不如说,这是 .Net Core 对象的一个字符串表现形式。就像任何 OOP 环境中的对象一样,它具有类型以及你可以调用的方法。

让我们来证明这一点:

> $(Get-Date).GetType().FullName
System.DateTime

$(...) 语法就像你所期望的 POSIX shell 中那样,计算括弧中的命令然后替换整个表达式。但是在 PowerShell 中,这种表达式中的 $ 是可选的。并且,最重要的是,结果是一个 .Net 对象,而不是文本。因此我们可以调用该对象中的 GetType() 方法来获取该对象类型(类似于 Java 中的 Class 对象),FullName 属性 则用来获取该类型的全称。

那么,这种对象导向的 shell 是如何让你的工作变得更加简单呢?

首先,你可将任何对象排进 Get-Member cmdlet 来查看它提供的所有方法和属性。

> (Get-Date) | Get-Member
PS /home/yevster/Documents/ArticlesInProgress> $(Get-Date) | Get-Member         


   TypeName: System.DateTime

Name                 MemberType     Definition                                 
----                 ----------     ----------                                 
Add                  Method         datetime Add(timespan value)               
AddDays              Method         datetime AddDays(double value)             
AddHours             Method         datetime AddHours(double value)            
AddMilliseconds      Method         datetime AddMilliseconds(double value)     
AddMinutes           Method         datetime AddMinutes(double value)          
AddMonths            Method         datetime AddMonths(int months)             
AddSeconds           Method         datetime AddSeconds(double value)          
AddTicks             Method         datetime AddTicks(long value)              
AddYears             Method         datetime AddYears(int value)               
CompareTo            Method         int CompareTo(System.Object value), int ...

你可以很快的看到 DateTime 对象具有一个 AddDays 方法,从而可以使用它来快速的获取昨天的日期:

> (Get-Date).AddDays(-1)

Saturday, January 20, 2018 8:24:42 PM

为了做一些更刺激的事,让我们调用 Yahoo 的天气服务(因为它不需要 API 令牌)然后获取你的本地天气。

$city="Boston"
$state="MA"
$url="https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22${city}%2C%20${state}%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"

现在,我们可以使用老派的方法然后直接运行 curl $url 来获取 JSON 二进制对象,或者……

$weather=(Invoke-RestMethod $url)

如果你查看了 $weather 类型(运行 echo $weather.GetType().FullName),你将会发现它是一个 PSCustomObject。这是一个用来反射 JSON 结构的动态对象。

然后 PowerShell 可以通过 tab 补齐来帮助你完成命令输入。只需要输入 $weather.(确报包含了 .)然后按下 Tab 键。你将看到所有根级别的 JSON 键。输入其中的一个,然后跟上 . ,再一次按下 Tab 键,你将看到它所有的子键(如果有的话)。

因此,你可以轻易的导航到你所想要的数据:

> echo $weather.query.results.channel.atmosphere.pressure                         
1019.0

> echo $weather.query.results.channel.wind.chill                                 41

并且如果你有非结构化的 JSON 或 CSV 数据(通过外部命令返回的),只需要将它相应的排进 ConverFrom-JsonConvertFrom-CSV cmdlet,然后你可以得到一个漂亮干净的对象。

计算 vs. 自动化

我们使用 shell 用于两种目的。一个是用于计算,运行独立的命令然后手动响应它们的输出。另一个是自动化,通过写脚本执行多个命令,然后以编程的方式相应它们的输出。

我们大多数人都能发现这两种目的在 shell 上的不同且互相冲突的要求。计算任务要求 shell 简洁明了。用户输入的越少越好。但如果用户输入对其他用户来说几乎难以理解,那这一点就不重要了。脚本,从另一个角度来讲是代码。可读性和可维护性是关键。这一方面,POSIX 工具通常是失败的。虽然一些命令通常会为它们的参数提供简洁明了的语法(如:-f--force),但是命令名字本身就不简洁明了。

PowerShell 提供了几个机制来消除这种浮士德式的平衡。

首先,tab 补齐可以消除键入参数名的需要。比如:键入 Get-Random -Mi,按下 Tab 然后 PowerShell 将会为你完成参数:Get-Random -Minimum。但是如果你想更简洁一些,你甚至不需要按下 Tab。如下所示,PowerShell 可以理解:

Get-Random -Mi 1 -Ma 10

因为 MiMa 每一个都具有独立不同的补齐。

你可能已经留意到所有的 PowerShell cmdlet 名称具有动名词结构。这有助于脚本的可读性,但是你可能不想一而再、再而三的键入 Get-。所以并不需要!如果你之间键入了一个名词而没有动词的话,PowerShell 将查找带有该名词的 Get- 命令。

小心:尽管 PowerShell 不区分大小写,但在使用 PowerShell 命令是时,名词首字母大写是一个好习惯。比如,键入 date 将会调用系统中的 date 工具。键入 Date 将会调用 PowerShell 的 Get-Date cmdlet。

如果这还不够,PowerShell 还提供了别名,用来创建简单的名字。比如,如果键入 alias -name cd,你将会发现 cd 在 PowerShell 实际上时 Set-Location 命令的别名。

所以回顾以下 —— 你可以使用强大的 tab 补全、别名,和名词补全来保持命令名词简洁、自动化和一致性参数名截断,与此同时还可以享受丰富、可读的语法格式。

那么……你看呢?

这些只是 PowerShell 的一部分优势。还有更多特性和 cmdlet,我还没讨论(如果你想弄哭 grep 的话,可以查看 Where-Object 或其别称 ?)。如果你有点怀旧的话,PowerShell 可以为你加载原来的本地工具。但是给自己足够的时间来适应 PowerShell 面向对象 cmdlet 的世界,然后你将发现自己会选择忘记回去的路。


via: https://opensource.com/article/18/2/powershell-people

作者:Yev Bronshteyn 译者:sanfusu 校对:wxy

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

如何修复 Mozilla Firefox 中出现的 “Network Protocol Error”

$
0
0

Mozilla Firefox 多年来一直是我的默认 Web 浏览器,我每天用它来进行日常网络活动,例如访问邮件,浏览喜欢的网站等。今天,我在使用 Firefox 时遇到了一个奇怪的错误。我试图在 Reddit 平台上分享我们的一个指南时,在 Firefox 上出现了以下错误消息:

Network Protocol Error

Firefox has experienced a network protocol violation that cannot be repaired.

The page you are trying to view cannot be shown because an error in the network protocol was detected.

Please contact the website owners to inform them of this problem.

老实说,我有点慌,我以为可能是我的系统受到了某种恶意软件的影响。哈哈!但是我发现我错了。我在 Arch Linux 桌面上使用的是最新的 Firefox 版本,我在 Chromium 浏览器中打开了相同的链接,它正确显示了,我猜这是 Firefox 相关的错误。在谷歌上搜索后,我解决了这个问题,如下所述。

出现这种问题主要是因为“浏览器缓存”,如果你遇到此类错误,例如 “Network Protocol Error” 或 “Corrupted Content Error”,遵循以下任何一种方法。

方法 1:

要修复 “Network Protocol Error” 或 “Corrupted Content Error”,你需要在重新加载网页时绕过缓存。为此,按下 Ctrl + F5Ctrl + Shift + R 快捷键,它将从服务器重新加载页面,而不是从 Firefox 缓存加载。这样网页就应该可以正常工作了。

方法 2:

如果方法 1 不起作用,尝试以下方法。

打开 “Edit - > Preferences”,在 &ldquoreferences” 窗口中,打开左窗格中的 &ldquorivacy & Security” 选项卡,单击 “Clear Data” 选项清除 Firefox 缓存。

确保你选中了 “Cookies and Site Data” 和 “Cached Web Content” 选项,然后单击 “Clear”。

完成!现在 Cookie 和离线内容将被删除。注意,Firefox 可能会将你从登录的网站中注销,稍后你可以重新登录这些网站。最后,关闭 Firefox 浏览器并重新启动系统。现在网页加载没有任何问题。

希望这对你有帮助。更多好东西要来了,敬请关注!

干杯!


via: https://www.ostechnix.com/how-to-fix-network-protocol-error-on-mozilla-firefox/

作者:SK 选题:lujun9972 译者:MjSeven 校对:wxy

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

第 1 届全球学生开源年会 sosconf 将于今年八月在美国南加州大学举行

$
0
0

学生开源年会:Studens Open Source Conference(简称 sosconf),是一个由学生组织、面向学生的非盈利全球性开源技术峰会。sosconf 2019 将于 8 月下旬在美国南加州大学举行。 

2019 年 3 月 18 日讯,美国洛杉矶

学生开源年会组委会今天正式宣布,第 1 届全球学生开源年会 sosconf 2019 将于今年 8 月在美国南加州大学举行,这是继去年第 0 届学生开源年会成功召开后,该会议第一次在美国举办。

学生开源年会(sosconf )是首个由学生组织面向学生的非盈利社区全球性开源技术峰会,峰会基于开放源代码的理念,鼓励学生享受开源、了解开源、参与开源、贡献开源,并能从开源中得到实践和乐趣。峰会每年在不同国家不同城市举办,从演讲者、组织者、志愿者到听众,绝大多数为在校学生,包括中学生、大学生硕士研究生和博士研究生,其中演讲者和志愿者仅限学生身份报名,听众不做任何限制。

第 1 届全球学生开源年会 sosconf 将于 2019 年 8 月在美国南加州大学举行

南加州大学University of Southern California ,简称南加大,位于加州洛杉矶市中心,由监理会于 1880 年创立,是加州最古老的私立研究型大学,亦是全球顶尖的重要学府,人类史上首位登上月球的宇航员阿姆斯特朗、导演斯皮尔伯格、日本首相安倍晋三、诺贝尔奖获得者盖尔曼等大一批知名人士均从该校毕业,本次在南加州大学举办的 sosconf 2019 也是该校首次举办开源盛会,预计将有超过 1500 名来自世界各地的与会者亲临现场参加。

学生开源年会(sosconf)由开源工场息壤开源生活方式平台创办,致力于纯粹的技术交流和多元的思想碰撞,为学生群体建立活跃、多元、纯粹、关注学习和未来的技术社区,让不同国家学生积极交流,站上国际舞台,展示在实验室和书本之外的无尽创想。该会议旨在积极推动学生参与开放源代码运动的历史进程,2018 年成功地在重庆举办第 0 届学生开源年会,计划未来在不同国家举办当地语言版本的学生开源年会。

本次峰会 sosconf 2019 将围绕着“开源”主题,囊括开源项目、网络安全、云计算、大数据、编程语言、人工智能、艺术设计、机器学习、区块链、社区治理等领域,并特设《全球学生开源项目博览会》板块,针对全球各国学生身份创办和发起的优秀开源项目设立现场展示区域和线上展示区域,以便让更多人了解学生开源项目,以及促进不同区域不同学生项目的可持续发展、交流和孵育。

随着活动正式宣布启动,大会即将开放志愿者报名(限学生)、演讲投稿(限学生)、征集赞助商等工作、欢迎关注开源领域的学生联系主办方报名参加,请访问学生开源年会官方网站 https://sosconf.org 获得更多资讯,以下通信方式为学生开源年会的官方联络方式,敬请关注:

全球学生开源年会提供一个绝佳的、多元友好的国际学生交流平台,帮助学生获取顶尖企业的关注,同时有利于企业发掘开源领域的种子学生。世界各地不同国家的学生讲者和各个领域的专业人士的协作交流将会进一步促进开源的发展和对学生、青年人的吸引力,我们鼓励学生亲临现场,交流在开源项目和社区中积累的想法与经验,分享蕴含在编码中的激情,同时畅聊属于开源理念的未来。

Linux 安全:Cmd 提供可视化控制用户活动

$
0
0

Cmd 可以帮助机构监控、验证和阻止那些超出系统预期使用范围的活动。

有一个新的 Linux 安全工具你值得了解一下:Cmd(读作 “see em dee”),它极大地改变了可以对 Linux 用户进行控制的类型。它远远超出了传统的用户权限配置,并在监视和控制用户能够在 Linux 系统上运行的命令方面发挥了积极作用。

Cmd 由同名公司开发,专注于云应用。鉴于越来越多的应用迁移到依赖于 Linux 的云环境中,而可用工具的缺口使得难以充分实施所需的安全性。除此以外,Cmd 还可用于管理和保护本地系统。

Cmd 与传统 Linux 安全控件的区别

Cmd 公司的领导 Milun Tesovic 和 Jake King 表示,除非了解了用户日常如何工作以及什么被视是“正常”,机构无法自信地预测或控制用户行为。他们寻求提供一种能够精细控制、监控和验证用户活动的工具。

Cmd 通过形成用户活动配置文件(描绘这些用户通常进行的活动)来监视用户活动,注意其在线行为的异常(登录时间、使用的命令、用户位置等),以及预防和报告某些意味着系统攻击的活动(例如,下载或修改文件和运行特权命令)。产品的行为是可配置的,可以快速进行更改。

如今大多数人用来检测威胁、识别漏洞和控制用户权限的工具,我们已经使用了很久了,但我们仍在努力抗争保持系统和数据的安全。Cmd 让我们更能够确定恶意用户的意图,无论这些用户是设法侵入帐户还是代表内部威胁。

1 sources live sessions

查看实时 Linux 会话

Cmd 如何工作?

在监视和管理用户活动时,Cmd 可以:

  • 收集描述用户活动的信息
  • 使用基线来确定什么是正常的
  • 使用特定指标检测并主动防止威胁
  • 向负责人发送警报

2 triggers

在 Cmd 中构建自定义策略

Cmd 扩展了系统管理员通过传统方法可以控制的内容,例如配置 sudo 权限,提供更精细和特定情境的控制。

管理员可以选择可以与 Linux 系统管理员所管理的用户权限控制分开管理的升级策略。

Cmd 客户端提供实时可视化(而不是事后日志分析),并且可以阻止操作、要求额外的身份验证或根据需要进行协商授权。

此外,如果有用户位置信息,Cmd 支持基于地理定位的自定义规则。并且可以在几分钟内将新策略推送到部署在主机上的客户端。

3 command blocked

在 Cmd 中构建触发器查询

Cmd 的融资新闻

Cmd 最近完成了由 GV (前身为 Google Ventures)领投,Expa、Amplify Partners 和其他战略投资者跟投的 1500 万美元的融资。这使该公司的融资金额达到了 2160 万美元,这将帮助其继续为该产品增加新的防御能力并发展其工程师团队。

此外,该公司还任命 GV 的普通合伙人 Karim Faris 为董事会成员。


via: https://www.networkworld.com/article/3342454/linux-security-cmd-provides-visibility-control-over-user-activity.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:geekpi 校对:wxy

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


toplip:一款十分强大的文件加密解密 CLI 工具

$
0
0

在市场上能找到许多用来保护文件的文档加密工具。我们已经介绍过其中一些例如 CryptomaterCryptkeeperCryptGoCryptrTomb,以及 GnuPG 等加密工具。今天我们将讨论另一款叫做 “toplip” 的命令行文件加密解密工具。它是一款使用一种叫做 AES256 的强大加密方法的自由开源的加密工具。它同时也使用了 XTS-AES 设计以保护你的隐私数据。它还使用了 Scrypt,一种基于密码的密钥生成函数来保护你的密码免于暴力破解。

优秀的特性

相比于其它文件加密工具,toplip 自带以下独特且杰出的特性。

  • 非常强大的基于 XTS-AES256 的加密方法。
  • 合理的推诿Plausible deniability
  • 加密并嵌入文件到图片(PNG/JPG)中。
  • 多重密码保护。
  • 可防护直接暴力破解。
  • 无可辨识的输出标记。
  • 开源(GPLv3)。

安装 toplip

没有什么需要安装的。toplip 是独立的可执行二进制文件。你所要做的仅是从 产品官方页面 下载最新版的 toplip 并赋予它可执行权限。为此你只要运行:

chmod +x toplip

使用

如果你不带任何参数运行 toplip,你将看到帮助页面。

./toplip

请允许我给你展示一些例子。

为了达到指导目的,我建了两个文件 file1file2。我同时也有 toplip 可执行二进制文件。我把它们全都保存进一个叫做 test 的目录。

加密/解密单个文件

现在让我们加密 file1。为此,运行:

./toplip file1 > file1.encrypted

这行命令将让你输入密码。一旦你输入完密码,它就会加密 file1 的内容并将它们保存进你当前工作目录下一个叫做 file1.encrypted 的文件。

上述命令行的示例输出将会是这样:

This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip file1 Passphrase #1: generating keys...Done 
Encrypting...Done

为了验证文件是否的确经过加密,试着打开它你会发现一些随机的字符。

为了解密加密过的文件,像以下这样使用 -d 参数:

./toplip -d file1.encrypted

这行命令会解密提供的文档并在终端窗口显示内容。

为了保存文档而不是写入到标准输出,运行:

./toplip -d file1.encrypted > file1.decrypted

输入正确的密码解密文档。file1.encrypted 的所有内容将会存入一个叫做 file1.decrypted 的文档。

请不要用这种命名方法,我这样用仅仅是为了便于理解。使用其它难以预测的名字。

加密/解密多个文件

现在我们将使用两个分别的密码加密每个文件。

./toplip -alt file1 file2 > file3.encrypted

你会被要求为每个文件输入一个密码,使用不同的密码。

上述命令行的示例输出将会是这样:

This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip 
file2 Passphrase #1 : generating keys...Done 
file1 Passphrase #1 : generating keys...Done 
Encrypting...Done

上述命令所做的是加密两个文件的内容并将它们保存进一个单独的叫做 file3.encrypted 的文件。在保存中分别给予各自的密码。比如说如果你提供 file1 的密码,toplip 将复原 file1。如果你提供 file2 的密码,toplip 将复原 file2

每个 toplip 加密输出都可能包含最多四个单独的文件,并且每个文件都建有各自独特的密码。由于加密输出放在一起的方式,一下判断出是否存在多个文档不是一件容易的事。默认情况下,甚至就算确实只有一个文件是由 toplip 加密,随机数据都会自动加上。如果指定了多于一个文件,每个都有自己的密码,那么你可以有选择性地独立解码每个文件,以此来否认其它文件存在的可能性。这能有效地使一个用户在可控的暴露风险下打开一个加密的捆绑文件包。并且对于敌人来说,在计算上没有一种低廉的办法来确认额外的秘密数据存在。这叫做“合理的推诿Plausible deniability”,是 toplip 著名的特性之一。

为了从 file3.encrypted 解码 file1,仅需输入:

./toplip -d file3.encrypted > file1.encrypted

你将会被要求输入 file1 的正确密码。

为了从 file3.encrypted 解码 file2,输入:

./toplip -d file3.encrypted > file2.encrypted

别忘了输入 file2 的正确密码。

使用多重密码保护

这是我中意的另一个炫酷特性。在加密过程中我们可以为单个文件提供多重密码。这样可以保护密码免于暴力尝试。

./toplip -c 2 file1 > file1.encrypted

这里,-c 2 代表两个不同的密码。上述命令行的示例输出将会是这样:

This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip 
file1 Passphrase #1: generating keys...Done
file1 Passphrase #2: generating keys...Done 
Encrypting...Done

正如你在上述示例中所看到的,toplip 要求我输入两个密码。请注意你必须提供两个不同的密码,而不是提供两遍同一个密码。

为了解码这个文件,这样做:

$ ./toplip -c 2 -d file1.encrypted > file1.decrypted 
This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip 
file1.encrypted Passphrase #1: generating keys...Done
file1.encrypted Passphrase #2: generating keys...Done
Decrypting...Done

将文件藏在图片中

将一个文件、消息、图片或视频藏在另一个文件里的方法叫做隐写术。幸运的是 toplip 默认包含这个特性。

为了将文件藏入图片中,像如下所示的样子使用 -m 参数。

$ ./toplip -m image.png file1 > image1.png
This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip 
file1 Passphrase #1: generating keys...Done 
Encrypting...Done

这行命令将 file1 的内容藏入一张叫做 image1.png 的图片中。

要解码,运行:

$ ./toplip -d image1.png > file1.decrypted This is toplip v1.20 (C) 2015, 2016 2 Ton Digital. Author: Jeff Marrison A showcase piece for the HeavyThing library. Commercial support available Proudly made in Cooroy, Australia. More info: https://2ton.com.au/toplip 
image1.png Passphrase #1: generating keys...Done 
Decrypting...Done

增加密码复杂度

为了进一步使文件变得难以破译,我们可以像以下这样增加密码复杂度:

./toplip -c 5 -i 0x8000 -alt file1 -c 10 -i 10 file2 > file3.encrypted

上述命令将会要求你为 file1 输入十条密码,为 file2 输入五条密码,并将它们存入单个叫做 file3.encrypted 的文件。如你所注意到的,我们在这个例子中又用了另一个 -i 参数。这是用来指定密钥生成循环次数。这个选项覆盖了 scrypt 函数初始和最终 PBKDF2 阶段的默认循环次数 1。十六进制和十进制数值都是允许的。比如说 0x800010 等。请注意这会大大增加计算次数。

为了解码 file1,使用:

./toplip -c 5 -i 0x8000 -d file3.encrypted > file1.decrypted

为了解码 file2,使用:

./toplip -c 10 -i 10 -d file3.encrypted > file2.decrypted

参考 toplip 官网以了解更多关于其背后的技术信息和使用的加密方式。

我个人对所有想要保护自己数据的人的建议是,别依赖单一的方法。总是使用多种工具/方法来加密文件。不要在纸上写下密码也不要将密码存入本地或云。记住密码,阅后即焚。如果你记不住,考虑使用任何了信赖的密码管理器。

今天就到此为止了,更多好东西后续推出,请保持关注。

顺祝时祺!


via: https://www.ostechnix.com/toplip-strong-file-encryption-decryption-cli-utility/

作者:SK 译者:tomjlw 校对:wxy

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

2018 年开源社区十大法律事件

$
0
0

自由和开源软件在 2018 年发生的法律问题将会在 2019 年及以后继续产生影响。

2018 年,当 IBM 以 340 亿美元的价格收购红帽时,我们看到了自由和开源软件(FOSS)商业模式的重要性。伴随着“开放源码促进会”Open Source Initiative(OSI)庆祝开源运动 20 周年,自由和开源软件生态系统也在去年展示了其持久性。

同时,旧有的法律问题又回来了。我们看到涉及自由和开源软件问题的诉讼判决再次显著增加,而其中一些案件非常重要。诉讼的增加提醒人们,对于所有使用自由和开源软件的公司(现在几乎所有公司都是如此)制定积极合规计划的重要性。

继续着回顾过去、展望未来趋势的传统,以下是2018年自由和开源软件社区的十大法律事件。

1、来自德国的 Linux 系统版权流氓 McHardy 又回来了

Patrick McHardy 是 Linux 系统的早期贡献者,他一直利用德国的诉讼威胁来获得金钱赔偿,基本上就像一个版权流氓copyright troll。McHardy 已经活跃了五年,据信接触过 80 多家公司。由于德国法院程序是保密的,许多公司在没有经过法院诉讼的情况下可能已经选择和解,准确数字很难估计。McHardy 的诉讼活动于 2016 年首次公开,2017 年他一直处于非活动状态。

然而,在 2018 年初,在 McHardy 针对 Geniatech 公司的法律行动中,我们看到了一个重要的判决:因为 Geniatech 公司涉嫌违反 Linux 软件的 GPL v2 协议,McHardy 赢得了禁止该公司继续分发其卫星电视接收器的禁令。然而,在 2018 年 3 月,德国科隆上诉法院撤销了该判决,裁定:

  1. McHardy 不是 Linux 内核和 Netfilter 的共同作者;
  2. McHardy 可能拥有衍生作品的权利,但没有提供足够的证据证明对其贡献拥有版权;和
  3. McHardy 可能滥用了他的权利(如果有的话),但法院指出这个问题需要进一步分析。McHardy 通过撤回他的禁令救济申请来避免进一步的诉讼。

关于“共同所有权”joint ownership的裁决非常重要,由于共同所有权的影响因国家而异,如果贡献者被认为是相关项目版权的共同所有者,那将引起非常多的混乱。

这个案子很不寻常,因为 McHardy 很少出庭;他的策略是通过使用德国法律规定的加急版权执法程序,威胁对侵犯 GPL v2 协议的公司进行版权执法。然后,McHardy 与他所指认违反协议的公司达成“和解”settlement。和解协议中包括一项规定,即该公司将遵守 GPL v2 协议的条款,这是德国此类和解协议中常用的条款。几个月后,McHardy 又回到该公司,根据和解协议提出另外的可能达到数十万欧元的索赔要求。执行 GPL v2 将会产生许多新问题,相比来说,执行和解协议简单得多。虽然 McHardy 有时会将自己的行为描述为聚焦在“合规”,但他显然更关心赚钱。 

2、欧盟反垄断判决禁止谷歌将 Android 软件与其服务捆绑在一起 

欧盟委员会因谷歌公司违反欧盟反垄断规定对其罚款 43.4 亿欧元。欧盟委员会表示,自 2011 年以来,谷歌已对 Android 设备制造商和移动网络运营商实施非法限制,以巩固其在常规互联网搜索领域的主导地位。此外,欧盟委员会要求谷歌在 2018 年 7 月 18 日判决生效起的 90 天内有效地终止该行为,否则谷歌将面临最高可达其母公司 Alphabet 全球每日平均营业额 5% 的罚款。据欧盟委员会称,谷歌使用反碎片协议将制造商保留在谷歌的 Android 版本上,目前大多数 Android 手机(除中国以外的所有国家/地区)都附带谷歌捆绑的软件和服务。负责竞争政策的委员 Margrethe Vestager 认定了三项违反欧盟反垄断法的限制:

  1. 作为许可其应用程序商店 Google Play 的条件,谷歌要求制造商预先安装 Google Search 应用程序和浏览器应用程序(Chrome);
  2. 谷歌已向某些大型制造商和移动网络运营商支付费用,条件是他们专门在其设备上预装 Google Search 应用程序;和
  3. 谷歌阻止了希望预装谷歌应用程序的制造商出售在未经谷歌批准的 Android 替代版本(所谓的 Android 分叉)上运行的单一智能移动设备。

谷歌已对此判决提出上诉。

3、红帽公司扩展其对“GPL 合作承诺”的承诺

GPL合作承诺GPL Cooperation Commitment是由 GPL v2 和 LGPL v2.x 版权所有者签署的声明,为被许可人提供了一个“修正”期限,用于那些根据 GPL v2 和 LGPL v2.x 许可其项目的被许可人在许可协议自动终止之前纠正其违规行为。该措施基于 GPL v3 中包含的修正条款。红帽公司在2018年显著扩大了签署该承诺的公司数量,从 2017 年的四家公司(红帽、Facebook、谷歌和 IBM)扩展到 2018 年底的 40 家公司。红帽公司也邀请个人贡献者签署该承诺。该公司在寻找开源社区重大问题的解决方案方面表现出了重要的思想领导力。

4、OIN 继续扩张

OIN(Open Invention Network)对于最大限度地降低 Linux 生态系统中专利诉讼的可能性至关重要。OIN 表示,它是历史上最大的非侵略性专利组织,拥有 2750 多名成员。2018 年加入 OIN 的著名新成员包括微软、腾讯、蚂蚁金服和阿里巴巴。微软是一个特别有趣的新成员,因为仅是在 2014 年,它通过将其专利授权给使用 Android 操作系统的产品制造商就赚了大约34亿美元。OIN 还扩大了专利非侵略协议的范围,将 151 个新软件包纳入进来,使得受保护的软件包总数达到 2873 个。

5、OpenSSL 变更许可协议

OpenSSL 项目宣布已完成从 OpenSSL/SSLeay 许可协议到 Apache 软件许可协议第2版(ASL v2)的转变。该项目于 2015 年宣布拟对许可协议进行变更。原始的 OpenSSL/SSLeay 许可协议是非标准的宽松许可协议,其中包括一些在早期自由和开源软件许可协议中很常见的条款(特别是与归属有关的条款),但这些条款从最近的许可协议中被删除了。OpenSSL 项目耗时三年完成了该过程,并强调完成此类过渡的难度以及在自由和开源软件项目开始时选择最合适许可协议的重要性。ASL v2 正成为企业自由和开源软件项目最受欢迎的许可协议。 

6、区块链项目中自由和开源软件的兴起

许多区块链项目都是依据自由和开源软件许可协议进行许可。然而,区块链社区没有与自由和开源软件社区开展合作,其许多选择似乎与基础设施技术不同。例如,传统的以太坊区块链客户端依据 GPL v3 和 LGPL v3.0 进行许可。不过,区块链社区似乎对这些问题变得越来越敏感,依据 ASL v2 发布的新 PegaSys 客户端代表了该问题新的复杂性。

开发 PegaSys 的团队指出:“为了让以太坊投入生产,我们还需要降低企业进入的门槛。许多公司的法律或合规部门限制他们使用遵循 GPL 许可协议的软件,而主流的以太坊客户端都是采用 GPL 协议。我们听说过许多公司在以太坊上成功试点,但因涉及开源许可协议的公司政策而被停止生产的故事。我们希望通过依据 Apache 2.0 发布 Pantheon Core 来解决这个痛点,让大家更为顺畅地使用。” 

7、Oracle v. Google案件反转

美国联邦巡回上诉法院(CAFC)在谷歌与甲骨文正在进行的案件中公布了其第二个判决,裁定谷歌未经授权在其 Android 操作系统中使用 37 个甲骨文的 Java 应用程序编程接口(API),侵犯了甲骨文的版权。CAFC 推翻了地区法院的的第一个判决,裁定 API 具有版权,并将案件发还给地区法院,以做出有关合理使用辩护的判决。地区法院基于谷歌对 API 的使用是合理使用而判决甲骨文败诉。甲骨文上诉之后,CAFC 再一次推翻了地区法院的判决,裁定作为法律问题,谷歌对 API 的使用并不是合理使用。该案已被发还给地区法院以裁定损害赔偿。鉴于 API 在自由和开源软件中的使用越来越多,这一案例对未来的自由和开源软件许可协议合规具有重要意义。

8、红帽公司以 340 亿美元被 IBM 收购

红帽公司已与 IBM 公司达成协议,将以 340 亿美元被收购。如果获得批准,这个价格将是对软件公司支付的最大收购金额,更不用说是收购开源软件公司了。

9、云计算领域冲突的增多和新许可协议的兴起

许多自由和开源软件公司对不向他们支付费用的云服务提供商使用他们的程序表示担忧。去年,Redis Labs 将 Redis Labs 开发的 Redis 模块许可协议从 AGPL 更改为使用 Commons Clause 修改的 Apache 2.0(这些 Redis 模块是 Redis 核心上的附加组件,包括 RediSearch、Redis Graph、ReJSON、ReBloom 和 Redis-ML)。Redis Labs 引入了 Commons Clause(将其添加到 ASL v2 中)以限制其产品被云服务提供商使用。这种混合许可协议的引入相当有争议,很少有公司采用它。

迄今为止,Redis Labs 尚未就此许可协议寻求 OSI 批准。2018年10月,一个名为 GoodFORM 的组织宣布它在采用 CommonsClause 之前就已经复刻(forking)了代码,并将依据 AGPL v3 提供源代码。最近,MongoDB 通过修改 AGPL v3 来创建服务器端公共许可协议(SSPL),对此问题采取了不同的方法。此许可协议具有更广泛的义务,可以为软件用户提供完整相应源代码Complete Corresponding Source Code。但是,MongoDB 宣布已将 SSPL 提交给 OSI 审批。

10、自由和开源软件项目与标准制定组织之间的紧张关系

由于自由和开源软件作为一种开发方法已经广泛普及,标准制定组织(SSO)一直致力于将自由和开源软件方法整合到自己的流程中。然而,自由和开源软件项目和标准制定组织的方法却截然不同:自由和开源软件项目在一个设定完全不同的更加分散的基础上运行。成员在许可使用费的基础上(依据 FRAND 条款)许可其专利,这是标准制定组织中的一种常见方法,却成为两者摩擦的来源之一。但是,大多数自由和开源软件社区都认为其项目中的专利应以免许可费的方式获得许可。 

虽然一些自由和开源软件许可协议具有明确的专利许可条款(例如 ASL v2),但其他自由和开源软件许可协议中专利许可的存在和范围更加模糊。专利使用费支付方式的差异正在造成自由和开源软件社区与标准制定社区之间的紧张关系。这个问题不太可能在短期内得到解决。


作者简介

Mark Radcliffe 是 DLA Piper 律所证券和知识产权事务高级合作人,以优异成绩获得密歇根大学化学学士学位以及哈佛大学法学院的法学博士学位,其业务重点是代表企业处理知识产权和财务事宜。

Victoria Lee 背景不详

Chris Stevenson 是 DLA Piper 律所董事总经理,以优异成绩获得塔夫斯大学生物和心理学学士学位以及波士顿大学法学院法学博士学位。

译者简介

薛亮,开源社法律事务工作组成员,集慧智佳知识产权咨询公司互联网事业部总监,擅长专利检索、专利分析、竞争对手跟踪、FTO 分析、开源软件知识产权风险分析,致力于为互联网企业、高科技公司提供知识产权咨询服务。

高效使用 Org 模式

$
0
0

简介

在我 前一篇关于 Emacs 的文章中 我提到了 Org 模式Org-mode,这是一个笔记管理工具和组织工具。本文中,我将会描述一下我日常的 Org 模式使用案例。

笔记和代办列表

首先而且最重要的是,Org 模式是一个管理笔记和待办列表的工具,Org 模式的所有工具都聚焦于使用纯文本文件记录笔记。我使用 Org 模式管理多种笔记。

一般性笔记

Org 模式最基本的应用场景就是以笔记的形式记录下你想记住的事情。比如,下面是我正在学习的笔记内容:

* Learn
** Emacs LISP
*** Plan

   - [ ] Read best practices
   - [ ] Finish reading Emacs Manual
   - [ ] Finish Exercism Exercises
   - [ ] Write a couple of simple plugins
     - Notification plugin

*** Resources

   https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html
   http://exercism.io/languages/elisp/about
   [[http://batsov.com/articles/2011/11/30/the-ultimate-collection-of-emacs-resources/][The Ultimate Collection of Emacs Resources]]

** Rust gamedev
*** Study [[https://github.com/SergiusIW/gate][gate]] 2d game engine with web assembly support
*** [[ggez][https://github.com/ggez/ggez]]
*** [[https://www.amethyst.rs/blog/release-0-8/][Amethyst 0.8 Relesed]]

** Upgrade Elixir/Erlang Skills
*** Read Erlang in Anger

借助 org-bullets 它看起来是这样的:

在这个简单的例子中,你能看到 Org 模式的一些功能:

  • 笔记允许嵌套
  • 链接
  • 带复选框的列表

项目待办

我在工作时时常会发现一些能够改进或修复的事情。我并不会在代码文件中留下 TODO 注释 (坏味道),相反我使用 org-projectile 来在另一个文件中记录一个 TODO 事项,并留下一个快捷方式。下面是一个该文件的例子:

* [[elisporg-projectile-open-project%20"mana")][mana]] [3/9]
  ROPERTIES:
  :CATEGORY: mana
  :END:
** DONE [[file:~/Development/mana/apps/blockchain/lib/blockchain/contract/create_contract.ex::insufficient_gas_before_homestead%20=][fix this check using evm.configuration]]
   CLOSED: [2018-08-08 Ср 09:14]
  [[https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md][eip2]]:
  If contract creation does not have enough gas to pay for the final gas fee for
  adding the contract code to the state, the contract creation fails (i.e. goes out-of-gas)
  rather than leaving an empty contract.
** DONE Upgrade Elixir to 1.7.
   CLOSED: [2018-08-08 Ср 09:14]
** TODO [#A] Difficulty tests
** TODO [#C] Upgrage to OTP 21
** DONE [#A] EIP150
   CLOSED: [2018-08-14 Вт 21:25]
*** DONE operation cost changes
    CLOSED: [2018-08-08 Ср 20:31]
*** DONE 1/64th for a call and create
    CLOSED: [2018-08-14 Вт 21:25]
** TODO [#C] Refactor interfaces
** TODO [#B] Caching for storage during execution
** TODO [#B] Removing old merkle trees
** TODO do not calculate cost twice
* [[elisporg-projectile-open-project%20".emacs.d")][.emacs.d]] [1/3]
  ROPERTIES:
  :CATEGORY: .emacs.d
  :END:
** TODO fix flycheck issues (emacs config)
** TODO use-package for fetching dependencies
** DONE clean configuration
   CLOSED: [2018-08-26 Вс 11:48]

它看起来是这样的:

本例中你能看到更多的 Org 模式的功能:

  • 代办列表具有 TODODONE 两个状态。你还可以定义自己的状态 (WAITING 等)
  • 关闭的事项有 CLOSED 时间戳
  • 有些事项有优先级 - A、B、C
  • 链接可以指向文件内部 ([[file:~/。..])

捕获模板

正如 Org 模式的文档中所描述的,捕获可以在不怎么干扰你工作流的情况下让你快速存储笔记。

我配置了许多捕获模板,可以帮我快速记录想要记住的事情。

  (setq org-capture-templates
        '(("t" "Todo" entry (file+headline "~/Dropbox/org/todo.org" "Todo soon")
           "* TODO %? \n  %^t")
          ("i" "Idea" entry (file+headline "~/Dropbox/org/ideas.org" "Ideas")
           "* %? \n %U")
          ("e" "Tweak" entry (file+headline "~/Dropbox/org/tweaks.org" "Tweaks")
           "* %? \n %U")
          ("l" "Learn" entry (file+headline "~/Dropbox/org/learn.org" "Learn")
           "* %? \n")
          ("w" "Work note" entry (file+headline "~/Dropbox/org/work.org" "Work")
           "* %? \n")
          ("m" "Check movie" entry (file+headline "~/Dropbox/org/check.org" "Movies")
           "* %? %^g")
          ("n" "Check book" entry (file+headline "~/Dropbox/org/check.org" "Books")
           "* %^{book name} by %^{author} %^g")))

做书本记录时我需要记下它的名字和作者,做电影记录时我需要记下标签,等等。

规划

Org 模式的另一个超棒的功能是你可以用它来作日常规划。让我们来看一个例子:

我没有挖空心思虚构一个例子,这就是我现在真实文件的样子。它看起来内容并不多,但它有助于你花时间在在重要的事情上并且帮你对抗拖延症。

习惯

根据 Org 模式的文档,Org 能够跟踪一种特殊的代办事情,称为 “习惯”。当我想养成新的习惯时,我会将该功能与日常规划功能一起连用:

你可以看到,目前我在尝试每天早期并且每两天锻炼一次。另外,它也有助于让我每天阅读书籍。

议事日程视图

最后,我还使用议事日程视图功能。待办事项可能分散在不同文件中(比如我就是日常规划和习惯分散在不同文件中),议事日程视图可以提供所有待办事项的总览:

更多 Org 模式的功能

总结

本文我描述了 Org 模式广泛功能中的一小部分,我每天都用它来提高工作效率,把时间花在重要的事情上。


via: https://www.badykov.com/emacs/2018/08/26/be-productive-with-org-mode/

作者:Ayrat Badykov 选题:lujun9972 译者:lujun9972 校对:wxy

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

如何在 Linux 中查看可用的网络接口

$
0
0

在我们安装完一个 Linux 系统后最为常见的任务便是网络配置了。当然,你可以在安装系统时进行网络接口的配置。但是,对于某些人来说,他们更偏爱在安装完系统后再进行网络的配置或者更改现存的设置。众所周知,为了在命令行中进行网络设定的配置,我们首先必须知道系统中有多少个可用的网络接口。本次这个简单的指南将列出所有可能的方式来在 Linux 和 Unix 操作系统中找到可用的网络接口。

在 Linux 中找到可用的网络接口

我们可以使用下面的这些方法来找到可用的网络接口。

方法 1 使用 ifconfig 命令

使用 ifconfig 命令来查看网络接口仍然是最常使用的方法。我相信还有很多 Linux 用户仍然使用这个方法。

$ ifconfig -a

示例输出:

enp5s0: flags=4098<BROADCAST,MULTICAST> mtu 1500
    ether 24:b6:fd:37:8b:29 txqueuelen 1000 (Ethernet)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
    inet 127.0.0.1 netmask 255.0.0.0
    inet6 ::1 prefixlen 128 scopeid 0x10<host>
    loop txqueuelen 1000 (Local Loopback)
    RX packets 171420 bytes 303980988 (289.8 MiB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 171420 bytes 303980988 (289.8 MiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

wlp9s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 192.168.225.37 netmask 255.255.255.0 broadcast 192.168.225.255
    inet6 2409:4072:6183:c604:c218:85ff:fe50:474f prefixlen 64 scopeid 0x0<global>
    inet6 fe80::c218:85ff:fe50:474f prefixlen 64 scopeid 0x20<link>
    ether c0:18:85:50:47:4f txqueuelen 1000 (Ethernet)
    RX packets 564574 bytes 628671925 (599.5 MiB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 299706 bytes 60535732 (57.7 MiB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

如上面的输出所示,在我的 Linux 机器上有两个网络接口,它们分别叫做 enp5s0(主板上的有线网卡)和 wlp9s0(无线网卡)。其中的 lo 是环回网卡,被用来访问本地的网络的服务,通常它的 IP 地址为 127.0.0.1

我们也可以在许多 UNIX 变种例如 FreeBSD 中使用相同的 ifconfig 来列出可用的网卡。

方法 2 使用 ip 命令

在最新的 Linux 版本中, ifconfig 命令已经被弃用了。你可以使用 ip 命令来罗列出网络接口,正如下面这样:

$ ip link show

示例输出:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp5s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 24:b6:fd:37:8b:29 brd ff:ff:ff:ff:ff:ff
3: wlp9s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether c0:18:85:50:47:4f brd ff:ff:ff:ff:ff:ff

你也可以使用下面的命令来查看。

$ ip addr
$ ip -s link

你注意到了吗?这些命令同时还显示出了已经连接的网络接口的状态。假如你仔细查看上面的输出,你将注意到我的有线网卡并没有跟网络线缆连接(从上面输出中的 DOWN 可以看出)。另外,我的无线网卡已经连接了(从上面输出中的 UP 可以看出)。想知晓更多的细节,可以查看我们先前的指南 在 Linux 中查看网络接口的已连接状态

这两个命令(ifconfigip)已经足够在你的 LInux 系统中查看可用的网卡了。

然而,仍然有其他方法来列出 Linux 中的网络接口,下面我们接着看。

方法 3 使用 /sys/class/net 目录

Linux 内核将网络接口的详细信息保存在 /sys/class/net 目录中,你可以通过查看这个目录的内容来检验可用接口的列表是否和前面的结果相符。

$ ls /sys/class/net

示例输出:

enp5s0 lo wlp9s0

方法 4 使用 /proc/net/dev 目录

在 Linux 操作系统中,文件 /proc/net/dev 中包含有关网络接口的信息。

要查看可用的网卡,只需使用下面的命令来查看上面文件的内容:

$ cat /proc/net/dev

示例输出:

Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
wlp9s0: 629189631 566078 0 0 0 0 0 0 60822472 300922 0 0 0 0 0 0
enp5s0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
lo: 303980988 171420 0 0 0 0 0 0 303980988 171420 0 0 0 0 0 0

方法 5 使用 netstat 命令

netstat 命令可以列出各种不同的信息,例如网络连接、路由表、接口统计信息、伪装连接和多播成员等。

$ netstat -i

示例输出:

Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
lo 65536 171420 0 0 0 171420 0 0 0 LRU
wlp9s0 1500 565625 0 0 0 300543 0 0 0 BMRU

请注意 netstat 被弃用了, netstat -i 的替代命令是 ip -s link。另外需要注意的是这个方法将只列出激活的接口,而不是所有可用的接口。

方法 6 使用 nmcli 命令

nmcli 是一个用来控制 NetworkManager 和报告网络状态的命令行工具。它可以被用来创建、展示、编辑、删除、激活、停用网络连接和展示网络状态。

假如你的 Linux 系统中安装了 NetworkManager,你便可以使用下面的命令来使用 nmcli 列出可以的网络接口:

$ nmcli device status

或者

$ nmcli connection show

现在你知道了如何在 Linux 中找到可用网络接口的方法,接下来,请查看下面的指南来知晓如何在 Linux 中配置 IP 地址吧。

假如你知道其他快捷的方法来在 Linux 中找到可用的网络接口,请在下面的评论部分中分享出来,我将检查你们的评论并更新这篇指南。

这就是全部的内容了,更多精彩内容即将呈现,请保持关注!

干杯!


via: https://www.ostechnix.com/how-to-find-available-network-interfaces-on-linux/

作者:SK 选题:lujun9972 译者:FSSlc 校对:wxy

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

开始使用 CryptPad 吧,一个开源的协作文档编辑器

$
0
0

使用 CryptPad 安全地共享你的笔记、文档、看板等,这是我们在开源工具系列中的第 5 个工具,它将使你在 2019 年更高效。

每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然,“抛弃旧的,拥抱新的”的态度促成了这一切。通常这时的建议严重偏向闭源和专有软件,但事实上并不用这样。

这是我挑选出的 19 个新的(或者对你而言新的)开源工具中的第 5 个工具来帮助你在 2019 年更有效率。

CryptPad

我们已经介绍过 Joplin,它能很好地保存自己的笔记,但是,你可能已经注意到,它没有任何共享或协作功能。

CryptPad 是一个安全、可共享的笔记应用和文档编辑器,它能够安全地协作编辑。与 Joplin 不同,它是一个 NodeJS 应用,这意味着你可以在桌面或其他服务器上运行它,并使用任何现代 Web 浏览器访问。它开箱即用,它支持富文本、Markdown、投票、白板,看板和 PPT。

它支持不同的文档类型且功能齐全。它的富文本编辑器涵盖了你所期望的所有基础功能,并允许你将文件导出为 HTML。它的 Markdown 的编辑能与 Joplin 相提并论,它的看板虽然不像 Wekan 那样功能齐全,但也做得不错。其他支持的文档类型和编辑器也很不错,并且有你希望在类似应用中看到的功能,尽管投票功能显得有些粗糙。

然而,CryptPad 的真正强大之处在于它的共享和协作功能。共享文档只需在“共享”选项中获取可共享 URL,CryptPad 支持使用 <iframe> 标签嵌入其他网站的文档。可以在“编辑”或“查看”模式下使用密码和会过期的链接共享文档。内置聊天能够让编辑者相互交谈(请注意,具有浏览权限的人也可以看到聊天但无法发表评论)。

所有文件都使用用户密码加密存储。服务器管理员无法读取文档,这也意味着如果你忘记或丢失了密码,文件将无法恢复。因此,请确保将密码保存在安全的地方,例如放在密码保险箱中。

当它在本地运行时,CryptPad 是一个用于创建和编辑文档的强大应用。当在服务器上运行时,它成为了用于多用户文档创建和编辑的出色协作平台。在我的笔记本电脑上安装它不到五分钟,并且开箱即用。开发者还加入了在 Docker 中运行 CryptPad 的说明,并且还有一个社区维护用于方便部署的 Ansible 角色。CryptPad 不支持任何第三方身份验证,因此用户必须创建自己的帐户。如果你不想运行自己的服务器,CryptPad 还有一个社区支持的托管版本。


via: https://opensource.com/article/19/1/productivity-tool-cryptpad

作者:Kevin Sonney 选题:lujun9972 译者:geekpi 校对:wxy

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

ODrive:Linux 中的 Google 云端硬盘图形客户端

$
0
0

这个我们已经多次讨论过。但是,我还要简要介绍一下它。截至目前,还没有官方的 Google 云端硬盘的 Linux 客户端,我们需要使用非官方客户端。Linux 中有许多集成 Google 云端硬盘的应用。每个应用都提供了一组功能。

我们过去在网站上写过一些此类文章。

这些文章是 DriveSyncGoogle Drive Ocamlfuse 客户端在 Linux 中使用 Nautilus 文件管理器挂载 Google 云端硬盘

今天我们也将讨论相同的主题,程序名字是 ODrive。

ODrive 是什么?

ODrive 意即 Open Drive。它是 Google 云端硬盘的图形客户端,它用 electron 框架编写。

它简单的图形界面能让用户几步就能集成 Google 云端硬盘。

如何在 Linux 上安装和设置 ODrive?

由于开发者提供了 AppImage 包,因此在 Linux 上安装 ODrive 没有任何困难。

只需使用 wget 命令从开发者的 GitHub 页面下载最新的 ODrive AppImage 包。

$ wget https://github.com/liberodark/ODrive/releases/download/0.1.3/odrive-0.1.3-x86_64.AppImage

你必须为 ODrive AppImage 文件设置可执行文件权限。

$ chmod +x odrive-0.1.3-x86_64.AppImage

只需运行 ODrive AppImage 文件以启动 ODrive GUI 以进行进一步设置。

$ ./odrive-0.1.3-x86_64.AppImage

运行上述命令时,可能会看到下面的窗口。只需按下“下一步”按钮即可进行进一步设置。

点击“连接”链接添加 Google 云端硬盘帐户。

输入你要设置 Google 云端硬盘帐户的电子邮箱。

输入邮箱密码。

允许 ODrive 访问你的 Google 帐户。

默认情况下,它将选择文件夹位置。如果你要选择特定文件夹,则可以更改。

最后点击“同步”按钮开始将文件从 Google 下载到本地系统。

同步正在进行中。

同步完成后。它会显示所有已下载的文件。

我看到所有文件都下载到上述目录中。

如果要将本地系统中的任何新文件同步到 Google 。只需从应用菜单启动 “ODrive”,但它不会实际启动应用。它将在后台运行,我们可以使用 ps 命令查看。

$ ps -df | grep odrive

将新文件添加到 Google文件夹后,它会自动开始同步。从通知菜单中也可以看到。是的,我看到一个文件已同步到 Google 中。

同步完成后图形界面没有加载,我不确定这个功能。我会向开发者反馈之后,根据他的反馈更新。


via: https://www.2daygeek.com/odrive-open-drive-google-drive-gui-client-for-linux/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:geekpi 校对:wxy

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

时隔两年,PuTTY 发布了一个新的安全修复版本

$
0
0

PuTTY 是 Windows 上使用最广泛的 SSH 客户端之一,它也有 Linux 版本。日前,得益于欧盟资助的 HackerOne 平台,PuTTY 发布了 0.71 版本,主要是修复了大量的安全缺陷。这个版本距其上个版本 0.70 的发布已近两年。

PuTTY 是一个自由开源且支持包括 SSH、Telnet 和 Rlogin 在内的多种协议的 GUI 客户端。

根据其变更日志,这个新版本的主要变更有:

  • 由欧盟资助的漏洞赏金计划发现的漏洞的安全修复:
    • 在 RSA 密钥交换过程中可由远程触发内容覆写,它发生在主机密钥校验之前
    • 循环利用用于加密算法的随机数的潜在风险
    • 在 Windows 上,通过与可执行文件位于同一目录中的恶意帮助文件进行劫持
    • 在Unix上,任何类型的服务器到客户端转发过程中的可远程触发的缓冲区溢出
    • 可以通过写入终端触发的多个拒绝服务攻击
  • 其它安全增强:重写加密代码以消除缓存和定时侧信道
  • 用户界面更改以防止来自恶意服务器的虚假身份验证提示
  • 首次提供了基于 ARM 的 Windows 版的预构建二进制
  • 最常见的加密算法的硬件加速版本:AES、SHA-256、SHA-1
  • GTK PuTTY 现在支持非 X11 显示(如 Wayland)和高分辨率配置
  • 现在,只要打开PuTTY窗口,就可以使用预先输入:在身份验证完成之前键入的键击将被缓冲而不是被删除
  • 支持 GSSAPI 密钥交换:这是旧版 GSSAPI 身份验证系统的替代方案,可以在长时间会话期间更新转发的 Kerberos 凭据
  • 用于剪贴板处理的更多用户界面选择
  • 新的终端功能:支持 REP 转义序列(修复 ncurses 屏幕重绘失败)、真彩色和 SGR 2 暗淡文本
  • Ctrl + Shift + PgUpCtrl + Shift + PgDn 现在可以直接到达终端回滚的顶部或底部

如果要下载使用 PuTTY,请从其官网下载,以避免使用了被恶意篡改的版本:

此外,也可以单独下载 putty 和 pscp 等的二进制执行文件:

 


在 Emacs 的 dired 和 tramp 中异步运行 rsync

$
0
0

Trần Xuân Trường 写的 tmtxt-dired-async 是一个不为人知的 Emacs 包,它可以扩展 dired(Emacs 内置的文件管理器),使之可以异步地运行 rsync 和其他命令 (例如压缩、解压缩和下载)。

这意味着你可以拷贝上 GB 的目录而不影响 Emacs 的其他任务。

它的一个功能时让你可以通过 C-c C-a 从不同位置添加任意多的文件到一个等待列表中,然后按下 C-c C-v 异步地使用 rsync 将整个等待列表中的文件同步到目标目录中。光这个功能就值得一试了。

例如这里将 arduino 1.9 的 beta 存档同步到另一个目录中:

整个进度完成后,底部的窗口会在 5 秒后自动退出。下面是异步解压上面的 arduino 存档后出现的另一个会话:

这个包进一步增加了我 dired 配置的实用性。

我刚刚贡献了 一个拉取请求来允许 tmtxt-dired-async 同步到远程 tramp 目录中,而且我立即使用该功能来将上 GB 的新照片传输到 Linux 服务器上。

若你想配置 tmtxt-dired-async,下载 tmtxt-async-tasks.el(被依赖的库)以及 tmtxt-dired-async.el(若你想让它支持 tramp,请确保合并使用了我的拉取请求)到 ~/.emacs.d/ 目录中,然后添加下面配置:

;; no MELPA packages of this, so we have to do a simple check here
(setq dired-async-el (expand-file-name "~/.emacs.d/tmtxt-dired-async.el"))
(when (file-exists-p dired-async-el)
  (load (expand-file-name "~/.emacs.d/tmtxt-async-tasks.el"))
  (load dired-async-el)
  (define-key dired-mode-map (kbd "C-c C-r") 'tda/rsync)
  (define-key dired-mode-map (kbd "C-c C-z") 'tda/zip)
  (define-key dired-mode-map (kbd "C-c C-u") 'tda/unzip)

  (define-key dired-mode-map (kbd "C-c C-a") 'tda/rsync-multiple-mark-file)
  (define-key dired-mode-map (kbd "C-c C-e") 'tda/rsync-multiple-empty-list)
  (define-key dired-mode-map (kbd "C-c C-d") 'tda/rsync-multiple-remove-item)
  (define-key dired-mode-map (kbd "C-c C-v") 'tda/rsync-multiple)

  (define-key dired-mode-map (kbd "C-c C-s") 'tda/get-files-size)

  (define-key dired-mode-map (kbd "C-c C-q") 'tda/download-to-current-dir))

祝你开心!


via: https://vxlabs.com/2018/03/30/asynchronous-rsync-with-emacs-dired-and-tramp/

作者:cpbotha 选题:lujun9972 译者:lujun9972 校对:wxy

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

x86 和 ARM 的 Python 爬虫速度对比

$
0
0

假如说,如果你的老板给你的任务是一次又一次地访问竞争对手的网站,把对方商品的价格记录下来,而且要纯手工操作,恐怕你会想要把整个办公室都烧掉。

之所以现在网络爬虫的影响力如此巨大,就是因为网络爬虫可以被用于追踪客户的情绪和趋向、搜寻空缺的职位、监控房地产的交易,甚至是获取 UFC 的比赛结果。除此以外,还有很多意想不到的用途。

对于有这方面爱好的人来说,爬虫无疑是一个很好的工具。因此,我使用了 Scrapy 这个基于 Python 编写的开源网络爬虫框架。

鉴于我不太了解这个工具是否会对我的计算机造成伤害,我并没有将它搭建在我的主力机器上,而是搭建在了一台树莓派上面。

令人感到意外的是,Scrapy 在树莓派上面的性能并不差,或许这是 ARM 架构服务器的又一个成功例子?

我尝试 Google 了一下,但并没有得到令我满意的结果,仅仅找到了一篇相关的《Drupal 建站对比》。这篇文章的结论是,ARM 架构服务器性能比昂贵的 x86 架构服务器要更好。

从另一个角度来看,这种 web 服务可以看作是一个“被爬虫”服务,但和 Scrapy 对比起来,前者是基于 LAMP 技术栈,而后者则依赖于 Python,这就导致两者之间没有太多的可比性。

那我们该怎样做呢?只能在一些 VPS 上搭建服务来对比一下了。

什么是 ARM 架构处理器?

ARM 是目前世界上最流行的 CPU 架构。

但 ARM 架构处理器在很多人眼中的地位只是作为一个省钱又省电的选择,而不是跑在生产环境中的处理器的首选。

然而,诞生于英国剑桥的 ARM CPU,最初是用于极其昂贵的 Acorn Archimedes 计算机上的,这是当时世界上最强大的桌面计算机,甚至在很长一段时间内,它的运算速度甚至比最快的 386 还要快好几倍。

Acorn 公司和 Commodore、Atari 的理念类似,他们认为一家伟大的计算机公司就应该制造出伟大的计算机,让人感觉有点目光短浅。而比尔盖茨的想法则有所不同,他力图在更多不同种类和价格的 x86 机器上使用他的 DOS 系统。

拥有大量用户基数的平台会成为第三方开发者开发软件的平台,而软件资源丰富又会让你的计算机更受用户欢迎。

即使是苹果公司也几乎被打败。在 x86 芯片上投入大量的财力,最终,这些芯片被用于生产环境计算任务。

但 ARM 架构也并没有消失。基于 ARM 架构的芯片不仅运算速度快,同时也非常节能。因此诸如机顶盒、PDA、数码相机、MP3 播放器这些电子产品多数都会采用 ARM 架构的芯片,甚至在很多需要用电池或不配备大散热风扇的电子产品上,都可以见到 ARM 芯片的身影。

而 ARM 则脱离 Acorn 成为了一种特殊的商业模式,他们不生产实物芯片,仅仅是向芯片生产厂商出售相关的知识产权。

因此,这或多或少是 ARM 芯片被应用于如此之多的手机和平板电脑上的原因。当 Linux 被移植到这种架构的芯片上时,开源技术的大门就已经向它打开了,这才让我们今天得以在这些芯片上运行 web 爬虫程序。

服务器端的 ARM

诸如微软Cloudflare 这些大厂都在基础设施建设上花了重金,所以对于我们这些预算不高的用户来说,可以选择的余地并不多。

实际上,如果你的信用卡只够付每月数美元的 VPS 费用,一直以来只能考虑 Scaleway 这个高性价比的厂商。

但自从数个月前公有云巨头 AWS 推出了他们自研的 ARM 处理器 AWS Graviton 之后,选择似乎就丰富了一些。

我决定在其中选择一款 VPS 厂商,将它提供的 ARM 处理器和 x86 处理器作出对比。

深入了解

所以我们要对比的是什么指标呢?

Scaleway

Scaleway 自身的定位是“专为开发者设计”。我觉得这个定位很准确,对于开发和原型设计来说,Scaleway 提供的产品确实可以作为一个很好的沙盒环境。

Scaleway 提供了一个简洁的仪表盘页面,让用户可以快速地从主页进入 bash shell 界面。对于很多小企业、自由职业者或者技术顾问,如果想要运行 web 爬虫,这个产品毫无疑问是一个物美价廉的选择。

ARM 方面我们选择 ARM64-2GB 这一款服务器,每月只需要 3 欧元。它带有 4 个 Cavium ThunderX 核心,这是在 2014 年推出的第一款服务器级的 ARMv8 处理器。但现在看来它已经显得有点落后了,并逐渐被更新的 ThunderX2 取代。

x86 方面我们选择 1-S,每月的费用是 4 欧元。它拥有 2 个英特尔 Atom C3995 核心。英特尔的 Atom 系列处理器的特点是低功耗、单线程,最初是用在笔记本电脑上的,后来也被服务器所采用。

两者在处理器以外的条件都大致相同,都使用 2 GB 的内存、50 GB 的 SSD 存储以及 200 Mbit/s 的带宽。磁盘驱动器可能会有所不同,但由于我们运行的是 web 爬虫,基本都是在内存中完成操作,因此这方面的差异可以忽略不计。

为了避免我不能熟练使用包管理器的尴尬局面,两方的操作系统我都会选择使用 Debian 9。

Amazon Web Services(AWS)

当你还在注册 AWS 账号的时候,使用 Scaleway 的用户可能已经把提交信用卡信息、启动 VPS 实例、添加 sudo 用户、安装依赖包这一系列流程都完成了。AWS 的操作相对来说比较繁琐,甚至需要详细阅读手册才能知道你正在做什么。

当然这也是合理的,对于一些需求复杂或者特殊的企业用户,确实需要通过详细的配置来定制合适的使用方案。

我们所采用的 AWS Graviton 处理器是 AWS EC2(弹性计算云Elastic Compute Cloud)的一部分,我会以按需实例的方式来运行,这也是最贵但最简捷的方式。AWS 同时也提供竞价实例,这样可以用较低的价格运行实例,但实例的运行时间并不固定。如果实例需要长时间持续运行,还可以选择预留实例

看,AWS 就是这么复杂……

我们分别选择 a1.mediumt2.small 两种型号的实例进行对比,两者都带有 2GB 内存。这个时候问题来了,这里提到的 vCPU 又是什么?两种型号的不同之处就在于此。

对于 a1.medium 型号的实例,vCPU 是 AWS Graviton 芯片提供的单个计算核心。这个芯片由被亚马逊在 2015 收购的以色列厂商 Annapurna Labs 研发,是 AWS 独有的单线程 64 位 ARMv8 内核。它的按需价格为每小时 0.0255 美元。

而 t2.small 型号实例使用英特尔至强系列芯片,但我不确定具体是其中的哪一款。它每个核心有两个线程,但我们并不能用到整个核心,甚至整个线程。

我们能用到的只是“20% 的基准性能,可以使用 CPU 积分突破这个基准”。这可能有一定的原因,但我没有弄懂。它的按需价格是每小时 0.023 美元。

在镜像库中没有 Debian 发行版的镜像,因此我选择了 Ubuntu 18.04。

瘪四与大头蛋爬取 Moz 排行榜前 500 的网站

要测试这些 VPS 的 CPU 性能,就该使用爬虫了。一个方法是对几个网站在尽可能短的时间里发出尽可能多的请求,但这种操作不太礼貌,我的做法是只向大量网站发出少数几个请求。

为此,我编写了 beavis.py(瘪四)这个爬虫程序(致敬我最喜欢的物理学家和制片人 Mike Judge)。这个程序会将 Moz 上排行前 500 的网站都爬取 3 层的深度,并计算 “wood” 和 “ass” 这两个单词在 HTML 文件中出现的次数。(LCTT 译注:beavis(瘪四)和 butt-head(大头蛋) 都是 Mike Judge 的动画片《瘪四与大头蛋》中的角色)

但我实际爬取的网站可能不足 500 个,因为我需要遵循网站的 robot.txt 协定,另外还有些网站需要提交 javascript 请求,也不一定会计算在内。但这已经是一个足以让 CPU 保持繁忙的爬虫任务了。

Python 的全局解释器锁机制会让我的程序只能用到一个 CPU 线程。为了测试多线程的性能,我需要启动多个独立的爬虫程序进程。

因此我还编写了 butthead.py,尽管大头蛋很粗鲁,它也总是比瘪四要略胜一筹。

我将整个爬虫任务拆分为多个部分,这可能会对爬取到的链接数量有一点轻微的影响。但无论如何,每次爬取都会有所不同,我们要关注的是爬取了多少个页面,以及耗时多长。

在 ARM 服务器上安装 Scrapy

安装 Scrapy 的过程与芯片的不同架构没有太大的关系,都是安装 pip 和相关的依赖包之后,再使用 pip 来安装 Scrapy。

据我观察,在使用 ARM 的机器上使用 pip 安装 Scrapy 确实耗时要长一点,我估计是由于需要从源码编译为二进制文件。

在 Scrapy 安装结束后,就可以通过 shell 来查看它的工作状态了。

在 Scaleway 的 ARM 机器上,Scrapy 安装完成后会无法正常运行,这似乎和 service_identity 模块有关。这个现象也会在树莓派上出现,但在 AWS Graviton 上不会出现。

对于这个问题,可以用这个命令来解决:

sudo pip3 install service_identity --force --upgrade

接下来就可以开始对比了。

单线程爬虫

Scrapy 的官方文档建议将爬虫程序的 CPU 使用率控制在 80% 到 90% 之间,在真实操作中并不容易,尤其是对于我自己写的代码。根据我的观察,实际的 CPU 使用率变动情况是一开始非常繁忙,随后稍微下降,接着又再次升高。

在爬取任务的最后,也就是大部分目标网站都已经被爬取了的这个阶段,会持续数分钟的时间。这让人有点失望,因为在这个阶段当中,任务的运行时长只和网站的大小有比较直接的关系,并不能以之衡量 CPU 的性能。

所以这并不是一次严谨的基准测试,只是我通过自己写的爬虫程序来观察实际的现象。

下面我们来看看最终的结果。首先是 Scaleway 的机器:

机器种类 耗时 爬取页面数 每小时爬取页面数 每百万页面费用(欧元)
Scaleway ARM64-2GB 108m 59.27s 38,205 21,032.623 0.28527
Scaleway 1-S 97m 44.067s 39,476 24,324.648 0.33011

我使用了 top 工具来查看爬虫程序运行期间的 CPU 使用率。在任务刚开始的时候,两者的 CPU 使用率都达到了 100%,但 ThunderX 大部分时间都达到了 CPU 的极限,无法看出来 Atom 的性能会比 ThunderX 超出多少。

通过 top 工具,我还观察了它们的内存使用情况。随着爬取任务的进行,ARM 机器的内存使用率最终达到了 14.7%,而 x86 则最终是 15%。

从运行日志还可以看出来,当 CPU 使用率到达极限时,会有大量的超时页面产生,最终导致页面丢失。这也是合理出现的现象,因为 CPU 过于繁忙会无法完整地记录所有爬取到的页面。

如果仅仅是为了对比爬虫的速度,页面丢失并不是什么大问题。但在实际中,业务成果和爬虫数据的质量是息息相关的,因此必须为 CPU 留出一些用量,以防出现这种现象。

再来看看 AWS 这边:

机器种类 耗时 爬取页面数 每小时爬取页面数 每百万页面费用(美元)
a1.medium 100m 39.900s 41,294 24,612.725 1.03605
t2.small 78m 53.171s 41,200 31,336.286 0.73397

为了方便比较,对于在 AWS 上跑的爬虫,我记录的指标和 Scaleway 上一致,但似乎没有达到预期的效果。这里我没有使用 top,而是使用了 AWS 提供的控制台来监控 CPU 的使用情况,从监控结果来看,我的爬虫程序并没有完全用到这两款服务器所提供的所有性能。

a1.medium 型号的机器尤为如此,在任务开始阶段,它的 CPU 使用率达到了峰值 45%,但随后一直在 20% 到 30% 之间。

让我有点感到意外的是,这个程序在 ARM 处理器上的运行速度相当慢,但却远未达到 Graviton CPU 能力的极限,而在 Intel Atom 处理器上则可以在某些时候达到 CPU 能力的极限。它们运行的代码是完全相同的,处理器的不同架构可能导致了对代码的不同处理方式。

个中原因无论是由于处理器本身的特性,还是二进制文件的编译,又或者是两者皆有,对我来说都是一个黑盒般的存在。我认为,既然在 AWS 机器上没有达到 CPU 处理能力的极限,那么只有在 Scaleway 机器上跑出来的性能数据是可以作为参考的。

t2.small 型号的机器性能让人费解。CPU 利用率大概 20%,最高才达到 35%,是因为手册中说的“20% 的基准性能,可以使用 CPU 积分突破这个基准”吗?但在控制台中可以看到 CPU 积分并没有被消耗。

为了确认这一点,我安装了 stress 这个软件,然后运行了一段时间,这个时候发现居然可以把 CPU 使用率提高到 100% 了。

显然,我需要调整一下它们的配置文件。我将 CONCURRENT_REQUESTS 参数设置为 5000,将 REACTOR_THREADPOOL_MAXSIZE 参数设置为 120,将爬虫任务的负载调得更大。

机器种类 耗时 爬取页面数 每小时爬取页面数 每万页面费用(美元)
a1.medium 46m 13.619s 40,283 52,285.047 0.48771
t2.small 41m7.619s 36,241 52,871.857 0.43501
t2.small(无 CPU 积分) 73m 8.133s 34,298 28,137.8891 0.81740

a1.medium 型号机器的 CPU 使用率在爬虫任务开始后 5 分钟飙升到了 100%,随后下降到 80% 并持续了 20 分钟,然后再次攀升到 96%,直到任务接近结束时再次下降。这大概就是我想要的效果了。

而 t2.small 型号机器在爬虫任务的前期就达到了 50%,并一直保持在这个水平直到任务接近结束。如果每个核心都有两个线程,那么 50% 的 CPU 使用率确实是单个线程可以达到的极限了。

现在我们看到它们的性能都差不多了。但至强处理器的线程持续跑满了 CPU,Graviton 处理器则只是有一段时间如此。可以认为 Graviton 略胜一筹。

然而,如果 CPU 积分耗尽了呢?这种情况下的对比可能更为公平。为了测试这种情况,我使用 stress 把所有的 CPU 积分用完,然后再次启动了爬虫任务。

在没有 CPU 积分的情况下,CPU 使用率在 27% 就到达极限不再上升了,同时又出现了丢失页面的现象。这么看来,它的性能比负载较低的时候更差。

多线程爬虫

将爬虫任务分散到不同的进程中,可以有效利用机器所提供的多个核心。

一开始,我将爬虫任务分布在 10 个不同的进程中并同时启动,结果发现比每个核心仅使用 1 个进程的时候还要慢。

经过尝试,我得到了一个比较好的方案。把爬虫任务分布在 10 个进程中,但每个核心只启动 1 个进程,在每个进程接近结束的时候,再从剩余的进程中选出 1 个进程启动起来。

如果还需要优化,还可以让运行时间越长的爬虫进程在启动顺序中排得越靠前,我也在尝试实现这个方法。

想要预估某个域名的页面量,一定程度上可以参考这个域名主页的链接数量。我用另一个程序来对这个数量进行了统计,然后按照降序排序。经过这样的预处理之后,只会额外增加 1 分钟左右的时间。

结果,爬虫运行的总耗时超过了两个小时!毕竟把链接最多的域名都堆在同一个进程中也存在一定的弊端。

针对这个问题,也可以通过调整各个进程爬取的域名数量来进行优化,又或者在排序之后再作一定的修改。不过这种优化可能有点复杂了。

因此,我还是用回了最初的方法,它的效果还是相当不错的:

机器种类 耗时 爬取页面数 每小时爬取页面数 每万页面费用(欧元)
Scaleway ARM64-2GB 62m 10.078s 36,158 34,897.0719 0.17193
Scaleway 1-S 60m 56.902s 36,725 36,153.5529 0.22128

毕竟,使用多个核心能够大大加快爬虫的速度。

我认为,如果让一个经验丰富的程序员来优化的话,一定能够更好地利用所有的计算核心。但对于开箱即用的 Scrapy 来说,想要提高性能,使用更快的线程似乎比使用更多核心要简单得多。

从数量来看,Atom 处理器在更短的时间内爬取到了更多的页面。但如果从性价比角度来看,ThunderX 又是稍稍领先的。不过总的来说差距不大。

爬取结果分析

在爬取了 38205 个页面之后,我们可以统计到在这些页面中 “ass” 出现了 24170435 次,而 “wood” 出现了 54368 次。

“wood” 的出现次数不少,但和 “ass” 比起来简直微不足道。

结论

从上面的数据来看,对于性能而言,CPU 的架构并没有它们的问世时间重要,2018 年生产的 AWS Graviton 是单线程情况下性能最佳的。

你当然可以说按核心来比,Xeon 仍然赢了。但是,你不但需要计算美元的变化,甚至还要计算线程数。

另外在性能方面 2017 年生产的 Atom 轻松击败了 2014 年生产的 ThunderX,而 ThunderX 则在性价比方面占优。当然,如果你使用 AWS 的机器的话,还是使用 Graviton 吧。

总之,ARM 架构的硬件是可以用来运行爬虫程序的,而且在性能和费用方面也相当有竞争力。

而这种差异是否足以让你将整个技术架构迁移到 ARM 上?这就是另一回事了。当然,如果你已经是 AWS 用户,并且你的代码有很强的可移植性,那么不妨尝试一下 a1 型号的实例。

希望 ARM 设备在不久的将来能够在公有云上大放异彩。

源代码

这是我第一次使用 Python 和 Scrapy 来做一个项目,所以我的代码写得可能不是很好,例如代码中使用全局变量就有点力不从心。

不过我仍然会在下面开源我的代码。

要运行这些代码,需要预先安装 Scrapy,并且需要 Moz 上排名前 500 的网站的 csv 文件。如果要运行 butthead.py,还需要安装 psutil 这个库。

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.crawler import CrawlerProcess

ass = 0
wood = 0
totalpages = 0

def getdomains():

  moz500file = open('top500.domains.05.18.csv')

  domains = []
  moz500csv = moz500file.readlines()

  del moz500csv[0]

  for csvline in moz500csv:
    leftquote = csvline.find('"')    
    rightquote = leftquote + csvline[leftquote + 1:].find('"')
    domains.append(csvline[leftquote + 1:rightquote])

  return domains

def getstartpages(domains):
  
  startpages = []
  
  for domain in domains:
    startpages.append('http://' + domain)
  
  return startpages
  
class AssWoodItem(scrapy.Item):
  ass = scrapy.Field()
  wood = scrapy.Field()
  url = scrapy.Field()
  
class AssWoodPipeline(object):
  def __init__(self):
    self.asswoodstats = []

  def process_item(self, item, spider):
    self.asswoodstats.append((item.get('url'), item.get('ass'), item.get('wood')))
    
  def close_spider(self, spider):
    asstally, woodtally = 0, 0
    
    for asswoodcount in self.asswoodstats:
      asstally += asswoodcount[1]
      woodtally += asswoodcount[2]
      
    global ass, wood, totalpages
    ass = asstally
    wood = woodtally
    totalpages = len(self.asswoodstats)

class BeavisSpider(CrawlSpider):
  name = "Beavis"
  allowed_domains = getdomains()
  start_urls = getstartpages(allowed_domains)
  #start_urls = [ 'http://medium.com' ]
  custom_settings = {
    'DEPTH_LIMIT': 3,
    'DOWNLOAD_DELAY': 3,
    'CONCURRENT_REQUESTS': 1500,
    'REACTOR_THREADPOOL_MAXSIZE': 60,
    'ITEM_PIPELINES': { '__main__.AssWoodPipeline': 10 },
    'LOG_LEVEL': 'INFO',
    'RETRY_ENABLED': False,
    'DOWNLOAD_TIMEOUT': 30,
    'COOKIES_ENABLED': False,
    'AJAXCRAWL_ENABLED': True
  }
    
  rules = ( Rule(LinkExtractor(), callback='parse_asswood'), )
  
  def parse_asswood(self, response):
    if isinstance(response, scrapy.http.TextResponse):
      item = AssWoodItem()
      item['ass'] = response.text.casefold().count('ass')
      item['wood'] = response.text.casefold().count('wood')
      item['url'] = response.url
      yield item


if __name__ == '__main__':

  process = CrawlerProcess({
      'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
  })

  process.crawl(BeavisSpider)
  process.start()

  print('Uhh, that was, like, ' + str(totalpages) + ' pages crawled.')
  print('Uh huhuhuhuh. It said ass ' + str(ass) + ' times.')
  print('Uh huhuhuhuh. It said wood ' + str(wood) + ' times.')

beavis.py

import scrapy, time, psutil
from scrapy.spiders import CrawlSpider, Rule, Spider
from scrapy.linkextractors import LinkExtractor
from scrapy.crawler import CrawlerProcess
from multiprocessing import Process, Queue, cpu_count

ass = 0
wood = 0
totalpages = 0
linkcounttuples =[]

def getdomains():

  moz500file = open('top500.domains.05.18.csv')

  domains = []
  moz500csv = moz500file.readlines()

  del moz500csv[0]

  for csvline in moz500csv:
    leftquote = csvline.find('"')    
    rightquote = leftquote + csvline[leftquote + 1:].find('"')
    domains.append(csvline[leftquote + 1:rightquote])

  return domains

def getstartpages(domains):
  
  startpages = []
  
  for domain in domains:
    startpages.append('http://' + domain)
  
  return startpages
  
class AssWoodItem(scrapy.Item):
  ass = scrapy.Field()
  wood = scrapy.Field()
  url = scrapy.Field()
  
class AssWoodPipeline(object):
  def __init__(self):
    self.asswoodstats = []

  def process_item(self, item, spider):
    self.asswoodstats.append((item.get('url'), item.get('ass'), item.get('wood')))
    
  def close_spider(self, spider):
    asstally, woodtally = 0, 0
    
    for asswoodcount in self.asswoodstats:
      asstally += asswoodcount[1]
      woodtally += asswoodcount[2]
      
    global ass, wood, totalpages
    ass = asstally
    wood = woodtally
    totalpages = len(self.asswoodstats)
          

class ButtheadSpider(CrawlSpider):
  name = "Butthead"
  custom_settings = {
    'DEPTH_LIMIT': 3,
    'DOWNLOAD_DELAY': 3,
    'CONCURRENT_REQUESTS': 250,
    'REACTOR_THREADPOOL_MAXSIZE': 30,
    'ITEM_PIPELINES': { '__main__.AssWoodPipeline': 10 },
    'LOG_LEVEL': 'INFO',
    'RETRY_ENABLED': False,
    'DOWNLOAD_TIMEOUT': 30,
    'COOKIES_ENABLED': False,
    'AJAXCRAWL_ENABLED': True
  }
    
  rules = ( Rule(LinkExtractor(), callback='parse_asswood'), )
  
  
  def parse_asswood(self, response):
    if isinstance(response, scrapy.http.TextResponse):
      item = AssWoodItem()
      item['ass'] = response.text.casefold().count('ass')
      item['wood'] = response.text.casefold().count('wood')
      item['url'] = response.url
      yield item

def startButthead(domainslist, urlslist, asswoodqueue):
  crawlprocess = CrawlerProcess({
      'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
  })

  crawlprocess.crawl(ButtheadSpider, allowed_domains = domainslist, start_urls = urlslist)
  crawlprocess.start()
  asswoodqueue.put( (ass, wood, totalpages) )
  

if __name__ == '__main__':
  asswoodqueue = Queue()
  domains=getdomains()
  startpages=getstartpages(domains)
  processlist =[]
  cores = cpu_count()
  
  for i in range(10):
    domainsublist = domains[i * 50i + 1) * 50]
    pagesublist = startpages[i * 50i + 1) * 50]
    p = Process(target = startButthead, args = (domainsublist, pagesublist, asswoodqueue))
    processlist.append(p)
  
  for i in range(cores):
    processlist.start()
    
  time.sleep(180)
  
  i = cores
  
  while i != 10:
    time.sleep(60)
    if psutil.cpu_percent() < 66.7:
      processlist.start()
      i += 1
  
  for i in range(10):
    processlist.join()
  
  for i in range(10):
    asswoodtuple = asswoodqueue.get()
    ass += asswoodtuple[0]
    wood += asswoodtuple[1]
    totalpages += asswoodtuple[2]

  print('Uhh, that was, like, ' + str(totalpages) + ' pages crawled.')
  print('Uh huhuhuhuh. It said ass ' + str(ass) + ' times.')
  print('Uh huhuhuhuh. It said wood ' + str(wood) + ' times.')

butthead.py


via: https://blog.dxmtechsupport.com.au/speed-test-x86-vs-arm-for-web-crawling-in-python/

作者:James Mawson 选题:lujun9972 译者:HankChow 校对:wxy

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

在 Linux 中运行特定命令而无需 sudo 密码

$
0
0

我有一台部署在 AWS 上的 Ubuntu 系统,在它的里面有一个脚本,这个脚本的原有目的是以一定间隔(准确来说是每隔 1 分钟)去检查某个特定服务是否正在运行,如果这个服务因为某些原因停止了,就自动重启这个服务。但问题是我需要 sudo 权限来开启这个服务。正如你所知道的那样,当我们以 sudo 用户运行命令时,我们应该提供密码,但我并不想这么做,实际上我想做的是以 sudo 用户的身份运行这个服务但无需提供密码。假如你曾经经历过这样的情形,那么我知道一个简单的方法来做到这点。今天,在这个简短的指南中,我将教你如何在类 Unix 的操作系统中运行特定命令而无需 sudo 密码。

就让我们看看下面的例子吧。

$ sudo mkdir /ostechnix
[sudo] password for sk:

正如上面的截图中看到的那样,当我在根目录(/)中创建一个名为 ostechnix 的目录时,我需要提供 sudo 密码。每当我们尝试以 sudo 特权执行一个命令时,我们必须输入密码。而在我的预想中,我不想提供 sudo 密码。下面的内容便是我如何在我的 Linux 机子上运行一个 sudo 命令而无需输入密码的过程。

在 Linux 中运行特定命令而无需 sudo 密码

基于某些原因,假如你想允许一个用户运行特定命令而无需提供 sudo 密码,则你需要在 sudoers 文件中添加上这个命令。

假如我想让名为 sk 的用户去执行 mkdir 而无需提供 sudo 密码,下面就让我们看看该如何做到这点。

使用下面的命令来编辑 sudoers 文件:

$ sudo visudo

将下面的命令添加到这个文件的最后。

sk ALL=NOPASSWD:/bin/mkdir

其中 sk 是用户名。根据上面一行的内容,用户 sk 可以从任意终端执行 mkdir 命令而不必输入 sudo 密码。

你可以用逗号分隔的值来添加额外的命令(例如 chmod),正如下面展示的那样。

sk ALL=NOPASSWD:/bin/mkdir,/bin/chmod

保存并关闭这个文件,然后注销(或重启)你的系统。现在以普通用户 sk 登录,然后试试使用 sudo 来运行这些命令,看会发生什么。

$ sudo mkdir /dir1

看到了吗?即便我以 sudo 特权运行 mkdir 命令,也不会弹出提示让我输入密码。从现在开始,当用户 sk 运行 mkdir 时,就不必输入 sudo 密码了。

当运行除了添加到 sudoers 文件之外的命令时,你将被提示输入 sudo 密码。

让我们用 sudo 来运行另一个命令。

$ sudo apt update

看到了吗?这个命令将提示我输入 sudo 密码。

假如你不想让这个命令提示你输入 sudo 密码,请编辑 sudoers 文件:

$ sudo visudo

像下面这样将 apt 命令添加到 sudoers 文件中:

sk ALL=NOPASSWD:/bin/mkdir,/usr/bin/apt

你注意到了上面命令中 apt 二进制执行文件的路径与 mkdir 的有所不同吗?是的,你必须提供一个正确的可执行文件路径。要找到任意命令的可执行文件路径,例如这里的 apt,可以像下面这样使用 whichis 命令来查看:

$ whereis apt
apt: /usr/bin/apt /usr/lib/apt /etc/apt /usr/share/man/man8/apt.8.gz

如你所见,apt 命令的可执行文件路径为 /usr/bin/apt,所以我将这个路径添加到了 sudoers 文件中。

正如我前面提及的那样,你可以添加任意多个以逗号分隔的命令。一旦你做完添加的动作,保存并关闭你的 sudoers 文件,接着注销,然后重新登录进你的系统。

现在就检验你是否可以直接运行以 sudo 开头的命令而不必使用密码:

$ sudo apt update

看到了吗?apt 命令没有让我输入 sudo 密码,即便我用 sudo 来运行它。

下面展示另一个例子。假如你想运行一个特定服务,例如 apache2,那么就添加下面这条命令到 sudoers 文件中:

sk ALL=NOPASSWD:/bin/mkdir,/usr/bin/apt,/bin/systemctl restart apache2

现在用户 sk 就可以运行 sudo systemctl restart apache 命令而不必输入 sudo 密码了。

我可以再次让一个特别的命令提醒输入 sudo 密码吗?当然可以!只需要删除添加的命令,注销然后再次登录即可。

除了这种方法外,你还可以在命令的前面添加 PASSWD: 指令。让我们看看下面的例子:

sudoers 文件中添加或者修改下面的一行:

sk ALL=NOPASSWD:/bin/mkdir,/bin/chmod,PASSWD:/usr/bin/apt

在这种情况下,用户 sk 可以运行 mkdirchmod 命令而不用输入 sudo 密码。然而,当他运行 apt 命令时,就必须提供 sudo 密码了。

免责声明:本篇指南仅具有教育意义。在使用这个方法的时候,你必须非常小心。这个命令既可能富有成效但也可能带来摧毁性效果。例如,假如你允许用户执行 rm 命令而不输入 sudo 密码,那么他们可能无意或有意地删除某些重要文件。我警告过你了!

那么这就是全部的内容了。希望这个能够给你带来帮助。更多精彩内容即将呈现,请保持关注!

干杯!


via: https://www.ostechnix.com/run-particular-commands-without-sudo-password-linux/

作者:SK 选题:lujun9972 译者:FSSlc 校对:校对者ID

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

开始使用 Cypht 吧,一个开源的电子邮件客户端

$
0
0

使用 Cypht 将你的电子邮件和新闻源集成到一个界面中,这是我们 19 个开源工具系列中的第 4 个,它将使你在 2019 年更高效。

每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然,“抛弃旧的,拥抱新的”的态度促成了这一切。通常这时的建议严重偏向闭源和专有软件,但事实上并不用这样。

这是我挑选出的 19 个新的(或者对你而言新的)开源工具中的第 4 个工具来帮助你在 2019 年更有效率。

Cypht

我们花了很多时间来处理电子邮件,有效地管理你的电子邮件可以对你的工作效率产生巨大影响。像 Thunderbird、Kontact/KMail 和 Evolution 这样的程序似乎都有一个共同点:它们试图复制 Microsoft Outlook 的功能,这在过去 10 年左右并没有真正改变。在过去十年中,甚至像 Mutt 和 Cone 这样的著名控制台程序也没有太大变化。

Cypht 是一个简单、轻量级和现代的 Webmail 客户端,它将多个帐户聚合到一个界面中。除了电子邮件帐户,它还包括 Atom/RSS 源。在 “Everything” 中,不仅可以显示收件箱中的邮件,还可以显示新闻源中的最新文章,从而使得阅读不同来源的内容变得简单。

它使用简化的 HTML 消息来显示邮件,或者你也可以将其设置为查看纯文本版本。由于 Cypht 不会加载远程图像(以帮助维护安全性),HTML 渲染可能有点粗糙,但它足以完成工作。你将看到包含大量富文本邮件的纯文本视图 —— 这意味着很多链接并且难以阅读。我不会说是 Cypht 的问题,因为这确实是发件人所做的,但它确实降低了阅读体验。阅读新闻源大致相同,但它们与你的电子邮件帐户集成,这意味着可以轻松获取最新的(我有时会遇到问题)。

用户可以使用预配置的邮件服务器并添加他们使用的任何其他服务器。Cypht 的自定义选项包括纯文本与 HTML 邮件显示,它支持多个配置文件以及更改主题(并自行创建)。你要记得单击左侧导航栏上的“保存”按钮,否则你的自定义设置将在该会话后消失。如果你在不保存的情况下注销并重新登录,那么所有更改都将丢失,你将获得开始时的设置。因此可以轻松地实验,如果你需要重置,只需在不保存的情况下注销,那么在再次登录时就会看到之前的配置。

本地安装 Cypht 非常容易。虽然它不使用容器或类似技术,但安装说明非常清晰且易于遵循,并且不需要我做任何更改。在我的笔记本上,从安装开始到首次登录大约需要 10 分钟。服务器上的共享安装使用相同的步骤,因此它应该大致相同。

最后,Cypht 是桌面和基于 Web 的电子邮件客户端的绝佳替代方案,它有简单的界面,可帮助你快速有效地处理电子邮件。


via: https://opensource.com/article/19/1/productivity-tool-cypht-email

作者:Kevin Sonney 选题:lujun9972 译者:geekpi 校对:wxy

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

区块链将会如何影响开源

$
0
0

中本聪十年前创立比特币伊始,就引来来众多的追随者,并慢慢演变为去中心化的一场运动。甚至于,对于某一些人来说,区块链技术就像互联网那样深刻影响着人类社会的技术,当然,也有很大一部分人认为,区块链不过是另外一场庞氏骗局罢了,就在这众说纷纭之中,区块链也在进化并不断的尝试寻找自己的位置。无论怎样,有一件事是确定的,那就是区块链是一项颠覆性的技术,将从根本上改变一些行业。我深信开源就是其中之一。

开源的模式

开源是一种软件协作开发方法,也是软件分发的模式,开源允许拥有共同兴趣的人们一起协作,进而生产出他们中间任何个体都无法独立完成的事情,它让整体所创建的价值远远大于部分的总和。开源通过分布式的协作工具(IRC、email、git、wiki、issue 跟踪等)、以及开源许可证模式下的分发和保护,当然还有诸如 Apache 软件基金会云原生基金会这样的非盈利基金会的治理。

说来已久,最让人们好奇的莫过于开源的模式本质上是缺乏金钱上的激励的。在开源界,像人类社会的其它方面一样,分很多的派系,如其中一些人就认为谈开源就不要谈钱,开源本应该就是由内在的激励的自由和资源的行为(诸如“共同理想”、“为了伟大的事情”);也有另外一些人认为开源需要获得外部的尤其是金钱上的激励。虽然开源项目仅仅通过世上的志愿者来完成是富有理想的浪漫主义色彩的,就目前的现状来看,事实上主要的开源完成的贡献均是在有支付的情形下搞定的。当然,毋庸置疑的是我们拥有大量的无偿贡献者,但是这些贡献都是来来回回的临时性的,或者是某些受追捧的项目备受世人关注。建立和维系开源项目是需要企业倾注大量心血和精力来进行开发、文档化、测试、修复缺陷,而且是持续性的一如既往的,绝不是一时心血来潮。要知道,开发软件产品是需要克服大量困难的事情,这类事情最好是有金钱上的激励方能持久。

开源的商业化

众所周知,Apache 软件基金会是通过捐助而生存的,当然还有其它的一些收入:赞助、会议费用等等。但是要知道这些资金主要是用于运营基金会本身,如为项目提供法律保护,以及确保有足够的服务器来运行构建程序、缺陷追踪、邮件列表等等。

同样的,云原生基金会 CNCF 会收取会员费,以及更多的会议费用,这些费用同样是用来运营基金会以及为项目提供资源。如今的年头,绝大多数的软件已经不能在自己的笔记本电脑里构建了,它们都的运行和测试都是在云平台中上百台服务器当中。这些都属于基金会的日常开销。其它如开展营销活动,品牌设计、分发一些小的宣传物品,也是基金会份内的事情。基金会的核心任务是实施正确的流程,与用户,开发人员和控制机制进行交互,并确保将可用财务资源分配给开源项目以实现共同利益。

看起来是一切都运行良好,不是吗?开源项目可以募捐到钱,基金会也可以公正的进行分发,那么哪里有问题了呢?

这里没有说明的是:用于在开源生产者和开源消费者之间进行价值转移,直接,透明,可信,分散,自动的双向链接。就目前而言,所有的链接都是单向或间接的:

  • 单向:一名开发者(广义上的开发者,可以是软件生产中的任何角色:码农、维护者、分发者),利用自己的聪明才智,绞尽脑汁,并花费无数时间来开发开源项目,且提交贡献为所有的开源用户分享这一价值。但是基本上都是一厢情愿的。
  • 间接:如果软件出现了 bug,影响到了特定的用户/公司的话,有下列几种情形出现:
    • 让内部开发人员修复 bug,然后提交一个拉取请求(PR),这是比较理想的状态,这些公司并不总是能够聘请到特定的开源项目的开发人员,因为一般公司都会使用成百上千个开源项目。
    • 聘请专门从事该特定开源项目的自由职业者并支付服务费用。理想情况下,自由职业者也是开源项目的提交者,可以直接快速更改项目代码。否则,修复程序可能永远不会进入上游项目。
    • 接近围绕开源项目提供服务的公司。这些公司通常雇用开源提交者来影响和获得社区的可信度,并提供产品、专业知识和专业服务。

第三种选择是维持许多开源项目的成功模式。无论这些公司提供服务(培训、咨询、workshop)、技术支持、打包、开放核心,还是 SaaS 服务,不可否认的是他们都需要雇佣上百个全职的员工来为开源做出努力,我们可以看到这样的公司有一大把,他们成功的建立了有效的开源商业模式,而且正在有更多的公司加入这个阵营。

支持开源项目的公司在这个生态系统中发挥着重要的作用:它们介于开源项目和用户之间,起着重要的催化剂作用。那些能够真正为用户创造价值的公司,不仅仅是能够打包出很棒的软件;而是他们能够识别用户的真实需求,且能够洞察技术趋势,有能力创建出一个完整的堆栈甚至是开源项目的生态系统来满足这些需求。 他们可以全身心的扑在一个有些寂寥和无聊的项目上,而且会一直支持很多年,只为坚守其中的价值。还有如果在某个软件堆栈中缺少了某一部分,他们随时可以从头开始一个开源项目,并围绕它来构建一个社区。他们甚至可以收购一家闭源的公司,然后将项目再整个的开源了(没错,可能很多读者看到这里已经猜到了说的是哪家公司了,没错,这里的特性红帽公司都拥有。)

简单总结一下,基于商业化的开源模式就是这样,项目由少数个人或公司正式或非正式的管理和控制着,这些个人或公司确保了项目的成功发布,而且有着商品化的能力,并有效的在回馈给开源的生态。对于开源开发人员,管理公司和最终用户来说,这是一个没有输家的美好格局。这可以很好的替代那些日薄西山且昂贵的闭源软件!

自我供给,去中心化的开源

毫无疑问,想要让项目赢得好口碑,就得满足一些人们的期望。举例来说,Apache 软件基金会和云原生计算基金会均需要孵化和毕业的过程,除了所有技术和形式要求之外,项目还必须拥有健康数量的活跃提交者和用户。这些都是形成可持续发展开源项目的关键。在 GitHub 上拥有源代码与拥有一个活跃的开源项目是有着本质上的不同。一个活跃的开源项目意指编写代码的提交者和使用代码的用户,两个组通过交换价值并形成一个每个人都受益的生态系统来不断的螺旋式成长。一些项目生态系统可能很小而且寿命很短,有些可能包含多个项目和竞争服务提供商,其中非常复杂的交互持续多年。但只要有价值交换,每个人都从中受益,项目就会得到发展、维护和可持续。

我们来看下 Apache 软件基金会的项目 Attic,该项目已经完成了它的历史使命,正在走入其生命周期中最后的阶段。这是非常正常的现象:当一个项目在技术上不再适合它的当初的开发目的时,它通常会自然结束。同样,在 ASF 的孵化基地,你会发现很多项目从未毕业但却已经退出了历史舞台,通常情况下,这些项目无法构建足够大的社区,要么因为它们过于偏门,要么是被更好的方案所替代。

但更多的情况是,具有高潜力和卓越技术的项目无法维系自身,因为它们无法形成或维持一个有效的生态系统来进行价值交换。目前的开源模式以及基金会并没有为开发者提供一个获得报酬或让用户获知他们的请求的框架或机制,这样的话,就没有任何一方拥有共同的价值承诺。这样的话,结果就是一些项目只能在商业的开源环境中维持自身,在商业化的开源中,公司充当中间人的角色,并在开发者和用户之间进行价值获取。这还增加了另外一个局限且要求服务提供商的公司来维持一些开源项目。这似乎离我们理想中的情况很是遥远:用户可以完整而直接的表达他们对项目的期望,开发人员能够以透明、可量化的方式来兑现他们对项目的承诺,这是一个具有共同利益和意图进行价值交换的社区。

现在各位看官可以想象一下,有这样一个模式,它的工作机制和工具可以实现开源用户和开发人员直接打交道。这不仅仅体现在诸如通过拉取请求来贡献代码、使用邮件列表发送问题、GitHub 的星星数量、以及笔记本电脑上的贴纸,而且还体现在用户有更多的方式、更加自控的、透明的行为来影响项目的走向。

该模型可包括对以下行为的激励:

  • 直接为开源项目提供资金,而不是通过软件基金会
  • 通过投票影响项目方向(通过代币持有人)
  • 由用户需求驱动的功能需求
  • 及时的合并拉取请求
  • 为提交缺陷者给予奖励
  • 为更好的测试覆盖率进行奖励
  • 奖励及时更新文档者
  • 及时的安全修复
  • 专家协助、支持和服务
  • 为项目的布道师和推广者进行最佳预算
  • 定期活动的预算
  • 更加快速的电子邮件和在线聊天帮助系统
  • 全面了解整体项目的状态,等

聪明的看官可能已经猜到了,没错,以上所谈就是使用区块链和智能合约,进而实现最终用户和开发者之间的积极互动。 智能合约可以让代币持有者拥有真实的权力来影响项目的走向。

上图所示:在开源生态系统中区块链的应用

目前现有的开源生态系统中,采用非正常手段来影响项目的走向是可能做得到的,如服务提供商的财务承诺、通过基金会的较为有限的方式等。但是在开源生态系统上增加基于区块链的技术会为用户和开发者之间打开一条新的通道,这么做并不是说会取代商业的开源模式;因为大多数使用开源的公司做了许多智能合约无法完成的事情。但是智能合约可以引发一种新型的开源项目,为那些不堪重负的项目提供二次生命的机会。它可以激励开发者去认领那些无聊的拉取请求、撰写文档、测试程序代码等等,在用户和开源开发人员之间提供直接的价值交换渠道。即使公司支持不可行,区块链也可以增加新渠道,帮助开源项目增长,并在长期内实现自我维持。它可以为自我维持的开源项目创建一个新的互补模型 —— 一种双赢的模式。

通证开源

其实已经有许多旨在将开源通证化的实现了,它们其中有一些是仅仅聚焦于开源模式的,也有一些是更加通用的(也适用于开源模式),以下是我收集的列表:

  • GitCoin,在开源成长起来的,这是该领域最有前途的开源项目之一。
  • oscoin,针对开源的加密货币。
  • 开放协作,一款支持开源项目的平台。
  • FundYourselfNow,针对项目的众筹和 ICO 平台。
  • Kauri,支持开源项目文档。
  • Liberapay,经常性的捐赠平台。
  • FundRequest,针对开源协作的去中心化市场。
  • CanYa,最近被 Bountysource 收购,Bountysource 是目前世界上最大的开源 P2P 赏金平台。
  • OpenGift,开源套现的新模式。
  • Hacken,为 Hacker 们提供的白帽令牌。
  • CoinLancer,一个去中心化的人力市场。
  • CodeFund,一款开源的广告平台。
  • IssueHunt,为开源维护者和贡献者提供的募捐平台。
  • District0x 1Hive,众包和策展平台。
  • District0x Fixit ,GitHub 缺陷悬赏系统。

这个列表在本文撰写之时仍然在增长着,而且是蛮快速的那种,它们其中一些肯定会消失,也有一些会转移目标,但是总有一些会融入到诸如 SourceForge、Apache 软件基金会、以及 GitHub。这些平台不会也没有必要去取代这些平台,但是令牌模型是对这些平台的很好补充,它可以让开源生态系统更加的丰富。每个项目都可以选择其分发模型(许可证)、管理模型(基金会)和激励模型(令牌)。无论哪种,都会为开源的世界诸如新鲜的血液!

开放和去中心化的未来

  • 软件正在吞噬世界
  • 每家公司都是软件公司
  • 开源是创新的良田

事实就在眼前,开源已经发展到如此巨大的产业,是不会轻易失败的,而且开源对于这个世界实在是太重要了。它是不可能被少数人所操纵,或者被世人所遗弃而自生自灭。开源是一个对所有人都有价值的共享资源系统,而且更要重要的是,它只能以这样的方式来被管理,这个世界上所有的公司都希望自身在开源拥有筹码和发言权,然而,颇为不幸的是,我们并没有一种工具或者习惯来这么去做,我们对工具的期望是:这些工具将允许任何人表达他们对软件项目的欣赏或忽视;它将在生产者和消费者之间,开发者和用户之间创建直接而且更快的反馈循环;它将促进由用户需求驱动的双创新模式,而且是通过令牌来进行追踪和衡量的。

关于作者

Bilgin Ibryam (@bibryam) 是开源的铁杆粉丝,博主、演讲者,《Camel 设计模式》和《Kubernetes 模式》等的书作者。他也是红帽的架构师,同时也是 Apache 软件基金会的贡献者,涉及的项目有 Camel、OFBiz、Isis 等,在日常工作中,Bilgin 非常热衷于指导、训练、带领团队搞一些正如应用程序集成、分布式系统、云原生的应用等。在闲暇时刻,他为开源项目做贡献,并撰写博客:ofbizian.com

Viewing all 9060 articles
Browse latest View live
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>