mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-25 23:11:02 +08:00
commit
decee23a02
@ -0,0 +1,245 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10625-1.html)
|
||||
[#]: subject: (Advanced Techniques for Reducing Emacs Startup Time)
|
||||
[#]: via: (https://blog.d46.us/advanced-emacs-startup/)
|
||||
[#]: author: (Joe Schafer https://blog.d46.us/)
|
||||
|
||||
降低 Emacs 启动时间的高级技术
|
||||
======
|
||||
|
||||
> 《[Emacs Start Up Profiler][1]》 的作者教你六项减少 Emacs 启动时间的技术。
|
||||
|
||||
简而言之:做下面几个步骤:
|
||||
|
||||
1. 使用 Esup 进行性能检测。
|
||||
2. 调整垃圾回收的阀值。
|
||||
3. 使用 use-package 来自动(延迟)加载所有东西。
|
||||
4. 不要使用会引起立即加载的辅助函数。
|
||||
5. 参考我的 [配置][2]。
|
||||
|
||||
### 从 .emacs.d 的失败到现在
|
||||
|
||||
我最近宣布了 .emacs.d 的第三次失败,并完成了第四次 Emacs 配置的迭代。演化过程为:
|
||||
|
||||
1. 拷贝并粘贴 elisp 片段到 `~/.emacs` 中,希望它能工作。
|
||||
2. 借助 `el-get` 来以更结构化的方式来管理依赖关系。
|
||||
3. 放弃自己从零配置,以 Spacemacs 为基础。
|
||||
4. 厌倦了 Spacemacs 的复杂性,基于 `use-package` 重写配置。
|
||||
|
||||
本文汇聚了三次重写和创建 《[Emacs Start Up Profiler][1]》过程中的技巧。非常感谢 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][1]》(ESUP)将会给你顶层语句执行的详细指标。
|
||||
|
||||
![esup.png][3]
|
||||
|
||||
*图 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][4] 中你只需要声明好需要哪个包中的哪个功能,`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][5] 或者我在 [abn-funcs-benchmark.el][6] 中的变体。输出看起来类似这样的:
|
||||
|
||||
```
|
||||
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][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://blog.d46.us/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/jschaf/esup
|
||||
[2]: https://github.com/jschaf/dotfiles/blob/master/emacs/start.el
|
||||
[3]: https://blog.d46.us/images/esup.png
|
||||
[4]: https://github.com/jwiegley/use-package
|
||||
[5]: https://gist.github.com/RockyRoad29/bd4ca6fdb41196a71662986f809e2b1c
|
||||
[6]: https://github.com/jschaf/dotfiles/blob/master/emacs/funcs/abn-funcs-benchmark.el
|
@ -0,0 +1,227 @@
|
||||
toplip:一款十分强大的文件加密解密 CLI 工具
|
||||
======
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2017/12/Toplip-720x340.jpg)
|
||||
|
||||
在市场上能找到许多用来保护文件的文档加密工具。我们已经介绍过其中一些例如 [Cryptomater][1]、[Cryptkeeper][2]、[CryptGo][3]、[Cryptr][4]、[Tomb][5],以及 [GnuPG][6] 等加密工具。今天我们将讨论另一款叫做 “toplip” 的命令行文件加密解密工具。它是一款使用一种叫做 [AES256][7] 的强大加密方法的自由开源的加密工具。它同时也使用了 XTS-AES 设计以保护你的隐私数据。它还使用了 [Scrypt][8],一种基于密码的密钥生成函数来保护你的密码免于暴力破解。
|
||||
|
||||
### 优秀的特性
|
||||
|
||||
相比于其它文件加密工具,toplip 自带以下独特且杰出的特性。
|
||||
|
||||
* 非常强大的基于 XTS-AES256 的加密方法。
|
||||
* <ruby>合理的推诿<rt>Plausible deniability</rt></ruby>。
|
||||
* 加密并嵌入文件到图片(PNG/JPG)中。
|
||||
* 多重密码保护。
|
||||
* 可防护直接暴力破解。
|
||||
* 无可辨识的输出标记。
|
||||
* 开源(GPLv3)。
|
||||
|
||||
### 安装 toplip
|
||||
|
||||
没有什么需要安装的。`toplip` 是独立的可执行二进制文件。你所要做的仅是从 [产品官方页面][9] 下载最新版的 `toplip` 并赋予它可执行权限。为此你只要运行:
|
||||
|
||||
```
|
||||
chmod +x toplip
|
||||
```
|
||||
|
||||
### 使用
|
||||
|
||||
如果你不带任何参数运行 `toplip`,你将看到帮助页面。
|
||||
|
||||
```
|
||||
./toplip
|
||||
```
|
||||
|
||||
![][10]
|
||||
|
||||
请允许我给你展示一些例子。
|
||||
|
||||
为了达到指导目的,我建了两个文件 `file1` 和 `file2`。我同时也有 `toplip` 可执行二进制文件。我把它们全都保存进一个叫做 `test` 的目录。
|
||||
|
||||
![][12]
|
||||
|
||||
#### 加密/解密单个文件
|
||||
|
||||
现在让我们加密 `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` 加密,随机数据都会自动加上。如果指定了多于一个文件,每个都有自己的密码,那么你可以有选择性地独立解码每个文件,以此来否认其它文件存在的可能性。这能有效地使一个用户在可控的暴露风险下打开一个加密的捆绑文件包。并且对于敌人来说,在计算上没有一种低廉的办法来确认额外的秘密数据存在。这叫做“<ruby>合理的推诿<rt>Plausible deniability</rt></ruby>”,是 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。十六进制和十进制数值都是允许的。比如说 `0x8000`、`10` 等。请注意这会大大增加计算次数。
|
||||
|
||||
为了解码 `file1`,使用:
|
||||
|
||||
```
|
||||
./toplip -c 5 -i 0x8000 -d file3.encrypted > file1.decrypted
|
||||
```
|
||||
|
||||
为了解码 `file2`,使用:
|
||||
|
||||
```
|
||||
./toplip -c 10 -i 10 -d file3.encrypted > file2.decrypted
|
||||
```
|
||||
|
||||
参考 `toplip` [官网](https://2ton.com.au/toplip/)以了解更多关于其背后的技术信息和使用的加密方式。
|
||||
|
||||
我个人对所有想要保护自己数据的人的建议是,别依赖单一的方法。总是使用多种工具/方法来加密文件。不要在纸上写下密码也不要将密码存入本地或云。记住密码,阅后即焚。如果你记不住,考虑使用任何了信赖的密码管理器。
|
||||
|
||||
- [KeeWeb – An Open Source, Cross Platform Password Manager](https://www.ostechnix.com/keeweb-an-open-source-cross-platform-password-manager/)
|
||||
- [Buttercup – A Free, Secure And Cross-platform Password Manager](https://www.ostechnix.com/buttercup-a-free-secure-and-cross-platform-password-manager/)
|
||||
- [Titan – A Command line Password Manager For Linux](https://www.ostechnix.com/titan-command-line-password-manager-linux/)
|
||||
|
||||
今天就到此为止了,更多好东西后续推出,请保持关注。
|
||||
|
||||
顺祝时祺!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/toplip-strong-file-encryption-decryption-cli-utility/
|
||||
|
||||
作者:[SK][a]
|
||||
译者:[tomjlw](https://github.com/tomjlw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.ostechnix.com/author/sk/
|
||||
[1]:https://www.ostechnix.com/cryptomator-open-source-client-side-encryption-tool-cloud/
|
||||
[2]:https://www.ostechnix.com/how-to-encrypt-your-personal-foldersdirectories-in-linux-mint-ubuntu-distros/
|
||||
[3]:https://www.ostechnix.com/cryptogo-easy-way-encrypt-password-protect-files/
|
||||
[4]:https://www.ostechnix.com/cryptr-simple-cli-utility-encrypt-decrypt-files/
|
||||
[5]:https://www.ostechnix.com/tomb-file-encryption-tool-protect-secret-files-linux/
|
||||
[6]:https://www.ostechnix.com/an-easy-way-to-encrypt-and-decrypt-files-from-commandline-in-linux/
|
||||
[7]:http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
|
||||
[8]:http://en.wikipedia.org/wiki/Scrypt
|
||||
[9]:https://2ton.com.au/Products/
|
||||
[10]:https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-2.png
|
||||
[12]:https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-1.png
|
||||
|
158
published/20180206 Power(Shell) to the people.md
Normal file
158
published/20180206 Power(Shell) to the people.md
Normal file
@ -0,0 +1,158 @@
|
||||
给大家安利一下 PowerShell
|
||||
======
|
||||
|
||||
> 代码更简洁、脚本更清晰、跨平台一致性等好处是让 Linux 和 OS X 用户喜爱 PowerShell 的原因。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_lightbulbs.png?itok=pwp22hTw)
|
||||
|
||||
今年(2018)早些时候,[Powershell Core][1] 以 [MIT][3] 开源协议发布了[正式可用版(GA)][2]。PowerShell 算不上是新技术。自 2006 年为 Windows 发布了第一版 PowerShell 以来,PowerShell 的创建者在[结合了][4] 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 命令和工具依赖于你使用和操控非结构化数据的能力。对于那些长期活在 `sed`、 `grep` 和 `awk` 环境下的人们来说,这可能是小菜一碟,但现在有更好的选择。
|
||||
|
||||
让我们使用 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` [属性][5] 则用来获取该类型的全称。
|
||||
|
||||
那么,这种对象导向的 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-Json` 或 `ConvertFrom-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
|
||||
```
|
||||
|
||||
因为 `Mi` 和 `Ma` 每一个都具有独立不同的补齐。
|
||||
|
||||
你可能已经留意到所有的 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][6] 或其别称 `?`)。如果你有点怀旧的话,PowerShell 可以为你加载原来的本地工具。但是给自己足够的时间来适应 PowerShell 面向对象 cmdlet 的世界,然后你将发现自己会选择忘记回去的路。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/2/powershell-people
|
||||
|
||||
作者:[Yev Bronshteyn][a]
|
||||
译者:[sanfusu](https://github.com/sanfusu)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/yevster
|
||||
[1]:https://github.com/PowerShell/PowerShell/blob/master/README.md
|
||||
[2]:https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-core-6-0-generally-available-ga-and-supported/
|
||||
[3]:https://spdx.org/licenses/MIT
|
||||
[4]:http://www.jsnover.com/Docs/MonadManifesto.pdf
|
||||
[5]:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
|
||||
[6]:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6
|
@ -0,0 +1,59 @@
|
||||
关于圆周率日的趣事与庆祝方式
|
||||
======
|
||||
|
||||
> 技术团队喜欢 3 月 14 日的圆周率日:你是否知道这也是阿尔伯特·爱因斯坦的生日和 Linux 内核1.0.0 发布周年纪念日?来看一些树莓派的趣事和 DIY 项目。
|
||||
|
||||
![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/cio_piday.png?itok=kTht0qV9)
|
||||
|
||||
今天,全世界的技术团队都会为一个数字庆祝。3 月 14 日是<ruby>圆周率日<rt>Pi Day</rt></ruby>,人们会在这一天举行吃派比赛、披萨舞会,玩<ruby>数学梗<rt>math puns</rt></ruby>。如果这个数学领域中的重要常数不足以让 3 月 14 日成为一个节日的话,再加上爱因斯坦的生日、Linux 内核 1.0.0 发布的周年纪念日,莱伊·惠特尼在这一天申请了轧花机的专利这些原因,应该足够了吧。(LCTT译注:[轧花机](https://zh.wikipedia.org/wiki/%E8%BB%8B%E6%A3%89%E6%A9%9F)是一种快速而且简单地分开棉花纤维和种子的机器,生产力比人手分离高得多。)
|
||||
|
||||
很荣幸,我们能在这一个特殊的日子里一起了解有关它的趣事和与 π 相关的好玩的活动。来吧,和你的团队一起庆祝圆周率日:找一两个点子来进行团队建设,或用新兴技术做一个项目。如果你有为这个大家所喜爱的无限小数庆祝的独特方式,请在评论区与大家分享。
|
||||
|
||||
### 圆周率日的庆祝方法:
|
||||
|
||||
* 今天是圆周率日的第 31 次周年纪念(LCTT 译注:本文写于 2018 年的圆周率日,故在细节上存在出入。例如今天(2019 年 3 月 14 日)是圆周率日的第 31 次周年纪念)。第一次为它庆祝是在旧金山的<ruby>探索博物馆<rt>Exploratorium</rt></ruby>由物理学家 Larry Shaw 举行。“在[第 1 次周年纪念日][1]当天,工作人员带来了水果派和茶壶来庆祝它。在 1 点 59 分(圆周率中紧接着 3.14 的数字),Shaw 在博物馆外领着队伍环馆一周。队伍中用扩音器播放着‘Pomp and Circumstance’。” 直到 21 年后,在 2009 年 3 月,圆周率正式成为了美国的法定假日。
|
||||
* 虽然该纪念日起源于旧金山,可规模最大的庆祝活动却是在普林斯顿举行的,这个小镇举办了为期五天的[许多活动][2],包括爱因斯坦模仿比赛、掷派比赛,圆周率背诵比赛等等。其中的某些活动甚至会给获胜者提供价值 314.5 美元的奖金。
|
||||
* <ruby>麻省理工的斯隆管理学院<rt>MIT Sloan School of Management</rt></ruby>正在庆祝圆周率日。他们在 Twitter 上分享着关于 π 和派的圆周率日趣事,详情请关注<ruby>推特话题<rt>Twitter hashtag</rt></ruby> #PiVersusPie 。
|
||||
|
||||
### 与圆周率有关的项目与活动:
|
||||
|
||||
* 如果你想锻炼你的数学技能,<ruby>美国国家航空航天局<rt>National Aeronautics and Space Administration</rt></ruby>(NASA)的<ruby>喷气推进实验室<rt>Jet Propulsion Lab</rt></ruby>(JPL)发布了[一系列新的数学问题][4],希望通过这些问题展现如何把圆周率用于空间探索。这也是美国国家航天局面向学生举办的第五届圆周率日挑战。
|
||||
* 想要领略圆周率日的精神,最好的方法也许就是开展一个[树莓派][5]项目了,无论是和你的孩子还是和你的团队一起完成,都是不错的。树莓派作为一项从 2012 年开启的项目,现在已经售出了数百万块的基本型的电脑主板。事实上,它已经在[通用计算机畅销榜上排名第三][6]了。这里列举一些可能会吸引你的树莓派项目或活动:
|
||||
* 来自谷歌的<ruby>自己做 AI<rt>AI-Yourself</rt></ruby>(AIY)项目让你自己创造一个[语音控制的数字助手][7]或者[一个图像识别设备][8]。
|
||||
* 在树莓派上[使用 Kubernets][9]。
|
||||
* 组装一台[怀旧游戏系统][10],目标:拯救桃子公主!
|
||||
* 和你的团队举办一场[树莓派 Jam][11]。树莓派基金会发布了一个帮助大家顺利举办活动的[指导手册][12]。据该网站说明,树莓派 Jam 旨在“给数字创作中所有年龄段的人提供支持,让世界各地志同道合的人们汇聚起来讨论和分享他们的最新项目,举办讲习班,讨论和派相关的一切。”
|
||||
|
||||
### 其他有关圆周率的事情:
|
||||
|
||||
* 当前背诵圆周率的[世界纪录保持者][13]是 Suresh Kumar Sharma,他在 2015 年 10 月花了 17 小时零 14 分钟背出了 70,030 位数字。然而,[非官方记录][14]的保持者 Akira Haraguchi 声称他可以背出 111,700 位数字。
|
||||
* 现在,已知的圆周率数字的长度比以往都要多。在 2016 年 11 月,R&D 科学家 Peter Trueb 计算出了 22,459,157,718,361 位圆周率数字,比 2013 年的世界记录多了 [9 万亿数字][15]。据<ruby>新科学家<rt>New Scientist</rt></ruby>所述,“最终文件包含了圆周率的 22 万亿位数字,大小接近 9 TB。如果将其打印出来,能用数百万本 1000 页的书装满一整个图书馆。”
|
||||
|
||||
祝你圆周率日快乐!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://enterprisersproject.com/article/2018/3/pi-day-12-fun-facts-and-ways-celebrate
|
||||
|
||||
作者:[Carla Rudder][a]
|
||||
译者:[wwhio](https://github.com/wwhio)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://enterprisersproject.com/user/crudder
|
||||
[1]:https://www.exploratorium.edu/pi/pi-day-history
|
||||
[2]:https://princetontourcompany.com/activities/pi-day/
|
||||
[3]:https://twitter.com/MITSloan
|
||||
[4]:https://www.jpl.nasa.gov/news/news.php?feature=7074
|
||||
[5]:https://opensource.com/resources/raspberry-pi
|
||||
[6]:https://www.theverge.com/circuitbreaker/2017/3/17/14962170/raspberry-pi-sales-12-5-million-five-years-beats-commodore-64
|
||||
[7]:http://www.zdnet.com/article/raspberry-pi-this-google-kit-will-turn-your-pi-into-a-voice-controlled-digital-assistant/
|
||||
[8]:http://www.zdnet.com/article/google-offers-raspberry-pi-owners-this-new-ai-vision-kit-to-spot-cats-people-emotions/
|
||||
[9]:https://opensource.com/article/17/3/kubernetes-raspberry-pi
|
||||
[10]:https://opensource.com/article/18/1/retro-gaming
|
||||
[11]:https://opensource.com/article/17/5/how-run-raspberry-pi-meetup
|
||||
[12]:https://www.raspberrypi.org/blog/support-raspberry-jam-community/
|
||||
[13]:http://www.pi-world-ranking-list.com/index.php?page=lists&category=pi
|
||||
[14]:https://www.theguardian.com/science/alexs-adventures-in-numberland/2015/mar/13/pi-day-2015-memory-memorisation-world-record-japanese-akira-haraguchi
|
||||
[15]:https://www.newscientist.com/article/2124418-celebrate-pi-day-with-9-trillion-more-digits-than-ever-before/?utm_medium=Social&utm_campaign=Echobox&utm_source=Facebook&utm_term=Autofeed&cmpid=SOC%7CNSNS%7C2017-Echobox#link_time=1489480071
|
@ -0,0 +1,77 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10639-1.html)
|
||||
[#]: subject: (Asynchronous rsync with Emacs,dired and tramp。)
|
||||
[#]: via: (https://vxlabs.com/2018/03/30/asynchronous-rsync-with-emacs-dired-and-tramp/)
|
||||
[#]: author: (cpbotha https://vxlabs.com/author/cpbotha/)
|
||||
|
||||
在 Emacs 的 dired 和 tramp 中异步运行 rsync
|
||||
======
|
||||
|
||||
[Trần Xuân Trường][2] 写的 [tmtxt-dired-async][1] 是一个不为人知的 Emacs 包,它可以扩展 dired(Emacs 内置的文件管理器),使之可以异步地运行 `rsync` 和其他命令 (例如压缩、解压缩和下载)。
|
||||
|
||||
这意味着你可以拷贝上 GB 的目录而不影响 Emacs 的其他任务。
|
||||
|
||||
它的一个功能时让你可以通过 `C-c C-a` 从不同位置添加任意多的文件到一个等待列表中,然后按下 `C-c C-v` 异步地使用 `rsync` 将整个等待列表中的文件同步到目标目录中。光这个功能就值得一试了。
|
||||
|
||||
例如这里将 arduino 1.9 的 beta 存档同步到另一个目录中:
|
||||
|
||||
![][4]
|
||||
|
||||
整个进度完成后,底部的窗口会在 5 秒后自动退出。下面是异步解压上面的 arduino 存档后出现的另一个会话:
|
||||
|
||||
![][6]
|
||||
|
||||
这个包进一步增加了我 dired 配置的实用性。
|
||||
|
||||
我刚刚贡献了 [一个拉取请求来允许 tmtxt-dired-async 同步到远程 tramp 目录中][7],而且我立即使用该功能来将上 GB 的新照片传输到 Linux 服务器上。
|
||||
|
||||
若你想配置 tmtxt-dired-async,下载 [tmtxt-async-tasks.el][8](被依赖的库)以及 [tmtxt-dired-async.el][9](若你想让它支持 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][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://vxlabs.com/author/cpbotha/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://truongtx.me/tmtxt-dired-async.html
|
||||
[2]: https://truongtx.me/about.html
|
||||
[3]: https://i0.wp.com/vxlabs.com/wp-content/uploads/2018/03/rsync-arduino-zip.png?resize=660%2C340&ssl=1
|
||||
[4]: https://i0.wp.com/vxlabs.com/wp-content/uploads/2018/03/rsync-arduino-zip.png?ssl=1
|
||||
[5]: https://i1.wp.com/vxlabs.com/wp-content/uploads/2018/03/progress-window-5s.png?resize=660%2C310&ssl=1
|
||||
[6]: https://i1.wp.com/vxlabs.com/wp-content/uploads/2018/03/progress-window-5s.png?ssl=1
|
||||
[7]: https://github.com/tmtxt/tmtxt-dired-async/pull/6
|
||||
[8]: https://github.com/tmtxt/tmtxt-async-tasks
|
||||
[9]: https://github.com/tmtxt/tmtxt-dired-async
|
@ -1,6 +1,6 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Get Flatpak Apps And Games Built With OpenGL To Work With Proprietary Nvidia Graphics Drivers)
|
||||
@ -9,9 +9,12 @@
|
||||
|
||||
如何使得支持 OpenGL 的 Flatpak 应用和游戏在专有 Nvidia 图形驱动下工作
|
||||
======
|
||||
**一些支持 OpenGL 并打包为 Flatpak 的应用和游戏无法使用专有 Nvidia 驱动启动。本文将介绍如何在不安装开源驱动(Nouveau)的情况下启动这些 Flatpak 应用或游戏。**
|
||||
> 一些支持 OpenGL 并打包为 Flatpak 的应用和游戏无法使用专有 Nvidia 驱动启动。本文将介绍如何在不安装开源驱动(Nouveau)的情况下启动这些 Flatpak 应用或游戏。
|
||||
|
||||
![](https://2.bp.blogspot.com/-A6PQn0xS7t8/WzYZDH6L_cI/AAAAAAAAAyE/ZBHroHnrY1scqo-dhSRV3YapO4OeBJlOQCLcBGAs/s1600/flatpak.png)
|
||||
|
||||
这有个例子。我在我的 Ubuntu 18.04 桌面上使用专有的 Nvidia 驱动程序 (`nvidia-driver-390`),当我尝试启动以 Flatpak 形式安装的最新版本 [Krita 4.1][2] (构建了 OpenGL 支持)时,显示了如下错误:
|
||||
|
||||
这有个例子。我在我的 Ubuntu 18.04 桌面上使用专有的 Nvidia 驱动程序 (`nvidia-driver-390`),当我尝试启动最新版本时:
|
||||
```
|
||||
$ /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=krita --file-forwarding org.kde.krita
|
||||
Gtk-Message: Failed to load module "canberra-gtk-module"
|
||||
@ -19,89 +22,85 @@ Gtk-Message: Failed to load module "canberra-gtk-module"
|
||||
libGL error: No matching fbConfigs or visuals found
|
||||
libGL error: failed to load driver: swrast
|
||||
Could not initialize GLX
|
||||
|
||||
```
|
||||
|
||||
要修复使用 OpenGL 和专有 Nvidia 图形驱动时无法启动的 Flatpak 游戏和应用,你需要为已安装的专有驱动安装运行时。以下是步骤。
|
||||
[Winepak][3] 游戏(以 Flatpak 方式打包的绑定了 Wine 的 Windows 游戏)似乎也受到了这个问题的影响,这个问题从 2016 年出现至今。
|
||||
|
||||
**1\. 如果尚未添加 FlatHub 仓库,请添加它。你可以在[此处][1]找到针对 Linux 发行版的说明。**
|
||||
要修复使用 OpenGL 和专有 Nvidia 图形驱动时无法启动的 Flatpak 游戏和应用的问题,你需要为已安装的专有驱动安装一个运行时环境。以下是步骤。
|
||||
|
||||
**2. 现在,你需要确定系统上安装的专有 Nvidia 驱动的确切版本。**
|
||||
1、如果尚未添加 FlatHub 仓库,请添加它。你可以在[此处][1]找到针对 Linux 发行版的说明。
|
||||
|
||||
_这一步取决于你使用的 Linux 发行版,我无法涵盖所有情况。下面的说明是面向 Ubuntu(以及 Ubuntu 风格的版本),但希望你可以自己弄清楚系统上安装的 Nvidia 驱动版本._
|
||||
2、现在,你需要确定系统上安装的专有 Nvidia 驱动的确切版本。
|
||||
|
||||
要在 Ubuntu 中执行此操作,请打开 `Software&Updates`,切换到 `Additional Drivers` 选项卡并记下 Nvidia 驱动包的名称。
|
||||
_这一步取决于你使用的 Linux 发行版,我无法涵盖所有情况。下面的说明是面向 Ubuntu(以及 Ubuntu 风格的版本),但希望你可以自己弄清楚系统上安装的 Nvidia 驱动版本。_
|
||||
|
||||
比如,你可以看到我的是 `nvidia-driver-390`:
|
||||
要在 Ubuntu 中执行此操作,请打开 “软件与更新”,切换到 “附加驱动” 选项卡并记下 Nvidia 驱动包的名称。
|
||||
|
||||
比如,你可以看到我的是 “nvidia-driver-390”:
|
||||
|
||||
![](https://1.bp.blogspot.com/-FAfjtGNeUJc/WzYXMYTFBcI/AAAAAAAAAx0/xUhIO83IAjMuK4Hn0jFUYKJhSKw8y559QCLcBGAs/s1600/additional-drivers-nvidia-ubuntu.png)
|
||||
|
||||
这里还没完成。我们只是找到了 Nvidia 驱动的主要版本,但我们还需要知道次要版本。要获得我们下一步所需的确切 Nvidia 驱动版本,请运行此命令(应该适用于任何基于 Debian 的 Linux 发行版,如 Ubuntu、Linux Mint 等):
|
||||
|
||||
```
|
||||
apt-cache policy NVIDIA-PACKAGE-NAME
|
||||
|
||||
```
|
||||
|
||||
NVIDIA-PACKAGE-NAME 是 `Software & Updates` 中列出的 Nvidia 驱动包名称。例如,要查看 `nvidia-driver-390` 包的确切安装版本,请运行以下命令:
|
||||
这里的 “NVIDIA-PACKAGE-NAME” 是 “软件与更新” 中列出的 Nvidia 驱动包名称。例如,要查看 “nvidia-driver-390” 包的确切安装版本,请运行以下命令:
|
||||
|
||||
```
|
||||
$ apt-cache policy nvidia-driver-390
|
||||
nvidia-driver-390:
|
||||
Installed: 390.48-0ubuntu3
|
||||
Candidate: 390.48-0ubuntu3
|
||||
Version table:
|
||||
* 390.48-0ubuntu3 500
|
||||
500 http://ro.archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages
|
||||
100 /var/lib/dpkg/status
|
||||
|
||||
Installed: 390.48-0ubuntu3
|
||||
Candidate: 390.48-0ubuntu3
|
||||
Version table:
|
||||
*** 390.48-0ubuntu3 500
|
||||
500 http://ro.archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages
|
||||
100 /var/lib/dpkg/status
|
||||
```
|
||||
|
||||
在这个命令的输出中,查找 `Installed` 部分并记下版本号(不包括 `-0ubuntu3` 之类)。现在我们知道了已安装的 Nvidia 驱动的确切版本(我例子中的是 `390.48`)。记住它,因为下一步我们需要。
|
||||
在这个命令的输出中,查找 “Installed” 部分并记下版本号(不包括 “-0ubuntu3” 之类)。现在我们知道了已安装的 Nvidia 驱动的确切版本(我例子中的是 “390.48”)。记住它,因为下一步我们需要。
|
||||
|
||||
**3\. 最后,你可以从 FlatHub 为你已安装的专有 Nvidia 图形驱动安装运行时。**
|
||||
3、最后,你可以从 FlatHub 为你已安装的专有 Nvidia 图形驱动安装运行时环境。
|
||||
|
||||
要列出 FlatHub 上所有可用的 Nvidia 运行时包,你可以使用以下命令:
|
||||
|
||||
```
|
||||
flatpak remote-ls flathub | grep nvidia
|
||||
|
||||
```
|
||||
|
||||
幸运地是 FlatHub 上提供这个 Nvidia 驱动的运行时。你现在可以使用以下命令继续安装运行时:
|
||||
|
||||
* 针对 64 位系统:
|
||||
幸运地是 FlatHub 上提供这个 Nvidia 驱动的运行时环境。你现在可以使用以下命令继续安装运行时:
|
||||
|
||||
针对 64 位系统:
|
||||
|
||||
```
|
||||
flatpak install flathub org.freedesktop.Platform.GL.nvidia-MAJORVERSION-MINORVERSION
|
||||
|
||||
```
|
||||
|
||||
将 MAJORVERSION 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390),将 MINORVERSION 替换为次要版本(步骤2,我例子中的为 48)。
|
||||
将 “MAJORVERSION” 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390),将 “MINORVERSION” 替换为次要版本(步骤2,我例子中的为 48)。
|
||||
|
||||
例如,要为 Nvidia 图形驱动版本 390.48 安装运行时,你必须使用以下命令:
|
||||
|
||||
```
|
||||
flatpak install flathub org.freedesktop.Platform.GL.nvidia-390-48
|
||||
|
||||
```
|
||||
|
||||
* 对于 32 位系统(或能够在 64 位上运行 32 位的应用或游戏),使用以下命令安装 32 位运行时:
|
||||
|
||||
对于 32 位系统(或能够在 64 位上运行 32 位的应用或游戏),使用以下命令安装 32 位运行时:
|
||||
|
||||
```
|
||||
flatpak install flathub org.freedesktop.Platform.GL32.nvidia-MAJORVERSION-MINORVERSION
|
||||
|
||||
```
|
||||
|
||||
再说一次,将 MAJORVERSION 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390),将 MINORVERSION 替换为次要版本(步骤2,我例子中的为 48)。
|
||||
再说一次,将 “MAJORVERSION” 替换为 Nvidia 驱动的主要版本(在上面的示例中为 390),将 “MINORVERSION” 替换为次要版本(步骤2,我例子中的为 48)。
|
||||
|
||||
比如,要为 Nvidia 图形驱动版本 390.48 安装 32 位运行时,你需要使用以下命令:
|
||||
|
||||
```
|
||||
flatpak install flathub org.freedesktop.Platform.GL32.nvidia-390-48
|
||||
|
||||
```
|
||||
|
||||
以上就是你要运行支持 OpenGL 的 Flatpak 的应用或游戏的方法。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-built.html
|
||||
@ -109,7 +108,7 @@ via: https://www.linuxuprising.com/2018/06/how-to-get-flatpak-apps-and-games-bui
|
||||
作者:[Logix][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
194
published/20180826 Be productive with Org-mode.md
Normal file
194
published/20180826 Be productive with Org-mode.md
Normal file
@ -0,0 +1,194 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (lujun9972)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10634-1.html)
|
||||
[#]: subject: (Be productive with Org-mode)
|
||||
[#]: via: (https://www.badykov.com/emacs/2018/08/26/be-productive-with-org-mode/)
|
||||
[#]: author: (Ayrat Badykov https://www.badykov.com)
|
||||
|
||||
高效使用 Org 模式
|
||||
======
|
||||
|
||||
![org-mode-collage][1]
|
||||
|
||||
### 简介
|
||||
|
||||
在我 [前一篇关于 Emacs 的文章中][2] 我提到了 <ruby>[Org 模式][3]<rt>Org-mode</rt></ruby>,这是一个笔记管理工具和组织工具。本文中,我将会描述一下我日常的 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][4] 它看起来是这样的:
|
||||
|
||||
![notes][5]
|
||||
|
||||
在这个简单的例子中,你能看到 Org 模式的一些功能:
|
||||
|
||||
- 笔记允许嵌套
|
||||
- 链接
|
||||
- 带复选框的列表
|
||||
|
||||
#### 项目待办
|
||||
|
||||
我在工作时时常会发现一些能够改进或修复的事情。我并不会在代码文件中留下 TODO 注释 (坏味道),相反我使用 [org-projectile][6] 来在另一个文件中记录一个 TODO 事项,并留下一个快捷方式。下面是一个该文件的例子:
|
||||
|
||||
```
|
||||
* [[elisp:(org-projectile-open-project%20"mana")][mana]] [3/9]
|
||||
:PROPERTIES:
|
||||
: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
|
||||
* [[elisp:(org-projectile-open-project%20".emacs.d")][.emacs.d]] [1/3]
|
||||
:PROPERTIES:
|
||||
: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]
|
||||
```
|
||||
|
||||
它看起来是这样的:
|
||||
|
||||
![project-todos][7]
|
||||
|
||||
本例中你能看到更多的 Org 模式的功能:
|
||||
|
||||
- 代办列表具有 `TODO`、`DONE` 两个状态。你还可以定义自己的状态 (`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 模式的另一个超棒的功能是你可以用它来作日常规划。让我们来看一个例子:
|
||||
|
||||
![schedule][8]
|
||||
|
||||
我没有挖空心思虚构一个例子,这就是我现在真实文件的样子。它看起来内容并不多,但它有助于你花时间在在重要的事情上并且帮你对抗拖延症。
|
||||
|
||||
#### 习惯
|
||||
|
||||
根据 Org 模式的文档,Org 能够跟踪一种特殊的代办事情,称为 “习惯”。当我想养成新的习惯时,我会将该功能与日常规划功能一起连用:
|
||||
|
||||
![habits][9]
|
||||
|
||||
你可以看到,目前我在尝试每天早期并且每两天锻炼一次。另外,它也有助于让我每天阅读书籍。
|
||||
|
||||
#### 议事日程视图
|
||||
|
||||
最后,我还使用议事日程视图功能。待办事项可能分散在不同文件中(比如我就是日常规划和习惯分散在不同文件中),议事日程视图可以提供所有待办事项的总览:
|
||||
|
||||
![agenda][10]
|
||||
|
||||
### 更多 Org 模式的功能
|
||||
|
||||
+ 手机应用([Android](https://play.google.com/store/apps/details?id=com.orgzly&hl=en)、[ios](https://itunes.apple.com/app/id1238649962]))
|
||||
+ [将 Org 模式文档导出为其他格式](https://orgmode.org/manual/Exporting.html)(html、markdown、pdf、latex 等)
|
||||
+ 使用 [ledger](https://github.com/ledger/ledger-mode) [追踪财务状况](https://orgmode.org/worg/org-tutorials/weaving-a-budget.html)
|
||||
|
||||
### 总结
|
||||
|
||||
本文我描述了 Org 模式广泛功能中的一小部分,我每天都用它来提高工作效率,把时间花在重要的事情上。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.badykov.com/emacs/2018/08/26/be-productive-with-org-mode/
|
||||
|
||||
作者:[Ayrat Badykov][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.badykov.com
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i.imgur.com/hgqCyen.jpg
|
||||
[2]: http://www.badykov.com/emacs/2018/07/31/why-emacs-is-a-great-editor/
|
||||
[3]: https://orgmode.org/
|
||||
[4]: https://github.com/sabof/org-bullets
|
||||
[5]: https://i.imgur.com/lGi60Uw.png
|
||||
[6]: https://github.com/IvanMalison/org-projectile
|
||||
[7]: https://i.imgur.com/Hbu8ilX.png
|
||||
[8]: https://i.imgur.com/z5HpuB0.png
|
||||
[9]: https://i.imgur.com/YJIp3d0.png
|
||||
[10]: https://i.imgur.com/CKX9BL9.png
|
@ -1,38 +1,36 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10621-1.html)
|
||||
[#]: subject: (HTTP: Brief History of HTTP)
|
||||
[#]: via: (https://hpbn.co/brief-history-of-http/#http-09-the-one-line-protocol)
|
||||
[#]: author: (Ilya Grigorik https://www.igvita.com/)
|
||||
|
||||
HTTP: HTTP 历史简介
|
||||
HTTP 简史
|
||||
======
|
||||
<to 校正:这篇可能得费费心了。。。>
|
||||
|
||||
译注:本文来源于 2013 年出版的《High Performance Browser Networking》的第九章,因此有些信息略有过时。事实上,现在 HTTP/2 已经有相当的不是,而新的 HTTP/3 也在设计和标准制定当中。
|
||||
|
||||
### 介绍
|
||||
|
||||
超文本传输协议(HTTP)是 Internet 上最普遍和广泛采用的应用程序协议之一。它是客户端和服务器之间的通用语言,支持现代 Web。从最初作为一个简单的关键字和文档路径开始,它已成为不仅仅是浏览器的首选协议,而且几乎是所有连接互联网硬件和软件应用程序的首选协议。
|
||||
<ruby>超文本传输协议<rt>Hypertext Transfer Protocol</rt></ruby>(HTTP)是互联网上最普遍和广泛采用的应用程序协议之一。它是客户端和服务器之间的通用语言,支持现代 Web。从最初作为单个的关键字和文档路径开始,它已成为不仅仅是浏览器的首选协议,而且几乎是所有连接互联网硬件和软件应用程序的首选协议。
|
||||
|
||||
在本文中,我们将简要回顾 HTTP 协议的发展历史。对 HTTP 不同语义的完整讨论超出了本文的范围,但理解 HTTP 的关键设计变更以及每个变更背后的动机将为我们讨论 HTTP 性能提供必要的背景,特别是在 HTTP/2 中即将进行的许多改进。
|
||||
|
||||
### §HTTP 0.9: 单向协议
|
||||
### HTTP 0.9: 单行协议
|
||||
|
||||
Tim Berners-Lee 最初的 HTTP 提案在设计时考虑到了简单性,以帮助他采用他的另一个新想法:万维网(World Wide Web)。这个策略看起来奏效了:注意,他是一个有抱负的协议设计者。
|
||||
<ruby>蒂姆·伯纳斯·李<rt>Tim Berners-Lee</rt></ruby> 最初的 HTTP 提案在设计时考虑到了简单性,以帮助他采用他的另一个新想法:<ruby>万维网<rt>World Wide Web</rt></ruby>。这个策略看起来奏效了:注意,他是一个有抱负的协议设计者。
|
||||
|
||||
1991 年,Berners-Lee 概述了新协议的动机,并列出了几个高级设计目标:文件传输功能,请求超文档存档索引搜索的能力,格式协商以及将客户端引用到另一个服务器的能力。为了证明该理论的实际应用,我们构建了一个简单原型,它实现了所提议功能的一小部分。
|
||||
1991 年,伯纳斯·李概述了这个新协议的动机,并列出了几个高级设计目标:文件传输功能、请求超文档存档索引搜索的能力,格式协商以及将客户端引用到另一个服务器的能力。为了证明该理论的实际应用,构建了一个简单原型,它实现了所提议功能的一小部分。
|
||||
|
||||
* 客户端请求是一个 ASCII 字符串。
|
||||
|
||||
* 客户端请求以回车符(CRLF)终止。
|
||||
|
||||
* 服务器响应是 ASCII 字符流。
|
||||
|
||||
* 服务器响应是一种超文本标记语言(HTML)。
|
||||
|
||||
* 文档传输完成后连接终止。
|
||||
|
||||
这些听起来就挺复杂,而实际情况比这复杂得多。这些规则支持的是一种非常简单的,对 Telnet 友好的协议,一些 Web 服务器至今仍然支持这种协议:
|
||||
然而,即使这听起来也比实际复杂得多。这些规则支持的是一种非常简单的,对 Telnet 友好的协议,一些 Web 服务器至今仍然支持这种协议:
|
||||
|
||||
```
|
||||
$> telnet google.com 80
|
||||
@ -45,39 +43,32 @@ GET /about/
|
||||
(connection closed)
|
||||
```
|
||||
|
||||
请求包含这样一行:`GET` 方法和请求文档的路径。响应是一个超文本文档-没有标题或任何其他元数据,只有 HTML。真的是再简单不过了。此外,由于之前的交互是预期协议的子集,因此它获得了一个非官方的 HTTP 0.9 标签。其余的,就像他们所说的,都是历史。
|
||||
请求包含这样一行:`GET` 方法和请求文档的路径。响应是一个超文本文档,没有标题或任何其他元数据,只有 HTML。真的是再简单不过了。此外,由于之前的交互是预期协议的子集,因此它获得了一个非官方的 HTTP 0.9 标签。其余的,就像他们所说的,都是历史。
|
||||
|
||||
从 1991 年这些不起眼的开始,HTTP 就有了自己的生命,并在接下来几年里迅速发展。让我们快速回顾一下 HTTP 0.9 的特性:
|
||||
|
||||
* 采用客户端-服务器架构,是一种请求-响应协议。
|
||||
|
||||
* 采用 ASCII 协议,运行在 TCP/IP 链路上。
|
||||
|
||||
* 旨在传输超文本文档(HTML)。
|
||||
|
||||
* 每次请求后,服务器和客户端之间的连接都将关闭。
|
||||
|
||||
```
|
||||
流行的 Web 服务器,如 Apache 和 Nginx,仍然支持 HTTP 0.9 协议,部分原因是因为它没有太多功能!如果你感兴趣,打开 Telnet 会话并尝试通过 HTTP 0.9 访问 google.com 或你最喜欢的网站,并检查早期协议的行为和限制。
|
||||
> 流行的 Web 服务器,如 Apache 和 Nginx,仍然支持 HTTP 0.9 协议,部分原因是因为它没有太多功能!如果你感兴趣,打开 Telnet 会话并尝试通过 HTTP 0.9 访问 google.com 或你最喜欢的网站,并检查早期协议的行为和限制。
|
||||
|
||||
```
|
||||
### §HTTP/1.0: 快速增长和 Informational RFC
|
||||
### HTTP/1.0: 快速增长和 Informational RFC
|
||||
|
||||
1991 年至 1995 年期间, HTML 规范和一种称为 “web 浏览器”的新型软件快速发展,面向消费者的公共互联网基础设施也开始出现并快速增长。
|
||||
1991 年至 1995 年期间,HTML 规范和一种称为 “web 浏览器”的新型软件快速发展,面向消费者的公共互联网基础设施也开始出现并快速增长。
|
||||
|
||||
```
|
||||
##### §完美风暴: 1990 年代初的互联网热潮
|
||||
> **完美风暴:1990 年代初的互联网热潮**
|
||||
|
||||
基于 Tim Berner-Lee 最初的浏览器原型,美国国家超级计算机应用中心(NCSA)的一个团队决定实现他们自己的版本。就这样,第一个流行的浏览器诞生了:NCSA Mosaic。1994 年 10 月,NCSA 团队的一名程序员 Marc Andreessen 与 Jim Clark 合作创建了 Mosaic Communications,该公司后来改名为 Netscape(网景),并于 1994 年 12 月发布了 Netscape Navigator 1.0。从这一点来说,已经很清楚了,万维网已经不仅仅是学术上的好奇心了。
|
||||
> 基于蒂姆·伯纳斯·李最初的浏览器原型,美国国家超级计算机应用中心(NCSA)的一个团队决定实现他们自己的版本。就这样,第一个流行的浏览器诞生了:NCSA Mosaic。1994 年 10 月,NCSA 团队的一名程序员 Marc Andreessen 与 Jim Clark 合作创建了 Mosaic Communications,该公司后来改名为 Netscape(网景),并于 1994 年 12 月发布了 Netscape Navigator 1.0。从这一点来说,已经很清楚了,万维网已经不仅仅是学术上的好奇心了。
|
||||
|
||||
实际上,同年在瑞士日内网组织了第一次万维网会议,这导致万维网联盟(W3C)的成立,以帮助指导 HTML 的发展。同样,在 IETF 内部建立了一个并行的 HTTP 工作组(HTTP-WG),专注于改进 HTTP 协议。后来这两个团体一直对 Web 的发展起着重要作用。
|
||||
> 实际上,同年在瑞士日内瓦组织了第一次万维网会议,这导致<ruby>万维网联盟<rt>World Wide Web Consortium</rt></ruby>(W3C)的成立,以帮助指导 HTML 的发展。同样,在 IETF 内部建立了一个并行的<ruby>HTTP 工作组<rt>HTTP Working Group</rt></ruby>(HTTP-WG),专注于改进 HTTP 协议。后来这两个团体一直对 Web 的发展起着重要作用。
|
||||
|
||||
最后,完美的风暴来临,CompuServe,AOL 和 Prodigy 在 1994-1995 年的同一时间开始向公众提供拨号上网服务。凭借这股迅速的浪潮,Netscape 在 1995 年 8 月 9 日凭借其成功的 IPO 创造了历史。这预示着互联网热潮已经到来,人人都想分一杯羹!
|
||||
```
|
||||
> 最后,完美风暴来临,CompuServe,AOL 和 Prodigy 在 1994-1995 年的同一时间开始向公众提供拨号上网服务。凭借这股迅速的浪潮,Netscape 在 1995 年 8 月 9 日凭借其成功的 IPO 创造了历史。这预示着互联网热潮已经到来,人人都想分一杯羹!
|
||||
|
||||
不断增长的新 Web 所需功能及其在公共网站上的用例很快暴露了 HTTP 0.9 的许多基础限制:我们需要一种能够提供超文本文档、提供关于请求和响应的更丰富的元数据,支持内容协商等等的协议。相应地,新兴的 Web 开发人员社区通过一个特殊的过程生成了大量实验性的 HTTP 服务器和客户端实现来回应:实现,部署,并查看其他人是否采用它。
|
||||
不断增长的新 Web 所需功能及其在公共网站上的应用场景很快暴露了 HTTP 0.9 的许多基础限制:我们需要一种能够提供超文本文档、提供关于请求和响应的更丰富的元数据,支持内容协商等等的协议。相应地,新兴的 Web 开发人员社区通过一个特殊的过程生成了大量实验性的 HTTP 服务器和客户端实现来回应:实现,部署,并查看其他人是否采用它。
|
||||
|
||||
从这些急速增长的实验开始,一系列最佳实践和常见模式开始出现。1996 年 5 月,HTTP 工作组(HTTP-WG)发布了 RFC 1945,它记录了许多被广泛使用的 HTTP/1.0 实现的“常见用法”。请注意,这只是一个信息 RFC:HTTP/1.0,因为我们知道它不是一个正式规范或 Internet 标准!
|
||||
从这些急速增长的实验开始,一系列最佳实践和常见模式开始出现。1996 年 5 月,<ruby>HTTP 工作组<rt>HTTP Working Group</rt></ruby>(HTTP-WG)发布了 RFC 1945,它记录了许多被广泛使用的 HTTP/1.0 实现的“常见用法”。请注意,这只是一个信息性 RFC:HTTP/1.0,如你所知的,它不是一个正式规范或 Internet 标准!
|
||||
|
||||
话虽如此,HTTP/1.0 请求看起来应该是:
|
||||
|
||||
@ -86,11 +77,11 @@ $> telnet website.org 80
|
||||
|
||||
Connected to xxx.xxx.xxx.xxx
|
||||
|
||||
GET /rfc/rfc1945.txt HTTP/1.0
|
||||
GET /rfc/rfc1945.txt HTTP/1.0 ❶
|
||||
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
|
||||
Accept: */*
|
||||
|
||||
HTTP/1.0 200 OK
|
||||
HTTP/1.0 200 OK ❷
|
||||
Content-Type: text/plain
|
||||
Content-Length: 137582
|
||||
Expires: Thu, 01 Dec 1997 16:00:00 GMT
|
||||
@ -101,34 +92,26 @@ Server: Apache 0.84
|
||||
(connection closed)
|
||||
```
|
||||
|
||||
1. 请求行有 HTTP 版本号,后面跟请求头
|
||||
- ❶ 请求行有 HTTP 版本号,后面跟请求头
|
||||
- ❷ 响应状态,后跟响应头
|
||||
|
||||
2. 响应状态,后跟响应头
|
||||
前面的交互并不是 HTTP/1.0 功能的详尽列表,但它确实说明了一些关键的协议更改:
|
||||
|
||||
* 请求可能多个由换行符分隔的请求头字段组成。
|
||||
* 响应对象的前缀是响应状态行。
|
||||
* 响应对象有自己的一组由换行符分隔的响应头字段。
|
||||
* 响应对象不限于超文本。
|
||||
* 每次请求后,服务器和客户端之间的连接都将关闭。
|
||||
|
||||
前面交换的并不是 HTTP/1.0 功能的详尽列表,但它确实说明了一些关键的协议更改:
|
||||
请求头和响应头都保留为 ASCII 编码,但响应对象本身可以是任何类型:HTML 文件、纯文本文件、图像或任何其他内容类型。因此,HTTP 的“超文本传输”部分在引入后不久就变成了用词不当。实际上,HTTP 已经迅速发展成为一种超媒体传输,但最初的名称没有改变。
|
||||
|
||||
* 请求可能多个由换行符分隔的请求头字段组成。
|
||||
除了媒体类型协商之外,RFC 还记录了许多其他常用功能:内容编码、字符集支持、多部分类型、授权、缓存、代理行为、日期格式等。
|
||||
|
||||
* 响应对象的前缀是响应状态行。
|
||||
> 今天,几乎所有 Web 上的服务器都可以并且仍将使用 HTTP/1.0。不过,现在你应该更加清楚了!每个请求都需要一个新的 TCP 连接,这会对 HTTP/1.0 造成严重的性能损失。参见[三次握手][1],接着会[慢启动][2]。
|
||||
|
||||
* 响应对象有自己的一组由换行符分隔的响应头字段。
|
||||
### HTTP/1.1: Internet 标准
|
||||
|
||||
* 响应对象不限于超文本。
|
||||
|
||||
* 每次请求后,服务器和客户端之间的连接都将关闭。
|
||||
|
||||
请求头和响应头都保留为 ASCII 编码,但响应对象本身可以是任何类型:一个 HTML 文件,一个纯文本文件,一个图像或任何其他内容类型。因此,HTTP 的“超文本传输”部分在引入后不久就变成了用词不当。实际上,HTTP 已经迅速发展成为一种超媒体传输,但最初的名称没有改变。
|
||||
|
||||
除了媒体类型协商之外,RFC 还记录了许多其他常用功能:内容编码,字符集支持,多部分类型,授权,缓存,代理行为,日期格式等。
|
||||
|
||||
```
|
||||
今天,几乎所有 Web 上的服务器都可以并且仍将使用 HTTP/1.0。不过,现在你应该更加清楚了!每个请求都需要一个新的 TCP 连接,这会对 HTTP/1.0 造成严重的性能损失。参见[三次握手][1],接着会[慢启动][2]。
|
||||
```
|
||||
|
||||
### §HTTP/1.1: Internet 标准
|
||||
|
||||
将 HTTP 转变为官方 IETF 互联网标准的工作与围绕 HTTP/1.0 的文档工作并行进行,并计划从 1995 年至 1999 年完成。事实上,第一个正式的 HTTP/1.1 标准定义于 RFC 2068,它在 HTTP/1.0 发布大约六个月后,即 1997 年 1 月正式发布。两年半后,即 1999 年 6 月,一些新的改进和更新被纳入标准,并作为 RFC 2616 发布。
|
||||
将 HTTP 转变为官方 IETF 互联网标准的工作与围绕 HTTP/1.0 的文档工作并行进行,并计划从 1995 年至 1999 年完成。事实上,第一个正式的 HTTP/1.1 标准定义于 RFC 2068,它在 HTTP/1.0 发布大约六个月后,即 1997 年 1 月正式发布。两年半后,即 1999 年 6 月,一些新的改进和更新被纳入标准,并作为 RFC 2616 发布。
|
||||
|
||||
HTTP/1.1 标准解决了早期版本中发现的许多协议歧义,并引入了一些关键的性能优化:保持连接,分块编码传输,字节范围请求,附加缓存机制,传输编码和请求管道。
|
||||
|
||||
@ -138,7 +121,7 @@ HTTP/1.1 标准解决了早期版本中发现的许多协议歧义,并引入
|
||||
$> telnet website.org 80
|
||||
Connected to xxx.xxx.xxx.xxx
|
||||
|
||||
GET /index.html HTTP/1.1
|
||||
GET /index.html HTTP/1.1 ❶
|
||||
Host: website.org
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||
@ -147,7 +130,7 @@ Accept-Language: en-US,en;q=0.8
|
||||
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
|
||||
Cookie: __qca=P0-800083390... (snip)
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
HTTP/1.1 200 OK ❷
|
||||
Server: nginx/1.0.11
|
||||
Connection: keep-alive
|
||||
Content-Type: text/html; charset=utf-8
|
||||
@ -157,27 +140,27 @@ Expires: Wed, 25 Jul 2012 20:23:35 GMT
|
||||
Cache-Control: max-age=0, no-cache
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
100
|
||||
100 ❸
|
||||
<!doctype html>
|
||||
(snip)
|
||||
|
||||
100
|
||||
(snip)
|
||||
|
||||
0
|
||||
0 ❹
|
||||
|
||||
GET /favicon.ico HTTP/1.1
|
||||
GET /favicon.ico HTTP/1.1 ❺
|
||||
Host: www.website.org
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
|
||||
Accept: */*
|
||||
Referer: http://website.org/
|
||||
Connection: close
|
||||
Connection: close ❻
|
||||
Accept-Encoding: gzip,deflate,sdch
|
||||
Accept-Language: en-US,en;q=0.8
|
||||
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
|
||||
Cookie: __qca=P0-800083390... (snip)
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
HTTP/1.1 200 OK ❼
|
||||
Server: nginx/1.0.11
|
||||
Content-Type: image/x-icon
|
||||
Content-Length: 3638
|
||||
@ -194,40 +177,29 @@ Etag: W/PSA-GAu26oXbDi
|
||||
(connection closed)
|
||||
```
|
||||
|
||||
1. 请求的 HTML 文件,包括编码,字符集和 cookie 元数据
|
||||
|
||||
2. 原始 HTML 请求的分块响应
|
||||
|
||||
3. 以 ASCII 十六进制数字(256 字节)表示块中的八位元数
|
||||
|
||||
4. 分块流响应结束
|
||||
|
||||
5. 在相同的 TCP 连接上请求一个图标文件
|
||||
|
||||
6. 通知服务器不再重用连接
|
||||
|
||||
7. 图标响应后,然后关闭连接
|
||||
|
||||
- ❶ 请求的 HTML 文件,包括编、字符集和 cookie 元数据
|
||||
- ❷ 原始 HTML 请求的分块响应
|
||||
- ❸ 以 ASCII 十六进制数字(256 字节)表示块中的八位元的数量
|
||||
- ❹ 分块流响应结束
|
||||
- ❺ 在相同的 TCP 连接上请求一个图标文件
|
||||
- ❻ 通知服务器不再重用连接
|
||||
- ❼ 图标响应后,然后关闭连接
|
||||
|
||||
哇,这里发生了很多事情!第一个也是最明显的区别是我们有两个对象请求,一个用于 HTML 页面,另一个用于图像,它们都通过一个连接完成。这就是保持连接的实际应用,它允许我们重用现有的 TCP 连接到同一个主机的多个请求,提供一个更快的最终用户体验。参见[TCP 优化][3]。
|
||||
|
||||
要终止持久连接,注意第二个客户端请求通过 `Connection` 请求头向服务器发送显示的 `close`。类似地,一旦传输响应,服务器就可以通知客户端关闭当前 TCP 连接。从技术上讲,任何一方都可以在没有此类信号的情况下终止 TCP 连接,但客户端和服务器应尽可能提供此类信号,以便双方都启用更好的连接重用策略。
|
||||
|
||||
```
|
||||
HTTP/1.1 改变了 HTTP 协议的语义,默认情况下使用保持连接。这意味着,除非另有说明(通过 `Connection:close` 头),否则服务器应默认保持连接打开。
|
||||
> HTTP/1.1 改变了 HTTP 协议的语义,默认情况下使用保持连接。这意味着,除非另有说明(通过 `Connection:close` 头),否则服务器应默认保持连接打开。
|
||||
|
||||
但是,同样的功能也被反向移植到 HTTP/1.0 上,通过 `Connection:keep-Alive` 头启用。因此,如果你使用 HTTP/1.1,从技术上讲,你不需要 `Connection:keep-Alive` 头,但许多客户端仍然选择提供它。
|
||||
```
|
||||
> 但是,同样的功能也被反向移植到 HTTP/1.0 上,通过 `Connection:keep-Alive` 头启用。因此,如果你使用 HTTP/1.1,从技术上讲,你不需要 `Connection:keep-Alive` 头,但许多客户端仍然选择提供它。
|
||||
|
||||
此外,HTTP/1.1 协议还添加了内容、编码、字符集,甚至语言协商、传输编码、缓存指令、客户端 cookie,以及可以针对每个请求协商的十几个其他功能。
|
||||
|
||||
我们不打算详细讨论每个 HTTP/1.1 特性的语义。这个主题可以写一本专门的书了,已经有了很多很棒的书。相反,前面的示例很好地说明了 HTTP 的快速进展和演变,以及每个客户端-服务器交换的错综复杂的过程,里面发生了很多事情!
|
||||
|
||||
```
|
||||
要了解 HTTP 协议所有内部工作原理,参考 David Gourley 和 Brian Totty 共同撰写的权威指南: The Definitive Guide。(to 校正:这里翻译的不准确)
|
||||
```
|
||||
> 要了解 HTTP 协议所有内部工作原理,参考 David Gourley 和 Brian Totty 共同撰写的权威指南: The Definitive Guide。
|
||||
|
||||
### §HTTP/2: 提高传输性能
|
||||
### HTTP/2: 提高传输性能
|
||||
|
||||
RFC 2616 自发布以来,已经成为互联网空前增长的基础:数十亿各种形状和大小的设备,从台式电脑到我们口袋里的小型网络设备,每天都在使用 HTTP 来传送新闻,视频,在我们生活中的数百万的其他网络应用程序都在依靠它。
|
||||
|
||||
@ -239,7 +211,7 @@ RFC 2616 自发布以来,已经成为互联网空前增长的基础:数十
|
||||
>
|
||||
> RFC 2616: HTTP/1.1, June 1999
|
||||
|
||||
HTTP 协议的简单性是它最初被采用和快速增长的原因。事实上,现在使用 HTTP 作为主要控制和数据协议的嵌入式设备(传感器,执行器和咖啡壶)并不罕见。但在其自身成功的重压下,随着我们越来越多地继续将日常互动转移到网络-社交、电子邮件、新闻和视频,以及越来越多的个人和工作空间,它也开始显示出压力的迹象。用户和 Web 开发人员现在都要求 HTTP/1.1 提供近乎实时的响应能力和协议
|
||||
HTTP 协议的简单性是它最初被采用和快速增长的原因。事实上,现在使用 HTTP 作为主要控制和数据协议的嵌入式设备(传感器,执行器和咖啡壶)并不罕见。但在其自身成功的重压下,随着我们越来越多地继续将日常互动转移到网络 —— 社交、电子邮件、新闻和视频,以及越来越多的个人和工作空间,它也开始显示出压力的迹象。用户和 Web 开发人员现在都要求 HTTP/1.1 提供近乎实时的响应能力和协议
|
||||
性能,如果不进行一些修改,就无法满足这些要求。
|
||||
|
||||
为了应对这些新挑战,HTTP 必须继续发展,因此 HTTPbis 工作组在 2012 年初宣布了一项针对 HTTP/2 的新计划:
|
||||
@ -252,7 +224,7 @@ HTTP 协议的简单性是它最初被采用和快速增长的原因。事实上
|
||||
|
||||
HTTP/2 的主要重点是提高传输性能并支持更低的延迟和更高的吞吐量。主要的版本增量听起来像是一个很大的步骤,但就性能而言,它将是一个重大的步骤,但重要的是要注意,没有任何高级协议语义收到影响:所有的 HTTP 头,值和用例是相同的。
|
||||
|
||||
任何现有的网站或应用程序都可以并且将通过 HTTP/2 传送而无需修改。你无需修改应用程序标记来利用 HTTP/2。HTTP 服务器必须使用 HTTP/2,但这对大多数用户来说应该是透明的升级。如果工作组实现目标,唯一的区别应该是我们的应用程序以更低的延迟和更好的网络连接利用率来传送数据。
|
||||
任何现有的网站或应用程序都可以并且将通过 HTTP/2 传送而无需修改。你无需修改应用程序标记来利用 HTTP/2。HTTP 服务器将来一定会使用 HTTP/2,但这对大多数用户来说应该是透明的升级。如果工作组实现目标,唯一的区别应该是我们的应用程序以更低的延迟和更好的网络连接利用率来传送数据。
|
||||
|
||||
话虽如此,但我们不要走的太远了。在讨论新的 HTTP/2 协议功能之前,有必要回顾一下我们现有的 HTTP/1.1 部署和性能最佳实践。HTTP/2 工作组正在新规范上取得快速的进展,但即使最终标准已经完成并准备就绪,在可预见的未来,我们仍然必须支持旧的 HTTP/1.1 客户端,实际上,这得十年或更长时间。
|
||||
|
||||
@ -263,7 +235,7 @@ via: https://hpbn.co/brief-history-of-http/#http-09-the-one-line-protocol
|
||||
作者:[Ilya Grigorik][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,60 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10636-1.html)
|
||||
[#]: subject: (Get started with CryptPad, an open source collaborative document editor)
|
||||
[#]: via: (https://opensource.com/article/19/1/productivity-tool-cryptpad)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney))
|
||||
|
||||
开始使用 CryptPad 吧,一个开源的协作文档编辑器
|
||||
======
|
||||
|
||||
> 使用 CryptPad 安全地共享你的笔记、文档、看板等,这是我们在开源工具系列中的第 5 个工具,它将使你在 2019 年更高效。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/web_browser_desktop_devlopment_design_system_computer.jpg?itok=pfqRrJgh)
|
||||
|
||||
每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然,“抛弃旧的,拥抱新的”的态度促成了这一切。通常这时的建议严重偏向闭源和专有软件,但事实上并不用这样。
|
||||
|
||||
这是我挑选出的 19 个新的(或者对你而言新的)开源工具中的第 5 个工具来帮助你在 2019 年更有效率。
|
||||
|
||||
### CryptPad
|
||||
|
||||
我们已经介绍过 [Joplin][1],它能很好地保存自己的笔记,但是,你可能已经注意到,它没有任何共享或协作功能。
|
||||
|
||||
[CryptPad][2] 是一个安全、可共享的笔记应用和文档编辑器,它能够安全地协作编辑。与 Joplin 不同,它是一个 NodeJS 应用,这意味着你可以在桌面或其他服务器上运行它,并使用任何现代 Web 浏览器访问。它开箱即用,它支持富文本、Markdown、投票、白板,看板和 PPT。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/cryptpad-1.png)
|
||||
|
||||
它支持不同的文档类型且功能齐全。它的富文本编辑器涵盖了你所期望的所有基础功能,并允许你将文件导出为 HTML。它的 Markdown 的编辑能与 Joplin 相提并论,它的看板虽然不像 [Wekan][3] 那样功能齐全,但也做得不错。其他支持的文档类型和编辑器也很不错,并且有你希望在类似应用中看到的功能,尽管投票功能显得有些粗糙。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/cryptpad-2.png)
|
||||
|
||||
然而,CryptPad 的真正强大之处在于它的共享和协作功能。共享文档只需在“共享”选项中获取可共享 URL,CryptPad 支持使用 `<iframe>` 标签嵌入其他网站的文档。可以在“编辑”或“查看”模式下使用密码和会过期的链接共享文档。内置聊天能够让编辑者相互交谈(请注意,具有浏览权限的人也可以看到聊天但无法发表评论)。
|
||||
|
||||
![](https://opensource.com/sites/default/files/pictures/cryptpad-3.png)
|
||||
|
||||
所有文件都使用用户密码加密存储。服务器管理员无法读取文档,这也意味着如果你忘记或丢失了密码,文件将无法恢复。因此,请确保将密码保存在安全的地方,例如放在[密码保险箱][4]中。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/cryptpad-4.png)
|
||||
|
||||
当它在本地运行时,CryptPad 是一个用于创建和编辑文档的强大应用。当在服务器上运行时,它成为了用于多用户文档创建和编辑的出色协作平台。在我的笔记本电脑上安装它不到五分钟,并且开箱即用。开发者还加入了在 Docker 中运行 CryptPad 的说明,并且还有一个社区维护用于方便部署的 Ansible 角色。CryptPad 不支持任何第三方身份验证,因此用户必须创建自己的帐户。如果你不想运行自己的服务器,CryptPad 还有一个社区支持的托管版本。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/1/productivity-tool-cryptpad
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney (Kevin Sonney)
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/1/productivity-tool-joplin
|
||||
[2]: https://cryptpad.fr/index.html
|
||||
[3]: https://opensource.com/article/19/1/productivity-tool-wekan
|
||||
[4]: https://opensource.com/article/18/4/3-password-managers-linux-command-line
|
@ -0,0 +1,131 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10637-1.html)
|
||||
[#]: subject: (ODrive (Open Drive) – Google Drive GUI Client For Linux)
|
||||
[#]: via: (https://www.2daygeek.com/odrive-open-drive-google-drive-gui-client-for-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
ODrive:Linux 中的 Google 云端硬盘图形客户端
|
||||
======
|
||||
|
||||
这个我们已经多次讨论过。但是,我还要简要介绍一下它。截至目前,还没有官方的 Google 云端硬盘的 Linux 客户端,我们需要使用非官方客户端。Linux 中有许多集成 Google 云端硬盘的应用。每个应用都提供了一组功能。
|
||||
|
||||
我们过去在网站上写过一些此类文章。
|
||||
|
||||
这些文章是 [DriveSync][1] 、[Google Drive Ocamlfuse 客户端][2] 和 [在 Linux 中使用 Nautilus 文件管理器挂载 Google 云端硬盘][3]。
|
||||
|
||||
今天我们也将讨论相同的主题,程序名字是 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
|
||||
```
|
||||
|
||||
运行上述命令时,可能会看到下面的窗口。只需按下“下一步”按钮即可进行进一步设置。
|
||||
|
||||
![][5]
|
||||
|
||||
点击“连接”链接添加 Google 云端硬盘帐户。
|
||||
|
||||
![][6]
|
||||
|
||||
输入你要设置 Google 云端硬盘帐户的电子邮箱。
|
||||
|
||||
![][7]
|
||||
|
||||
输入邮箱密码。
|
||||
|
||||
![][8]
|
||||
|
||||
允许 ODrive 访问你的 Google 帐户。
|
||||
|
||||
![][9]
|
||||
|
||||
默认情况下,它将选择文件夹位置。如果你要选择特定文件夹,则可以更改。
|
||||
|
||||
![][10]
|
||||
|
||||
最后点击“同步”按钮开始将文件从 Google 下载到本地系统。
|
||||
|
||||
![][11]
|
||||
|
||||
同步正在进行中。
|
||||
|
||||
![][12]
|
||||
|
||||
同步完成后。它会显示所有已下载的文件。
|
||||
|
||||
![][13]
|
||||
|
||||
我看到所有文件都下载到上述目录中。
|
||||
|
||||
![][14]
|
||||
|
||||
如果要将本地系统中的任何新文件同步到 Google 。只需从应用菜单启动 “ODrive”,但它不会实际启动应用。它将在后台运行,我们可以使用 `ps` 命令查看。
|
||||
|
||||
```
|
||||
$ ps -df | grep odrive
|
||||
```
|
||||
|
||||
![][15]
|
||||
|
||||
将新文件添加到 Google文件夹后,它会自动开始同步。从通知菜单中也可以看到。是的,我看到一个文件已同步到 Google 中。
|
||||
|
||||
![][16]
|
||||
|
||||
同步完成后图形界面没有加载,我不确定这个功能。我会向开发者反馈之后,根据他的反馈更新。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/odrive-open-drive-google-drive-gui-client-for-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/drivesync-google-drive-sync-client-for-linux/
|
||||
[2]: https://linux.cn/article-10517-1.html
|
||||
[3]: https://www.2daygeek.com/mount-access-setup-google-drive-in-linux/
|
||||
[4]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[5]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-1.png
|
||||
[6]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-2.png
|
||||
[7]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-3.png
|
||||
[8]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-4.png
|
||||
[9]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-5.png
|
||||
[10]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-6.png
|
||||
[11]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-7.png
|
||||
[12]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-8a.png
|
||||
[13]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-9.png
|
||||
[14]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-11.png
|
||||
[15]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-9b.png
|
||||
[16]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-10.png
|
154
published/20190128 Top Hex Editors for Linux.md
Normal file
154
published/20190128 Top Hex Editors for Linux.md
Normal file
@ -0,0 +1,154 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "zero-mk"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-10614-1.html"
|
||||
[#]: subject: "Top Hex Editors for Linux"
|
||||
[#]: via: "https://itsfoss.com/hex-editors-linux"
|
||||
[#]: author: "Ankush Das https://itsfoss.com/author/ankush/"
|
||||
|
||||
Linux 上最好的十进制编辑器
|
||||
======
|
||||
|
||||
十六进制编辑器可以让你以十六进制的形式查看/编辑文件的二进制数据,因此其被命名为“十六进制”编辑器。说实话,并不是每个人都需要它。只有必须处理二进制数据的特定用户组才会使用到它。
|
||||
|
||||
如果你不知道它是什么,让我来举个例子。假设你拥有一个游戏的配置文件,你可以使用十六进制编辑器打开它们并更改某些值以获得更多的弹药/分数等等。想要了解有关十六进制编辑器的更多信息,你可以参阅 [Wikipedia 页面][1]。
|
||||
|
||||
如果你已经知道它用来干什么了 —— 让我们来看看 Linux 上最好的十六进制编辑器。
|
||||
|
||||
### 5 个最好的十六进制编辑器
|
||||
|
||||
![Best Hex Editors for Linux][2]
|
||||
|
||||
**注意:**这里提到的十六进制编辑器没有特定的排名顺序。
|
||||
|
||||
#### 1、Bless Hex Editor
|
||||
|
||||
![bless hex editor][3]
|
||||
|
||||
**主要特点:**
|
||||
|
||||
* 编辑裸设备(Raw disk)
|
||||
* 多级撤消/重做操作
|
||||
* 多个标签页
|
||||
* 转换表
|
||||
* 支持插件扩展功能
|
||||
|
||||
Bless 是 Linux 上最流行的十六进制编辑器之一。你可以在应用中心或软件中心中找到它。否则,你可以查看它们的 [GitHub 页面][4] 获取构建和相关的说明。
|
||||
|
||||
它可以轻松处理编辑大文件而不会降低速度 —— 因此它是一个快速的十六进制编辑器。
|
||||
|
||||
- [GitHub 项目](https://github.com/bwrsandman/Bless)
|
||||
|
||||
#### 2、GNOME Hex Editor
|
||||
|
||||
![gnome hex editor][5]
|
||||
|
||||
**主要特点:**
|
||||
|
||||
* 以十六进制/ASCII 格式查看/编辑
|
||||
* 编辑大文件
|
||||
|
||||
另一个神奇的十六进制编辑器 —— 专门为 GNOME 量身定做的。我个人用的是 Elementary OS, 所以我可以在应用中心找到它。你也可以在软件中心找到它。否则请参考 [GitHub 页面][6] 获取源代码。
|
||||
|
||||
你可以使用此编辑器以十六进制或 ASCII 格式查看/编辑文件。用户界面非常简单 —— 正如你在上面的图像中看到的那样。
|
||||
|
||||
- [官方网站](https://wiki.gnome.org/Apps/Ghex)
|
||||
|
||||
#### 3、Okteta
|
||||
|
||||
![okteta][7]
|
||||
|
||||
**主要特点:**
|
||||
|
||||
* 可自定义的数据视图
|
||||
* 多个标签页
|
||||
* 字符编码:支持 Qt、EBCDIC 的所有 8 位编码
|
||||
* 解码表列出常见的简单数据类型
|
||||
|
||||
Okteta 是一个简单的十六进制编辑器,没有那么奇特的功能。虽然它可以处理大部分任务。它有一个单独的模块,你可以使用它嵌入其他程序来查看/编辑文件。
|
||||
|
||||
与上述所有编辑器类似,你也可以在应用中心和软件中心上找到列出的编辑器。
|
||||
|
||||
- [官方网站](https://www.kde.org/applications/utilities/okteta/)
|
||||
|
||||
#### 4、wxHexEditor
|
||||
|
||||
![wxhexeditor][8]
|
||||
|
||||
**主要特点:**
|
||||
|
||||
* 轻松处理大文件
|
||||
* 支持 x86 反汇编
|
||||
* 对磁盘设备可以显示扇区指示
|
||||
* 支持自定义十六进制面板格式和颜色
|
||||
|
||||
这很有趣。它主要是一个十六进制编辑器,但你也可以将其用作低级磁盘编辑器。例如,如果你的硬盘有问题,可以使用此编辑器以 RAW 格式编辑原始数据以修复它。
|
||||
|
||||
你可以在你的应用中心和软件中心找到它。否则,可以去看看 [Sourceforge][9]。
|
||||
|
||||
- [官方网站](http://www.wxhexeditor.org/home.php)
|
||||
|
||||
#### 5、Hexedit (命令行工具)
|
||||
|
||||
![hexedit][10]
|
||||
|
||||
**主要特点:**
|
||||
|
||||
* 运行在命令行终端上
|
||||
* 它又快又简单
|
||||
|
||||
如果你想在终端上工作,可以继续通过控制台安装 hexedit。它是我最喜欢的 Linux 命令行的十六进制编辑器。
|
||||
|
||||
当你启动它时,你必须指定要打开的文件的位置,然后它会为你打开它。
|
||||
|
||||
要安装它,只需输入:
|
||||
|
||||
```
|
||||
sudo apt install hexedit
|
||||
```
|
||||
|
||||
### 结束
|
||||
|
||||
十六进制编辑器可以方便地进行实验和学习。如果你是一个有经验的人,你应该选择一个有更多功能的——GUI。 尽管这一切都取决于个人喜好。
|
||||
|
||||
你认为十六进制编辑器的有用性如何?你用哪一个?我们没有列出你最喜欢的吗?请在评论中告诉我们!
|
||||
|
||||
### 额外福利
|
||||
|
||||
译者注:要我说,以上这些十六进制编辑器都太丑了。如果你只是想美美的查看查看一下十六进制输出,那么下面的这个查看器十分值得看看。虽然在功能上还有些不够成熟,但至少在美颜方面可以将上面在座的各位都视作垃圾。
|
||||
|
||||
它就是 hexyl,是一个面向终端的简单的十六进制查看器。它使用颜色来区分不同的字节类型(NULL、可打印的 ASCII 字符、ASCII 空白字符、其它 ASCII 字符和非 ASCII 字符)。
|
||||
|
||||
上图:
|
||||
|
||||
![](https://camo.githubusercontent.com/1f71ee7031e1962b23f21c8cc89cb837e1201238/68747470733a2f2f692e696d6775722e636f6d2f4d574f3975534c2e706e67)
|
||||
|
||||
![](https://camo.githubusercontent.com/2c7114d1b3159fc91e6c1e289e23b79d1186c6d5/68747470733a2f2f692e696d6775722e636f6d2f447037576e637a2e706e67)
|
||||
|
||||
它不仅支持各种 Linux 发行版,还支持 MacOS、FreeBSD、Windows,请自行去其[项目页](https://github.com/sharkdp/hexyl)选用,
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/hex-editors-linux
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zero-mk](https://github.com/zero-mk)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Hex_editor
|
||||
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/Linux-hex-editors-800x450.jpeg?resize=800%2C450&ssl=1
|
||||
[3]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/bless-hex-editor.jpg?ssl=1
|
||||
[4]: https://github.com/bwrsandman/Bless
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/01/ghex-hex-editor.jpg?ssl=1
|
||||
[6]: https://github.com/GNOME/ghex
|
||||
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/okteta-hex-editor-800x466.jpg?resize=800%2C466&ssl=1
|
||||
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/01/wxhexeditor.jpg?ssl=1
|
||||
[9]: https://sourceforge.net/projects/wxhexeditor/
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/hexedit-console.jpg?resize=800%2C566&ssl=1
|
||||
[11]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/01/Linux-hex-editors.jpeg?fit=800%2C450&ssl=1
|
@ -0,0 +1,189 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (pityonline)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10626-1.html)
|
||||
[#]: subject: (How To Remove/Delete The Empty Lines In A File In Linux)
|
||||
[#]: via: (https://www.2daygeek.com/remove-delete-empty-lines-in-a-file-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
在 Linux 中如何删除文件中的空行
|
||||
======
|
||||
|
||||
有时你可能需要在 Linux 中删除某个文件中的空行。如果是的,你可以使用下面方法中的其中一个。有很多方法可以做到,但我在这里只是列举一些简单的方法。
|
||||
|
||||
你可能已经知道 `grep`、`awk` 和 `sed` 命令是专门用来处理文本数据的工具。
|
||||
|
||||
如果你想了解更多关于这些命令的文章,请访问这几个 URL:[在 Linux 中创建指定大小的文件的几种方法][1],[在 Linux 中创建一个文件的几种方法][2] 以及 [在 Linux 中删除一个文件中的匹配的字符串][3]。
|
||||
|
||||
这些属于高级命令,它们可用在大多数 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` 是一个<ruby>流编辑器<rt>stream editor</rt></ruby>。流编辑器是用来编辑输入流(文件或管道)中的文本的。
|
||||
|
||||
```
|
||||
$ 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` 是<ruby>串联(拼接)<rt>concatenate</rt></ruby>的简写。经常用于在 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 表示<ruby>实用的提取和报告语言<rt>Practical Extraction and Reporting Language</rt></ruby>。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][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[pityonline](https://github.com/pityonline)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/create-a-file-in-specific-certain-size-linux/
|
||||
[2]: https://www.2daygeek.com/linux-command-to-create-a-file/
|
||||
[3]: https://www.2daygeek.com/empty-a-file-delete-contents-lines-from-a-file-remove-matching-string-from-a-file-remove-empty-blank-lines-from-a-file/
|
@ -0,0 +1,260 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "zero-MK"
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-10622-1.html"
|
||||
[#]: subject: "How To Install, Configure And Use Fish Shell In Linux?"
|
||||
[#]: via: "https://www.2daygeek.com/linux-fish-shell-friendly-interactive-shell/"
|
||||
[#]: author: "Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/"
|
||||
|
||||
如何在 Linux 中安装、配置和使用 Fish Shell?
|
||||
======
|
||||
|
||||
每个 Linux 管理员都可能听到过 shell 这个词。你知道什么是 shell 吗? 你知道 shell 在 Linux 中的作用是什么吗? Linux 中有多少个 shell 可用?
|
||||
|
||||
shell 是一个程序,它是提供用户和内核之间交互的接口。
|
||||
|
||||
内核是 Linux 操作系统的核心,它管理用户和操作系统之间的所有内容。Shell 可供所有用户在启动终端时使用。终端启动后,用户可以运行任何可用的命令。当 shell 完成命令的执行时,你将在终端窗口上获取输出。
|
||||
|
||||
Bash(全称是 Bourne Again Shell)是运行在今天的大多数 Linux 发行版上的默认的 shell,它非常受欢迎,并具有很多功能。但今天我们将讨论 Fish Shell 。
|
||||
|
||||
### 什么是 Fish Shell?
|
||||
|
||||
[Fish][1] 是友好的交互式 shell ,是一个功能齐全,智能且对用户友好的 Linux 命令行 shell ,它带有一些在大多数 shell 中都不具备的方便功能。
|
||||
|
||||
这些功能包括自动补全建议、Sane Scripting、手册页补全、基于 Web 的配置器和 Glorious VGA Color 。你对它感到好奇并想测试它吗?如果是这样,请按照以下安装步骤继续安装。
|
||||
|
||||
### 如何在 Linux 中安装 Fish Shell ?
|
||||
|
||||
它的安装非常简单,除了少数几个发行版外,它在大多数发行版中都没有。但是,可以使用以下 [fish 仓库][2] 轻松安装。
|
||||
|
||||
对于基于 Arch Linux 的系统, 使用 [Pacman 命令][3] 来安装 fish shell。
|
||||
|
||||
```
|
||||
$ sudo pacman -S fish
|
||||
```
|
||||
|
||||
对于 Ubuntu 16.04/18.04 系统来说,请使用 [APT-GET 命令][4] 或者 [APT 命令][5] 安装 fish shell。
|
||||
|
||||
```
|
||||
$ sudo apt-add-repository ppa:fish-shell/release-3
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install fish
|
||||
```
|
||||
|
||||
对于 Fedora 系统来说,请使用 [DNF 命令][6] 安装 fish shell。
|
||||
|
||||
对于 Fedora 29 系统来说:
|
||||
|
||||
```
|
||||
$ sudo dnf config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/Fedora_29/shells:fish:release:3.repo
|
||||
$ sudo dnf install fish
|
||||
```
|
||||
|
||||
对于 Fedora 28 系统来说:
|
||||
|
||||
```
|
||||
$ sudo dnf config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/Fedora_28/shells:fish:release:3.repo
|
||||
$ sudo dnf install fish
|
||||
```
|
||||
|
||||
对于 Debian 系统来说,请使用 [APT-GET 命令][4] 或者 [APT 命令][5] 安装 fish shell。
|
||||
|
||||
对于 Debian 9 系统来说:
|
||||
|
||||
```
|
||||
$ sudo wget -nv https://download.opensuse.org/repositories/shells:fish:release:3/Debian_9.0/Release.key -O Release.key
|
||||
$ sudo apt-key add - < Release.key
|
||||
$ sudo echo 'deb http://download.opensuse.org/repositories/shells:/fish:/release:/3/Debian_9.0/ /' > /etc/apt/sources.list.d/shells:fish:release:3.list
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install fish
|
||||
```
|
||||
|
||||
对于 Debian 8 系统来说:
|
||||
|
||||
```
|
||||
$ sudo wget -nv https://download.opensuse.org/repositories/shells:fish:release:3/Debian_8.0/Release.key -O Release.key
|
||||
$ sudo apt-key add - < Release.key
|
||||
$ sudo echo 'deb http://download.opensuse.org/repositories/shells:/fish:/release:/3/Debian_8.0/ /' > /etc/apt/sources.list.d/shells:fish:release:3.list
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install fish
|
||||
```
|
||||
|
||||
对于 RHEL/CentOS 系统来说,请使用 [YUM 命令][7] 安装 fish shell。
|
||||
|
||||
对于 RHEL 7 系统来说:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/RHEL_7/shells:fish:release:3.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
对于 RHEL 6 系统来说:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/RedHat_RHEL-6/shells:fish:release:3.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
对于 CentOS 7 系统来说:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:fish:release:2/CentOS_7/shells:fish:release:2.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
对于 CentOS 6 系统来说:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:fish:release:2/CentOS_6/shells:fish:release:2.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统来说,请使用 [Zypper 命令][8] 安装 fish shell。
|
||||
|
||||
```
|
||||
$ sudo zypper addrepo https://download.opensuse.org/repositories/shells:/fish:/release:/3/openSUSE_Leap_42.3/shells:fish:release:3.repo
|
||||
$ suod zypper refresh
|
||||
$ sudo zypper install fish
|
||||
```
|
||||
|
||||
### 如何使用 Fish Shell ?
|
||||
|
||||
一旦你成功安装了 fish shell 。只需在你的终端上输入 `fish` ,它将自动从默认的 bash shell 切换到 fish shell 。
|
||||
|
||||
```
|
||||
$ fish
|
||||
```
|
||||
|
||||
![][10]
|
||||
|
||||
### 自动补全建议
|
||||
|
||||
当你在 fish shell 中键入任何命令时,它会在输入几个字母后以浅灰色自动建议一个命令。
|
||||
|
||||
![][11]
|
||||
|
||||
一旦你得到一个建议然后按下向右光标键(LCTT 译注:原文是左,错的)就能完成它而不是输入完整的命令。
|
||||
|
||||
![][12]
|
||||
|
||||
你可以在键入几个字母后立即按下向上光标键检索该命令以前的历史记录。它类似于 bash shell 的 `CTRL+r` 选项。
|
||||
|
||||
### Tab 补全
|
||||
|
||||
如果你想查看给定命令是否还有其他可能性,那么在键入几个字母后,只需按一下 `Tab` 键即可。
|
||||
|
||||
![][13]
|
||||
|
||||
再次按 `Tab` 键可查看完整列表。
|
||||
|
||||
![][14]
|
||||
|
||||
### 语法高亮
|
||||
|
||||
fish 会进行语法高亮显示,你可以在终端中键入任何命令时看到。无效的命令被着色为 `RED color` 。
|
||||
|
||||
![][15]
|
||||
|
||||
同样的,有效的命令以不同的颜色显示。此外,当你键入有效的文件路径时,fish 会在其下面加下划线,如果路径无效,则不会显示下划线。
|
||||
|
||||
![][16]
|
||||
|
||||
### 基于 Web 的配置器
|
||||
|
||||
fish shell 中有一个很酷的功能,它允许我们通过网络浏览器设置颜色、提示符、功能、变量、历史和键绑定。
|
||||
|
||||
在终端上运行以下命令以启动 Web 配置界面。只需按下 `Ctrl+c` 即可退出。
|
||||
|
||||
```
|
||||
$ fish_config
|
||||
Web config started at 'file:///home/daygeek/.cache/fish/web_config-86ZF5P.html'. Hit enter to stop.
|
||||
qt5ct: using qt5ct plugin
|
||||
^C
|
||||
Shutting down.
|
||||
```
|
||||
|
||||
![][17]
|
||||
|
||||
### 手册页补全
|
||||
|
||||
其他 shell 支持可编程的补全,但只有 fish 可以通过解析已安装的手册页自动生成它们。
|
||||
|
||||
要使用该功能,请运行以下命令:
|
||||
|
||||
```
|
||||
$ fish_update_completions
|
||||
Parsing man pages and writing completions to /home/daygeek/.local/share/fish/generated_completions/
|
||||
3466 / 3466 : zramctl.8.gz
|
||||
```
|
||||
|
||||
### 如何将 Fish 设置为默认 shell
|
||||
|
||||
如果你想测试 fish shell 一段时间,你可以将 fish shell 设置为默认 shell,而不用每次都切换它。
|
||||
|
||||
要这样做,首先使用以下命令获取 Fish Shell 的位置。
|
||||
|
||||
```
|
||||
$ whereis fish
|
||||
fish: /usr/bin/fish /etc/fish /usr/share/fish /usr/share/man/man1/fish.1.gz
|
||||
```
|
||||
|
||||
通过运行以下命令将默认 shell 更改为 fish shell 。
|
||||
|
||||
```
|
||||
$ chsh -s /usr/bin/fish
|
||||
```
|
||||
|
||||
![][18]
|
||||
|
||||
提示:只需验证 Fish Shell 是否已添加到 `/etc/shells` 目录中。如果不是,则运行以下命令以附加它。
|
||||
|
||||
```
|
||||
$ echo /usr/bin/fish | sudo tee -a /etc/shells
|
||||
```
|
||||
|
||||
完成测试后,如果要返回 bash shell ,请使用以下命令。
|
||||
|
||||
暂时返回:
|
||||
|
||||
```
|
||||
$ bash
|
||||
```
|
||||
|
||||
永久返回:
|
||||
|
||||
```
|
||||
$ chsh -s /bin/bash
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/linux-fish-shell-friendly-interactive-shell/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[zero-MK](https://github.com/zero-MK)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fishshell.com/
|
||||
[2]: https://download.opensuse.org/repositories/shells:/fish:/release:/
|
||||
[3]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[4]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[5]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[6]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[7]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[8]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
||||
[9]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[10]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-1.png
|
||||
[11]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-2.png
|
||||
[12]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-5.png
|
||||
[13]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-3.png
|
||||
[14]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-4.png
|
||||
[15]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-6.png
|
||||
[16]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-8.png
|
||||
[17]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-9.png
|
||||
[18]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-7.png
|
@ -0,0 +1,183 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10627-1.html)
|
||||
[#]: subject: (Emoji-Log: A new way to write Git commit messages)
|
||||
[#]: via: (https://opensource.com/article/19/2/emoji-log-git-commit-messages)
|
||||
[#]: author: (Ahmad Awais https://opensource.com/users/mrahmadawais)
|
||||
|
||||
Emoji-Log:编写 Git 提交信息的新方法
|
||||
======
|
||||
|
||||
> 使用 Emoji-Log 为你的提交添加上下文。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/emoji_tech_keyboard.jpg?itok=ncBNKZFl)
|
||||
|
||||
我是一名全职的开源开发人员,我喜欢称自己为“开源者”。我从事开源软件工作已经超过十年,并[构建了数以百计的][1]开源软件应用程序。
|
||||
|
||||
同时我也是“<ruby>避免重复工作<rt>Don't Repeat Yourself</rt></ruby>”(DRY)哲学的忠实粉丝,并且我相信编写更好的 Git 提交消息是 DRY 的一个重要组成部分。它们具有足够的上下文关联,可以作为你开源软件的变更日志。我编写的众多工作流之一是 [Emoji-Log][2],它是一个简单易用的开源 Git 提交日志标准。它通过使用表情符号来创建更好的 Git 提交消息,从而改善了开发人员的体验(DX)。
|
||||
|
||||
我使用 Emoji-Log 构建了 [VSCode Tips & Tricks 仓库][3] 和我的 🦄 [紫色 VSCode 主题仓库][4],以及一个看起来很漂亮的[自动变更日志][5]。
|
||||
|
||||
### Emoji-Log 的哲学
|
||||
|
||||
我喜欢(很多)表情符号,我很喜欢它们。编程、代码、极客/书呆子、开源……所有这一切本质上都很枯燥,有时甚至很无聊。表情符号帮助我添加颜色和情感。想要将感受添加到这个 2D 的、平板的、基于文本的代码世界并没有错。
|
||||
|
||||
相比于[数百个表情符号][6],我学会的更好办法是让类别较小和普遍性。以下是指导使用 Emoji-Log 编写提交信息的原则:
|
||||
|
||||
1. **必要的**
|
||||
* Git 提交信息是必要的。
|
||||
* 像下订单一样编写提交信息。
|
||||
* 例如,使用 ✅ **Add** 而不是 ❌ **Added**
|
||||
* 例如,使用 ✅ **Create** 而不是 ❌ **Creating**
|
||||
2. **规则**
|
||||
* 少数类别易于记忆。
|
||||
* 不多也不少
|
||||
* 例如 **📦 NEW** 、 **👌 IMPROVE** 、 **🐛 FIX** 、 **📖 DOC** 、 **🚀 RELEASE** 、 **✅ TEST**
|
||||
3. **行为**
|
||||
* 让 Git 的提交基于你所采取的操作
|
||||
* 使用像 [VSCode][7] 这样的编辑器来提交带有提交信息的正确文件。
|
||||
|
||||
### 编写提交信息
|
||||
|
||||
仅使用以下 Git 提交信息。简单而小巧的占地面积是 Emoji-Log 的核心。
|
||||
|
||||
1. **📦 NEW: 必要的信息**
|
||||
* 当你添加一些全新的东西时使用。
|
||||
* 例如 **📦 NEW: 添加 Git 忽略的文件**
|
||||
2. **👌 IMPROVE: 必要的信息**
|
||||
* 用于改进/增强代码段,如重构等。
|
||||
* 例如 **👌 IMPROVE: 远程 IP API 函数**
|
||||
3. **🐛 FIX: 必要的信息**
|
||||
* 修复 bug 时使用,不用解释了吧?
|
||||
* 例如 **🐛 FIX: Case converter**
|
||||
4. **📖 DOC: 必要的信息**
|
||||
* 添加文档时使用,比如 README.md 甚至是内联文档。
|
||||
* 例如 **📖 DOC: API 接口教程**
|
||||
5. **🚀 RELEASE: 必要的信息**
|
||||
* 发布新版本时使用。例如, **🚀 RELEASE: Version 2.0.0**
|
||||
6. **✅ 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][8] 安装这些函数,运行以下命令:
|
||||
|
||||
```
|
||||
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 的仓库:
|
||||
|
||||
- [Create-guten-block toolkit](https://github.com/ahmadawais/create-guten-block/commits/)
|
||||
- [VSCode Shades of Purple theme](https://github.com/ahmadawais/shades-of-purple-vscode/commits/)
|
||||
- [Ahmad Awais' GitHub repos](https://github.com/ahmadawais) (我的最新的仓库)
|
||||
- [CaptainCore CLI](https://github.com/CaptainCore/captaincore-cli/commits/) (WordPress 管理工具)
|
||||
- [CaptainCore GUI](https://github.com/CaptainCore/captaincore-gui/commits/) (WordPress 插件)
|
||||
|
||||
你呢?如果你的仓库使用 Emoji-Log,请将这个 [Emoji-Log 徽章](https://on.ahmda.ws/rOMZ/c)放到你的 README 中,并给我发送一个[拉取请求](https://github.com/ahmadawais/Emoji-Log/pulls),以让我可以将你的仓库列在这里。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/2/emoji-log-git-commit-messages
|
||||
|
||||
作者:[Ahmad Awais][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mrahmadawais
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/ahmadawais
|
||||
[2]: https://github.com/ahmadawais/Emoji-Log/
|
||||
[3]: https://github.com/ahmadawais/VSCode-Tips-Tricks
|
||||
[4]: https://github.com/ahmadawais/shades-of-purple-vscode/commits/master
|
||||
[5]: https://github.com/ahmadawais/shades-of-purple-vscode/blob/master/CHANGELOG.md
|
||||
[6]: https://gitmoji.carloscuesta.me/
|
||||
[7]: https://VSCode.pro
|
||||
[8]: https://en.wikipedia.org/wiki/Friendly_interactive_shell
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10640-1.html)
|
||||
[#]: subject: (SPEED TEST: x86 vs. ARM for Web Crawling in Python)
|
||||
[#]: via: (https://blog.dxmtechsupport.com.au/speed-test-x86-vs-arm-for-web-crawling-in-python/)
|
||||
[#]: author: (James Mawson https://blog.dxmtechsupport.com.au/author/james-mawson/)
|
||||
@ -12,7 +12,7 @@ x86 和 ARM 的 Python 爬虫速度对比
|
||||
|
||||
![][1]
|
||||
|
||||
如果你的老板给你的任务是不断地访问竞争对手的网站,把对方商品的价格记录下来,而且要纯手工操作,恐怕你会想要把整个办公室都烧掉。
|
||||
假如说,如果你的老板给你的任务是一次又一次地访问竞争对手的网站,把对方商品的价格记录下来,而且要纯手工操作,恐怕你会想要把整个办公室都烧掉。
|
||||
|
||||
之所以现在网络爬虫的影响力如此巨大,就是因为网络爬虫可以被用于追踪客户的情绪和趋向、搜寻空缺的职位、监控房地产的交易,甚至是获取 UFC 的比赛结果。除此以外,还有很多意想不到的用途。
|
||||
|
||||
@ -32,21 +32,21 @@ x86 和 ARM 的 Python 爬虫速度对比
|
||||
|
||||
ARM 是目前世界上最流行的 CPU 架构。
|
||||
|
||||
但 ARM 架构处理器在很多人眼中的地位只是作为一个节省成本的选择,而不是跑在生产环境中的处理器的首选。
|
||||
但 ARM 架构处理器在很多人眼中的地位只是作为一个省钱又省电的选择,而不是跑在生产环境中的处理器的首选。
|
||||
|
||||
然而,诞生于英国剑桥的 ARM CPU,最初是用于昂贵的 [Acorn Archimedes][4] 计算机上的,这是当时世界上最强大的计算机,它的运算速度甚至比最快的 386 还要快好几倍。
|
||||
然而,诞生于英国剑桥的 ARM CPU,最初是用于极其昂贵的 [Acorn Archimedes][4] 计算机上的,这是当时世界上最强大的桌面计算机,甚至在很长一段时间内,它的运算速度甚至比最快的 386 还要快好几倍。
|
||||
|
||||
Acorn 公司和 Commodore、Atari 的理念类似,他们认为一家伟大的计算机公司就应该制造出伟大的计算机,让人感觉有点目光短浅。而比尔盖茨的想法则有所不同,他力图在更多不同种类和价格的 x86 机器上使用他的 DOS 系统。
|
||||
|
||||
拥有大量用户基础的平台会让更多开发者开发出众多适应平台的软件,而软件资源丰富又让计算机更受用户欢迎。
|
||||
拥有大量用户基数的平台会成为第三方开发者开发软件的平台,而软件资源丰富又会让你的计算机更受用户欢迎。
|
||||
|
||||
即使是苹果公司也在这上面吃到了苦头,不得不在 x86 芯片上投入大量的财力。最终,这些芯片不再仅仅用于专业的计算任务,走进了人们的日常生活中。
|
||||
即使是苹果公司也几乎被打败。在 x86 芯片上投入大量的财力,最终,这些芯片被用于生产环境计算任务。
|
||||
|
||||
ARM 架构也并没有消失。基于 ARM 架构的芯片不仅运算速度快,同时也非常节能。因此诸如机顶盒、PDA、数码相机、MP3 播放器这些电子产品多数都会采用 ARM 架构的芯片,甚至在很多需要用电池、不配备大散热风扇的电子产品上,都可以见到 ARM 芯片的身影。
|
||||
但 ARM 架构也并没有消失。基于 ARM 架构的芯片不仅运算速度快,同时也非常节能。因此诸如机顶盒、PDA、数码相机、MP3 播放器这些电子产品多数都会采用 ARM 架构的芯片,甚至在很多需要用电池或不配备大散热风扇的电子产品上,都可以见到 ARM 芯片的身影。
|
||||
|
||||
而 ARM 则脱离 Acorn 成为了一种独立的商业模式,他们不生产实物芯片,仅仅是向芯片生产厂商出售相关的知识产权。
|
||||
而 ARM 则脱离 Acorn 成为了一种特殊的商业模式,他们不生产实物芯片,仅仅是向芯片生产厂商出售相关的知识产权。
|
||||
|
||||
因此,ARM 芯片被应用于很多手机和平板电脑上。当 Linux 被移植到这种架构的芯片上时,开源技术的大门就已经向它打开了,这才让我们今天得以在这些芯片上运行 web 爬虫程序。
|
||||
因此,这或多或少是 ARM 芯片被应用于如此之多的手机和平板电脑上的原因。当 Linux 被移植到这种架构的芯片上时,开源技术的大门就已经向它打开了,这才让我们今天得以在这些芯片上运行 web 爬虫程序。
|
||||
|
||||
#### 服务器端的 ARM
|
||||
|
||||
@ -64,11 +64,11 @@ ARM 架构也并没有消失。基于 ARM 架构的芯片不仅运算速度快
|
||||
|
||||
#### Scaleway
|
||||
|
||||
Scaleway 自身的定位是“专为开发者设计”。我觉得这个定位很准确,对于开发原型来说,Scaleway 提供的产品确实可以作为一个很好的沙盒环境。
|
||||
Scaleway 自身的定位是“专为开发者设计”。我觉得这个定位很准确,对于开发和原型设计来说,Scaleway 提供的产品确实可以作为一个很好的沙盒环境。
|
||||
|
||||
Scaleway 提供了一个简洁的页面,让用户可以快速地从主页进入 bash shell 界面。对于很多小企业、自由职业者或者技术顾问,如果想要运行 web 爬虫,这个产品毫无疑问是一个物美价廉的选择。
|
||||
Scaleway 提供了一个简洁的仪表盘页面,让用户可以快速地从主页进入 bash shell 界面。对于很多小企业、自由职业者或者技术顾问,如果想要运行 web 爬虫,这个产品毫无疑问是一个物美价廉的选择。
|
||||
|
||||
ARM 方面我们选择 [ARM64-2GB][10] 这一款服务器,每月只需要 3 欧元。它带有 4 个 Cavium ThunderX 核心,是在 2014 年推出的第一款服务器级的 ARMv8 处理器。但现在看来它已经显得有点落后了,并逐渐被更新的 ThunderX2 取代。
|
||||
ARM 方面我们选择 [ARM64-2GB][10] 这一款服务器,每月只需要 3 欧元。它带有 4 个 Cavium ThunderX 核心,这是在 2014 年推出的第一款服务器级的 ARMv8 处理器。但现在看来它已经显得有点落后了,并逐渐被更新的 ThunderX2 取代。
|
||||
|
||||
x86 方面我们选择 [1-S][11],每月的费用是 4 欧元。它拥有 2 个英特尔 Atom C3995 核心。英特尔的 Atom 系列处理器的特点是低功耗、单线程,最初是用在笔记本电脑上的,后来也被服务器所采用。
|
||||
|
||||
@ -76,43 +76,45 @@ x86 方面我们选择 [1-S][11],每月的费用是 4 欧元。它拥有 2 个
|
||||
|
||||
为了避免我不能熟练使用包管理器的尴尬局面,两方的操作系统我都会选择使用 Debian 9。
|
||||
|
||||
#### Amazon Web Services
|
||||
#### Amazon Web Services(AWS)
|
||||
|
||||
当你还在注册 AWS 账号的时候,使用 Scaleway 的用户可能已经把提交信用卡信息、启动 VPS 实例、添加sudoer、安装依赖包这一系列流程都完成了。AWS 的操作相对来说比较繁琐,甚至需要详细阅读手册才能知道你正在做什么。
|
||||
当你还在注册 AWS 账号的时候,使用 Scaleway 的用户可能已经把提交信用卡信息、启动 VPS 实例、添加 sudo 用户、安装依赖包这一系列流程都完成了。AWS 的操作相对来说比较繁琐,甚至需要详细阅读手册才能知道你正在做什么。
|
||||
|
||||
当然这也是合理的,对于一些需求复杂或者特殊的企业用户,确实需要通过详细的配置来定制合适的使用方案。
|
||||
|
||||
我们所采用的 AWS Graviton 处理器是 AWS EC2(Elastic Compute Cloud)的一部分,我会以按需实例的方式来运行,这也是最贵但最简捷的方式。AWS 同时也提供[竞价实例][12],这样可以用较低的价格运行实例,但实例的运行时间并不固定。如果实例需要长时间持续运行,还可以选择[预留实例][13]。
|
||||
我们所采用的 AWS Graviton 处理器是 AWS EC2(<ruby>弹性计算云<rt>Elastic Compute Cloud</rt></ruby>)的一部分,我会以按需实例的方式来运行,这也是最贵但最简捷的方式。AWS 同时也提供[竞价实例][12],这样可以用较低的价格运行实例,但实例的运行时间并不固定。如果实例需要长时间持续运行,还可以选择[预留实例][13]。
|
||||
|
||||
看,AWS 就是这么复杂……
|
||||
|
||||
我们分别选择 [a1.medium][14] 和 [t2.small][15] 两种型号的实例进行对比,两者都带有 2GB 内存。这个时候问题来了,手册中提到的 vCPU 又是什么?两种型号的不同之处就在于此。
|
||||
我们分别选择 [a1.medium][14] 和 [t2.small][15] 两种型号的实例进行对比,两者都带有 2GB 内存。这个时候问题来了,这里提到的 vCPU 又是什么?两种型号的不同之处就在于此。
|
||||
|
||||
对于 a1.medium 型号的实例,vCPU 是 AWS Graviton 芯片提供的单个计算核心。这个芯片由被亚马逊在 2015 收购的以色列厂商 Annapurna Labs 研发,是 AWS 独有的单线程 64 位 ARMv8 内核。它的按需价格为每小时 0.0255 美元。
|
||||
|
||||
而 t2.small 型号实例使用英特尔至强系列芯片,但我不确定具体是其中的哪一款。它每个核心有两个线程,但我们并不能用到整个核心,甚至整个线程。我们能用到的只是“20% 的基准性能,可以使用 CPU 积分突破这个基准”。这可能有一定的原因,但我没有弄懂。它的按需价格是每小时 0.023 美元。
|
||||
而 t2.small 型号实例使用英特尔至强系列芯片,但我不确定具体是其中的哪一款。它每个核心有两个线程,但我们并不能用到整个核心,甚至整个线程。
|
||||
|
||||
我们能用到的只是“20% 的基准性能,可以使用 CPU 积分突破这个基准”。这可能有一定的原因,但我没有弄懂。它的按需价格是每小时 0.023 美元。
|
||||
|
||||
在镜像库中没有 Debian 发行版的镜像,因此我选择了 Ubuntu 18.04。
|
||||
|
||||
### Beavis and Butthead Do Moz’s Top 500
|
||||
### 瘪四与大头蛋爬取 Moz 排行榜前 500 的网站
|
||||
|
||||
要测试这些 VPS 的 CPU 性能,就该使用爬虫了。一般来说都是对几个网站在尽可能短的时间里发出尽可能多的请求,但这种操作太暴力了,我的做法是只向大量网站发出少数几个请求。
|
||||
要测试这些 VPS 的 CPU 性能,就该使用爬虫了。一个方法是对几个网站在尽可能短的时间里发出尽可能多的请求,但这种操作不太礼貌,我的做法是只向大量网站发出少数几个请求。
|
||||
|
||||
为此,我编写了 `beavs.py` 这个爬虫程序(致敬我最喜欢的物理学家和制片人 Mike Judge)。这个程序会将 Moz 上排行前 500 的网站都爬取 3 层的深度,并计算 “wood” 和 “ass” 这两个单词在 HTML 文件中出现的次数。
|
||||
为此,我编写了 `beavis.py`(瘪四)这个爬虫程序(致敬我最喜欢的物理学家和制片人 Mike Judge)。这个程序会将 Moz 上排行前 500 的网站都爬取 3 层的深度,并计算 “wood” 和 “ass” 这两个单词在 HTML 文件中出现的次数。(LCTT 译注:beavis(瘪四)和 butt-head(大头蛋) 都是 Mike Judge 的动画片《瘪四与大头蛋》中的角色)
|
||||
|
||||
但我实际爬取的网站可能不足 500 个,因为我需要遵循网站的 `robot.txt` 协定,另外还有些网站需要提交 javascript 请求,也不一定会计算在内。但这已经是一个足以让 CPU 保持繁忙的爬虫任务了。
|
||||
|
||||
Python 的[全局解释器锁][16]机制会让我的程序只能用到一个 CPU 线程。为了测试多线程的性能,我需要启动多个独立的爬虫程序进程。
|
||||
|
||||
因此我还编写了 `butthead.py`,尽管 Butthead 很粗鲁,它也比 Beavis 要略胜一筹(译者注:beavis 和 butt-head 都是 Mike Judge 的动画片《Beavis and Butt-head》中的角色)。
|
||||
因此我还编写了 `butthead.py`,尽管大头蛋很粗鲁,它也总是比瘪四要略胜一筹。
|
||||
|
||||
我将整个爬虫任务拆分为多个部分,这可能会对爬取到的链接数量有一点轻微的影响。但无论如何,每次爬取都会有所不同,我们要关注的是爬取了多少个页面,以及耗时多长。
|
||||
|
||||
### 在 ARM 服务器上安装 Scrapy
|
||||
|
||||
安装 Scrapy 的过程与芯片的不同架构没有太大的关系,都是安装 pip 和相关的依赖包之后,再使用 pip 来安装Scrapy。
|
||||
安装 Scrapy 的过程与芯片的不同架构没有太大的关系,都是安装 `pip` 和相关的依赖包之后,再使用 `pip` 来安装 Scrapy。
|
||||
|
||||
据我观察,在使用 ARM 的机器上使用 pip 安装 Scrapy 确实耗时要长一点,我估计是由于需要从源码编译为二进制文件。
|
||||
据我观察,在使用 ARM 的机器上使用 `pip` 安装 Scrapy 确实耗时要长一点,我估计是由于需要从源码编译为二进制文件。
|
||||
|
||||
在 Scrapy 安装结束后,就可以通过 shell 来查看它的工作状态了。
|
||||
|
||||
@ -143,7 +145,7 @@ Scrapy 的官方文档建议[将爬虫程序的 CPU 使用率控制在 80% 到 9
|
||||
|
||||
我使用了 [top][18] 工具来查看爬虫程序运行期间的 CPU 使用率。在任务刚开始的时候,两者的 CPU 使用率都达到了 100%,但 ThunderX 大部分时间都达到了 CPU 的极限,无法看出来 Atom 的性能会比 ThunderX 超出多少。
|
||||
|
||||
通过 top 工具,我还观察了它们的内存使用情况。随着爬取任务的进行,ARM 机器的内存使用率最终达到了 14.7%,而 x86 则最终是 15%。
|
||||
通过 `top` 工具,我还观察了它们的内存使用情况。随着爬取任务的进行,ARM 机器的内存使用率最终达到了 14.7%,而 x86 则最终是 15%。
|
||||
|
||||
从运行日志还可以看出来,当 CPU 使用率到达极限时,会有大量的超时页面产生,最终导致页面丢失。这也是合理出现的现象,因为 CPU 过于繁忙会无法完整地记录所有爬取到的页面。
|
||||
|
||||
@ -156,19 +158,19 @@ Scrapy 的官方文档建议[将爬虫程序的 CPU 使用率控制在 80% 到 9
|
||||
| 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 的使用情况,从监控结果来看,我的爬虫程序并没有完全用到这两款服务器所提供的所有性能。
|
||||
为了方便比较,对于在 AWS 上跑的爬虫,我记录的指标和 Scaleway 上一致,但似乎没有达到预期的效果。这里我没有使用 `top`,而是使用了 AWS 提供的控制台来监控 CPU 的使用情况,从监控结果来看,我的爬虫程序并没有完全用到这两款服务器所提供的所有性能。
|
||||
|
||||
a1.medium 型号的机器尤为如此,在任务开始阶段,它的 CPU 使用率达到了峰值 45%,但随后一直在 20% 到 30% 之间。
|
||||
|
||||
让我有点感到意外的是,这个程序在 ARM 处理器上的运行速度相当慢,但却远未达到 Graviton CPU 能力的极限,而在 Inter 处理器上则可以在某些时候达到 CPU 能力的极限。它们运行的代码是完全相同的,处理器的不同架构可能导致了对代码的不同处理方式。
|
||||
让我有点感到意外的是,这个程序在 ARM 处理器上的运行速度相当慢,但却远未达到 Graviton CPU 能力的极限,而在 Intel Atom 处理器上则可以在某些时候达到 CPU 能力的极限。它们运行的代码是完全相同的,处理器的不同架构可能导致了对代码的不同处理方式。
|
||||
|
||||
个中原因无论是由于处理器本身的特性,还是而今是文件的编译,又或者是两者皆有,对我来说都是一个黑盒般的存在。我认为,既然在 AWS 机器上没有达到 CPU 处理能力的极限,那么只有在 Scaleway 机器上跑出来的性能数据是可以作为参考的。
|
||||
个中原因无论是由于处理器本身的特性,还是二进制文件的编译,又或者是两者皆有,对我来说都是一个黑盒般的存在。我认为,既然在 AWS 机器上没有达到 CPU 处理能力的极限,那么只有在 Scaleway 机器上跑出来的性能数据是可以作为参考的。
|
||||
|
||||
t2.small 型号的机器性能让人费解。CPU 利用率大概 20%,最高才达到 35%,是因为手册中说的“20% 的基准性能,可以使用 CPU 积分突破这个基准”吗?但在控制台中可以看到 CPU 积分并没有被消耗。
|
||||
|
||||
为了确认这一点,我安装了 [stress][19] 这个软件,然后运行了一段时间,这个时候发现居然可以把 CPU 使用率提高到 100% 了。
|
||||
|
||||
显然,我需要调整一下它们的配置文件。我将 CONCURRENT_REQUESTS 参数设置为 5000,将 REACTOR_THREADPOOL_MAXSIZE 参数设置为 120,将爬虫任务的负载调得更大。
|
||||
显然,我需要调整一下它们的配置文件。我将 `CONCURRENT_REQUESTS` 参数设置为 5000,将 `REACTOR_THREADPOOL_MAXSIZE` 参数设置为 120,将爬虫任务的负载调得更大。
|
||||
|
||||
| 机器种类 | 耗时 | 爬取页面数 | 每小时爬取页面数 | 每万页面费用(美元) |
|
||||
| ----------------------- | ----------- | ---------- | ---------------- | -------------------- |
|
||||
@ -182,7 +184,7 @@ a1.medium 型号机器的 CPU 使用率在爬虫任务开始后 5 分钟飙升
|
||||
|
||||
现在我们看到它们的性能都差不多了。但至强处理器的线程持续跑满了 CPU,Graviton 处理器则只是有一段时间如此。可以认为 Graviton 略胜一筹。
|
||||
|
||||
然而,如果 CPU 积分耗尽了呢?这种情况下的对比可能更为公平。为了测试这种情况,我使用 stress 把所有的 CPU 积分用完,然后再次启动了爬虫任务。
|
||||
然而,如果 CPU 积分耗尽了呢?这种情况下的对比可能更为公平。为了测试这种情况,我使用 `stress` 把所有的 CPU 积分用完,然后再次启动了爬虫任务。
|
||||
|
||||
在没有 CPU 积分的情况下,CPU 使用率在 27% 就到达极限不再上升了,同时又出现了丢失页面的现象。这么看来,它的性能比负载较低的时候更差。
|
||||
|
||||
@ -190,7 +192,7 @@ a1.medium 型号机器的 CPU 使用率在爬虫任务开始后 5 分钟飙升
|
||||
|
||||
将爬虫任务分散到不同的进程中,可以有效利用机器所提供的多个核心。
|
||||
|
||||
一开始,我将爬虫任务分布在 10 个不同的进程中并同时启动,结果发现比仅使用 1 个进程的时候还要慢。
|
||||
一开始,我将爬虫任务分布在 10 个不同的进程中并同时启动,结果发现比每个核心仅使用 1 个进程的时候还要慢。
|
||||
|
||||
经过尝试,我得到了一个比较好的方案。把爬虫任务分布在 10 个进程中,但每个核心只启动 1 个进程,在每个进程接近结束的时候,再从剩余的进程中选出 1 个进程启动起来。
|
||||
|
||||
@ -198,7 +200,7 @@ a1.medium 型号机器的 CPU 使用率在爬虫任务开始后 5 分钟飙升
|
||||
|
||||
想要预估某个域名的页面量,一定程度上可以参考这个域名主页的链接数量。我用另一个程序来对这个数量进行了统计,然后按照降序排序。经过这样的预处理之后,只会额外增加 1 分钟左右的时间。
|
||||
|
||||
结果,爬虫运行的总耗时找过了两个小时!毕竟把链接最多的域名都堆在同一个进程中也存在一定的弊端。
|
||||
结果,爬虫运行的总耗时超过了两个小时!毕竟把链接最多的域名都堆在同一个进程中也存在一定的弊端。
|
||||
|
||||
针对这个问题,也可以通过调整各个进程爬取的域名数量来进行优化,又或者在排序之后再作一定的修改。不过这种优化可能有点复杂了。
|
||||
|
||||
@ -225,7 +227,9 @@ a1.medium 型号机器的 CPU 使用率在爬虫任务开始后 5 分钟飙升
|
||||
|
||||
### 结论
|
||||
|
||||
从上面的数据来看,不同架构的 CPU 性能和它们的问世时间没有直接的联系,AWS Graviton 是单线程情况下性能最佳的。
|
||||
从上面的数据来看,对于性能而言,CPU 的架构并没有它们的问世时间重要,2018 年生产的 AWS Graviton 是单线程情况下性能最佳的。
|
||||
|
||||
你当然可以说按核心来比,Xeon 仍然赢了。但是,你不但需要计算美元的变化,甚至还要计算线程数。
|
||||
|
||||
另外在性能方面 2017 年生产的 Atom 轻松击败了 2014 年生产的 ThunderX,而 ThunderX 则在性价比方面占优。当然,如果你使用 AWS 的机器的话,还是使用 Graviton 吧。
|
||||
|
||||
@ -243,7 +247,7 @@ a1.medium 型号机器的 CPU 使用率在爬虫任务开始后 5 分钟飙升
|
||||
|
||||
要运行这些代码,需要预先安装 Scrapy,并且需要 [Moz 上排名前 500 的网站][21]的 csv 文件。如果要运行 `butthead.py`,还需要安装 [psutil][22] 这个库。
|
||||
|
||||
##### beavis.py
|
||||
*beavis.py*
|
||||
|
||||
```
|
||||
import scrapy
|
||||
@ -347,7 +351,7 @@ if __name__ == '__main__':
|
||||
print('Uh huhuhuhuh. It said wood ' + str(wood) + ' times.')
|
||||
```
|
||||
|
||||
##### butthead.py
|
||||
*butthead.py*
|
||||
|
||||
```
|
||||
import scrapy, time, psutil
|
||||
@ -494,7 +498,7 @@ via: https://blog.dxmtechsupport.com.au/speed-test-x86-vs-arm-for-web-crawling-i
|
||||
作者:[James Mawson][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
221
published/20190226 All about -Curly Braces- in Bash.md
Normal file
221
published/20190226 All about -Curly Braces- in Bash.md
Normal file
@ -0,0 +1,221 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10624-1.html)
|
||||
[#]: subject: (All about {Curly Braces} in Bash)
|
||||
[#]: via: (https://www.linux.com/blog/learn/2019/2/all-about-curly-braces-bash)
|
||||
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
|
||||
|
||||
浅析 Bash 中的 {花括号}
|
||||
======
|
||||
> 让我们继续我们的 Bash 基础之旅,来近距离观察一下花括号,了解一下如何和何时使用它们。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/curly-braces-1920.jpg?itok=cScRhWrX)
|
||||
|
||||
在前面的 Bash 基础系列文章中,我们或多或少地使用了一些还没有讲到的符号。在之前文章的很多例子中,我们都使用到了括号,但并没有重点讲解关于括号的内容。
|
||||
|
||||
这个系列接下来的文章中,我们会研究括号们的用法:如何使用这些括号?将它们放在不同的位置会有什么不同的效果?除了圆括号、方括号、花括号以外,我们还会接触另外的将一些内容“包裹”起来的符号,例如单引号、双引号和反引号。
|
||||
|
||||
在这周,我们先来看看花括号 `{}`。
|
||||
|
||||
### 构造序列
|
||||
|
||||
花括号在之前的《[点的含义][1]》这篇文章中已经出现过了,当时我们只对点号 `.` 的用法作了介绍。但在构建一个序列的过程中,同样不可以缺少花括号。
|
||||
|
||||
我们使用
|
||||
|
||||
```
|
||||
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]}
|
||||
```
|
||||
|
||||
在这里,花括号的作用就不是构造序列了,而是用于<ruby>参数展开<rt>parameter expansion</rt></ruby>。顾名思义,参数展开就是将花括号中的变量展开为这个变量实际的内容。
|
||||
|
||||
我们继续使用上面的 `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][3] 是一套可以用于操作图像文件的命令行工具,它有一个 `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][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://linux.cn/article-10465-1.html
|
||||
[3]: http://www.imagemagick.org/
|
||||
|
@ -0,0 +1,111 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10618-1.html)
|
||||
[#]: subject: (How To SSH Into A Particular Directory On Linux)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-ssh-into-a-particular-directory-on-linux/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
如何 SSH 登录到 Linux 上的特定目录
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/SSH-Into-A-Particular-Directory-720x340.png)
|
||||
|
||||
你是否遇到过需要 SSH 登录到远程服务器并立即 `cd` 到一个目录来继续交互式作业?你找对地方了!这个简短的教程描述了如何直接 SSH 登录到远程 Linux 系统的特定目录。而且不仅是 SSH 登录到特定目录,你还可以在连接到 SSH 服务器后立即运行任何命令。这些没有你想的那么难。请继续阅读。
|
||||
|
||||
### SSH 登录到远程系统的特定目录
|
||||
|
||||
在我知道这个方法之前,我通常首先使用以下命令 SSH 登录到远程系统:
|
||||
|
||||
```
|
||||
$ ssh user@remote-system
|
||||
```
|
||||
|
||||
然后如下 `cd` 进入某个目录:
|
||||
|
||||
```
|
||||
$ cd <some-directory>
|
||||
```
|
||||
|
||||
然而,你不需要使用两个单独的命令。你可以用一条命令组合并简化这个任务。
|
||||
|
||||
看看下面的例子。
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix ; bash'
|
||||
```
|
||||
|
||||
上面的命令将通过 SSH 连接到远程系统 (192.168.225.22) 并立即进入名为 `/home/sk/ostechnix/` 的目录,并停留在提示符中。
|
||||
|
||||
这里,`-t` 标志用于强制分配伪终端,这是一个必要的交互式 shell。
|
||||
|
||||
以下是上面命令的输出:
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/ssh-1.gif)
|
||||
|
||||
你也可以使用此命令:
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix ; exec bash'
|
||||
```
|
||||
|
||||
或者,
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix && exec bash -l'
|
||||
```
|
||||
|
||||
这里,`-l` 标志将 bash 设置为登录 shell。
|
||||
|
||||
在上面的例子中,我在最后一个参数中使用了 `bash`。它是我的远程系统中的默认 shell。如果你不知道远程系统上的 shell 类型,请使用以下命令:
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix && exec $SHELL'
|
||||
```
|
||||
|
||||
就像我已经说过的,它不仅仅是连接到远程系统后 `cd` 进入目录。你也可以使用此技巧运行其他命令。例如,以下命令将进入 `/home/sk/ostechnix/`,然后执行命令 `uname -a` 。
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix && uname -a && exec $SHELL'
|
||||
```
|
||||
|
||||
或者,你可以在远程系统上的 `.bash_profile` 文件中添加你想在 SSH 登录后执行的命令。
|
||||
|
||||
编辑 `.bash_profile` 文件:
|
||||
|
||||
```
|
||||
$ nano ~/.bash_profile
|
||||
```
|
||||
|
||||
每个命令一行。在我的例子中,我添加了下面这行:
|
||||
|
||||
```
|
||||
cd /home/sk/ostechnix >& /dev/null
|
||||
```
|
||||
|
||||
保存并关闭文件。最后,运行以下命令更新修改。
|
||||
|
||||
```
|
||||
$ source ~/.bash_profile
|
||||
```
|
||||
|
||||
请注意,你应该在远程系统的 `.bash_profile` 或 `.bashrc` 文件中添加此行,而不是在本地系统中。从现在开始,无论何时登录(无论是通过 SSH 还是直接登录),`cd` 命令都将执行,你将自动进入 `/home/sk/ostechnix/` 目录。
|
||||
|
||||
就是这些了。希望这篇文章有用。还有更多好东西。敬请关注!
|
||||
|
||||
干杯!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-ssh-into-a-particular-directory-on-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
@ -0,0 +1,83 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10631-1.html)
|
||||
[#]: subject: (Linux security: Cmd provides visibility, control over user activity)
|
||||
[#]: via: (https://www.networkworld.com/article/3342454/linux-security-cmd-provides-visibility-control-over-user-activity.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
Linux 安全:Cmd 提供可视化控制用户活动
|
||||
======
|
||||
> Cmd 可以帮助机构监控、验证和阻止那些超出系统预期使用范围的活动。
|
||||
|
||||
![](https://images.techhive.com/images/article/2017/01/background-1900329_1920-100705659-large.jpg)
|
||||
|
||||
有一个新的 Linux 安全工具你值得了解一下:Cmd(读作 “see em dee”),它极大地改变了可以对 Linux 用户进行控制的类型。它远远超出了传统的用户权限配置,并在监视和控制用户能够在 Linux 系统上运行的命令方面发挥了积极作用。
|
||||
|
||||
Cmd 由同名公司开发,专注于云应用。鉴于越来越多的应用迁移到依赖于 Linux 的云环境中,而可用工具的缺口使得难以充分实施所需的安全性。除此以外,Cmd 还可用于管理和保护本地系统。
|
||||
|
||||
### Cmd 与传统 Linux 安全控件的区别
|
||||
|
||||
Cmd 公司的领导 Milun Tesovic 和 Jake King 表示,除非了解了用户日常如何工作以及什么被视是“正常”,机构无法自信地预测或控制用户行为。他们寻求提供一种能够精细控制、监控和验证用户活动的工具。
|
||||
|
||||
Cmd 通过形成用户活动配置文件(描绘这些用户通常进行的活动)来监视用户活动,注意其在线行为的异常(登录时间、使用的命令、用户位置等),以及预防和报告某些意味着系统攻击的活动(例如,下载或修改文件和运行特权命令)。产品的行为是可配置的,可以快速进行更改。
|
||||
|
||||
如今大多数人用来检测威胁、识别漏洞和控制用户权限的工具,我们已经使用了很久了,但我们仍在努力抗争保持系统和数据的安全。Cmd 让我们更能够确定恶意用户的意图,无论这些用户是设法侵入帐户还是代表内部威胁。
|
||||
|
||||
![1 sources live sessions][1]
|
||||
|
||||
*查看实时 Linux 会话*
|
||||
|
||||
### Cmd 如何工作?
|
||||
|
||||
在监视和管理用户活动时,Cmd 可以:
|
||||
|
||||
* 收集描述用户活动的信息
|
||||
* 使用基线来确定什么是正常的
|
||||
* 使用特定指标检测并主动防止威胁
|
||||
* 向负责人发送警报
|
||||
|
||||
![2 triggers][3]
|
||||
|
||||
*在 Cmd 中构建自定义策略*
|
||||
|
||||
Cmd 扩展了系统管理员通过传统方法可以控制的内容,例如配置 `sudo` 权限,提供更精细和特定情境的控制。
|
||||
|
||||
管理员可以选择可以与 Linux 系统管理员所管理的用户权限控制分开管理的升级策略。
|
||||
|
||||
Cmd 客户端提供实时可视化(而不是事后日志分析),并且可以阻止操作、要求额外的身份验证或根据需要进行协商授权。
|
||||
|
||||
此外,如果有用户位置信息,Cmd 支持基于地理定位的自定义规则。并且可以在几分钟内将新策略推送到部署在主机上的客户端。
|
||||
|
||||
![3 command blocked][4]
|
||||
|
||||
*在 Cmd 中构建触发器查询*
|
||||
|
||||
### Cmd 的融资新闻
|
||||
|
||||
[Cmd][2] 最近完成了由 [GV][6] (前身为 Google Ventures)领投,Expa、Amplify Partners 和其他战略投资者跟投的 [1500 万美元的融资][5]。这使该公司的融资金额达到了 2160 万美元,这将帮助其继续为该产品增加新的防御能力并发展其工程师团队。
|
||||
|
||||
此外,该公司还任命 GV 的普通合伙人 Karim Faris 为董事会成员。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3342454/linux-security-cmd-provides-visibility-control-over-user-activity.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://images.idgesg.net/images/article/2019/02/1-sources-live-sessions-100789431-large.jpg
|
||||
[2]: https://cmd.com
|
||||
[3]: https://images.idgesg.net/images/article/2019/02/2-triggers-100789432-large.jpg
|
||||
[4]: https://images.idgesg.net/images/article/2019/02/3-command-blocked-100789433-large.jpg
|
||||
[5]: https://www.linkedin.com/pulse/changing-cybersecurity-announcing-cmds-15-million-funding-jake-king/
|
||||
[6]: https://www.gv.com/
|
||||
[7]: https://www.facebook.com/NetworkWorld/
|
||||
[8]: https://www.linkedin.com/company/network-world
|
@ -0,0 +1,155 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10623-1.html)
|
||||
[#]: subject: (How To Check Password Complexity/Strength And Score In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-check-password-complexity-strength-and-score-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
如何在 Linux 中检查密码的复杂性/强度和评分?
|
||||
======
|
||||
|
||||
我们都知道密码的重要性。最好的密码就是使用难以猜测密码。另外,我建议你为每个服务使用不同的密码,如电子邮件、ftp、ssh 等。最重要的是,我建议你们经常更改密码,以避免不必要的黑客攻击。
|
||||
|
||||
默认情况下,RHEL 和它的衍生版使用 cracklib 模块来检查密码强度。我们将教你如何使用 cracklib 模块检查密码强度。
|
||||
|
||||
如果你想检查你创建的密码评分,请使用 pwscore 包。
|
||||
|
||||
如果你想创建一个好密码,最起码它应该至少有 12-15 个字符长度。它应该按以下组合创建,如字母(小写和大写)、数字和特殊字符。Linux 中有许多程序可用于检查密码复杂性,我们今天将讨论有关 cracklib 模块和 pwscore 评分。
|
||||
|
||||
### 如何在 Linux 中安装 cracklib 模块?
|
||||
|
||||
cracklib 模块在大多数发行版仓库中都有,因此,请使用发行版官方软件包管理器来安装它。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][1]来安装 cracklib。
|
||||
|
||||
```
|
||||
$ sudo dnf install cracklib
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][2] 或 [APT 命令][3]来安装 libcrack2。
|
||||
|
||||
```
|
||||
$ sudo apt install libcrack2
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,使用 [Pacman 命令][4]来安装 cracklib。
|
||||
|
||||
```
|
||||
$ sudo pacman -S cracklib
|
||||
```
|
||||
|
||||
对于 RHEL/CentOS 系统,使用 [YUM 命令][5]来安装 cracklib。
|
||||
|
||||
```
|
||||
$ sudo yum install cracklib
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][6]来安装 cracklib。
|
||||
|
||||
```
|
||||
$ sudo zypper install cracklib
|
||||
```
|
||||
|
||||
### 如何在 Linux 中使用 cracklib 模块检查密码复杂性?
|
||||
|
||||
我在本文中添加了一些示例来助你更好地了解此模块。
|
||||
|
||||
如果你提供了任何如人名或地名或常用字,那么你将看到一条消息“它存在于字典的单词中”。
|
||||
|
||||
```
|
||||
$ echo "password" | cracklib-check
|
||||
password: it is based on a dictionary word
|
||||
```
|
||||
|
||||
Linux 中的默认密码长度为 7 个字符。如果你提供的密码少于 7 个字符,那么你将看到一条消息“它太短了”。
|
||||
|
||||
```
|
||||
$ echo "123" | cracklib-check
|
||||
123: it is WAY too short
|
||||
```
|
||||
|
||||
当你提供像我们这样的好密码时,你会看到 “OK”。
|
||||
|
||||
```
|
||||
$ echo "ME$2w!@fgty6723" | cracklib-check
|
||||
ME!@fgty6723: OK
|
||||
```
|
||||
|
||||
### 如何在 Linux 中安装 pwscore?
|
||||
|
||||
pwscore 包在大多数发行版仓库中都有,因此,请使用发行版官方软件包管理器来安装它。
|
||||
|
||||
对于 Fedora 系统,使用 [DNF 命令][1]来安装 libpwquality。
|
||||
|
||||
```
|
||||
$ sudo dnf install libpwquality
|
||||
```
|
||||
|
||||
对于 Debian/Ubuntu 系统,使用 [APT-GET 命令][2] 或 [APT 命令][3]来安装 libpwquality。
|
||||
|
||||
```
|
||||
$ sudo apt install libpwquality
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,使用 [Pacman 命令][4]来安装 libpwquality。
|
||||
|
||||
```
|
||||
$ sudo pacman -S libpwquality
|
||||
```
|
||||
|
||||
对于 RHEL/CentOS 系统,使用 [YUM 命令][5]来安装 libpwquality。
|
||||
|
||||
```
|
||||
$ sudo yum install libpwquality
|
||||
```
|
||||
|
||||
对于 openSUSE Leap 系统,使用 [Zypper 命令][6]来安装 libpwquality。
|
||||
|
||||
```
|
||||
$ sudo zypper install libpwquality
|
||||
```
|
||||
|
||||
如果你提供了任何如人名或地名或常用字,那么你将看到一条消息“它存在于字典的单词中”。
|
||||
|
||||
```
|
||||
$ echo "password" | pwscore
|
||||
Password quality check failed:
|
||||
The password fails the dictionary check - it is based on a dictionary word
|
||||
```
|
||||
|
||||
Linux 中的默认密码长度为 7 个字符。如果你提供的密码少于 7 个字符,那么你将看到一条消息“密码短于 8 个字符”。
|
||||
|
||||
```
|
||||
$ echo "123" | pwscore
|
||||
Password quality check failed:
|
||||
The password is shorter than 8 characters
|
||||
```
|
||||
|
||||
当你像我们这样提供了一个好的密码时,你将会看到“密码评分”。
|
||||
|
||||
```
|
||||
$ echo "ME!@fgty6723" | pwscore
|
||||
90
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-check-password-complexity-strength-and-score-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[2]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[3]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[4]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[5]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[6]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
@ -0,0 +1,199 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (FSSlc)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10635-1.html)
|
||||
[#]: subject: (How To Find Available Network Interfaces On Linux)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-find-available-network-interfaces-on-linux/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
如何在 Linux 中查看可用的网络接口
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/network-interface-720x340.jpeg)
|
||||
|
||||
在我们安装完一个 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
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/ip-command.png)
|
||||
|
||||
你也可以使用下面的命令来查看。
|
||||
|
||||
```
|
||||
$ ip addr
|
||||
```
|
||||
|
||||
```
|
||||
$ ip -s link
|
||||
```
|
||||
|
||||
你注意到了吗?这些命令同时还显示出了已经连接的网络接口的状态。假如你仔细查看上面的输出,你将注意到我的有线网卡并没有跟网络线缆连接(从上面输出中的 `DOWN` 可以看出)。另外,我的无线网卡已经连接了(从上面输出中的 `UP` 可以看出)。想知晓更多的细节,可以查看我们先前的指南 [在 Linux 中查看网络接口的已连接状态][1]。
|
||||
|
||||
这两个命令(`ifconfig` 和 `ip`)已经足够在你的 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 和 Unix 中配置静态 IP 地址][2]
|
||||
- [如何在 Ubuntu 18.04 LTS 中配置 IP 地址][3]
|
||||
- [如何在 Arch Linux 中配置静态和动态 IP 地址][4]
|
||||
- [如何在 Linux 中为单个网卡分配多个 IP 地址][5]
|
||||
|
||||
假如你知道其他快捷的方法来在 Linux 中找到可用的网络接口,请在下面的评论部分中分享出来,我将检查你们的评论并更新这篇指南。
|
||||
|
||||
这就是全部的内容了,更多精彩内容即将呈现,请保持关注!
|
||||
|
||||
干杯!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-find-available-network-interfaces-on-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[FSSlc](https://github.com/FSSlc)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/how-to-find-out-the-connected-state-of-a-network-cable-in-linux/
|
||||
[2]: https://www.ostechnix.com/configure-static-ip-address-linux-unix/
|
||||
[3]: https://www.ostechnix.com/how-to-configure-ip-address-in-ubuntu-18-04-lts/
|
||||
[4]: https://www.ostechnix.com/configure-static-dynamic-ip-address-arch-linux/
|
||||
[5]: https://www.ostechnix.com/how-to-assign-multiple-ip-addresses-to-single-network-card-in-linux/
|
@ -0,0 +1,75 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10620-1.html)
|
||||
[#]: subject: (Connecting a VoIP phone directly to an Asterisk server)
|
||||
[#]: via: (https://feeding.cloud.geek.nz/posts/connecting-voip-phone-directly-to-asterisk-server/)
|
||||
[#]: author: (François Marier https://fmarier.org/)
|
||||
|
||||
将 VoIP 电话直接连接到 Asterisk 服务器
|
||||
======
|
||||
|
||||
在我的 [Asterisk][1] 服务器上正好有张以太网卡。由于我只用了其中一个,因此我决定将我的 VoIP 电话从本地网络交换机换成连接到 Asterisk 服务器。
|
||||
|
||||
主要的好处是这台运行着未知质量的专有软件的电话,在我的一般家庭网络中不能用了。最重要的是,它不再能访问互联网,因此无需手动配置防火墙。
|
||||
|
||||
以下是我配置的方式。
|
||||
|
||||
### 私有网络配置
|
||||
|
||||
在服务器上,我在 `/etc/network/interfaces` 中给第二块网卡分配了一个静态 IP:
|
||||
|
||||
```
|
||||
auto eth1
|
||||
iface eth1 inet static
|
||||
address 192.168.2.2
|
||||
netmask 255.255.255.0
|
||||
```
|
||||
|
||||
在 VoIP 电话上,我将静态 IP 设置成 `192.168.2.3`,DNS 服务器设置成 `192.168.2.2`。我接着将 SIP 注册 IP 地址设置成 `192.168.2.2`。
|
||||
|
||||
DNS 服务器实际上是一个在 Asterisk 服务器上运行的 [unbound 守护进程][2]。我唯一需要更改的配置是监听第二张网卡,并允许 VoIP 电话进入:
|
||||
|
||||
```
|
||||
server:
|
||||
interface: 127.0.0.1
|
||||
interface: 192.168.2.2
|
||||
access-control: 0.0.0.0/0 refuse
|
||||
access-control: 127.0.0.1/32 allow
|
||||
access-control: 192.168.2.3/32 allow
|
||||
```
|
||||
|
||||
最后,我在 `/etc/network/iptables.up.rules` 中打开了服务器防火墙上的正确端口:
|
||||
|
||||
```
|
||||
-A INPUT -s 192.168.2.3/32 -p udp --dport 5060 -j ACCEPT
|
||||
-A INPUT -s 192.168.2.3/32 -p udp --dport 10000:20000 -j ACCEPT
|
||||
```
|
||||
|
||||
### 访问管理页面
|
||||
|
||||
现在 VoIP 电话不能在本地网络上用了,因此无法访问其管理页面。从安全的角度来看,这是一件好事,但它有点不方便。
|
||||
|
||||
因此,在通过 ssh 连接到 Asterisk 服务器之后,我将以下内容放在我的 `~/.ssh/config` 中以便通过 `http://localhost:8081` 访问管理页面:
|
||||
|
||||
```
|
||||
Host asterisk
|
||||
LocalForward 8081 192.168.2.3:80
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://feeding.cloud.geek.nz/posts/connecting-voip-phone-directly-to-asterisk-server/
|
||||
|
||||
作者:[François Marier][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fmarier.org/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.asterisk.org/
|
||||
[2]: https://feeding.cloud.geek.nz/posts/setting-up-your-own-dnssec-aware/
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10616-1.html)
|
||||
[#]: subject: (How to use sudo access in winSCP)
|
||||
[#]: via: (https://kerneltalks.com/tools/how-to-use-sudo-access-in-winscp/)
|
||||
[#]: author: (kerneltalks https://kerneltalks.com)
|
||||
@ -10,9 +10,11 @@
|
||||
如何在 winSCP 中使用 sudo
|
||||
======
|
||||
|
||||
用截图了解如何在 winSCP 中使用 sudo
|
||||
> 用截图了解如何在 winSCP 中使用 sudo。
|
||||
|
||||
![How to use sudo access in winSCP][1]sudo access in winSCP
|
||||
![How to use sudo access in winSCP][1]
|
||||
|
||||
*sudo access in winSCP*
|
||||
|
||||
首先你需要检查你尝试使用 winSCP 连接的 sftp 服务器的二进制文件的位置。
|
||||
|
||||
@ -28,18 +30,20 @@ Subsystem sftp /usr/libexec/openssh/sftp-server
|
||||
打开 winSCP 并单击“高级”按钮打开高级设置。
|
||||
|
||||
![winSCP advance settings][2]
|
||||
winSCP 高级设置
|
||||
|
||||
它将打开如下高级设置窗口。在左侧面板上选择`环境`下的 `SFTP`。你会在右侧看到选项。
|
||||
*winSCP 高级设置*
|
||||
|
||||
它将打开如下高级设置窗口。在左侧面板上选择“Environment”下的 “SFTP”。你会在右侧看到选项。
|
||||
|
||||
现在,使用命令 `sudo su -c` 在这里添加 SFTP 服务器值,如下截图所示:
|
||||
|
||||
![SFTP server setting in winSCP][3]
|
||||
winSCP 中的 SFTP 服务器设置
|
||||
|
||||
所以我们在设置中添加了 `sudo su -c /usr/libexec/openssh/sftp-server`。单击“确定”并像平常一样连接到服务器。
|
||||
*winSCP 中的 SFTP 服务器设置*
|
||||
|
||||
连接之后,你将可以从需要 sudo 权限的目录传输文件了。
|
||||
所以我们在设置中添加了 `sudo su -c /usr/libexec/openssh/sftp-server`。单击“Ok”并像平常一样连接到服务器。
|
||||
|
||||
连接之后,你将可以从你以前需要 sudo 权限的目录传输文件了。
|
||||
|
||||
完成了!你已经使用 winSCP 使用 sudo 登录服务器了。
|
||||
|
||||
@ -50,7 +54,7 @@ via: https://kerneltalks.com/tools/how-to-use-sudo-access-in-winscp/
|
||||
作者:[kerneltalks][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,21 +1,22 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "qhwdw"
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
[#]: reviewer: "wxy"
|
||||
[#]: publisher: "wxy"
|
||||
[#]: url: "https://linux.cn/article-10615-1.html"
|
||||
[#]: subject: "How to buy a Raspberry Pi"
|
||||
[#]: via: "https://opensource.com/article/19/3/how-buy-raspberry-pi"
|
||||
[#]: author: "Anderson Silva https://opensource.com/users/ansilva"
|
||||
|
||||
如何购买一个树莓派
|
||||
树莓派使用入门:如何购买一个树莓派
|
||||
======
|
||||
在我们的《树莓派入门指南》系列文章的第二篇中,我们将介绍获取树莓派的最佳途径。
|
||||
|
||||
> 在我们的《树莓派使用入门》系列文章的第二篇中,我们将介绍获取树莓派的最佳途径。
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/open_business_sign_store.jpg?itok=g4QibRqg)
|
||||
|
||||
在本系列指南的第一篇文章中,我们提供了一个关于 [你应该购买哪个版本的树莓派][1] 的一些建议。哪个版本才是你想要的,你应该有了主意了,现在,我们来看一下如何获得它。
|
||||
|
||||
最显而易见的方式— 并且也或许是最安全最简单的方式 —非[树莓派的官方网站][2] 莫属了。如果你从官网主页上点击“Buy a Raspberry Pi”,它将跳转到官方的 [在线商店][3],在那里,它可以给你提供你的国家所在地的授权销售商。如果你的国家没有在清单中,还有一个“其它”选项,它可以提供国际订购。
|
||||
最显而易见的方式 —— 并且也或许是最安全最简单的方式 —— 非 [树莓派的官方网站][2] 莫属了。如果你从官网主页上点击 “Buy a Raspberry Pi”,它将跳转到官方的 [在线商店][3],在那里,它可以给你提供你的国家所在地的授权销售商。如果你的国家没有在清单中,还有一个“其它”选项,它可以提供国际订购。
|
||||
|
||||
第二,查看亚马逊或在你的国家里允许销售新的或二手商品的其它主流技术类零售商。鉴于树莓派比较便宜并且尺寸很小,一些小商家基于转售目的的进出口它,应该是非常容易的。在你下订单时,一定要关注对卖家的评价。
|
||||
|
||||
@ -23,11 +24,11 @@
|
||||
|
||||
### 不要忘了外设
|
||||
|
||||
最后一个建设是:不要忘了外设,你将需要一些外设去配置和操作你的树莓派。至少你会用到键盘、一个 HDMI 线缆去连接显示器、一个 Micro SD 卡去安装操作系统,一个供电线、以及一个好用的鼠标。
|
||||
最后一个建设是:不要忘了外设,你将需要一些外设去配置和操作你的树莓派。至少你会用到键盘、一个 HDMI 线缆去连接显示器、一个 Micro SD 卡去安装操作系统,一个电源线、以及一个好用的鼠标。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/raspberrypi_2a_pi0w-kit.jpg)
|
||||
|
||||
如果你没有准备好这些东西,试着从朋友那儿借用,或与树莓派一起购买。你可以从授权的树莓派销售商那儿考虑订购一个起步套装 — 它可以让你避免查找的麻烦而一次性搞定。
|
||||
如果你没有准备好这些东西,试着从朋友那儿借用,或与树莓派一起购买。你可以从授权的树莓派销售商那儿考虑订购一个起步套装 —— 它可以让你避免查找的麻烦而一次性搞定。
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/raspberrypi_2b_pi3b.jpg)
|
||||
|
||||
@ -40,12 +41,12 @@ via: https://opensource.com/article/19/3/how-buy-raspberry-pi
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/2/which-raspberry-pi-should-you-get
|
||||
[1]: https://linux.cn/article-10611-1.html
|
||||
[2]: https://www.raspberrypi.org/
|
||||
[3]: https://www.raspberrypi.org/products/
|
@ -0,0 +1,65 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10629-1.html)
|
||||
[#]: subject: (How To Fix “Network Protocol Error” On Mozilla Firefox)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-fix-network-protocol-error-on-mozilla-firefox/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
如何修复 Mozilla Firefox 中出现的 “Network Protocol Error”
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/03/firefox-logo-1-720x340.png)
|
||||
|
||||
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.
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/03/firefox.png)
|
||||
|
||||
老实说,我有点慌,我以为可能是我的系统受到了某种恶意软件的影响。哈哈!但是我发现我错了。我在 Arch Linux 桌面上使用的是最新的 Firefox 版本,我在 Chromium 浏览器中打开了相同的链接,它正确显示了,我猜这是 Firefox 相关的错误。在谷歌上搜索后,我解决了这个问题,如下所述。
|
||||
|
||||
出现这种问题主要是因为“浏览器缓存”,如果你遇到此类错误,例如 “Network Protocol Error” 或 “Corrupted Content Error”,遵循以下任何一种方法。
|
||||
|
||||
**方法 1:**
|
||||
|
||||
要修复 “Network Protocol Error” 或 “Corrupted Content Error”,你需要在重新加载网页时绕过缓存。为此,按下 `Ctrl + F5` 或 `Ctrl + Shift + R` 快捷键,它将从服务器重新加载页面,而不是从 Firefox 缓存加载。这样网页就应该可以正常工作了。
|
||||
|
||||
**方法 2:**
|
||||
|
||||
如果方法 1 不起作用,尝试以下方法。
|
||||
|
||||
打开 “Edit - > Preferences”,在 “Preferences” 窗口中,打开左窗格中的 “Privacy & Security” 选项卡,单击 “Clear Data” 选项清除 Firefox 缓存。
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/03/firefox-1.png)
|
||||
|
||||
确保你选中了 “Cookies and Site Data” 和 “Cached Web Content” 选项,然后单击 “Clear”。
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/03/firefox-2.png)
|
||||
|
||||
完成!现在 Cookie 和离线内容将被删除。注意,Firefox 可能会将你从登录的网站中注销,稍后你可以重新登录这些网站。最后,关闭 Firefox 浏览器并重新启动系统。现在网页加载没有任何问题。
|
||||
|
||||
希望这对你有帮助。更多好东西要来了,敬请关注!
|
||||
|
||||
干杯!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-fix-network-protocol-error-on-mozilla-firefox/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[MjSeven](https://github.com/MjSeven)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
100
sources/talk/20190306 How to pack an IT travel kit.md
Normal file
100
sources/talk/20190306 How to pack an IT travel kit.md
Normal file
@ -0,0 +1,100 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to pack an IT travel kit)
|
||||
[#]: via: (https://opensource.com/article/19/3/it-toolkit-remote)
|
||||
[#]: author: (Peter Cheer https://opensource.com/users/petercheer)
|
||||
|
||||
How to pack an IT travel kit
|
||||
======
|
||||
Before you travel, make sure you're ready for challenges in hardware, infrastructure, and software.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/tools_sysadmin_cloud.png?itok=sUciG0Cn)
|
||||
|
||||
I've had several opportunities to do IT work in less-developed and remote areas, where internet coverage and technology access aren't at the high level we have in our first-world cities. Many people heading off to undeveloped areas ask me for advice on preparing for the local technology landscape. Since conditions vary greatly around this big world, it's impossible to give specific advice for most areas, but I do have some general suggestions based on my experience that may help you.
|
||||
|
||||
Also, before you leave home, do as much research as you can about the general IT and telecom environment where you are traveling so you're a little better prepared for what you may encounter there.
|
||||
|
||||
### Planning for the local hardware and infrastructure
|
||||
|
||||
* Even in many cities, internet connections tend to be expensive, slow, and not reliable for large downloads. Don't forget that internet coverage, speeds, and cost in cities are unlikely to be matched in more remote areas.
|
||||
|
||||
|
||||
* The electricity supply may be unreliable with inconsistent voltage. If you are taking your computer, bring some surge protection—although in my experience, the electricity voltage is more likely to drop than to spike.
|
||||
|
||||
|
||||
* It is always useful to have a small selection of hand tools, such as screwdrivers and needle-nose pliers, for repairing computer hardware. A lack of spare parts can limit opportunities for much beyond basic troubleshooting, although stripping usable components from dead computers can be worthwhile.
|
||||
|
||||
|
||||
|
||||
### Planning for the software you'll find
|
||||
|
||||
* You can assume that most of the computer systems you'll find will be some incarnation of Microsoft Windows. You can expect that many will not be officially licensed, not be getting updates nor security patches, and are infected by multiple viruses and other malware.
|
||||
|
||||
|
||||
* You can also expect that most application software will be proprietary and much of it will be unlicensed and lag behind the latest release versions. These conditions are depressing for open source enthusiasts, but this is the world as it is, rather than the world we would like it to be.
|
||||
|
||||
|
||||
* It is wise to view any Windows system you do not control as potentially infected with viruses and malware. It's good practice to reserve a USB thumb drive for files you'll use with these Windows systems; this means that if (or more likely when) that thumb drive becomes infected, you can just reformat it at no cost.
|
||||
|
||||
|
||||
* Bring copies of free antivirus software such as [AVG][1] and [Avast][2], including recent virus definition files for them, as well as virus removal and repair tools such as [Sophos][3] and [Hirens Boot CD][4].
|
||||
|
||||
|
||||
* Trying to keep software current on machines that have no or infrequent access to the internet is a challenge. This is particularly true with web browsers, which tend to go through rapid release cycles. My preferred web browser is Mozilla Firefox and having a copy of the latest release is useful.
|
||||
|
||||
|
||||
* Bring repair discs for a selection of recent Microsoft operating systems, and make sure that includes service packs for Windows and Microsoft Office.
|
||||
|
||||
|
||||
|
||||
### Planning for the software you'll bring
|
||||
|
||||
There's no better way to convey the advantages of open source software than by showing it to people. Here are some recommendations along that line.
|
||||
|
||||
* When gathering software to take with you, make sure you get the full offline installation option. Often, the most prominently displayed download links on websites are stubs that require internet access to download the components. They won't work if you're in an area with poor (or no) internet service.
|
||||
|
||||
|
||||
* Also, make sure to get the 32-bit and 64-bit versions of the software. While 32-bit machines are becoming less common, you may encounter them and it's best to be prepared.
|
||||
|
||||
|
||||
* Having a [bootable version of Linux][5] is vital for two reasons. First, it can be used to rescue data from a seriously damaged Windows machine. Second, it's an easy way to show off Linux without installing it on someone's machine. [Linux Mint][6] is my favorite distro for this purpose, because the graphical interface (GUI) is similar enough to Windows to appear non-threatening and it includes a good range of application software.
|
||||
|
||||
|
||||
* Bring the widest selection of open source applications you can—you can't count on being able to download something from the internet.
|
||||
|
||||
|
||||
* When possible, bring your open source software library as portable applications that will run without installing them. One of the many ways to mess up those Windows machines is to install and uninstall a lot of software, and using portable apps gets around this problem. Many open source applications, including Libre Office, GIMP, Blender, and Inkscape, have portable app versions for Windows.
|
||||
|
||||
|
||||
* It's smart to bring a supply of blank disks so you can give away copies of your open source software stash on media that is a bit more secure than a USB thumb drive.
|
||||
|
||||
|
||||
* Don't forget to bring programs and resources related to projects you will be working on. (For example, most of my overseas work involves tuition, mentoring, and skills transfer, so I usually add a selection of open source software tools for creating learning resources.)
|
||||
|
||||
|
||||
|
||||
### Your turn
|
||||
|
||||
There are many variables and surprises when doing IT work in undeveloped areas. If you have suggestions—for programs I've missed or tips that I didn't cover—please share them in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/it-toolkit-remote
|
||||
|
||||
作者:[Peter Cheer][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/petercheer
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.avg.com/en-gb/free-antivirus-download
|
||||
[2]: https://www.avast.com/en-gb/free-antivirus-download
|
||||
[3]: https://www.sophos.com/en-us/products/free-tools/virus-removal-tool.aspx
|
||||
[4]: https://www.hiren.info/
|
||||
[5]: https://opensource.com/article/18/7/getting-started-etcherio
|
||||
[6]: https://linuxmint.com/
|
106
sources/talk/20190307 Small Scale Scrum vs. Large Scale Scrum.md
Normal file
106
sources/talk/20190307 Small Scale Scrum vs. Large Scale Scrum.md
Normal file
@ -0,0 +1,106 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Small Scale Scrum vs. Large Scale Scrum)
|
||||
[#]: via: (https://opensource.com/article/19/3/small-scale-scrum-vs-large-scale-scrum)
|
||||
[#]: author: (Agnieszka Gancarczyk https://opensource.com/users/agagancarczyk)
|
||||
|
||||
Small Scale Scrum vs. Large Scale Scrum
|
||||
======
|
||||
We surveyed individual members of small and large scrum teams. Here are some key findings.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_crowdvsopen.png?itok=AFjno_8v)
|
||||
|
||||
Following the publication of the [Small Scale Scrum framework][1], we wanted to collect feedback on how teams in our target demographic (consultants, open source developers, and students) work and what they value. With this first opportunity to inspect, adapt, and help shape the next stage of Small Scale Scrum, we decided to create a survey to capture some data points and begin to validate some of our assumptions and hypotheses.
|
||||
|
||||
**[[Download the Introduction to Small Scale Scrum guide]][2]**
|
||||
|
||||
Our reasons for using the survey were multifold, but chief among them were the global distribution of teams, the small local data sample available in our office, access to customers, and the industry’s utilization of surveys (e.g., the [Stack Overflow Developer Survey 2018][3], [HackerRank 2018 Developer Skills Report][4], and [GitLab 2018 Global Developer Report][5]).
|
||||
|
||||
The scrum’s iterative process was used to facilitate the creation of the survey shown below:
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/survey_process.png)
|
||||
|
||||
[The survey][6], which we invite you to complete, consisted of 59 questions and was distributed at a local college ([Waterford Institute of Technology][7]) and to Red Hat's consultancy and engineering teams. Our initial data was gathered from the responses of 54 individuals spread across small and large scrum teams, who were asked about their experiences with agile within their teams.
|
||||
|
||||
Here are the main results and initial findings of the survey:
|
||||
|
||||
* A full 96% of survey participants practice a form of agile, work in distributed teams, think scrum principles help them reduce development complexity, and believe agile contributes to the success of their projects.
|
||||
|
||||
* Only 8% of survey participants belong to small (one- to three-person) teams, and 10 out of 51 describe their typical project as short-lived (three months or less).
|
||||
|
||||
* The majority of survey participants were software engineers, but quality engineers (QE), project managers (PM), product owners (PO), and scrum masters were also represented.
|
||||
|
||||
* Scrum master, PO, and team member are typical roles in projects.
|
||||
|
||||
* Nearly half of survey respondents work on, or are assigned to, more than one project at the same time.
|
||||
|
||||
* Almost half of projects are customer/value-generating vs. improvement/not directly value-generating or unclassified.
|
||||
|
||||
* Almost half of survey participants said that their work is clarified sometimes or most of the time and estimated before development with extensions available sometimes or most of the time. They said asking for clarification of work items is the team’s responsibility.
|
||||
|
||||
* Almost half of survey respondents said they write tests for their code, and they adhere to best coding practices, document their code, and get their code reviewed before merging.
|
||||
|
||||
* Almost all survey participants introduce bugs to the codebase, which are prioritized by them, the team, PM, PO, team lead, or the scrum master.
|
||||
|
||||
* Participants ask for help and mentoring when a task is complex. They also take on additional roles on their projects when needed, including business analyst, PM, QE, and architect, and they sometimes find changing roles difficult.
|
||||
|
||||
* When changing roles on a daily basis, individuals feel they lose one to two hours on average, but they still complete their work on time most of the time.
|
||||
|
||||
* Most survey participants use scrum (65%), followed by hybrid (18%) and Kanban (12%). This is consistent with results of [VersionOne’s State of Agile Report][8].
|
||||
|
||||
* The daily standup, sprint, sprint planning and estimating, backlog grooming, and sprint retrospective are among the top scrum ceremonies and principles followed, and team members do preparation work before meetings.
|
||||
|
||||
* The majority of sprints (62%) are three weeks long, followed by two-week sprints (26%), one-week sprints (6%), and four-week sprints (4%). Two percent of participants are not using sprints due to strict release and update timings, with all activities organized and planned around those dates.
|
||||
|
||||
* Teams use [planning poker][9] to estimate (storypoint) user stories. User stories contain acceptance criteria.
|
||||
|
||||
* Teams create and use a [Definition of Done][10] mainly in respect to features and determining completion of user stories.
|
||||
|
||||
* The majority of teams don’t have or use a [Definition of Ready][11] to ensure that user stories are actionable, testable, and clear.
|
||||
|
||||
* Unit, integration, functional, automated, performance/load, and acceptance tests are commonly used.
|
||||
|
||||
* Overall collaboration between team members is considered high, and team members use various communication channels.
|
||||
|
||||
* The majority of survey participants spend more than four hours weekly in meetings, including face-to-face meetings, web conferences, and email communication.
|
||||
|
||||
* The majority of customers are considered large, and half of them understand and follow scrum principles.
|
||||
|
||||
* Customers respect “no deadlines” most of the time and sometimes help create user stories and participate in sprint planning, sprint review and demonstration, sprint retrospective, and backlog review and refinement.
|
||||
|
||||
* Only 27% of survey participants know their customers have a high level of satisfaction with the adoption of agile, while the majority (58%) don’t know this information at all.
|
||||
|
||||
|
||||
|
||||
|
||||
These survey results will inform the next stage of our data-gathering exercise. We will apply Small Scale Scrum to real-world projects, and the guidance obtained from the survey will help us gather key data points as we move toward version 2.0 of Small Scale Scrum. If you want to help, take our [survey][6]. If you have a project to which you'd like to apply Small Scale Scrum, please get in touch.
|
||||
|
||||
[Download the Introduction to Small Scale Scrum guide][2]
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/small-scale-scrum-vs-large-scale-scrum
|
||||
|
||||
作者:[Agnieszka Gancarczyk][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/agagancarczyk
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/2/small-scale-scrum-framework
|
||||
[2]: https://opensource.com/downloads/small-scale-scrum
|
||||
[3]: https://insights.stackoverflow.com/survey/2018/
|
||||
[4]: https://research.hackerrank.com/developer-skills/2018/
|
||||
[5]: https://about.gitlab.com/developer-survey/2018/
|
||||
[6]: https://docs.google.com/forms/d/e/1FAIpQLScAXf52KMEiEzS68OOIsjLtwZJto_XT7A3b9aB0RhasnE_dEw/viewform?c=0&w=1
|
||||
[7]: https://www.wit.ie/
|
||||
[8]: https://explore.versionone.com/state-of-agile/versionone-12th-annual-state-of-agile-report
|
||||
[9]: https://en.wikipedia.org/wiki/Planning_poker
|
||||
[10]: https://www.scruminc.com/definition-of-done/
|
||||
[11]: https://www.scruminc.com/definition-of-ready/
|
45
sources/talk/20190311 Discuss everything Fedora.md
Normal file
45
sources/talk/20190311 Discuss everything Fedora.md
Normal file
@ -0,0 +1,45 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Discuss everything Fedora)
|
||||
[#]: via: (https://fedoramagazine.org/discuss-everything-fedora/)
|
||||
[#]: author: (Ryan Lerch https://fedoramagazine.org/introducing-flatpak/)
|
||||
|
||||
Discuss everything Fedora
|
||||
======
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2019/03/fedora-discussion-816x345.jpg)
|
||||
|
||||
Are you interested in how Fedora is being developed? Do you want to get involved, or see what goes into making a release? You want to check out [Fedora Discussion][1]. It is a relatively new place where members of the Fedora Community meet to discuss, ask questions, and interact. Keep reading for more information.
|
||||
|
||||
Note that the Fedora Discussion system is mainly aimed at contributors. If you have questions on using Fedora, check out [Ask Fedora][2] (which is being migrated in the future).
|
||||
|
||||
![][3]
|
||||
|
||||
Fedora Discussion is a forum and discussion site that uses the [Discourse open source discussion platform][4].
|
||||
|
||||
There are already several categories useful for Fedora users, including [Desktop][5] (covering Fedora Workstation, Fedora Silverblue, KDE, XFCE, and more) and the [Server, Cloud, and IoT][6] category . Additionally, some of the [Fedora Special Interest Groups (SIGs) have discussions as well][7]. Finally, the [Fedora Friends][8] category helps you connect with other Fedora users and Community members by providing discussions about upcoming meetups and hackfests.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/discuss-everything-fedora/
|
||||
|
||||
作者:[Ryan Lerch][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/introducing-flatpak/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://discussion.fedoraproject.org/
|
||||
[2]: https://ask.fedoraproject.org
|
||||
[3]: https://fedoramagazine.org/wp-content/uploads/2019/03/discussion-screenshot-1024x663.png
|
||||
[4]: https://www.discourse.org/about
|
||||
[5]: https://discussion.fedoraproject.org/c/desktop
|
||||
[6]: https://discussion.fedoraproject.org/c/server
|
||||
[7]: https://discussion.fedoraproject.org/c/sigs
|
||||
[8]: https://discussion.fedoraproject.org/c/friends
|
@ -0,0 +1,65 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (When the web grew up: A browser story)
|
||||
[#]: via: (https://opensource.com/article/19/3/when-web-grew)
|
||||
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
|
||||
|
||||
When the web grew up: A browser story
|
||||
======
|
||||
A personal story of when the internet came of age.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_Internet_Sign.png?itok=5MFGKs14)
|
||||
|
||||
Recently, I [shared how][1] upon leaving university in 1994 with a degree in English literature and theology, I somehow managed to land a job running a web server in a world where people didn't really know what a web server was yet. And by "in a world," I don't just mean within the organisation in which I worked, but the world in general. The web was new—really new—and people were still trying to get their heads around it.
|
||||
|
||||
That's not to suggest that the place where I was working—an academic publisher—particularly "got it" either. This was a world in which a large percentage of the people visiting their website were still running 28k8 modems. I remember my excitement in getting a 33k6 modem. At least we were past the days of asymmetric upload/download speeds,1 where 1200/300 seemed like an eminently sensible bandwidth description. This meant that the high-design, high-colour, high-resolution documents created by the print people (with whom I shared a floor) were completely impossible on the web. I wouldn't allow anything bigger than a 40k GIF on the front page of the website, and that was pushing it for many of our visitors. Anything larger than 60k or so would be explicitly linked as a standalone image from a thumbnail on the referring page.
|
||||
|
||||
To say that the marketing department didn't like this was an understatement. Even worse was the question of layout. "Browsers decide how to lay out documents," I explained, time after time, "you can use headers or paragraphs, but how documents appear on the page isn't defined by the document, but by the renderer!" They wanted control. They wanted different coloured backgrounds. After a while, they got that. I went to what I believe was the first W3C meeting at which the idea of Cascading Style Sheets (CSS) was discussed. And argued vehemently against them. The suggestion that document writers should control layout was anathema.2 It took some while for CSS to be adopted, and in the meantime, those who cared about such issues adopted the security trainwreck that was Portable Document Format (PDF).
|
||||
|
||||
How documents were rendered wasn't the only issue. Being a publisher of actual physical books, the whole point of having a web presence, as far as the marketing department was concerned, was to allow customers—or potential customers—to know not only what a book was about, but also how much it was going to cost them to buy. This, however, presented a problem. You see, the internet—in which I include the rapidly growing World Wide Web—was an open, free-for-all libertarian sort of place where nobody was interested in money; in fact, where talk of money was to be shunned and avoided.
|
||||
|
||||
I took the mainstream "Netizen" view that there was no place for pricing information online. My boss—and, indeed, pretty much everybody else in the organisation—took a contrary view. They felt that customers should be able to see how much books would cost them. They also felt that my bank manager would like to see how much money was coming into my bank account on a monthly basis, which might be significantly reduced if I didn't come round to their view.
|
||||
|
||||
Luckily, by the time I'd climbed down from my high horse and got over myself a bit—probably only a few weeks after I'd started digging my heels in—the web had changed, and there were other people putting pricing information up about their products. These newcomers were generally looked down upon by the old schoolers who'd been running web servers since the early days,3 but it was clear which way the wind was blowing. This didn't mean that the battle was won for our website, however. As an academic publisher, we shared an academic IP name ("ac.uk") with the University. The University was less than convinced that publishing pricing information was appropriate until some senior folks at the publisher pointed out that Princeton University Press was doing it, and wouldn't we look a bit silly if…?
|
||||
|
||||
The fun didn't stop there, either. A few months into my tenure as webmaster ("webmaster@…"), we started to see a worrying trend, as did lots of other websites. Certain visitors were single-handedly bringing our webserver to its knees. These visitors were running a new web browser: Netscape. Netscape was badly behaved. Netscape was multi-threaded.
|
||||
|
||||
Why was this an issue? Well, before Netscape, all web browsers had been single-threaded. They would open one connection at a time, so even if you had, say five GIFs on a page,4 they would request the HTML base file, parse that, then download the first GIF, complete that, then the second, complete that, and so on. In fact, they often did the GIFs in the wrong order, which made for very odd page loading, but still, that was the general idea. The rude people at Netscape decided that they could open multiple connections to the webserver at a time to request all the GIFs at the same time, for example! And why was this a problem? Well, the problem was that most webservers were single-threaded. They weren't designed to have multiple connections open at any one time. Certainly, the HTTP server that we ran (MacHTTP) was single-threaded. Even though we had paid for it (it was originally shareware), the version we had couldn't cope with multiple requests at a time.
|
||||
|
||||
The debate raged across the internet. Who did these Netscape people think they were, changing how the world worked? How it was supposed to work? The world settled into different camps, and as with all technical arguments, heated words were exchanged on both sides. The problem was that not only was Netscape multi-threaded, it was also just better than the alternatives. Lots of web server code maintainers, MacHTTP author Chuck Shotton among them, sat down and did some serious coding to produce multi-threaded beta versions of their existing code. Everyone moved almost immediately to the beta versions, they got stable, and in the end, single-threaded browsers either adapted and became multi-threaded themselves, or just went the way of all outmoded products and died a quiet death.6
|
||||
|
||||
This, for me, is when the web really grew up. It wasn't prices on webpages nor designers being able to define what you'd see on a page,8 but rather when browsers became easier to use and when the network effect of thousands of viewers moving to many millions tipped the balance in favour of the consumer, not the producer. There were more steps in my journey—which I'll save for another time—but from around this point, my employers started looking at our monthly, then weekly, then daily logs, and realising that this was actually going to be something big and that they'd better start paying some real attention.
|
||||
|
||||
1\. How did they come back, again?
|
||||
|
||||
2\. It may not surprise you to discover that I'm still happiest at the command line.
|
||||
|
||||
3\. About six months before.
|
||||
|
||||
4\. Reckless, true, but it was beginning to happen.5
|
||||
|
||||
5\. Oh, and no—it was GIFs or BMP. JPEG was still a bright idea that hadn't yet taken off.
|
||||
|
||||
6\. It's never actually quiet: there are always a few diehard enthusiasts who insist that their preferred solution is technically superior and bemoan the fact that the rest of the internet has gone to the devil.7
|
||||
|
||||
7\. I'm not one to talk: I still use Lynx from time to time.
|
||||
|
||||
8\. Creating major and ongoing problems for those with different accessibility needs, I would point out.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/when-web-grew
|
||||
|
||||
作者:[Mike Bursell][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mikecamel
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/18/11/how-web-was-won
|
104
sources/talk/20190313 Why is no one signing their emails.md
Normal file
104
sources/talk/20190313 Why is no one signing their emails.md
Normal file
@ -0,0 +1,104 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Why is no one signing their emails?)
|
||||
[#]: via: (https://arp242.net/weblog/signing-emails.html)
|
||||
[#]: author: (Martin Tournoij https://arp242.net/)
|
||||
|
||||
Why is no one signing their emails?
|
||||
======
|
||||
|
||||
|
||||
I received this email a while ago:
|
||||
|
||||
> Queensland University of Technology sent you an Amazon.com Gift Card!
|
||||
>
|
||||
> You’ve received an Amazon.com gift card! You’ll need the claim code below to place your order.
|
||||
>
|
||||
> Happy shopping!
|
||||
|
||||
Queensland University of Technology? Why would they send me anything? Where is that even? Australia right? That’s the other side of the world! Looks like spam!
|
||||
|
||||
It did look pretty good for spam, so I took a second look. And a very close third look, and then I decided it wasn’t spam.
|
||||
|
||||
I was still confused why they sent me this. A week later I remembered: half a year prior I had done an interview regarding my participation on Stack Overflow for someone’s paper; she was studying somewhere in Australia – presumably the university of Queensland. No one had ever mentioned anything about a reward or Amazon gift card so I wasn’t expecting it. It’s a nice bonus though.
|
||||
|
||||
Here’s the thing: I’ve spent several years professionally developing email systems; I administered email servers; I read all the relevant RFCs. While there are certainly people who are more knowledgable, I know more about email than the vast majority of the population. And I still had to take a careful look to verify the email wasn’t a phishing attempt.
|
||||
|
||||
And I’m not even a target; I’m just this guy, you know? [Ask John Podesta what it is to be targeted][1]:
|
||||
|
||||
> SecureWorks concluded Fancy Bear had sent Podesta an email on March 19, 2016, that had the appearance of a Google security alert, but actually contained a misleading link—a strategy known as spear-phishing. [..] The email was initially sent to the IT department as it was suspected of being a fake but was described as “legitimate” in an e-mail sent by a department employee, who later said he meant to write “illegitimate”.
|
||||
|
||||
Yikes! If I was even remotely high-profile I’d be crazy paranoid about all emails I get.
|
||||
|
||||
It seems to me that there is a fairly easy solution to verify the author of an email: sign it with a digital signature; PGP is probably the best existing solution right now. I don’t even care about encryption here, just signing to prevent phishing.
|
||||
|
||||
PGP has a well-deserved reputation for being hard, but that’s only for certain scenarios. A lot of the problems/difficulties stem from trying to accommodate the “random person A emails random person B” use case, but this isn’t really what I care about here. “Large company with millions of users sends thousands of emails daily” is a very different use case.
|
||||
|
||||
Much of the key exchange/web-of-trust dilemma can be bypassed by shipping email clients with keys for large organisations (PayPal, Google, etc.) baked in, like browsers do with some certificates. Even just publishing your key on your website (or, if you’re a bank, in local branches etc.) is already a lot better than not signing anything at all. Right now there seems to be a catch-22 scenario: clients don’t implement better support as very few people are using PGP, while very few companies bother signing their emails with PGP because so few people can benefit from it.
|
||||
|
||||
On the end-user side, things are also not very hard; we’re just conceded with validating signatures, nothing more. For this purpose PGP isn’t hard. It’s like verifying your Linux distro’s package system: all of them sign their packages (usually with PGP) and they get verified on installation, but as an end-user I never see it unless something goes wrong.
|
||||
|
||||
There are many aspects of PGP that are hard to set up and manage, but verifying signatures isn’t one of them. The user-visible part of this is very limited. Remember, no one is expected to sign their own emails: just verify that the signature is correct (which the software will do). Conceptually, it’s not that different from verifying a handwritten signature.
|
||||
|
||||
DKIM and SPF already exist and are useful, but limited. All both do is verify that an email which claims to be from `amazon.com` is really from `amazon.com`. If I send an email from `mail.amazon-account-security.com` or `amazonn.com` then it just verifies that it was sent from that domain, not that it was sent from the organisation Amazon.
|
||||
|
||||
What I am proposing is subtly different. In my (utopian) future every serious organisation will sign their email with PGP (just like every serious organisation uses https). Then every time I get an email which claims to be from Amazon I can see it’s either not signed, or not signed by a key I know. If adoption is broad enough we can start showing warnings such as “this email wasn’t signed, do you want to trust it?” and “this signature isn’t recognized, yikes!”
|
||||
|
||||
There’s also S/MIME, which has better client support and which works more or less the same as HTTPS: you get a certificate from the Certificate Authority Mafia, sign your email with it, and presto. The downside of this is that anyone can sign their emails with a valid key, which isn’t necessarily telling you much (just because haxx0r.ru has a certificate doesn’t mean it’s trustworthy).
|
||||
|
||||
Is it perfect? No. I understand stuff like key exchange is hard and that baking in keys isn’t perfect. Is it better? Hell yes. Would probably have avoided Podesta and the entire Democratic Party a lot of trouble. Here’s a “[sophisticated new phishing campaign][2]” targeted at PayPal users. How “sophisticated”? Well, by not having glaring stupid spelling errors, duplicating the PayPal layout in emails, duplicating the PayPal login screen, a few forms, and getting an SSL certificate. Truly, the pinnacle of Computer Science.
|
||||
|
||||
Okay sure, they spent some effort on it; but any nincompoop can do it; if this passes for “sophisticated phishing” where “it’s easy to see how users could be fooled” then the bar is pretty low.
|
||||
|
||||
I can’t recall receiving a single email from any organisation that is signed (much less encrypted). Banks, financial services, utilities, immigration services, governments, tax services, voting registration, Facebook, Twitter, a zillion websites … all happily sent me emails hoping I wouldn’t consider them spam and hoping I wouldn’t confuse a phishing email for one of theirs.
|
||||
|
||||
Interesting experiment: send invoices for, say, a utility bill for a local provider. Just copy the layout from the last utility bill you received. I’ll bet you’ll make more money than freelancing on UpWork if you do it right.
|
||||
|
||||
I’ve been intending to write this post for years, but never quite did because “surely not everyone is stupid?” I’m not a crypto expert, so perhaps I’m missing something here, but I wouldn’t know what. Let me know if I am.
|
||||
|
||||
In the meanwhile PayPal is attempting to solve the problem by publishing [articles which advise you to check for spelling errors][3]. Okay, it’s good advice, but do we really want this to be the barrier between an attacker and your money? Or Russian hacking groups and your emails? Anyone can sign any email with any key, but “unknown signature” warnings strike me as a lot better UX than “carefully look for spelling errors or misleading domain names”.
|
||||
|
||||
The way forward is to make it straight-forward to implement signing in apps and then just do it as a developer, whether asked or not; just as you set up https whether you’re asked or not. I’ll write a follow-up with more technical details later, assuming no one pokes holes in this article :-)
|
||||
|
||||
#### Response to some feedback
|
||||
|
||||
Some response to some feedback that I couldn’t be bothered to integrate in the article’s prose:
|
||||
|
||||
* “You can’t trust webmail with crypto!”
|
||||
If you use webmail then you’re already trusting the email provider with everything. What’s so bad with trusting them to verify a signature, too?
|
||||
|
||||
We’re not communicating state secrets over encrypted email here; we’re just verifying the signature on “PayPal sent you a message, click here to view it”-kind of emails.
|
||||
|
||||
* “Isn’t this ignoring the massive problem that is key management?”
|
||||
Yes, it’s hard problem; but that doesn’t mean it can’t be done. I already mentioned some possible solutions in the article.
|
||||
|
||||
|
||||
|
||||
|
||||
**Footnotes**
|
||||
|
||||
1. We could make something better; PGP contians a lot of cruft. But for now PGP is “good enough”.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://arp242.net/weblog/signing-emails.html
|
||||
|
||||
作者:[Martin Tournoij][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://arp242.net/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Podesta_emails#Data_theft
|
||||
[2]: https://www.eset.com/us/about/newsroom/corporate-blog/paypal-users-targeted-in-sophisticated-new-phishing-campaign/
|
||||
[3]: https://www.paypal.com/cs/smarthelp/article/how-to-spot-fake,-spoof,-or-phishing-emails-faq2340
|
115
sources/talk/20190314 A Look Back at the History of Firefox.md
Normal file
115
sources/talk/20190314 A Look Back at the History of Firefox.md
Normal file
@ -0,0 +1,115 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (A Look Back at the History of Firefox)
|
||||
[#]: via: (https://itsfoss.com/history-of-firefox)
|
||||
[#]: author: (John Paul https://itsfoss.com/author/john/)
|
||||
|
||||
A Look Back at the History of Firefox
|
||||
======
|
||||
|
||||
The Firefox browser has been a mainstay of the open-source community for a long time. For many years it was the default web browser on (almost) all Linux distros and the lone obstacle to Microsoft’s total dominance of the internet. This browser has roots that go back all the way to the very early days of the internet. Since this week marks the 30th anniversary of the internet, there is no better time to talk about how Firefox became the browser we all know and love.
|
||||
|
||||
### Early Roots
|
||||
|
||||
In the early 1990s, a young man named [Marc Andreessen][1] was working on his bachelor’s degree in computer science at the University of Illinois. While there, he started working for the [National Center for Supercomputing Applications][2]. During that time [Sir Tim Berners-Lee][3] released an early form of the web standards that we know today. Marc [was introduced][4] to a very primitive web browser named [ViolaWWW][5]. Seeing that the technology had potential, Marc and Eric Bina created an easy to install browser for Unix named [NCSA Mosaic][6]). The first alpha was released in June 1993. By September, there were ports to Windows and Macintosh. Mosaic became very popular because it was easier to use than other browsing software.
|
||||
|
||||
In 1994, Marc graduated and moved to California. He was approached by Jim Clark, who had made his money selling computer hardware and software. Clark had used Mosaic and saw the financial possibilities of the internet. Clark recruited Marc and Eric to start an internet software company. The company was originally named Mosaic Communications Corporation, however, the University of Illinois did not like [their use of the name Mosaic][7]. As a result, the company name was changed to Netscape Communications Corporation.
|
||||
|
||||
The company’s first project was an online gaming network for the Nintendo 64, but that fell through. The first product they released was a web browser named Mosaic Netscape 0.9, subsequently renamed Netscape Navigator. Internally, the browser project was codenamed mozilla, which stood for “Mosaic killer”. An employee created a cartoon of a [Godzilla like creature][8]. They wanted to take out the competition.
|
||||
|
||||
![Early Firefox Mascot][9]Early Mozilla mascot at Netscape
|
||||
|
||||
They succeed mightily. At the time, one of the biggest advantages that Netscape had was the fact that its browser looked and functioned the same on every operating system. Netscape described this as giving everyone a level playing field.
|
||||
|
||||
As usage of Netscape Navigator increase, the market share of NCSA Mosaic cratered. In 1995, Netscape went public. [On the first day][10], the stock started at $28, jumped to $75 and ended the day at $58. Netscape was without any rivals.
|
||||
|
||||
But that didn’t last for long. In the summer of 1994, Microsoft released Internet Explorer 1.0, which was based on Spyglass Mosaic which was based on NCSA Mosaic. The [browser wars][11] had begun.
|
||||
|
||||
Over the next few years, Netscape and Microsoft competed for dominance of the internet. Each added features to compete with the other. Unfortunately, Internet Explorer had an advantage because it came bundled with Windows. On top of that, Microsoft had more programmers and money to throw at the problem. Toward the end of 1997, Netscape started to run into financial problems.
|
||||
|
||||
### Going Open Source
|
||||
|
||||
![Mozilla Firefox][12]
|
||||
|
||||
In January 1998, Netscape open-sourced the code of the Netscape Communicator 4.0 suite. The [goal][13] was to “harness the creative power of thousands of programmers on the Internet by incorporating their best enhancements into future versions of Netscape’s software. This strategy is designed to accelerate development and free distribution by Netscape of future high-quality versions of Netscape Communicator to business customers and individuals.”
|
||||
|
||||
The project was to be shepherded by the newly created Mozilla Organization. However, the code from Netscape Communicator 4.0 proved to be very difficult to work with due to its size and complexity. On top of that, several parts could not be open sourced because of licensing agreements with third parties. In the end, it was decided to rewrite the browser from scratch using the new [Gecko][14]) rendering engine.
|
||||
|
||||
In November 1998, Netscape was acquired by AOL for [stock swap valued at $4.2 billion][15].
|
||||
|
||||
Starting from scratch was a major undertaking. Mozilla Firefox (initially nicknamed Phoenix) was created in June 2002 and it worked on multiple operating systems, such as Linux, Mac OS, Microsoft Windows, and Solaris.
|
||||
|
||||
The following year, AOL announced that they would be shutting down browser development. The Mozilla Foundation was subsequently created to handle the Mozilla trademarks and handle the financing of the project. Initially, the Mozilla Foundation received $2 million in donations from AOL, IBM, Sun Microsystems, and Red Hat.
|
||||
|
||||
In March 2003, Mozilla [announced pl][16][a][16][ns][16] to separate the suite into stand-alone applications because of creeping software bloat. The stand-alone browser was initially named Phoenix. However, the name was changed due to a trademark dispute with the BIOS manufacturer Phoenix Technologies, which had a BIOS-based browser named trademark dispute with the BIOS manufacturer Phoenix Technologies. Phoenix was renamed Firebird only to run afoul of the Firebird database server people. The browser was once more renamed to the Firefox that we all know.
|
||||
|
||||
At the time, [Mozilla said][17], “We’ve learned a lot about choosing names in the past year (more than we would have liked to). We have been very careful in researching the name to ensure that we will not have any problems down the road. We have begun the process of registering our new trademark with the US Patent and Trademark office.”
|
||||
|
||||
![Mozilla Firefox 1.0][18]Firefox 1.0 : [Picture Credit][19]
|
||||
|
||||
The first official release of Firefox was [0.8][20] on February 8, 2004. 1.0 followed on November 9, 2004. Version 2.0 and 3.0 followed in October 2006 and June 2008 respectively. Each major release brought with it many new features and improvements. In many respects, Firefox pulled ahead of Internet Explorer in terms of features and technology, but IE still had more users.
|
||||
|
||||
That changed with the release of Google’s Chrome browser. In the months before the release of Chrome in September 2008, Firefox accounted for 30% of all [browser usage][21] and IE had over 60%. According to StatCounter’s [January 2019 report][22], Firefox accounts for less than 10% of all browser usage, while Chrome has over 70%.
|
||||
|
||||
Fun Fact
|
||||
|
||||
Contrary to popular belief, the logo of Firefox doesn’t feature a fox. It’s actually a [Red Panda][23]. In Chinese, “fire fox” is another name for the red panda.
|
||||
|
||||
### The Future
|
||||
|
||||
As noted above, Firefox currently has the lowest market share in its recent history. There was a time when a bunch of browsers were based on Firefox, such as the early version of the [Flock browser][24]). Now most browsers are based on Google technology, such as Opera and Vivaldi. Even Microsoft is giving up on browser development and [joining the Chromium band wagon][25].
|
||||
|
||||
This might seem like quite a downer after the heights of the early Netscape years. But don’t forget what Firefox has accomplished. A group of developers from around the world have created the second most used browser in the world. They clawed 30% market share away from Microsoft’s monopoly, they can do it again. After all, they have us, the open source community, behind them.
|
||||
|
||||
The fight against the monopoly is one of the several reasons [why I use Firefox][26]. Mozilla regained some of its lost market-share with the revamped release of [Firefox Quantum][27] and I believe that it will continue the upward path.
|
||||
|
||||
What event from Linux and open source history would you like us to write about next? Please let us know in the comments below.
|
||||
|
||||
If you found this article interesting, please take a minute to share it on social media, Hacker News or [Reddit][28].
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/history-of-firefox
|
||||
|
||||
作者:[John Paul][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/john/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Marc_Andreessen
|
||||
[2]: https://en.wikipedia.org/wiki/National_Center_for_Supercomputing_Applications
|
||||
[3]: https://en.wikipedia.org/wiki/Tim_Berners-Lee
|
||||
[4]: https://www.w3.org/DesignIssues/TimBook-old/History.html
|
||||
[5]: http://viola.org/
|
||||
[6]: https://en.wikipedia.org/wiki/Mosaic_(web_browser
|
||||
[7]: http://www.computinghistory.org.uk/det/1789/Marc-Andreessen/
|
||||
[8]: http://www.davetitus.com/mozilla/
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/Mozilla_boxing.jpg?ssl=1
|
||||
[10]: https://www.marketwatch.com/story/netscape-ipo-ignited-the-boom-taught-some-hard-lessons-20058518550
|
||||
[11]: https://en.wikipedia.org/wiki/Browser_wars
|
||||
[12]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/mozilla-firefox.jpg?resize=800%2C450&ssl=1
|
||||
[13]: https://web.archive.org/web/20021001071727/wp.netscape.com/newsref/pr/newsrelease558.html
|
||||
[14]: https://en.wikipedia.org/wiki/Gecko_(software)
|
||||
[15]: http://news.cnet.com/2100-1023-218360.html
|
||||
[16]: https://web.archive.org/web/20050618000315/http://www.mozilla.org/roadmap/roadmap-02-Apr-2003.html
|
||||
[17]: https://www-archive.mozilla.org/projects/firefox/firefox-name-faq.html
|
||||
[18]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/firefox-1.jpg?ssl=1
|
||||
[19]: https://www.iceni.com/blog/firefox-1-0-introduced-2004/
|
||||
[20]: https://en.wikipedia.org/wiki/Firefox_version_history
|
||||
[21]: https://en.wikipedia.org/wiki/Usage_share_of_web_browsers
|
||||
[22]: http://gs.statcounter.com/browser-market-share/desktop/worldwide/#monthly-201901-201901-bar
|
||||
[23]: https://en.wikipedia.org/wiki/Red_panda
|
||||
[24]: https://en.wikipedia.org/wiki/Flock_(web_browser
|
||||
[25]: https://www.windowscentral.com/microsoft-building-chromium-powered-web-browser-windows-10
|
||||
[26]: https://itsfoss.com/why-firefox/
|
||||
[27]: https://itsfoss.com/firefox-quantum-ubuntu/
|
||||
[28]: http://reddit.com/r/linuxusersgroup
|
||||
[29]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/mozilla-firefox.jpg?fit=800%2C450&ssl=1
|
@ -0,0 +1,84 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Why feedback, not metrics, is critical to DevOps)
|
||||
[#]: via: (https://opensource.com/article/19/3/devops-feedback-not-metrics)
|
||||
[#]: author: (Ranjith Varakantam (Red Hat) https://opensource.com/users/ranjith)
|
||||
|
||||
Why feedback, not metrics, is critical to DevOps
|
||||
======
|
||||
|
||||
Metrics can tell you some things, but not the most important things about how your products and teams are doing.
|
||||
|
||||
![CICD with gears][1]
|
||||
|
||||
Most managers and agile coaches depend on metrics over feedback from their teams, users, and even customers. In fact, quite a few use feedback and metrics synonymously, where they present feedback from teams or customers as a bunch of numbers or a graphical representation of those numbers. This is not only unfortunate, but it can be misleading as it presents only part of the story and not the entire truth.
|
||||
|
||||
When it comes to two critical factors—how we manage or guide our teams and how we operate and influence the product that our teams are developing—few exceptional leaders and teams get it right. For one thing, it has become very easy to get your hands on data and metrics. Furthermore, it's still hard to get real feedback from teams and users. It requires significant investments and energy, and unless everyone understands the critical need for it, getting and giving feedback tends to be a low priority and keeps getting pushed to the back burner.
|
||||
|
||||
### How to manage and guide teams
|
||||
|
||||
With the acceptance of agile, a lot of teams have put a ridiculously high value on metrics, such as velocity, burndown charts, cumulative flow diagram (CFD), etc., instead of the value delivered by the team in each iteration or deployment. The focus is on the delivery or output produced without a clear understanding of how this relates to personal performance or implications for the project, product, or service.
|
||||
|
||||
A few managers and agile coaches even abuse the true spirit of agile by misusing metrics to chastise or even penalize their teams. Instead of creating an environment of empowerment, they are slipping back into the command-and-control method where metrics are used to bully teams into submission.
|
||||
|
||||
In our group, the best managers have weekly one-on-one meetings with every team member. These meetings not only give them a real pulse on team morale but also a profound understanding of the project and the decisions being made to move it forward. This weekly feedback loop also helps the team members communicate technical, functional, and even personal issues better. As a result, the team is much more cohesive in understanding the overall project needs and able to make decisions promptly.
|
||||
|
||||
These leaders also skip levels—reaching out to team members two or three levels below them—and have frequent conversations with other group members who interact with their teams on a regular basis. These actions give the managers a holistic picture, which they couldn't get if they relied on feedback from one manager or lead, and help them identify any blind spots the leads and managers may have.
|
||||
|
||||
These one-on-one meetings effectively transform a manager into a coach who has a close understanding of every team member. Like a good coach, these managers both give and receive feedback from the team members regarding the product, decision-making transparency, places where the team feels management is lagging, and areas that are being ignored. This empowers the teams by giving them a voice, not once in a while in an annual meeting or an annual survey, but every week. This is the level where DevOps teams should be in order to deliver their commitments successfully.
|
||||
|
||||
This demands significant investments of time and energy, but the results more than justify it. The alternative is to rely on metrics and annual reviews and surveys, which has failed miserably. Unless we begin valuing feedback over metrics, we will keep seeing the metrics we want to see but failed projects and miserable team morale.
|
||||
|
||||
### Influencing projects and product development
|
||||
|
||||
We see similar behavior on the project or product side, with too few conversations with the users and developers and too much focus on metrics. Let's take the example of a piece of software that was released to the community or market, and the primary success metric is the number of downloads or installs. This can be deceiving for several reasons:
|
||||
|
||||
1. This product was packaged into another piece of software that users installed; even though the users are not even aware of your product's existence or purpose, it is still counted as a win and something the user needs.
|
||||
|
||||
2. The marketing team spent a huge budget promoting the product—and even offered an incentive to developers to download it. The _incentive_ drives the downloads, not user need or desire, but the metric is still considered a measure of success.
|
||||
|
||||
3. Software updates are counted as downloads, even when they are involuntary updates pushed rather than initiated by the user. This keeps bumping up the number, even though the user might have used it once, a year ago, for a specific task.
|
||||
|
||||
|
||||
|
||||
|
||||
In these cases, the user automatically becomes a metric that's used to report how well the product is doing, just based on the fact it was downloaded and it's accepting updates, regardless of whether the user likes or uses the software. Instead, we should be focusing on actual usage of the product and the feedback these users have to offer us, rather than stopping short at the download numbers.
|
||||
|
||||
The same holds true for SaaS products—instead of counting the number of signups, we should look at how often users use the product or service. Signups by themselves have little meaning, especially to the DevOps team where the focus is on getting constant feedback and striving for continuous improvements.
|
||||
|
||||
### Gathering feedback
|
||||
|
||||
So, why do we rely on metrics so much? My guess is they are easy to collect, and the marketing team is more interested in getting the product into the users' hands than evaluating how it is fairing. Unless the engineering team invests quite a bit of time in collecting feedback with tracing, which captures how often the program is executed and which components are used most often, it can be difficult to collect feedback.
|
||||
|
||||
A big advantage of working in an open source community is that we first release the piece of software into a community where we can get feedback. Most open source enthusiasts take the time to log issues and bugs based on their experience with the product. If we can supplement this data with tracing, the team has an accurate record of how the product is used.
|
||||
|
||||
Open as many channels of communication as possible–chat, email, Twitter, etc.—and allow users to choose their feedback channel.
|
||||
|
||||
A few DevOps teams have integrated blue-green deployments, A/B testing, and canary releases to shorten the feedback loop. Setting up these frameworks it is not a trivial matter and calls for a huge upfront investment and constant updates to make them seamlessly work. But once everything is set up and data begins to flow, the team can act upon real feedback based on real user interactions with every new bit of software released.
|
||||
|
||||
Most agile practitioners and lean movement activists push for a build-deploy-measure-learn cycle, and for this to happen, we need to collect feedback in addition to metrics. It might seem expensive and time consuming in the short term, but in the long run, it is a foolproof way of learning.
|
||||
|
||||
### Proof that feedback pays off
|
||||
|
||||
Whether it pertains to people or projects, it pays to rely on first-hand feedback rather than metrics, which are seldom interpreted in impartial ways. We have ample proof of this in other industries, where companies such as Zappos and the Virgin Group have done wonders for their business simply by listening to their customers. There is no reason we cannot follow suit, especially those of us working in open source communities.
|
||||
|
||||
Feedback is the only effective way we can uncover our blind spots. Metrics are not of much help in this regard, as we can't find out what's wrong when we are dealing with unknowns. Blind spots can create serious gaps between reality and what we think we know. Feedback not only encourages continuous improvement, whether it's on a personal or a product level, but the simple act of listening and acting on it increases trust and loyalty.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/devops-feedback-not-metrics
|
||||
|
||||
作者:[Ranjith Varakantam (Red Hat)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ranjith
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cicd_continuous_delivery_deployment_gears.png?itok=kVlhiEkc (CICD with gears)
|
@ -0,0 +1,148 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (6 steps to stop ethical debt in AI product development)
|
||||
[#]: via: (https://opensource.com/article/19/3/ethical-debt-ai-product-development)
|
||||
[#]: author: (Lauren Maffeo https://opensource.com/users/lmaffeo)
|
||||
|
||||
6 steps to stop ethical debt in AI product development
|
||||
======
|
||||
|
||||
Machine bias in artificial intelligence is a known and unavoidable problem—but it is not unmanageable.
|
||||
|
||||
![old school calculator][1]
|
||||
|
||||
It's official: artificial intelligence (AI) isn't the unbiased genius we want it to be.
|
||||
|
||||
Alphabet (Google's parent company) used its latest annual report [to warn][2] that ethical concerns about its products might hurt future revenue. Entrepreneur Joy Buolamwini established the [Safe Face Pledge][3] to prevent abuse of facial analysis technology.
|
||||
|
||||
And years after St. George's Hospital Medical School in London was found to have used AI that inadvertently [screened out qualified female candidates][4], Amazon scrapped a recruiting tool last fall after machine learning (ML) specialists found it [doing the same thing][5].
|
||||
|
||||
We've learned the hard way that technologies built with AI are biased like people. Left unchecked, the datasets used to train such products can pose [life-or-death consequences][6] for their end users.
|
||||
|
||||
For example, imagine a self-driving car that can't recognize commands from people with certain accents. If the dataset used to train the technology powering that car isn't exposed to enough voice variations and inflections, it risks not recognizing all its users as fully human.
|
||||
|
||||
Here's the good news: Machine bias in AI is unavoidable—but it is _not_ unmanageable. Just like product and development teams work to reduce technical debt, you can [reduce the risk of ethical debt][7] as well.
|
||||
|
||||
Here are six steps that your technical team can start taking today:
|
||||
|
||||
### 1\. Document your priorities upfront
|
||||
|
||||
Reducing ethical debt within your product will require you to answer two key questions in the product specification phase:
|
||||
|
||||
* Which methods of fairness will you use?
|
||||
* How will you prioritize them?
|
||||
|
||||
|
||||
|
||||
If your team is building a product based on ML, it's not enough to reactively fix bugs or pull products from shelves. Instead, answer these questions [in your tech spec][8] so that they're included from the start of your product lifecycle.
|
||||
|
||||
### 2\. Train your data under fairness constraints
|
||||
|
||||
This step is tough because when you try to control or eliminate both direct and indirect bias, you'll find yourself in a Catch-22.
|
||||
|
||||
If you train exclusively on non-sensitive attributes, you eliminate direct discrimination but introduce or reinforce indirect bias.
|
||||
|
||||
However, if you train separate classifiers for each sensitive feature, you reintroduce direct discrimination.
|
||||
|
||||
Another challenge is that detection can occur only after you've trained your model. When this occurs, the only recourse is to scrap the model and retrain it from scratch.
|
||||
|
||||
To reduce these risks, don't just measure average strengths of acceptance and rejection across sensitive groups. Instead, use limits to determine what is or isn't included in the model you're training. When you do this, discrimination tests are expressed as restrictions and limitations on the learning process.
|
||||
|
||||
### 3\. Monitor your datasets throughout the product lifecycle
|
||||
|
||||
Developers build training sets based on data they hope the model will encounter. But many don't monitor the data their creations receive from the real world.
|
||||
|
||||
ML products are unique in that they're continuously taking in data. New data allows the algorithms powering these products to keep refining their results.
|
||||
|
||||
But such products often encounter data in deployment that differs from what they were trained on in production. It's also not uncommon for the algorithm to be updated without the model itself being revalidated.
|
||||
|
||||
This risk will decrease if you appoint someone to monitor the source, history, and context of the data in your algorithm. This person should conduct continuous audits to find unacceptable behavior.
|
||||
|
||||
Bias should be reduced as much as possible while maintaining an acceptable level of accuracy, as defined in the product specification. If unacceptable biases or behaviors are detected, the model should be rolled back to an earlier state prior to the first time you saw bias.
|
||||
|
||||
### 4\. Use tagged training data
|
||||
|
||||
We live in a world with trillions of images and videos at our fingertips, but most neural networks can't use this data for one reason: Most of it isn't tagged.
|
||||
|
||||
Tagging refers to which classes are present in an image and their locations. When you tag an image, you share which classes are present and where they're located.
|
||||
|
||||
This sounds simple—until you realize how much work it would take to draw shapes around every single person in a photo of a crowd or a box around every single person on a highway.
|
||||
|
||||
Even if you succeeded, you might rush your tagging and draw your shapes sloppily, leading to a poorly trained neural network.
|
||||
|
||||
The good news is that more products are coming to market so they can decrease the time and cost of tagging.
|
||||
|
||||
As one example, [Brain Builder][9] is a data annotation product from Neurala that uses open source frameworks like TensorFlow and Caffe. Its goal is to help users [manage and annotate their training data][10]. It also aims to bring diverse class examples to datasets—another key step in data training.
|
||||
|
||||
### 5\. Use diverse class examples
|
||||
|
||||
Training data needs positive and negative examples of classes. If you want specific classes of objects, you need negative examples as well. This (hopefully) mimics the data that the algorithm will encounter in the wild.
|
||||
|
||||
Consider the example of “homes” within a dataset. If the algorithm contains only images of homes in North America, it won't know to recognize homes in Japan, Morocco, or other international locations. Its concept of a “home” is thus limited.
|
||||
|
||||
Neurala warns, "Most AI applications require thousands of images to be tagged, and since data tagging cost is proportional to the time spent tagging, this step alone often costs tens to hundreds of thousands of dollars per project."
|
||||
|
||||
Luckily, 2018 saw a strong increase in the number of open source AI datasets. Synced has a helpful [roundup of 10 datasets][11]—from multi-label images to semantic parsing—that were open sourced last year. If you're looking for datasets by industry, GitHub [has a longer list][12].
|
||||
|
||||
### 6\. Focus on the subject, not the context
|
||||
|
||||
Tech leaders in monitoring ML datasets should aim to understand how the algorithm classifies data. That's because AI sometimes focuses on irrelevant attributes that are shared by several targets in the training set.
|
||||
|
||||
Let's start by looking at the biased training set below. Wolves were tagged standing in snow, but the model wasn't shown images of dogs. So, when dogs were introduced, the model started tagging them as wolves because both animals were standing in snow. In this case, the AI put too much emphasis on the context (a snowy backdrop).
|
||||
|
||||
![Wolves in snow][13]
|
||||
|
||||
Source: [Gartner][14] (full research available for clients)
|
||||
|
||||
By contrast, here is a training set from Brain Builder that is focused on the subject dogs. When monitoring your own training set, make sure the AI is giving more weight to the subject of each image. If you saw an image classifier state that one of the dogs below is a wolf, you would need to know which aspects of the input led to this misclassification. This is a sign to check your training set and confirm that the data is accurate.
|
||||
|
||||
![Dogs training set][15]
|
||||
|
||||
Source: [Brain Builder][16]
|
||||
|
||||
Reducing ethical debt isn't just the “right thing to do”—it also reduces _technical_ debt. Since programmatic bias is so tough to detect, working to reduce it, from the start of your lifecycle, will save you the need to retrain models from scratch.
|
||||
|
||||
This isn't an easy or perfect job; tech teams will have to make tradeoffs between fairness and accuracy. But this is the essence of product management: compromises based on what's best for the product and its end users.
|
||||
|
||||
Strategy is the soul of all strong products. If your team includes measures of fairness and algorithmic priorities from the start, you'll sail ahead of your competition.
|
||||
|
||||
* * *
|
||||
|
||||
_Lauren Maffeo will present_ [_Erase Unconscious Bias From Your AI Datasets_][17] _at[DrupalCon][18] in Seattle, April 8-12, 2019._
|
||||
|
||||
* * *
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/ethical-debt-ai-product-development
|
||||
|
||||
作者:[Lauren Maffeo][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/lmaffeo
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/math_money_financial_calculator_colors.jpg?itok=_yEVTST1 (old school calculator)
|
||||
[2]: https://www.yahoo.com/news/google-warns-rise-ai-may-181710642.html?soc_src=mail&soc_trk=ma
|
||||
[3]: https://www.safefacepledge.org/
|
||||
[4]: https://futurism.com/ai-bias-black-box
|
||||
[5]: https://uk.reuters.com/article/us-amazon-com-jobs-automation-insight/amazon-scraps-secret-ai-recruiting-tool-that-showed-bias-against-women-idUKKCN1MK08G
|
||||
[6]: https://opensource.com/article/18/10/open-source-classifiers-ai-algorithms
|
||||
[7]: https://thenewstack.io/tech-ethics-new-years-resolution-dont-build-software-you-will-regret/
|
||||
[8]: https://eng.lyft.com/awesome-tech-specs-86eea8e45bb9
|
||||
[9]: https://www.neurala.com/tech
|
||||
[10]: https://www.roboticsbusinessreview.com/ai/brain-builder-neurala-video-annotation/
|
||||
[11]: https://medium.com/syncedreview/2018-in-review-10-open-sourced-ai-datasets-696b3b49801f
|
||||
[12]: https://github.com/awesomedata/awesome-public-datasets
|
||||
[13]: https://opensource.com/sites/default/files/uploads/wolves_in_snow.png (Wolves in snow)
|
||||
[14]: https://www.gartner.com/doc/3889586/control-bias-eliminate-blind-spots
|
||||
[15]: https://opensource.com/sites/default/files/uploads/ai_ml_canine_recognition.png (Dogs training set)
|
||||
[16]: https://www.neurala.com/
|
||||
[17]: https://events.drupal.org/seattle2019/sessions/erase-unconscious-bias-your-ai-datasets
|
||||
[18]: https://events.drupal.org/seattle2019
|
356
sources/tech/20160301 How To Set Password Policies In Linux.md
Normal file
356
sources/tech/20160301 How To Set Password Policies In Linux.md
Normal file
@ -0,0 +1,356 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Set Password Policies In Linux)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-set-password-policies-in-linux/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
How To Set Password Policies In Linux
|
||||
======
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2016/03/How-To-Set-Password-Policies-In-Linux-720x340.jpg)
|
||||
|
||||
Even though Linux is secure by design, there are many chances for the security breach. One of them is weak passwords. As a System administrator, you must provide a strong password for the users. Because, mostly system breaches are happening due to weak passwords. This tutorial describes how to set password policies such as **password length** , **password complexity** , **password** **expiration period** etc., in DEB based systems like Debian, Ubuntu, Linux Mint, and RPM based systems like RHEL, CentOS, Scientific Linux.
|
||||
|
||||
### Set password length in DEB based systems
|
||||
|
||||
By default, all Linux operating systems requires **password length of minimum 6 characters** for the users. I strongly advice you not to go below this limit. Also, don’t use your real name, parents/spouse/kids name, or your date of birth as a password. Even a novice hacker can easily break such kind of passwords in minutes. The good password must always contains more than 6 characters including a number, a capital letter, and a special character.
|
||||
|
||||
Usually, the password and authentication-related configuration files will be stored in **/etc/pam.d/** location in DEB based operating systems.
|
||||
|
||||
To set minimum password length, edit**/etc/pam.d/common-password** file;
|
||||
|
||||
```
|
||||
$ sudo nano /etc/pam.d/common-password
|
||||
```
|
||||
|
||||
Find the following line:
|
||||
|
||||
```
|
||||
password [success=2 default=ignore] pam_unix.so obscure sha512
|
||||
```
|
||||
|
||||
![][2]
|
||||
|
||||
And add an extra word: **minlen=8** at the end. Here I set the minimum password length as **8**.
|
||||
|
||||
```
|
||||
password [success=2 default=ignore] pam_unix.so obscure sha512 minlen=8
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2016/03/sk@sk-_002-3-1.jpg)
|
||||
|
||||
Save and close the file. So, now the users can’t use less than 8 characters for their password.
|
||||
|
||||
### Set password length in RPM based systems
|
||||
|
||||
**In RHEL, CentOS, Scientific Linux 7.x** systems, run the following command as root user to set password length.
|
||||
|
||||
```
|
||||
# authconfig --passminlen=8 --update
|
||||
```
|
||||
|
||||
To view the minimum password length, run:
|
||||
|
||||
```
|
||||
# grep "^minlen" /etc/security/pwquality.conf
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
minlen = 8
|
||||
```
|
||||
|
||||
**In RHEL, CentOS, Scientific Linux 6.x** systems, edit **/etc/pam.d/system-auth** file:
|
||||
|
||||
```
|
||||
# nano /etc/pam.d/system-auth
|
||||
```
|
||||
|
||||
Find the following line and add the following at the end of the line:
|
||||
|
||||
```
|
||||
password requisite pam_cracklib.so try_first_pass retry=3 type= minlen=8
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2016/03/root@server_003-3.jpg)
|
||||
|
||||
As per the above setting, the minimum password length is **8** characters.
|
||||
|
||||
### Set password complexity in DEB based systems
|
||||
|
||||
This setting enforces how many classes, i.e upper-case, lower-case, and other characters, should be in a password.
|
||||
|
||||
First install password quality checking library using command:
|
||||
|
||||
```
|
||||
$ sudo apt-get install libpam-pwquality
|
||||
```
|
||||
|
||||
Then, edit **/etc/pam.d/common-password** file:
|
||||
|
||||
```
|
||||
$ sudo nano /etc/pam.d/common-password
|
||||
```
|
||||
|
||||
To set at least one **upper-case** letters in the password, add a word **‘ucredit=-1’** at the end of the following line.
|
||||
|
||||
```
|
||||
password requisite pam_pwquality.so retry=3 ucredit=-1
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2016/03/sk@sk-_001-7.jpg)
|
||||
|
||||
Set at least one **lower-case** letters in the password as shown below.
|
||||
|
||||
```
|
||||
password requisite pam_pwquality.so retry=3 dcredit=-1
|
||||
```
|
||||
|
||||
Set at least **other** letters in the password as shown below.
|
||||
|
||||
```
|
||||
password requisite pam_pwquality.so retry=3 ocredit=-1
|
||||
```
|
||||
|
||||
As you see in the above examples, we have set at least (minimum) one upper-case, lower-case, and a special character in the password. You can set any number of maximum allowed upper-case, lower-case, and other letters in your password.
|
||||
|
||||
You can also set the minimum/maximum number of allowed classes in the password.
|
||||
|
||||
The following example shows the minimum number of required classes of characters for the new password:
|
||||
|
||||
```
|
||||
password requisite pam_pwquality.so retry=3 minclass=2
|
||||
```
|
||||
|
||||
### Set password complexity in RPM based systems
|
||||
|
||||
**In RHEL 7.x / CentOS 7.x / Scientific Linux 7.x:**
|
||||
|
||||
To set at least one lower-case letter in the password, run:
|
||||
|
||||
```
|
||||
# authconfig --enablereqlower --update
|
||||
```
|
||||
|
||||
To view the settings, run:
|
||||
|
||||
```
|
||||
# grep "^lcredit" /etc/security/pwquality.conf
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
lcredit = -1
|
||||
```
|
||||
|
||||
Similarly, set at least one upper-case letter in the password using command:
|
||||
|
||||
```
|
||||
# authconfig --enablerequpper --update
|
||||
```
|
||||
|
||||
To view the settings:
|
||||
|
||||
```
|
||||
# grep "^ucredit" /etc/security/pwquality.conf
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
ucredit = -1
|
||||
```
|
||||
|
||||
To set at least one digit in the password, run:
|
||||
|
||||
```
|
||||
# authconfig --enablereqdigit --update
|
||||
```
|
||||
|
||||
To view the setting, run:
|
||||
|
||||
```
|
||||
# grep "^dcredit" /etc/security/pwquality.conf
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
dcredit = -1
|
||||
```
|
||||
|
||||
To set at least one other character in the password, run:
|
||||
|
||||
```
|
||||
# authconfig --enablereqother --update
|
||||
```
|
||||
|
||||
To view the setting, run:
|
||||
|
||||
```
|
||||
# grep "^ocredit" /etc/security/pwquality.conf
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
ocredit = -1
|
||||
```
|
||||
|
||||
In **RHEL 6.x / CentOS 6.x / Scientific Linux 6.x systems** , edit **/etc/pam.d/system-auth** file as root user:
|
||||
|
||||
```
|
||||
# nano /etc/pam.d/system-auth
|
||||
```
|
||||
|
||||
Find the following line and add the following at the end of the line:
|
||||
|
||||
```
|
||||
password requisite pam_cracklib.so try_first_pass retry=3 type= minlen=8 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1
|
||||
```
|
||||
|
||||
As per the above setting, the password must have at least 8 characters. In addtion, the password should also have at least one upper-case letter, one lower-case letter, one digit, and one other characters.
|
||||
|
||||
### Set password expiration period in DEB based systems
|
||||
|
||||
Now, We are going to set the following policies.
|
||||
|
||||
1. Maximum number of days a password may be used.
|
||||
2. Minimum number of days allowed between password changes.
|
||||
3. Number of days warning given before a password expires.
|
||||
|
||||
|
||||
|
||||
To set this policy, edit:
|
||||
|
||||
```
|
||||
$ sudo nano /etc/login.defs
|
||||
```
|
||||
|
||||
Set the values as per your requirement.
|
||||
|
||||
```
|
||||
PASS_MAX_DAYS 100
|
||||
PASS_MIN_DAYS 0
|
||||
PASS_WARN_AGE 7
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2016/03/sk@sk-_002-8.jpg)
|
||||
|
||||
As you see in the above example, the user should change the password once in every **100** days and the warning message will appear **7** days before password expiration.
|
||||
|
||||
Be mindful that these settings will impact the newly created users.
|
||||
|
||||
To set maximum number of days between password change to existing users, you must run the following command:
|
||||
|
||||
```
|
||||
$ sudo chage -M <days> <username>
|
||||
```
|
||||
|
||||
To set minimum number of days between password change, run:
|
||||
|
||||
```
|
||||
$ sudo chage -m <days> <username>
|
||||
```
|
||||
|
||||
To set warning before password expires, run:
|
||||
|
||||
```
|
||||
$ sudo chage -W <days> <username>
|
||||
```
|
||||
|
||||
To display the password for the existing users, run:
|
||||
|
||||
```
|
||||
$ sudo chage -l sk
|
||||
```
|
||||
|
||||
Here, **sk** is my username.
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
Last password change : Feb 24, 2017
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : never
|
||||
Minimum number of days between password change : 0
|
||||
Maximum number of days between password change : 99999
|
||||
Number of days of warning before password expires : 7
|
||||
```
|
||||
|
||||
As you see in the above output, the password never expires.
|
||||
|
||||
To change the password expiration period of an existing user,
|
||||
|
||||
```
|
||||
$ sudo chage -E 24/06/2018 -m 5 -M 90 -I 10 -W 10 sk
|
||||
```
|
||||
|
||||
The above command will set password of the user **‘sk’** to expire on **24/06/2018**. Also the the minimum number days between password change is set 5 days and the maximum number of days between password changes is set to **90** days. The user account will be locked automatically after **10 days** and It will display a warning message for **10 days** before password expiration.
|
||||
|
||||
### Set password expiration period in RPM based systems
|
||||
|
||||
This is same as DEB based systems.
|
||||
|
||||
### Forbid previously used passwords in DEB based systems
|
||||
|
||||
You can limit the users to set a password which is already used in the past. To put this in layman terms, the users can’t use the same password again.
|
||||
|
||||
To do so, edit**/etc/pam.d/common-password** file:
|
||||
|
||||
```
|
||||
$ sudo nano /etc/pam.d/common-password
|
||||
```
|
||||
|
||||
Find the following line and add the word **‘remember=5’** at the end:
|
||||
|
||||
```
|
||||
password [success=2 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512 remember=5
|
||||
```
|
||||
|
||||
The above policy will prevent the users to use the last 5 used passwords.
|
||||
|
||||
### Forbid previously used passwords in RPM based systems
|
||||
|
||||
This is same for both RHEL 6.x and RHEL 7.x and it’s clone systems like CentOS, Scientific Linux.
|
||||
|
||||
Edit **/etc/pam.d/system-auth** file as root user,
|
||||
|
||||
```
|
||||
# vi /etc/pam.d/system-auth
|
||||
```
|
||||
|
||||
Find the following line, and add **remember=5** at the end.
|
||||
|
||||
```
|
||||
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5
|
||||
```
|
||||
|
||||
You know now what is password policies in Linux, and how to set different password policies in DEB and RPM based systems.
|
||||
|
||||
That’s all for now. I will be here soon with another interesting and useful article. Until then stay tuned with OSTechNix. If you find this tutorial helpful, share it on your social, professional networks and support us.
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-set-password-policies-in-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: http://www.ostechnix.com/wp-content/uploads/2016/03/sk@sk-_003-2-1.jpg
|
146
sources/tech/20170414 5 projects for Raspberry Pi at home.md
Normal file
146
sources/tech/20170414 5 projects for Raspberry Pi at home.md
Normal file
@ -0,0 +1,146 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (5 projects for Raspberry Pi at home)
|
||||
[#]: via: (https://opensource.com/article/17/4/5-projects-raspberry-pi-home)
|
||||
[#]: author: (Ben Nuttall (Community Moderator) )
|
||||
|
||||
5 projects for Raspberry Pi at home
|
||||
======
|
||||
|
||||
![5 projects for Raspberry Pi at home][1]
|
||||
|
||||
The [Raspberry Pi][2] computer can be used in all kinds of settings and for a variety of purposes. It obviously has a place in education for helping students with learning programming and maker skills in the classroom and the hackspace, and it has plenty of industrial applications in the workplace and in factories. I'm going to introduce five projects you might want to build in your own home.
|
||||
|
||||
### Media center
|
||||
|
||||
One of the most common uses for Raspberry Pi in people's homes is behind the TV running media center software serving multimedia files. It's easy to set this up, and the Raspberry Pi provides plenty of GPU (Graphics Processing Unit) power to render HD TV shows and movies to your big screen TV. [Kodi][3] (formerly XBMC) on a Raspberry Pi is a great way to playback any media you have on a hard drive or network-attached storage. You can also install a plugin to play YouTube videos.
|
||||
|
||||
There are a few different options available, most prominently [OSMC][4] (Open Source Media Center) and [LibreELEC][5], both based on Kodi. They both perform well at playing media content, but OSMC has a more visually appearing user interface, while LibreElec is much more lightweight. All you have to do is choose a distribution, download the image and install on an SD card (or just use [NOOBS][6]), boot it up, and you're ready to go.
|
||||
|
||||
![LibreElec ][7]
|
||||
|
||||
LibreElec; Raspberry Pi Foundation, CC BY-SA
|
||||
|
||||
![OSMC][8]
|
||||
|
||||
OSMC.tv, Copyright, Used with permission
|
||||
|
||||
Before proceeding you'll need to decide [w][9][hich Raspberry Pi model to use][9]. These distributions will work on any Pi (1, 2, 3, or Zero), and video playback will essentially be matched on each of these. Apart from the Pi 3 (and Zero W) having built-in Wi-Fi, the only noticeable difference is the reaction speed of the user interface, which will be much faster on a Pi 3. A Pi 2 will not be much slower, so that's fine if you don't need Wi-Fi, but the Pi 3 will noticeably outperform the Pi 1 and Zero when it comes to flicking through the menus.
|
||||
|
||||
### SSH gateway
|
||||
|
||||
If you want to be able to access computers and devices on your home network from outside over the internet, you have to open up ports on those devices to allow outside traffic. Opening ports to the internet is a security risk, meaning you're always at risk of attack, misuse, or any kind of unauthorized access. However, if you install a Raspberry Pi on your network and set up port forwarding to allow only SSH access to that Pi, you can use that as a secure gateway to hop onto other Pis and PCs on the network.
|
||||
|
||||
Most routers allow you to configure port-forwarding rules. You'll need to give your Pi a fixed internal IP address and set up port 22 on your router to map to port 22 on your Raspberry Pi. If your ISP provides you with a static IP address, you'll be able to SSH into it with this as the host address (for example, **ssh pi@123.45.56.78** ). If you have a domain name, you can configure a subdomain to point to this IP address, so you don't have to remember it (for example, **ssh[pi@home.mydomain.com][10]** ).
|
||||
|
||||
![][11]
|
||||
|
||||
However, if you're going to expose a Raspberry Pi to the internet, you should be very careful not to put your network at risk. There are a few simple procedures you can follow to make it sufficiently secure:
|
||||
|
||||
1\. Most people suggest you change your login password (which makes sense, seeing as the default password “raspberry” is well known), but this does not protect against brute-force attacks. You could change your password and add a two-factor authentication (so you need your password _and_ a time-dependent passcode generated by your phone), which is more secure. However, I believe the best way to secure your Raspberry Pi from intruders is to [disable][12] [“password authentication”][12] in your SSH configuration, so you allow only SSH key access. This means that anyone trying to SSH in by guessing your password will never succeed. Only with your private SSH key can anyone gain access. Similarly, most people suggest changing the SSH port from the default 22 to something unexpected, but a simple [Nmap][13] of your IP address will reveal your true SSH port.
|
||||
|
||||
2\. Ideally, you would not run much in the way of other software on this Pi, so you don't end up accidentally exposing anything else. If you want to run other software, you might be better running it on another Pi on the network that is not exposed to the internet. Ensure that you keep your packages up to date by upgrading regularly, particularly the **openssh-server** package, so that any security vulnerabilities are patched.
|
||||
|
||||
3\. Install [sshblack][14] or [fail2ban][15] to blacklist any users who seem to be acting maliciously, such as attempting to brute force your SSH password.
|
||||
|
||||
Once you've secured your Raspberry Pi and put it online, you'll be able to log in to your network from anywhere in the world. Once you're on your Raspberry Pi, you can SSH into other devices on the network using their local IP address (for example, 192.168.1.31). If you have passwords on these devices, just use the password. If they're also SSH-key-only, you'll need to ensure your key is forwarded over SSH by using the **-A** flag: **ssh -A pi@123.45.67.89**.
|
||||
|
||||
### CCTV / pet camera
|
||||
|
||||
Another great home project is to set up a camera module to take photos or stream video, capture and save files, or streamed internally or to the internet. There are many reasons you might want to do this, but two common use cases are for a homemade security camera or to monitor a pet.
|
||||
|
||||
The [Raspberry Pi camera module][16] is a brilliant accessory. It provides full HD photo and video, lots of advanced configuration, and is [easy to][17] [program][17]. The [infrared camera][18] is ideal for this kind of use, and with an infrared LED (which the Pi can control) you can see in the dark!
|
||||
|
||||
If you want to take still images on a regular basis to keep an eye on things, you can just write a short [Python][19] script or use the command line tool [raspistill][20], and schedule it to recur in [Cron][21]. You might want to have it save them to [Dropbox][22] or another web service, upload them to a web server, or you can even create a [web app][23] to display them.
|
||||
|
||||
If you want to stream video, internally or externally, that's really easy, too. A simple MJPEG (Motion JPEG) example is provided in the [picamera documentation][24] (under “web streaming”). Just download or copy that code into a file, run it and visit the Pi's IP address at port 8000, and you'll see your camera's output live.
|
||||
|
||||
A more advanced streaming project, [pistreaming][25], is available, which uses [JSMpeg][26] (a JavaScript video player) with the web server and a websocket for the camera stream running separately. This method is more performant and is just as easy to get running as the previous example, but there is more code involved and if set up to stream on the internet, requires you to open two ports.
|
||||
|
||||
Once you have web streaming set up, you can position the camera where you want it. I have one set up to keep an eye on my pet tortoise:
|
||||
|
||||
![Tortoise ][27]
|
||||
|
||||
Ben Nuttall, CC BY-SA
|
||||
|
||||
If you want to be able to control where the camera actually points, you can do so using servos. A neat solution is to use Pimoroni's [Pan-Tilt HAT][28], which allows you to move the camera easily in two dimensions. To integrate this with pistreaming, see the project's [pantilthat branch][29].
|
||||
|
||||
![Pan-tilt][30]
|
||||
|
||||
Pimoroni.com, Copyright, Used with permission
|
||||
|
||||
If you want to position your Pi outside, you'll need a waterproof enclosure and some way of getting power to the Pi. PoE (Power-over-Ethernet) cables can be a good way of achieving this.
|
||||
|
||||
### Home automation and IoT
|
||||
|
||||
It's 2017 and there are internet-connected devices everywhere, especially in the home. Our lightbulbs have Wi-Fi, our toasters are smarter than they used to be, and our tea kettles are at risk of attack from Russia. As long as you keep your devices secure, or don't connect them to the internet if they don't need to be, then you can make great use of IoT devices to automate tasks around the home.
|
||||
|
||||
There are plenty of services you can buy or subscribe to, like Nest Thermostat or Philips Hue lightbulbs, which allow you to control your heating or your lighting from your phone, respectively—whether you're inside or away from home. You can use a Raspberry Pi to boost the power of these kinds of devices by automating interactions with them according to a set of rules involving timing or even sensors. One thing you can't do with Philips Hue is have the lights come on when you enter the room, but with a Raspberry Pi and a motion sensor, you can use a Python API to turn on the lights. Similarly, you can configure your Nest to turn on the heating when you're at home, but what if you only want it to turn on if there's at least two people home? Write some Python code to check which phones are on the network and if there are at least two, tell the Nest to turn on the heat.
|
||||
|
||||
You can do a great deal more without integrating with existing IoT devices and with only using simple components. A homemade burglar alarm, an automated chicken coop door opener, a night light, a music box, a timed heat lamp, an automated backup server, a print server, or whatever you can imagine.
|
||||
|
||||
### Tor proxy and blocking ads
|
||||
|
||||
Adafruit's [Onion Pi][31] is a [Tor][32] proxy that makes your web traffic anonymous, allowing you to use the internet free of snoopers and any kind of surveillance. Follow Adafruit's tutorial on setting up Onion Pi and you're on your way to a peaceful anonymous browsing experience.
|
||||
|
||||
![Onion-Pi][33]
|
||||
|
||||
Onion-pi from Adafruit, Copyright, Used with permission
|
||||
|
||||
![Pi-hole][34]You can install a Raspberry Pi on your network that intercepts all web traffic and filters out any advertising. Simply download the [Pi-hole][35] software onto the Pi, and all devices on your network will be ad-free (it even blocks in-app ads on your mobile devices).
|
||||
|
||||
There are plenty more uses for the Raspberry Pi at home. What do you use Raspberry Pi for at home? What do you want to use it for?
|
||||
|
||||
Let us know in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/4/5-projects-raspberry-pi-home
|
||||
|
||||
作者:[Ben Nuttall (Community Moderator)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberry_pi_home_automation.png?itok=2TnmJpD8 (5 projects for Raspberry Pi at home)
|
||||
[2]: https://www.raspberrypi.org/
|
||||
[3]: https://kodi.tv/
|
||||
[4]: https://osmc.tv/
|
||||
[5]: https://libreelec.tv/
|
||||
[6]: https://www.raspberrypi.org/downloads/noobs/
|
||||
[7]: https://opensource.com/sites/default/files/libreelec_0.png (LibreElec )
|
||||
[8]: https://opensource.com/sites/default/files/osmc.png (OSMC)
|
||||
[9]: https://opensource.com/life/16/10/which-raspberry-pi-should-you-choose-your-project
|
||||
[10]: mailto:pi@home.mydomain.com
|
||||
[11]: https://opensource.com/sites/default/files/resize/screenshot_from_2017-04-07_15-13-01-700x380.png
|
||||
[12]: http://stackoverflow.com/questions/20898384/ssh-disable-password-authentication
|
||||
[13]: https://nmap.org/
|
||||
[14]: http://www.pettingers.org/code/sshblack.html
|
||||
[15]: https://www.fail2ban.org/wiki/index.php/Main_Page
|
||||
[16]: https://www.raspberrypi.org/products/camera-module-v2/
|
||||
[17]: https://opensource.com/life/15/6/raspberry-pi-camera-projects
|
||||
[18]: https://www.raspberrypi.org/products/pi-noir-camera-v2/
|
||||
[19]: http://picamera.readthedocs.io/
|
||||
[20]: https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspistill.md
|
||||
[21]: https://www.raspberrypi.org/documentation/linux/usage/cron.md
|
||||
[22]: https://github.com/RZRZR/plant-cam
|
||||
[23]: https://github.com/bennuttall/bett-bot
|
||||
[24]: http://picamera.readthedocs.io/en/release-1.13/recipes2.html#web-streaming
|
||||
[25]: https://github.com/waveform80/pistreaming
|
||||
[26]: http://jsmpeg.com/
|
||||
[27]: https://opensource.com/sites/default/files/tortoise.jpg (Tortoise)
|
||||
[28]: https://shop.pimoroni.com/products/pan-tilt-hat
|
||||
[29]: https://github.com/waveform80/pistreaming/tree/pantilthat
|
||||
[30]: https://opensource.com/sites/default/files/pan-tilt.gif (Pan-tilt)
|
||||
[31]: https://learn.adafruit.com/onion-pi/overview
|
||||
[32]: https://www.torproject.org/
|
||||
[33]: https://opensource.com/sites/default/files/onion-pi.jpg (Onion-Pi)
|
||||
[34]: https://opensource.com/sites/default/files/resize/pi-hole-250x250.png (Pi-hole)
|
||||
[35]: https://pi-hole.net/
|
@ -1,3 +1,6 @@
|
||||
Translating by MjSeven
|
||||
|
||||
|
||||
iWant – The Decentralized Peer To Peer File Sharing Commandline Application
|
||||
======
|
||||
|
||||
|
@ -1,283 +0,0 @@
|
||||
tomjlw is translatting
|
||||
Toplip – A Very Strong File Encryption And Decryption CLI Utility
|
||||
======
|
||||
There are numerous file encryption tools available on the market to protect
|
||||
your files. We have already reviewed some encryption tools such as
|
||||
[**Cryptomater**][1], [**Cryptkeeper**][2], [**CryptGo**][3], [**Cryptr**][4],
|
||||
[**Tomb**][5], and [**GnuPG**][6] etc. Today, we will be discussing yet
|
||||
another file encryption and decryption command line utility named **"
|
||||
Toplip"**. It is a free and open source encryption utility that uses a very
|
||||
strong encryption method called **[AES256][7]** , along with an **XTS-AES**
|
||||
design to safeguard your confidential data. Also, it uses [**Scrypt**][8], a
|
||||
password-based key derivation function, to protect your passphrases against
|
||||
brute-force attacks.
|
||||
|
||||
### Prominent features
|
||||
|
||||
Compared to other file encryption tools, toplip ships with the following
|
||||
unique and prominent features.
|
||||
|
||||
* Very strong XTS-AES256 based encryption method.
|
||||
* Plausible deniability.
|
||||
* Encrypt files inside images (PNG/JPG).
|
||||
* Multiple passphrase protection.
|
||||
* Simplified brute force recovery protection.
|
||||
* No identifiable output markers.
|
||||
* Open source/GPLv3.
|
||||
|
||||
### Installing Toplip
|
||||
|
||||
There is no installation required. Toplip is a standalone executable binary
|
||||
file. All you have to do is download the latest toplip from the [**official
|
||||
products page**][9] and make it as executable. To do so, just run:
|
||||
|
||||
```
|
||||
chmod +x toplip
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
If you run toplip without any arguments, you will see the help section.
|
||||
|
||||
```
|
||||
./toplip
|
||||
```
|
||||
|
||||
[![][10]][11]
|
||||
|
||||
Allow me to show you some examples.
|
||||
|
||||
For the purpose of this guide, I have created two files namely **file1** and
|
||||
**file2**. Also, I have an image file which we need it to hide the files
|
||||
inside it. And finally, I have **toplip** executable binary file. I have kept
|
||||
them all in a directory called **test**.
|
||||
|
||||
[![][12]][13]
|
||||
|
||||
**Encrypt/decrypt a single file**
|
||||
|
||||
Now, let us encrypt **file1**. To do so, run:
|
||||
|
||||
```
|
||||
./toplip file1 > file1.encrypted
|
||||
```
|
||||
|
||||
This command will prompt you to enter a passphrase. Once you have given the
|
||||
passphrase, it will encrypt the contents of **file1** and save them in a file
|
||||
called **file1.encrypted** in your current working directory.
|
||||
|
||||
Sample output of the above command would be:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
To verify if the file is really encrypted., try to open it and you will see
|
||||
some random characters.
|
||||
|
||||
To decrypt the encrypted file, use **-d** flag like below:
|
||||
|
||||
```
|
||||
./toplip -d file1.encrypted
|
||||
```
|
||||
|
||||
This command will decrypt the given file and display the contents in the
|
||||
Terminal window.
|
||||
|
||||
To restore the file instead of writing to stdout, do:
|
||||
|
||||
```
|
||||
./toplip -d file1.encrypted > file1.decrypted
|
||||
```
|
||||
|
||||
Enter the correct passphrase to decrypt the file. All contents of **file1.encrypted** will be restored in a file called **file1.decrypted**.
|
||||
|
||||
Please don't follow this naming method. I used it for the sake of easy understanding. Use any other name(s) which is very hard to predict.
|
||||
|
||||
**Encrypt/decrypt multiple files
|
||||
**
|
||||
|
||||
Now we will encrypt two files with two separate passphrases for each one.
|
||||
|
||||
```
|
||||
./toplip -alt file1 file2 > file3.encrypted
|
||||
```
|
||||
|
||||
You will be asked to enter passphrase for each file. Use different
|
||||
passphrases.
|
||||
|
||||
Sample output of the above command will be:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
What the above command will do is encrypt the contents of two files and save
|
||||
them in a single file called **file3.encrypted**. While restoring, just give
|
||||
the respective password. For example, if you give the passphrase of the file1,
|
||||
toplip will restore file1. If you enter the passphrase of file2, toplip will
|
||||
restore file2.
|
||||
|
||||
Each **toplip** encrypted output may contain up to four wholly independent
|
||||
files, and each created with their own separate and unique passphrase. Due to
|
||||
the way the encrypted output is put together, there is no way to easily
|
||||
determine whether or not multiple files actually exist in the first place. By
|
||||
default, even if only one file is encrypted using toplip, random data is added
|
||||
automatically. If more than one file is specified, each with their own
|
||||
passphrase, then you can selectively extract each file independently and thus
|
||||
deny the existence of the other files altogether. This effectively allows a
|
||||
user to open an encrypted bundle with controlled exposure risk, and no
|
||||
computationally inexpensive way for an adversary to conclusively identify that
|
||||
additional confidential data exists. This is called **Plausible deniability**
|
||||
, one of the notable feature of toplip.
|
||||
|
||||
To decrypt **file1** from **file3.encrypted** , just enter:
|
||||
|
||||
```
|
||||
./toplip -d file3.encrypted > file1.encrypted
|
||||
```
|
||||
|
||||
You will be prompted to enter the correct passphrase of file1.
|
||||
|
||||
To decrypt **file2** from **file3.encrypted** , enter:
|
||||
|
||||
```
|
||||
./toplip -d file3.encrypted > file2.encrypted
|
||||
```
|
||||
|
||||
Do not forget to enter the correct passphrase of file2.
|
||||
|
||||
**Use multiple passphrase protection**
|
||||
|
||||
This is another cool feature that I admire. We can provide multiple
|
||||
passphrases for a single file when encrypting it. It will protect the
|
||||
passphrases against brute force attempts.
|
||||
|
||||
```
|
||||
./toplip -c 2 file1 > file1.encrypted
|
||||
```
|
||||
|
||||
Here, **-c 2** represents two different passphrases. Sample output of above
|
||||
command would be:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
As you see in the above example, toplip prompted me to enter two passphrases.
|
||||
Please note that you must **provide two different passphrases** , not a single
|
||||
passphrase twice.
|
||||
|
||||
To decrypt this file, do:
|
||||
|
||||
```
|
||||
$ ./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
|
||||
```
|
||||
|
||||
**Hide files inside image**
|
||||
|
||||
The practice of concealing a file, message, image, or video within another
|
||||
file is called **steganography**. Fortunately, this feature exists in toplip
|
||||
by default.
|
||||
|
||||
To hide a file(s) inside images, use **-m** flag as shown below.
|
||||
|
||||
```
|
||||
$ ./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
|
||||
```
|
||||
|
||||
This command conceals the contents of file1 inside an image named image1.png.
|
||||
To decrypt it, run:
|
||||
|
||||
```
|
||||
$ ./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
|
||||
```
|
||||
|
||||
**Increase password complexity**
|
||||
|
||||
To make things even harder to break, we can increase the password complexity
|
||||
like below.
|
||||
|
||||
```
|
||||
./toplip -c 5 -i 0x8000 -alt file1 -c 10 -i 10 file2 > file3.encrypted
|
||||
```
|
||||
|
||||
The above command will prompt to you enter 10 passphrases for the file1, 5
|
||||
passphrases for the file2 and encrypt both of them in a single file called
|
||||
"file3.encrypted". As you may noticed, we have used one more additional flag
|
||||
**-i** in this example. This is used to specify key derivation iterations.
|
||||
This option overrides the default iteration count of 1 for scrypt's initial
|
||||
and final PBKDF2 stages. Hexadecimal or decimal values permitted, e.g.
|
||||
**0x8000** , **10** , etc. Please note that this can dramatically increase the
|
||||
calculation times.
|
||||
|
||||
To decrypt file1, use:
|
||||
|
||||
```
|
||||
./toplip -c 5 -i 0x8000 -d file3.encrypted > file1.decrypted
|
||||
```
|
||||
|
||||
To decrypt file2, use:
|
||||
|
||||
```
|
||||
./toplip -c 10 -i 10 -d file3.encrypted > file2.decrypted
|
||||
```
|
||||
|
||||
To know more about the underlying technical information and crypto methods
|
||||
used in toplip, refer its official website given at the end.
|
||||
|
||||
My personal recommendation to all those who wants to protect their data. Don't
|
||||
rely on single method. Always use more than one tools/methods to encrypt
|
||||
files. Do not write passphrases/passwords in a paper and/or do not save them
|
||||
in your local or cloud storage. Just memorize them and destroy the notes. If
|
||||
you're poor at remembering passwords, consider to use any trustworthy password
|
||||
managers.
|
||||
|
||||
And, that's all. More good stuffs to come. Stay tuned!
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/toplip-strong-file-encryption-decryption-cli-utility/
|
||||
|
||||
作者:[SK][a]
|
||||
译者:[tomjlw](https://github.com/tomjlw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.ostechnix.com/author/sk/
|
||||
[1]:https://www.ostechnix.com/cryptomator-open-source-client-side-encryption-tool-cloud/
|
||||
[2]:https://www.ostechnix.com/how-to-encrypt-your-personal-foldersdirectories-in-linux-mint-ubuntu-distros/
|
||||
[3]:https://www.ostechnix.com/cryptogo-easy-way-encrypt-password-protect-files/
|
||||
[4]:https://www.ostechnix.com/cryptr-simple-cli-utility-encrypt-decrypt-files/
|
||||
[5]:https://www.ostechnix.com/tomb-file-encryption-tool-protect-secret-files-linux/
|
||||
[6]:https://www.ostechnix.com/an-easy-way-to-encrypt-and-decrypt-files-from-commandline-in-linux/
|
||||
[7]:http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
|
||||
[8]:http://en.wikipedia.org/wiki/Scrypt
|
||||
[9]:https://2ton.com.au/Products/
|
||||
[10]:https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-2.png%201366w,%20https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-2-300x157.png%20300w,%20https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-2-768x403.png%20768w,%20https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-2-1024x537.png%201024w
|
||||
[11]:http://www.ostechnix.com/wp-content/uploads/2017/12/toplip-2.png
|
||||
[12]:https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-1.png%20779w,%20https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-1-300x101.png%20300w,%20https://www.ostechnix.com/wp-content/uploads/2017/12/toplip-1-768x257.png%20768w
|
||||
[13]:http://www.ostechnix.com/wp-content/uploads/2017/12/toplip-1.png
|
||||
|
@ -0,0 +1,283 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Build a game framework with Python using the module Pygame)
|
||||
[#]: via: (https://opensource.com/article/17/12/game-framework-python)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Build a game framework with Python using the module Pygame
|
||||
======
|
||||
The first part of this series explored Python by creating a simple dice game. Now it's time to make your own game from scratch.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python2-header.png?itok=tEvOVo4A)
|
||||
|
||||
In my [first article in this series][1], I explained how to use Python to create a simple, text-based dice game. This time, I'll demonstrate how to use the Python module Pygame to create a graphical game. It will take several articles to get a game that actually does anything, but by the end of the series, you will have a better understanding of how to find and learn new Python modules and how to build an application from the ground up.
|
||||
|
||||
Before you start, you must install [Pygame][2].
|
||||
|
||||
### Installing new Python modules
|
||||
|
||||
There are several ways to install Python modules, but the two most common are:
|
||||
|
||||
* From your distribution's software repository
|
||||
* Using the Python package manager, pip
|
||||
|
||||
|
||||
|
||||
Both methods work well, and each has its own set of advantages. If you're developing on Linux or BSD, leveraging your distribution's software repository ensures automated and timely updates.
|
||||
|
||||
However, using Python's built-in package manager gives you control over when modules are updated. Also, it is not OS-specific, meaning you can use it even when you're not on your usual development machine. Another advantage of pip is that it allows local installs of modules, which is helpful if you don't have administrative rights to a computer you're using.
|
||||
|
||||
### Using pip
|
||||
|
||||
If you have both Python and Python3 installed on your system, the command you want to use is probably `pip3`, which differentiates it from Python 2.x's `pip` command. If you're unsure, try `pip3` first.
|
||||
|
||||
The `pip` command works a lot like most Linux package managers. You can search for Python modules with `search`, then install them with `install`. If you don't have permission to install software on the computer you're using, you can use the `--user` option to just install the module into your home directory.
|
||||
|
||||
```
|
||||
$ pip3 search pygame
|
||||
[...]
|
||||
Pygame (1.9.3) - Python Game Development
|
||||
sge-pygame (1.5) - A 2-D game engine for Python
|
||||
pygame_camera (0.1.1) - A Camera lib for PyGame
|
||||
pygame_cffi (0.2.1) - A cffi-based SDL wrapper that copies the pygame API.
|
||||
[...]
|
||||
$ pip3 install Pygame --user
|
||||
```
|
||||
|
||||
Pygame is a Python module, which means that it's just a set of libraries that can be used in your Python programs. In other words, it's not a program that you launch, like [IDLE][3] or [Ninja-IDE][4] are.
|
||||
|
||||
### Getting started with Pygame
|
||||
|
||||
A video game needs a setting; a world in which it takes place. In Python, there are two different ways to create your setting:
|
||||
|
||||
* Set a background color
|
||||
* Set a background image
|
||||
|
||||
|
||||
|
||||
Your background is only an image or a color. Your video game characters can't interact with things in the background, so don't put anything too important back there. It's just set dressing.
|
||||
|
||||
### Setting up your Pygame script
|
||||
|
||||
To start a new Pygame project, create a folder on your computer. All your game files go into this directory. It's vitally important that you keep all the files needed to run your game inside of your project folder.
|
||||
|
||||
![](https://opensource.com/sites/default/files/u128651/project.jpg)
|
||||
|
||||
A Python script starts with the file type, your name, and the license you want to use. Use an open source license so your friends can improve your game and share their changes with you:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python3
|
||||
# by Seth Kenlon
|
||||
|
||||
## GPLv3
|
||||
# This program is free software: you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
```
|
||||
|
||||
Then you tell Python what modules you want to use. Some of the modules are common Python libraries, and of course, you want to include the one you just installed, Pygame.
|
||||
|
||||
```
|
||||
import pygame # load pygame keywords
|
||||
import sys # let python use your file system
|
||||
import os # help python identify your OS
|
||||
```
|
||||
|
||||
Since you'll be working a lot with this script file, it helps to make sections within the file so you know where to put stuff. You do this with block comments, which are comments that are visible only when looking at your source code. Create three blocks in your code.
|
||||
|
||||
```
|
||||
'''
|
||||
Objects
|
||||
'''
|
||||
|
||||
# put Python classes and functions here
|
||||
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
|
||||
# put run-once code here
|
||||
|
||||
'''
|
||||
Main Loop
|
||||
'''
|
||||
|
||||
# put game loop here
|
||||
```
|
||||
|
||||
Next, set the window size for your game. Keep in mind that not everyone has a big computer screen, so it's best to use a screen size that fits on most people's computers.
|
||||
|
||||
There is a way to toggle full-screen mode, the way many modern video games do, but since you're just starting out, keep it simple and just set one size.
|
||||
|
||||
```
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
worldx = 960
|
||||
worldy = 720
|
||||
```
|
||||
|
||||
The Pygame engine requires some basic setup before you can use it in a script. You must set the frame rate, start its internal clock, and start (`init`) Pygame.
|
||||
|
||||
```
|
||||
fps = 40 # frame rate
|
||||
ani = 4 # animation cycles
|
||||
clock = pygame.time.Clock()
|
||||
pygame.init()
|
||||
```
|
||||
|
||||
Now you can set your background.
|
||||
|
||||
### Setting the background
|
||||
|
||||
Before you continue, open a graphics application and create a background for your game world. Save it as `stage.png` inside a folder called `images` in your project directory.
|
||||
|
||||
There are several free graphics applications you can use.
|
||||
|
||||
* [Krita][5] is a professional-level paint materials emulator that can be used to create beautiful images. If you're very interested in creating art for video games, you can even purchase a series of online [game art tutorials][6].
|
||||
* [Pinta][7] is a basic, easy to learn paint application.
|
||||
* [Inkscape][8] is a vector graphics application. Use it to draw with shapes, lines, splines, and Bézier curves.
|
||||
|
||||
|
||||
|
||||
Your graphic doesn't have to be complex, and you can always go back and change it later. Once you have it, add this code in the setup section of your file:
|
||||
|
||||
```
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
backdrop = pygame.image.load(os.path.join('images','stage.png').convert())
|
||||
backdropbox = world.get_rect()
|
||||
```
|
||||
|
||||
If you're just going to fill the background of your game world with a color, all you need is:
|
||||
|
||||
```
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
```
|
||||
|
||||
You also must define a color to use. In your setup section, create some color definitions using values for red, green, and blue (RGB).
|
||||
|
||||
```
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
|
||||
BLUE = (25,25,200)
|
||||
BLACK = (23,23,23 )
|
||||
WHITE = (254,254,254)
|
||||
```
|
||||
|
||||
At this point, you could theoretically start your game. The problem is, it would only last for a millisecond.
|
||||
|
||||
To prove this, save your file as `your-name_game.py` (replace `your-name` with your actual name). Then launch your game.
|
||||
|
||||
If you are using IDLE, run your game by selecting `Run Module` from the Run menu.
|
||||
|
||||
If you are using Ninja, click the `Run file` button in the left button bar.
|
||||
|
||||
![](https://opensource.com/sites/default/files/u128651/ninja_run_0.png)
|
||||
|
||||
You can also run a Python script straight from a Unix terminal or a Windows command prompt.
|
||||
|
||||
```
|
||||
$ python3 ./your-name_game.py
|
||||
```
|
||||
|
||||
If you're using Windows, use this command:
|
||||
|
||||
```
|
||||
py.exe your-name_game.py
|
||||
```
|
||||
|
||||
However you launch it, don't expect much, because your game only lasts a few milliseconds right now. You can fix that in the next section.
|
||||
|
||||
### Looping
|
||||
|
||||
Unless told otherwise, a Python script runs once and only once. Computers are very fast these days, so your Python script runs in less than a second.
|
||||
|
||||
To force your game to stay open and active long enough for someone to see it (let alone play it), use a `while` loop. To make your game remain open, you can set a variable to some value, then tell a `while` loop to keep looping for as long as the variable remains unchanged.
|
||||
|
||||
This is often called a "main loop," and you can use the term `main` as your variable. Add this anywhere in your setup section:
|
||||
|
||||
```
|
||||
main = True
|
||||
```
|
||||
|
||||
During the main loop, use Pygame keywords to detect if keys on the keyboard have been pressed or released. Add this to your main loop section:
|
||||
|
||||
```
|
||||
'''
|
||||
Main loop
|
||||
'''
|
||||
while main == True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit(); sys.exit()
|
||||
main = False
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == ord('q'):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
main = False
|
||||
```
|
||||
|
||||
Also in your main loop, refresh your world's background.
|
||||
|
||||
If you are using an image for the background:
|
||||
|
||||
```
|
||||
world.blit(backdrop, backdropbox)
|
||||
```
|
||||
|
||||
If you are using a color for the background:
|
||||
|
||||
```
|
||||
world.fill(BLUE)
|
||||
```
|
||||
|
||||
Finally, tell Pygame to refresh everything on the screen and advance the game's internal clock.
|
||||
|
||||
```
|
||||
pygame.display.flip()
|
||||
clock.tick(fps)
|
||||
```
|
||||
|
||||
Save your file, and run it again to see the most boring game ever created.
|
||||
|
||||
To quit the game, press `q` on your keyboard.
|
||||
|
||||
In the [next article][9] of this series, I'll show you how to add to your currently empty game world, so go ahead and start creating some graphics to use!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/12/game-framework-python
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/17/10/python-101
|
||||
[2]: http://www.pygame.org/wiki/about
|
||||
[3]: https://en.wikipedia.org/wiki/IDLE
|
||||
[4]: http://ninja-ide.org/
|
||||
[5]: http://krita.org
|
||||
[6]: https://gumroad.com/l/krita-game-art-tutorial-1
|
||||
[7]: https://pinta-project.com/pintaproject/pinta/releases
|
||||
[8]: http://inkscape.org
|
||||
[9]: https://opensource.com/article/17/12/program-game-python-part-3-spawning-player
|
162
sources/tech/20171215 How to add a player to your Python game.md
Normal file
162
sources/tech/20171215 How to add a player to your Python game.md
Normal file
@ -0,0 +1,162 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to add a player to your Python game)
|
||||
[#]: via: (https://opensource.com/article/17/12/game-python-add-a-player)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
How to add a player to your Python game
|
||||
======
|
||||
Part three of a series on building a game from scratch with Python.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python3-game.png?itok=jG9UdwC3)
|
||||
|
||||
In the [first article of this series][1], I explained how to use Python to create a simple, text-based dice game. In the second part, I showed you how to build a game from scratch, starting with [creating the game's environment][2]. But every game needs a player, and every player needs a playable character, so that's what we'll do next in the third part of the series.
|
||||
|
||||
In Pygame, the icon or avatar that a player controls is called a sprite. If you don't have any graphics to use for a player sprite yet, create something for yourself using [Krita][3] or [Inkscape][4]. If you lack confidence in your artistic skills, you can also search [OpenClipArt.org][5] or [OpenGameArt.org][6] for something pre-generated. Then, if you didn't already do so in the previous article, create a directory called `images` alongside your Python project directory. Put the images you want to use in your game into the `images` folder.
|
||||
|
||||
To make your game truly exciting, you ought to use an animated sprite for your hero. It means you have to draw more assets, but it makes a big difference. The most common animation is a walk cycle, a series of drawings that make it look like your sprite is walking. The quick and dirty version of a walk cycle requires four drawings.
|
||||
|
||||
![](https://opensource.com/sites/default/files/u128651/walk-cycle-poses.jpg)
|
||||
|
||||
Note: The code samples in this article allow for both a static player sprite and an animated one.
|
||||
|
||||
Name your player sprite `hero.png`. If you're creating an animated sprite, append a digit after the name, starting with `hero1.png`.
|
||||
|
||||
### Create a Python class
|
||||
|
||||
In Python, when you create an object that you want to appear on screen, you create a class.
|
||||
|
||||
Near the top of your Python script, add the code to create a player. In the code sample below, the first three lines are already in the Python script that you're working on:
|
||||
|
||||
```
|
||||
import pygame
|
||||
import sys
|
||||
import os # new code below
|
||||
|
||||
class Player(pygame.sprite.Sprite):
|
||||
'''
|
||||
Spawn a player
|
||||
'''
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.images = []
|
||||
img = pygame.image.load(os.path.join('images','hero.png')).convert()
|
||||
self.images.append(img)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect()
|
||||
```
|
||||
|
||||
If you have a walk cycle for your playable character, save each drawing as an individual file called `hero1.png` to `hero4.png` in the `images` folder.
|
||||
|
||||
Use a loop to tell Python to cycle through each file.
|
||||
|
||||
```
|
||||
'''
|
||||
Objects
|
||||
'''
|
||||
|
||||
class Player(pygame.sprite.Sprite):
|
||||
'''
|
||||
Spawn a player
|
||||
'''
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.images = []
|
||||
for i in range(1,5):
|
||||
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
|
||||
self.images.append(img)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect()
|
||||
```
|
||||
|
||||
### Bring the player into the game world
|
||||
|
||||
Now that a Player class exists, you must use it to spawn a player sprite in your game world. If you never call on the Player class, it never runs, and there will be no player. You can test this out by running your game now. The game will run just as well as it did at the end of the previous article, with the exact same results: an empty game world.
|
||||
|
||||
To bring a player sprite into your world, you must call the Player class to generate a sprite and then add it to a Pygame sprite group. In this code sample, the first three lines are existing code, so add the lines afterwards:
|
||||
|
||||
```
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
|
||||
backdropbox = screen.get_rect()
|
||||
|
||||
# new code below
|
||||
|
||||
player = Player() # spawn player
|
||||
player.rect.x = 0 # go to x
|
||||
player.rect.y = 0 # go to y
|
||||
player_list = pygame.sprite.Group()
|
||||
player_list.add(player)
|
||||
```
|
||||
|
||||
Try launching your game to see what happens. Warning: it won't do what you expect. When you launch your project, the player sprite doesn't spawn. Actually, it spawns, but only for a millisecond. How do you fix something that only happens for a millisecond? You might recall from the previous article that you need to add something to the main loop. To make the player spawn for longer than a millisecond, tell Python to draw it once per loop.
|
||||
|
||||
Change the bottom clause of your loop to look like this:
|
||||
|
||||
```
|
||||
world.blit(backdrop, backdropbox)
|
||||
player_list.draw(screen) # draw player
|
||||
pygame.display.flip()
|
||||
clock.tick(fps)
|
||||
```
|
||||
|
||||
Launch your game now. Your player spawns!
|
||||
|
||||
### Setting the alpha channel
|
||||
|
||||
Depending on how you created your player sprite, it may have a colored block around it. What you are seeing is the space that ought to be occupied by an alpha channel. It's meant to be the "color" of invisibility, but Python doesn't know to make it invisible yet. What you are seeing, then, is the space within the bounding box (or "hit box," in modern gaming terms) around the sprite.
|
||||
|
||||
![](https://opensource.com/sites/default/files/u128651/greenscreen.jpg)
|
||||
|
||||
You can tell Python what color to make invisible by setting an alpha channel and using RGB values. If you don't know the RGB values your drawing uses as alpha, open your drawing in Krita or Inkscape and fill the empty space around your drawing with a unique color, like #00ff00 (more or less a "greenscreen green"). Take note of the color's hex value (#00ff00, for greenscreen green) and use that in your Python script as the alpha channel.
|
||||
|
||||
Using alpha requires the addition of two lines in your Sprite creation code. Some version of the first line is already in your code. Add the other two lines:
|
||||
|
||||
```
|
||||
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
|
||||
img.convert_alpha() # optimise alpha
|
||||
img.set_colorkey(ALPHA) # set alpha
|
||||
```
|
||||
|
||||
Python doesn't know what to use as alpha unless you tell it. In the setup area of your code, add some more color definitions. Add this variable definition anywhere in your setup section:
|
||||
|
||||
```
|
||||
ALPHA = (0, 255, 0)
|
||||
```
|
||||
|
||||
In this example code, **0,255,0** is used, which is the same value in RGB as #00ff00 is in hex. You can get all of these color values from a good graphics application like [GIMP][7], Krita, or Inkscape. Alternately, you can also detect color values with a good system-wide color chooser, like [KColorChooser][8].
|
||||
|
||||
![](https://opensource.com/sites/default/files/u128651/kcolor.png)
|
||||
|
||||
If your graphics application is rendering your sprite's background as some other value, adjust the values of your alpha variable as needed. No matter what you set your alpha value, it will be made "invisible." RGB values are very strict, so if you need to use 000 for alpha, but you need 000 for the black lines of your drawing, just change the lines of your drawing to 111, which is close enough to black that nobody but a computer can tell the difference.
|
||||
|
||||
Launch your game to see the results.
|
||||
|
||||
![](https://opensource.com/sites/default/files/u128651/alpha.jpg)
|
||||
|
||||
In the [fourth part of this series][9], I'll show you how to make your sprite move. How exciting!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/12/game-python-add-a-player
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/17/10/python-101
|
||||
[2]: https://opensource.com/article/17/12/program-game-python-part-2-creating-game-world
|
||||
[3]: http://krita.org
|
||||
[4]: http://inkscape.org
|
||||
[5]: http://openclipart.org
|
||||
[6]: https://opengameart.org/
|
||||
[7]: http://gimp.org
|
||||
[8]: https://github.com/KDE/kcolorchooser
|
||||
[9]: https://opensource.com/article/17/12/program-game-python-part-4-moving-your-sprite
|
@ -1,156 +0,0 @@
|
||||
Power(Shell) to the people
|
||||
======
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_lightbulbs.png?itok=pwp22hTw)
|
||||
|
||||
Earlier this year, [PowerShell Core][1] [became generally available][2] under an Open Source ([MIT][3]) license. PowerShell is hardly a new technology. From its first release for Windows in 2006, PowerShell's creators [sought][4] to incorporate the power and flexibility of Unix shells while remedying their perceived deficiencies, particularly the need for text manipulation to derive value from combining commands.
|
||||
|
||||
Five major releases later, PowerShell Core allows the same innovative shell and command environment to run natively on all major operating systems, including OS X and Linux. Some (read: almost everyone) may still scoff at the audacity and/or the temerity of this Windows-born interloper to offer itself to platforms that have had strong shell environments since time immemorial (at least as defined by a millennial). In this post, I hope to make the case that PowerShell can provide advantages to even seasoned users.
|
||||
|
||||
### Consistency across platforms
|
||||
|
||||
If you plan to port your scripts from one execution environment to another, you need to make sure you use only the commands and syntaxes that work. For example, on GNU systems, you would obtain yesterday's date as follows:
|
||||
```
|
||||
date --date="1 day ago"
|
||||
|
||||
```
|
||||
|
||||
On BSD systems (such as OS X), the above syntax wouldn't work, as the BSD date utility requires the following syntax:
|
||||
```
|
||||
date -v -1d
|
||||
|
||||
```
|
||||
|
||||
Because PowerShell is licensed under a permissive license and built for all platforms, you can ship it with your application. Thus, when your scripts run in the target environment, they'll be running on the same shell using the same command implementations as the environment in which you tested your scripts.
|
||||
|
||||
### Objects and structured data
|
||||
|
||||
*nix commands and utilities rely on your ability to consume and manipulate unstructured data. Those who have lived for years with `sed` `grep` and `awk` may be unbothered by this statement, but there is a better way.
|
||||
|
||||
Let's redo the yesterday's date example in PowerShell. To get the current date, run the `Get-Date` cmdlet (pronounced "commandlet"):
|
||||
```
|
||||
> Get-Date
|
||||
|
||||
|
||||
|
||||
Sunday, January 21, 2018 8:12:41 PM
|
||||
|
||||
```
|
||||
|
||||
The output you see isn't really a string of text. Rather, it is a string representation of a .Net Core object. Just like any other object in any other OOP environment, it has a type and most often, methods you can call.
|
||||
|
||||
Let's prove this:
|
||||
```
|
||||
> $(Get-Date).GetType().FullName
|
||||
|
||||
System.DateTime
|
||||
|
||||
```
|
||||
|
||||
The `$(...)` syntax behaves exactly as you'd expect from POSIX shells—the result of the evaluation of the command in parentheses is substituted for the entire expression. In PowerShell, however, the $ is strictly optional in such expressions. And, most importantly, the result is a .Net object, not text. So we can call the `GetType()` method on that object to get its type object (similar to `Class` object in Java), and the `FullName` [property][5] to get the full name of the type.
|
||||
|
||||
So, how does this object-orientedness make your life easier?
|
||||
|
||||
First, you can pipe any object to the `Get-Member` cmdlet to see all the methods and properties it has to offer.
|
||||
```
|
||||
> (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 ...
|
||||
```
|
||||
|
||||
You can quickly see that the DateTime object has an `AddDays` that you can quickly use to get yesterday's date:
|
||||
```
|
||||
> (Get-Date).AddDays(-1)
|
||||
|
||||
|
||||
Saturday, January 20, 2018 8:24:42 PM
|
||||
```
|
||||
|
||||
To do something slightly more exciting, let's call Yahoo's weather service (because it doesn't require an API token) and get your local weather.
|
||||
```
|
||||
$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"
|
||||
```
|
||||
|
||||
Now, we could do things the old-fashioned way and just run `curl $url` to get a giant blob of JSON, or...
|
||||
```
|
||||
$weather=(Invoke-RestMethod $url)
|
||||
```
|
||||
|
||||
If you look at the type of `$weather` (by running `echo $weather.GetType().FullName`), you will see that it's a `PSCustomObject`. It's a dynamic object that reflects the structure of the JSON.
|
||||
|
||||
And PowerShell will be thrilled to help you navigate through it with its tab completion. Just type `$weather.` (making sure to include the ".") and press Tab. You will see all the root-level JSON keys. Type one, followed by a "`.`", press Tab again, and you'll see its children (if any).
|
||||
|
||||
Thus, you can easily navigate to the data you want:
|
||||
```
|
||||
> echo $weather.query.results.channel.atmosphere.pressure
|
||||
1019.0
|
||||
|
||||
|
||||
> echo $weather.query.results.channel.wind.chill
|
||||
41
|
||||
```
|
||||
|
||||
And if you have JSON or CSV lying around (or returned by an outside command) as unstructured data, just pipe it into the `ConvertFrom-Json` or `ConvertFrom-CSV` cmdlet, respectively, and you can have your data in nice clean objects.
|
||||
|
||||
### Computing vs. automation
|
||||
|
||||
We use shells for two purposes. One is for computing, to run individual commands and to manually respond to their output. The other is automation, to write scripts that execute multiple commands and respond to their output programmatically.
|
||||
|
||||
A problem that most of us have learned to overlook is that these two purposes place different and conflicting requirements on the shell. Computing requires the shell to be laconic. The fewer keystrokes a user can get away with, the better. It's unimportant if what the user has typed is barely legible to another human being. Scripts, on the other hand, are code. Readability and maintainability are key. And here, POSIX utilities often fail us. While some commands do offer both laconic and readable syntaxes (e.g. `-f` and `--force`) for some of their parameters, the command names themselves err on the side of brevity, not readability.
|
||||
|
||||
PowerShell includes several mechanisms to eliminate that Faustian tradeoff.
|
||||
|
||||
First, tab completion eliminates typing of argument names. For instance, type `Get-Random -Mi`, press Tab and PowerShell will complete the argument for you: `Get-Random -Minimum`. But if you really want to be laconic, you don't even need to press Tab. For instance, PowerShell will understand
|
||||
```
|
||||
Get-Random -Mi 1 -Ma 10
|
||||
```
|
||||
|
||||
because `Mi` and `Ma` each have unique completions.
|
||||
|
||||
You may have noticed that all PowerShell cmdlet names have a verb-noun structure. This can help script readability, but you probably don't want to keep typing `Get-` over and over in the command line. So don't! If you type a noun without a verb, PowerShell will look for a `Get-` command with that noun.
|
||||
|
||||
Caution: although PowerShell is not case-sensitive, it's a good practice to capitalize the first letter of the noun when you intend to use a PowerShell command. For example, typing `date` will call your system's `date` utility. Typing `Date` will call PowerShell's `Get-Date` cmdlet.
|
||||
|
||||
And if that's not enough, PowerShell has aliases to create simple names. For example, if you type `alias -name cd`, you will discover the `cd` command in PowerShell is itself an alias for the `Set-Location` command.
|
||||
|
||||
So to review—you get powerful tab completion, aliases, and noun completions to keep your command names short, automatic and consistent parameter name truncation, while still enjoying a rich, readable syntax for scripting.
|
||||
|
||||
### So... friends?
|
||||
|
||||
There are just some of the advantages of PowerShell. There are more features and cmdlets I haven't discussed (check out [Where-Object][6] or its alias `?` if you want to make `grep` cry). And hey, if you really feel homesick, PowerShell will be happy to launch your old native utilities for you. But give yourself enough time to get acclimated in PowerShell's object-oriented cmdlet world, and you may find yourself choosing to forget the way back.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/2/powershell-people
|
||||
|
||||
作者:[Yev Bronshteyn][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/yevster
|
||||
[1]:https://github.com/PowerShell/PowerShell/blob/master/README.md
|
||||
[2]:https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-core-6-0-generally-available-ga-and-supported/
|
||||
[3]:https://spdx.org/licenses/MIT
|
||||
[4]:http://www.jsnover.com/Docs/MonadManifesto.pdf
|
||||
[5]:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
|
||||
[6]:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6
|
@ -1,212 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (JSON vs XML vs TOML vs CSON vs YAML)
|
||||
[#]: via: (https://www.zionandzion.com/json-vs-xml-vs-toml-vs-cson-vs-yaml/)
|
||||
[#]: author: (Tim Anderson https://www.zionandzion.com)
|
||||
|
||||
JSON vs XML vs TOML vs CSON vs YAML
|
||||
======
|
||||
|
||||
|
||||
### A Super Serious Segment About Sets, Subsets, and Supersets of Sample Serialization
|
||||
|
||||
I’m a developer. I read code. I write code. I write code that writes code. I write code that writes code for other code to read. It’s all very mumbo-jumbo, but beautiful in its own way. However, that last bit, writing code that writes code for other code to read, can get more convoluted than this paragraph—quickly. There are a lot of ways to do it. One not-so-convoluted way and a favorite among the developer community is through data serialization. For those who aren’t savvy on the super buzzword I just threw at you, data serialization is the process of taking some information from one system, churning it into a format that other systems can read, and then passing it along to those other systems.
|
||||
|
||||
While there are enough [data serialization formats][1] out there to bury the Burj Khalifa, they all mostly fall into two categories:
|
||||
|
||||
* simplicity for humans to read and write,
|
||||
* and simplicity for machines to read and write.
|
||||
|
||||
|
||||
|
||||
It’s difficult to have both as we humans enjoy loosely typed, flexible formatting standards that allow us to be more expressive, whereas machines tend to enjoy being told exactly what everything is without doubt or lack of detail, and consider “strict specifications” to be their favorite flavor of Ben & Jerry’s.
|
||||
|
||||
Since I’m a web developer and we’re an agency who creates websites, we’ll stick to those special formats that web systems can understand, or be made to understand without much effort, and that are particularly useful for human readability: XML, JSON, TOML, CSON, and YAML. Each has benefits, cons, and appropriate use cases.
|
||||
|
||||
### Facts First
|
||||
|
||||
Back in the early days of the interwebs, [some really smart fellows][2] decided to put together a standard language which every system could read and creatively named it Standard Generalized Markup Language, or SGML for short. SGML was incredibly flexible and well defined by its publishers. It became the father of languages such as XML, SVG, and HTML. All three fall under the SGML specification, but are subsets with stricter rules and shorter flexibility.
|
||||
|
||||
Eventually, people started seeing a great deal of benefit in having very small, concise, easy to read, and easy to generate data that could be shared programmatically between systems with very little overhead. Around that time, JSON was born and was able to fulfil all requirements. In turn, other languages began popping up to deal with more specialized cases such as CSON, TOML, and YAML.
|
||||
|
||||
### XML: Ixnayed
|
||||
|
||||
Originally, the XML language was amazingly flexible and easy to write, but its drawback was that it was verbose, difficult for humans to read, really difficult for computers to read, and had a lot of syntax that wasn’t entirely necessary to communicate information.
|
||||
|
||||
Today, it’s all but dead for data serialization purposes on the web. Unless you’re writing HTML or SVG, both siblings to XML, you probably aren’t going to see XML in too many other places. Some outdated systems still use it today, but using it to pass data around tends to be overkill for the web.
|
||||
|
||||
I can already hear the XML greybeards beginning to scribble upon their stone tablets as to why XML is ah-may-zing, so I’ll provide a small addendum: XML can be easy to read and write by systems and people. However, it is really, and I mean ridiculously, hard to create a system that can read it to specification. Here’s a simple, beautiful example of XML:
|
||||
|
||||
```
|
||||
<book id="bk101">
|
||||
<author>Gambardella, Matthew</author>
|
||||
<title>XML Developer's Guide</title>
|
||||
<genre>Computer</genre>
|
||||
<price>44.95</price>
|
||||
<publish_date>2000-10-01</publish_date>
|
||||
<description>An in-depth look at creating applications
|
||||
with XML.</description>
|
||||
</book>
|
||||
```
|
||||
|
||||
Wonderful. Easy to read, reason about, write, and code a system that can read and write. But consider this example:
|
||||
|
||||
```
|
||||
<!DOCTYPE r [ <!ENTITY y "a]>b"> ]>
|
||||
<r>
|
||||
<a b="&y;>" />
|
||||
<![CDATA[[a>b <a>b <a]]>
|
||||
<?x <a> <!-- <b> ?> c --> d
|
||||
</r>
|
||||
```
|
||||
|
||||
The above is 100% valid XML. Impossible to read, understand, or reason about. Writing code that can consume and understand this would cost at least 36 heads of hair and 248 pounds of coffee grounds. We don’t have that kind of time nor coffee, and most of us greybeards are balding nowadays. So let’s let it live only in our memory alongside [css hacks][3], [internet explorer 6][4], and [vacuum tubes][5].
|
||||
|
||||
### JSON: Juxtaposition Jamboree
|
||||
|
||||
Okay, we’re all in agreement. XML = bad. So, what’s a good alternative? JavaScript Object Notation, or JSON for short. JSON (read like the name Jason) was invented by Brendan Eich, and made popular by the great and powerful Douglas Crockford, the [Dutch Uncle of JavaScript][6]. It’s used just about everywhere nowadays. The format is easy to write by both human and machine, fairly easy to [parse][7] with strict rules in the specification, and flexible—allowing deep nesting of data, all of the primitive data types, and interpretation of collections as either arrays or objects. JSON became the de facto standard for transferring data from one system to another. Nearly every language out there has built-in functionality for reading and writing it.
|
||||
|
||||
JSON syntax is straightforward. Square brackets denote arrays, curly braces denote records, and two values separated by semicolons denote properties (or ‘keys’) on the left, and values on the right. All keys must be wrapped in double quotes:
|
||||
|
||||
```
|
||||
{
|
||||
"books": [
|
||||
{
|
||||
"id": "bk102",
|
||||
"author": "Crockford, Douglas",
|
||||
"title": "JavaScript: The Good Parts",
|
||||
"genre": "Computer",
|
||||
"price": 29.99,
|
||||
"publish_date": "2008-05-01",
|
||||
"description": "Unearthing the Excellence in JavaScript"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This should make complete sense to you. It’s nice and concise, and has stripped much of the extra nonsense from XML to convey the same amount of information. JSON is king right now, and the rest of this article will go into other language formats that are nothing more than JSON boiled down in an attempt to be either more concise or more readable by humans, but follow very similar structure.
|
||||
|
||||
### TOML: Truncated to Total Altruism
|
||||
|
||||
TOML (Tom’s Obvious, Minimal Language) allows for defining deeply-nested data structures rather quickly and succinctly. The name-in-the-name refers to the inventor, [Tom Preston-Werner][8], an inventor and software developer who’s active in our industry. The syntax is a bit awkward when compared to JSON, and is more akin to an [ini file][9]. It’s not a bad syntax, but could take some getting used to:
|
||||
|
||||
```
|
||||
[[books]]
|
||||
id = 'bk101'
|
||||
author = 'Crockford, Douglas'
|
||||
title = 'JavaScript: The Good Parts'
|
||||
genre = 'Computer'
|
||||
price = 29.99
|
||||
publish_date = 2008-05-01T00:00:00+00:00
|
||||
description = 'Unearthing the Excellence in JavaScript'
|
||||
```
|
||||
|
||||
A couple great features have been integrated into TOML, such as multiline strings, auto-escaping of reserved characters, datatypes such as dates, time, integers, floats, scientific notation, and “table expansion”. That last bit is special, and is what makes TOML so concise:
|
||||
|
||||
```
|
||||
[a.b.c]
|
||||
d = 'Hello'
|
||||
e = 'World'
|
||||
```
|
||||
|
||||
The above expands to the following:
|
||||
|
||||
```
|
||||
{
|
||||
"a": {
|
||||
"b": {
|
||||
"c": {
|
||||
"d": "Hello"
|
||||
"e": "World"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can definitely see how much you can save in both time and file length using TOML. There are few systems which use it or something very similar for configuration, and that is its biggest con. There simply aren’t very many languages or libraries out there written to interpret TOML.
|
||||
|
||||
### CSON: Simple Samples Enslaved by Specific Systems
|
||||
|
||||
First off, there are two CSON specifications. One stands for CoffeeScript Object Notation, the other stands for Cursive Script Object Notation. The latter isn’t used too often, so we won’t be getting into it. Let’s just focus on the CoffeeScript one.
|
||||
|
||||
[CSON][10] will take a bit of intro. First, let’s talk about CoffeeScript. [CoffeeScript][11] is a language that runs through a compiler to generate JavaScript. It allows you to write JavaScript in a more syntactically concise way, and have it [transcompiled][12] into actual JavaScript, which you would then use in your web application. CoffeeScript makes writing JavaScript easier by removing a lot of the extra syntax necessary in JavaScript. A big one that CoffeeScript gets rid of is curly braces—no need for them. In that same token, CSON is JSON without the curly braces. It instead relies on indentation to determine hierarchy of your data. CSON is very easy to read and write and usually requires fewer lines of code than JSON because there are no brackets.
|
||||
|
||||
CSON also offers up some extra niceties that JSON doesn’t have to offer. Multiline strings are incredibly easy to write, you can enter [comments][13] by starting a line with a hash, and there’s no need for separating key-value pairs with commas.
|
||||
|
||||
```
|
||||
books: [
|
||||
id: 'bk102'
|
||||
author: 'Crockford, Douglas'
|
||||
title: 'JavaScript: The Good Parts'
|
||||
genre: 'Computer'
|
||||
price: 29.99
|
||||
publish_date: '2008-05-01'
|
||||
description: 'Unearthing the Excellence in JavaScript'
|
||||
]
|
||||
```
|
||||
|
||||
Here’s the big issue with CSON. It’s **CoffeeScript** Object Notation. Meaning CoffeeScript is what you use to parse/tokenize/lex/transcompile or otherwise use CSON. CoffeeScript is the system that reads the data. If the intent of data serialization is to allow data to be passed from one system to another, and here we have a data serialization format that’s only read by a single system, well that makes it about as useful as a fireproof match, or a waterproof sponge, or that annoyingly flimsy fork part of a spork.
|
||||
|
||||
If this format is adopted by other systems, it could be pretty useful in the developer world. Thus far that hasn’t happened in a comprehensive manner, so using it in alternative languages such as PHP or JAVA are a no-go.
|
||||
|
||||
### YAML: Yielding Yips from Youngsters
|
||||
|
||||
Developers rejoice, as YAML comes into the scene from [one of the contributors to Python][14]. YAML has the same feature set and similar syntax as CSON, a boatload of new features, and parsers available in just about every web programming language there is. It also has some extra features, like circular referencing, soft-wraps, multi-line keys, typecasting tags, binary data, object merging, and [set maps][15]. It has incredibly good human readability and writability, and is a superset of JSON, so you can use fully qualified JSON syntax inside YAML and all will work well. You almost never need quotes, and it can interpret most of your base data types (strings, integers, floats, booleans, etc.).
|
||||
|
||||
```
|
||||
books:
|
||||
- id: bk102
|
||||
author: Crockford, Douglas
|
||||
title: 'JavaScript: The Good Parts'
|
||||
genre: Computer
|
||||
price: 29.99
|
||||
publish_date: !!str 2008-05-01
|
||||
description: Unearthing the Excellence in JavaScript
|
||||
```
|
||||
|
||||
The younglings of the industry are rapidly adopting YAML as their preferred data serialization and system configuration format. They are smart to do so. YAML has all the benefits of being as terse as CSON, and all the features of datatype interpretation as JSON. YAML is as easy to read as Canadians are to hang out with.
|
||||
|
||||
There are two issues with YAML that stick out to me, and the first is a big one. At the time of this writing, YAML parsers haven’t yet been built into very many languages, so you’ll need to use a third-party library or extension for your chosen language to parse .yaml files. This wouldn’t be a big deal, however it seems most developers who’ve created parsers for YAML have chosen to throw “additional features” into their parsers at random. Some allow [tokenization][16], some allow [chain referencing][17], some even allow inline calculations. This is all well and good (sort of), except that none of these features are part of the specification, and so are difficult to find amongst other parsers in other languages. This results in system-locking; you end up with the same issue that CSON is subject to. If you use a feature found in only one parser, other parsers won’t be able to interpret the input. Most of these features are nonsense that don’t belong in a dataset, but rather in your application logic, so it’s best to simply ignore them and write your YAML to specification.
|
||||
|
||||
The second issue is there are few parsers that yet completely implement the specification. All the basics are there, but it can be difficult to find some of the more complex and newer things like soft-wraps, document markers, and circular references in your preferred language. I have yet to see an absolute need for these things, so hopefully they shouldn’t slow you down too much. With the above considered, I tend to keep to the more matured feature set presented in the [1.1 specification][18], and avoid the newer stuff found in the [1.2 specification][19]. However, programming is an ever-evolving monster, so by the time you finish reading this article, you’re likely to be able to use the 1.2 spec.
|
||||
|
||||
### Final Philosophy
|
||||
|
||||
The final word here is that each serialization language should be treated with a case-by-case reverence. Some are the bee’s knees when it comes to machine readability, some are the cat’s meow for human readability, and some are simply gilded turds. Here’s the ultimate breakdown: If you are writing code for other code to read, use YAML. If you are writing code that writes code for other code to read, use JSON. Finally, if you are writing code that transcompiles code into code that other code will read, rethink your life choices.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.zionandzion.com/json-vs-xml-vs-toml-vs-cson-vs-yaml/
|
||||
|
||||
作者:[Tim Anderson][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.zionandzion.com
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats
|
||||
[2]: https://en.wikipedia.org/wiki/Standard_Generalized_Markup_Language#History
|
||||
[3]: https://www.quirksmode.org/css/csshacks.html
|
||||
[4]: http://www.ie6death.com/
|
||||
[5]: https://en.wikipedia.org/wiki/Vacuum_tube
|
||||
[6]: https://twitter.com/BrendanEich/status/773403975865470976
|
||||
[7]: https://en.wikipedia.org/wiki/Parsing#Parser
|
||||
[8]: https://en.wikipedia.org/wiki/Tom_Preston-Werner
|
||||
[9]: https://en.wikipedia.org/wiki/INI_file
|
||||
[10]: https://github.com/bevry/cson#what-is-cson
|
||||
[11]: http://coffeescript.org/
|
||||
[12]: https://en.wikipedia.org/wiki/Source-to-source_compiler
|
||||
[13]: https://en.wikipedia.org/wiki/Comment_(computer_programming)
|
||||
[14]: http://clarkevans.com/
|
||||
[15]: http://exploringjs.com/es6/ch_maps-sets.html
|
||||
[16]: https://www.tutorialspoint.com/compiler_design/compiler_design_lexical_analysis.htm
|
||||
[17]: https://en.wikipedia.org/wiki/Fluent_interface
|
||||
[18]: http://yaml.org/spec/1.1/current.html
|
||||
[19]: http://www.yaml.org/spec/1.2/spec.html
|
@ -1,241 +0,0 @@
|
||||
Python ChatOps libraries: Opsdroid and Errbot
|
||||
======
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/idea_innovation_mobile_phone.png?itok=RqVtvxkd)
|
||||
This article was co-written with [Lacey Williams Henschel][1].
|
||||
|
||||
ChatOps is conversation-driven development. The idea is you can write code that is executed in response to something typed in a chat window. As a developer, you could use ChatOps to merge pull requests from Slack, automatically assign a support ticket to someone from a received Facebook message, or check the status of a deployment through IRC.
|
||||
|
||||
In the Python world, the most widely used ChatOps libraries are Opsdroid and Errbot. In this month's Python column, let's chat about what it's like to use them, what each does well, and how to get started with them.
|
||||
|
||||
### Opsdroid
|
||||
|
||||
[Opsdroid][2] is a relatively young (since 2016) open source chatbot library written in Python. It has good documentation, a great tutorial, and includes plugins to help you connect to popular chat services.
|
||||
|
||||
#### What's built in
|
||||
|
||||
The library itself doesn't ship with everything you need to get started, but this is by design. The lightweight framework encourages you to enable its existing connectors (what Opsdroid calls the plugins that help you connect to chat services) or write your own, but it doesn't weigh itself down by shipping with connectors you may not need. You can easily enable existing Opsdroid connectors for:
|
||||
|
||||
|
||||
+ The command line
|
||||
+ Cisco Spark
|
||||
+ Facebook
|
||||
+ GitHub
|
||||
+ Matrix
|
||||
+ Slack
|
||||
+ Telegram
|
||||
+ Twitter
|
||||
+ Websockets
|
||||
|
||||
|
||||
Opsdroid calls the functions the chatbot performs "skills." Skills are `async` Python functions and use Opsdroid's matching decorators, called "matchers." You can configure your Opsdroid project to use skills from the same codebase your configuration file is in or import skills from outside public or private repositories.
|
||||
|
||||
You can enable some existing Opsdroid skills as well, including [seen][3], which tells you when a specific user was last seen by the bot, and [weather][4], which will report the weather to the user.
|
||||
|
||||
Finally, Opdroid allows you to configure databases using its existing database modules. Current databases with Opsdroid support include:
|
||||
|
||||
|
||||
+ Mongo
|
||||
+ Redis
|
||||
+ SQLite
|
||||
|
||||
|
||||
You configure databases, skills, and connectors in the `configuration.yaml` file in your Opsdroid project.
|
||||
|
||||
#### Opsdroid pros
|
||||
|
||||
**Docker support:** Opsdroid is meant to work well in Docker from the get-go. Docker instructions are part of its [installation documentation][5]. Using Opsdroid with Docker Compose is also simple: Set up Opsdroid as a service and when you run `docker-compose up`, your Opsdroid service will start and your chatbot will be ready to chat.
|
||||
```
|
||||
version: "3"
|
||||
|
||||
|
||||
|
||||
services:
|
||||
|
||||
opsdroid:
|
||||
|
||||
container_name: opsdroid
|
||||
|
||||
build:
|
||||
|
||||
context: .
|
||||
|
||||
dockerfile: Dockerfile
|
||||
|
||||
```
|
||||
|
||||
**Lots of connectors:** Opsdroid supports nine connectors to services like Slack and GitHub out of the box; all you need to do is enable those connectors in your configuration file and pass necessary tokens or API keys. For example, to enable Opsdroid to post in a Slack channel named `#updates`, add this to the `connectors` section of your configuration file:
|
||||
```
|
||||
- name: slack
|
||||
|
||||
api-token: "this-is-my-token"
|
||||
|
||||
default-room: "#updates"
|
||||
|
||||
```
|
||||
|
||||
You will have to [add a bot user][6] to your Slack workspace before configuring Opsdroid to connect to Slack.
|
||||
|
||||
If you need to connect to a service that Opsdroid does not support, there are instructions for adding your own connectors in the [docs][7].
|
||||
|
||||
**Pretty good docs.** Especially for a young-ish library in active development, Opsdroid's docs are very helpful. The docs include a [tutorial][8] that leads you through creating a couple of different basic skills. The Opsdroid documentation on [skills][9], [connectors][7], [databases][10], and [matchers][11] is also clear.
|
||||
|
||||
The repositories for its supported skills and connectors provide helpful example code for when you start writing your own custom skills and connectors.
|
||||
|
||||
**Natural language processing:** Opsdroid supports regular expressions for its skills, but also several NLP APIs, including [Dialogflow][12], [luis.ai][13], [Recast.AI][14], and [wit.ai][15].
|
||||
|
||||
#### Possible Opsdroid concern
|
||||
|
||||
Opsdroid doesn't yet enable the full features of some of its connectors. For example, the Slack API allows you to add color bars, images, and other "attachments" to your message. The Opsdroid Slack connector doesn't enable the "attachments" feature, so you would need to write a custom Slack connector if those features were important to you. If a connector is missing a feature you need, though, Opsdroid would welcome your [contribution][16]. The docs could use some more examples, especially of expected use cases.
|
||||
|
||||
#### Example usage
|
||||
|
||||
`hello/__init__.py`
|
||||
```
|
||||
from opsdroid.matchers import match_regex
|
||||
|
||||
import random
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@match_regex(r'hi|hello|hey|hallo')
|
||||
|
||||
async def hello(opsdroid, config, message):
|
||||
|
||||
text = random.choice(["Hi {}", "Hello {}", "Hey {}"]).format(message.user)
|
||||
|
||||
await message.respond(text)
|
||||
|
||||
```
|
||||
|
||||
`configuration.yaml`
|
||||
```
|
||||
connectors:
|
||||
|
||||
- name: websocket
|
||||
|
||||
|
||||
|
||||
skills:
|
||||
|
||||
|
||||
|
||||
- name: hello
|
||||
|
||||
repo: "https://github.com/<user_id>/hello-skill"
|
||||
|
||||
```
|
||||
|
||||
### Errbot
|
||||
|
||||
[Errbot][17] is a batteries-included open source chatbot. Errbot was released in 2012 and has everything anyone would expect from a mature project, including good documentation, a great tutorial, and plenty of plugins to help you connect to existing popular chat services.
|
||||
|
||||
#### What's built in
|
||||
|
||||
Unlike Opsdroid, which takes a more lightweight approach, Errbot ships with everything you need to build a customized bot safely.
|
||||
|
||||
Errbot includes support for XMPP, IRC, Slack, Hipchat, and Telegram services natively. It lists support for 10 other services through community-supplied backends.
|
||||
|
||||
#### Errbot pros
|
||||
|
||||
**Good docs:** Errbot's docs are mature and easy to use.
|
||||
|
||||
**Dynamic plugin architecture:** Errbot allow you to securely install, uninstall, update, enable, and disable plugins by chatting with the bot. This makes development and adding features easy. For the security conscious, this can all be locked down thanks to Errbot's granular permission system.
|
||||
|
||||
Errbot uses your plugin docstrings to generate documentation for available commands when someone types `!help`, which makes it easier to know what each command does.
|
||||
|
||||
**Built-in administration and security:** Errbot allows you to restrict lists of users who have administrative rights and even has fine-grained access controls. For example, you can restrict which commands may be called by specific users and/or specific rooms.
|
||||
|
||||
**Extensive plugin framework:** Errbot supports hooks, callbacks, subcommands, webhooks, polling, and many [more features][18]. If those aren't enough, you can even write [Dynamic plugins][19]. This feature is useful if you want to enable chat commands based on what commands are available on a remote server.
|
||||
|
||||
**Ships with a testing framework:** Errbot supports [pytest][20] and ships with some useful utilities that make testing your plugins easy and possible. Its "[testing your plugins][21]" docs are well thought out and provide enough to get started.
|
||||
|
||||
#### Possible Errbot concerns
|
||||
|
||||
**Initial !:** By default, Errbot commands are issued starting with an exclamation mark (`!help` and `!hello`). Some people may like this, but others may find it annoying. Thankfully, this is easy to turn off.
|
||||
|
||||
**Plugin metadata:** At first, Errbot's [Hello World][22] plugin example seems easy to use. However, I couldn't get my plugin to load until I read further into the tutorial and discovered that I also needed a `.plug` file, a file Errbot uses to load plugins. This is a pretty minor nitpick, but it wasn't obvious to me until I dug further into the docs.
|
||||
|
||||
#### Example usage
|
||||
|
||||
`hello.py`
|
||||
```
|
||||
import random
|
||||
|
||||
from errbot import BotPlugin, botcmd
|
||||
|
||||
|
||||
|
||||
class Hello(BotPlugin):
|
||||
|
||||
|
||||
|
||||
@botcmd
|
||||
|
||||
def hello(self, msg, args):
|
||||
|
||||
text = random.choice(["Hi {}", "Hello {}", "Hey {}"]).format(message.user)
|
||||
|
||||
return text
|
||||
|
||||
```
|
||||
|
||||
`hello.plug`
|
||||
```
|
||||
[Core]
|
||||
|
||||
Name = Hello
|
||||
|
||||
Module = hello
|
||||
|
||||
|
||||
|
||||
[Python]
|
||||
|
||||
Version = 2+
|
||||
|
||||
|
||||
|
||||
[Documentation]
|
||||
|
||||
Description = Example "Hello" plugin
|
||||
|
||||
```
|
||||
|
||||
Have you used Errbot or Opsdroid? If so, please leave a comment with your impressions on these tools.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/3/python-chatops-libraries-opsdroid-and-errbot
|
||||
|
||||
作者:[Jeff Triplett][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/laceynwilliams
|
||||
[1]:https://opensource.com/users/laceynwilliams
|
||||
[2]:https://opsdroid.github.io/
|
||||
[3]:https://github.com/opsdroid/skill-seen
|
||||
[4]:https://github.com/opsdroid/skill-weather
|
||||
[5]:https://opsdroid.readthedocs.io/en/stable/#docker
|
||||
[6]:https://api.slack.com/bot-users
|
||||
[7]:https://opsdroid.readthedocs.io/en/stable/extending/connectors/
|
||||
[8]:https://opsdroid.readthedocs.io/en/stable/tutorials/introduction/
|
||||
[9]:https://opsdroid.readthedocs.io/en/stable/extending/skills/
|
||||
[10]:https://opsdroid.readthedocs.io/en/stable/extending/databases/
|
||||
[11]:https://opsdroid.readthedocs.io/en/stable/matchers/overview/
|
||||
[12]:https://opsdroid.readthedocs.io/en/stable/matchers/dialogflow/
|
||||
[13]:https://opsdroid.readthedocs.io/en/stable/matchers/luis.ai/
|
||||
[14]:https://opsdroid.readthedocs.io/en/stable/matchers/recast.ai/
|
||||
[15]:https://opsdroid.readthedocs.io/en/stable/matchers/wit.ai/
|
||||
[16]:https://opsdroid.readthedocs.io/en/stable/contributing/
|
||||
[17]:http://errbot.io/en/latest/
|
||||
[18]:http://errbot.io/en/latest/features.html#extensive-plugin-framework
|
||||
[19]:http://errbot.io/en/latest/user_guide/plugin_development/dynaplugs.html
|
||||
[20]:http://pytest.org/
|
||||
[21]:http://errbot.io/en/latest/user_guide/plugin_development/testing.html
|
||||
[22]:http://errbot.io/en/latest/index.html#simple-to-build-upon
|
@ -1,3 +1,12 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (pityonline)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Get Started with Snap Packages in Linux)
|
||||
[#]: via: (https://www.linux.com/learn/intro-to-linux/2018/5/get-started-snap-packages-linux)
|
||||
[#]: author: (Jack Wallen https://www.linux.com/users/jlwallen)
|
||||
|
||||
Get Started with Snap Packages in Linux
|
||||
======
|
||||
|
||||
@ -139,7 +148,7 @@ via: https://www.linux.com/learn/intro-to-linux/2018/5/get-started-snap-packages
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
选题:[lujun9972](https://github.com/lujun9972)
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[pityonline](https://github.com/pityonline)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,3 +1,4 @@
|
||||
DaivdMax2006 is translating
|
||||
100 Best Ubuntu Apps
|
||||
======
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
hankchow translating
|
||||
|
||||
Building tiny container images
|
||||
======
|
||||
|
||||
|
@ -0,0 +1,590 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Put platforms in a Python game with Pygame)
|
||||
[#]: via: (https://opensource.com/article/18/7/put-platforms-python-game)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Put platforms in a Python game with Pygame
|
||||
======
|
||||
In part six of this series on building a Python game from scratch, create some platforms for your characters to travel.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/header.png?itok=iq8HFoEJ)
|
||||
|
||||
This is part 6 in an ongoing series about creating video games in Python 3 using the Pygame module. Previous articles are:
|
||||
|
||||
+ [Learn how to program in Python by building a simple dice game][24]
|
||||
+ [Build a game framework with Python using the Pygame module][25]
|
||||
+ [How to add a player to your Python game][26]
|
||||
+ [Using Pygame to move your game character around][27]
|
||||
+ [What's a hero without a villain? How to add one to your Python game][28]
|
||||
|
||||
|
||||
A platformer game needs platforms.
|
||||
|
||||
In [Pygame][1], the platforms themselves are sprites, just like your playable sprite. That's important because having platforms that are objects makes it a lot easier for your player sprite to interact with them.
|
||||
|
||||
There are two major steps in creating platforms. First, you must code the objects, and then you must map out where you want the objects to appear.
|
||||
|
||||
### Coding platform objects
|
||||
|
||||
To build a platform object, you create a class called `Platform`. It's a sprite, just like your [`Player`][2] [sprite][2], with many of the same properties.
|
||||
|
||||
Your `Platform` class needs to know a lot of information about what kind of platform you want, where it should appear in the game world, and what image it should contain. A lot of that information might not even exist yet, depending on how much you have planned out your game, but that's all right. Just as you didn't tell your Player sprite how fast to move until the end of the [Movement article][3], you don't have to tell `Platform` everything upfront.
|
||||
|
||||
Near the top of the script you've been writing in this series, create a new class. The first three lines in this code sample are for context, so add the code below the comment:
|
||||
|
||||
```
|
||||
import pygame
|
||||
import sys
|
||||
import os
|
||||
## new code below:
|
||||
|
||||
class Platform(pygame.sprite.Sprite):
|
||||
# x location, y location, img width, img height, img file
|
||||
def __init__(self,xloc,yloc,imgw,imgh,img):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.image = pygame.image.load(os.path.join('images',img)).convert()
|
||||
self.image.convert_alpha()
|
||||
self.image.set_colorkey(ALPHA)
|
||||
self.rect = self.image.get_rect()
|
||||
self.rect.y = yloc
|
||||
self.rect.x = xloc
|
||||
```
|
||||
|
||||
When called, this class creates an object onscreen in some X and Y location, with some width and height, using some image file for texture. It's very similar to how players or enemies are drawn onscreen.
|
||||
|
||||
### Types of platforms
|
||||
|
||||
The next step is to map out where all your platforms need to appear.
|
||||
|
||||
#### The tile method
|
||||
|
||||
There are a few different ways to implement a platform game world. In the original side-scroller games, such as Mario Super Bros. and Sonic the Hedgehog, the technique was to use "tiles," meaning that there were a few blocks to represent the ground and various platforms, and these blocks were used and reused to make a level. You have only eight or 12 different kinds of blocks, and you line them up onscreen to create the ground, floating platforms, and whatever else your game needs. Some people find this the easier way to make a game since you just have to make (or download) a small set of level assets to create many different levels. The code, however, requires a little more math.
|
||||
|
||||
![Supertux, a tile-based video game][5]
|
||||
|
||||
[SuperTux][6], a tile-based video game.
|
||||
|
||||
#### The hand-painted method
|
||||
|
||||
Another method is to make each and every asset as one whole image. If you enjoy creating assets for your game world, this is a great excuse to spend time in a graphics application, building each and every part of your game world. This method requires less math, because all the platforms are whole, complete objects, and you tell [Python][7] where to place them onscreen.
|
||||
|
||||
Each method has advantages and disadvantages, and the code you must use is slightly different depending on the method you choose. I'll cover both so you can use one or the other, or even a mix of both, in your project.
|
||||
|
||||
### Level mapping
|
||||
|
||||
Mapping out your game world is a vital part of level design and game programming in general. It does involve math, but nothing too difficult, and Python is good at math so it can help some.
|
||||
|
||||
You might find it helpful to design on paper first. Get a sheet of paper and draw a box to represent your game window. Draw platforms in the box, labeling each with its X and Y coordinates, as well as its intended width and height. The actual positions in the box don't have to be exact, as long as you keep the numbers realistic. For instance, if your screen is 720 pixels wide, then you can't fit eight platforms at 100 pixels each all on one screen.
|
||||
|
||||
Of course, not all platforms in your game have to fit in one screen-sized box, because your game will scroll as your player walks through it. So keep drawing your game world to the right of the first screen until the end of the level.
|
||||
|
||||
If you prefer a little more precision, you can use graph paper. This is especially helpful when designing a game with tiles because each grid square can represent one tile.
|
||||
|
||||
![Example of a level map][9]
|
||||
|
||||
Example of a level map.
|
||||
|
||||
#### Coordinates
|
||||
|
||||
You may have learned in school about the [Cartesian coordinate system][10]. What you learned applies to Pygame, except that in Pygame, your game world's coordinates place `0,0` in the top-left corner of your screen instead of in the middle, which is probably what you're used to from Geometry class.
|
||||
|
||||
![Example of coordinates in Pygame][12]
|
||||
|
||||
Example of coordinates in Pygame.
|
||||
|
||||
The X axis starts at 0 on the far left and increases infinitely to the right. The Y axis starts at 0 at the top of the screen and extends down.
|
||||
|
||||
#### Image sizes
|
||||
|
||||
Mapping out a game world is meaningless if you don't know how big your players, enemies, and platforms are. You can find the dimensions of your platforms or tiles in a graphics program. In [Krita][13], for example, click on the **Image** menu and select **Properties**. You can find the dimensions at the very top of the **Properties** window.
|
||||
|
||||
Alternately, you can create a simple Python script to tell you the dimensions of an image. Open a new text file and type this code into it:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from PIL import Image
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
print(sys.argv[1])
|
||||
else:
|
||||
sys.exit('Syntax: identify.py [filename]')
|
||||
|
||||
pic = sys.argv[1]
|
||||
dim = Image.open(pic)
|
||||
X = dim.size[0]
|
||||
Y = dim.size[1]
|
||||
|
||||
print(X,Y)
|
||||
```
|
||||
|
||||
Save the text file as `identify.py`.
|
||||
|
||||
To set up this script, you must install an extra set of Python modules that contain the new keywords used in the script:
|
||||
|
||||
```
|
||||
$ pip3 install Pillow --user
|
||||
```
|
||||
|
||||
Once that is installed, run your script from within your game project directory:
|
||||
|
||||
```
|
||||
$ python3 ./identify.py images/ground.png
|
||||
(1080, 97)
|
||||
```
|
||||
|
||||
The image size of the ground platform in this example is 1080 pixels wide and 97 high.
|
||||
|
||||
### Platform blocks
|
||||
|
||||
If you choose to draw each asset individually, you must create several platforms and any other elements you want to insert into your game world, each within its own file. In other words, you should have one file per asset, like this:
|
||||
|
||||
![One image file per object][15]
|
||||
|
||||
One image file per object.
|
||||
|
||||
You can reuse each platform as many times as you want, just make sure that each file only contains one platform. You cannot use a file that contains everything, like this:
|
||||
|
||||
![Your level cannot be one image file][17]
|
||||
|
||||
Your level cannot be one image file.
|
||||
|
||||
You might want your game to look like that when you've finished, but if you create your level in one big file, there is no way to distinguish a platform from the background, so either paint your objects in their own file or crop them from a large file and save individual copies.
|
||||
|
||||
**Note:** As with your other assets, you can use [GIMP][18], Krita, [MyPaint][19], or [Inkscape][20] to create your game assets.
|
||||
|
||||
Platforms appear on the screen at the start of each level, so you must add a `platform` function in your `Level` class. The special case here is the ground platform, which is important enough to be treated as its own platform group. By treating the ground as its own special kind of platform, you can choose whether it scrolls or whether it stands still while other platforms float over the top of it. It's up to you.
|
||||
|
||||
Add these two functions to your `Level` class:
|
||||
|
||||
```
|
||||
def ground(lvl,x,y,w,h):
|
||||
ground_list = pygame.sprite.Group()
|
||||
if lvl == 1:
|
||||
ground = Platform(x,y,w,h,'block-ground.png')
|
||||
ground_list.add(ground)
|
||||
|
||||
if lvl == 2:
|
||||
print("Level " + str(lvl) )
|
||||
|
||||
return ground_list
|
||||
|
||||
def platform( lvl ):
|
||||
plat_list = pygame.sprite.Group()
|
||||
if lvl == 1:
|
||||
plat = Platform(200, worldy-97-128, 285,67,'block-big.png')
|
||||
plat_list.add(plat)
|
||||
plat = Platform(500, worldy-97-320, 197,54,'block-small.png')
|
||||
plat_list.add(plat)
|
||||
if lvl == 2:
|
||||
print("Level " + str(lvl) )
|
||||
|
||||
return plat_list
|
||||
```
|
||||
|
||||
The `ground` function requires an X and Y location so Pygame knows where to place the ground platform. It also requires the width and height of the platform so Pygame knows how far the ground extends in each direction. The function uses your `Platform` class to generate an object onscreen, and then adds that object to the `ground_list` group.
|
||||
|
||||
The `platform` function is essentially the same, except that there are more platforms to list. In this example, there are only two, but you can have as many as you like. After entering one platform, you must add it to the `plat_list` before listing another. If you don't add a platform to the group, then it won't appear in your game.
|
||||
|
||||
> **Tip:** It can be difficult to think of your game world with 0 at the top, since the opposite is what happens in the real world; when figuring out how tall you are, you don't measure yourself from the sky down, you measure yourself from your feet to the top of your head.
|
||||
>
|
||||
> If it's easier for you to build your game world from the "ground" up, it might help to express Y-axis values as negatives. For instance, you know that the bottom of your game world is the value of `worldy`. So `worldy` minus the height of the ground (97, in this example) is where your player is normally standing. If your character is 64 pixels tall, then the ground minus 128 is exactly twice as tall as your player. Effectively, a platform placed at 128 pixels is about two stories tall, relative to your player. A platform at -320 is three more stories. And so on.
|
||||
|
||||
As you probably know by now, none of your classes and functions are worth much if you don't use them. Add this code to your setup section (the first line is just for context, so add the last two lines):
|
||||
|
||||
```
|
||||
enemy_list = Level.bad( 1, eloc )
|
||||
ground_list = Level.ground( 1,0,worldy-97,1080,97 )
|
||||
plat_list = Level.platform( 1 )
|
||||
```
|
||||
|
||||
And add these lines to your main loop (again, the first line is just for context):
|
||||
|
||||
```
|
||||
enemy_list.draw(world) # refresh enemies
|
||||
ground_list.draw(world) # refresh ground
|
||||
plat_list.draw(world) # refresh platforms
|
||||
```
|
||||
|
||||
### Tiled platforms
|
||||
|
||||
Tiled game worlds are considered easier to make because you just have to draw a few blocks upfront and can use them over and over to create every platform in the game. There are even sets of tiles for you to use on sites like [OpenGameArt.org][21].
|
||||
|
||||
The `Platform` class is the same as the one provided in the previous sections.
|
||||
|
||||
The `ground` and `platform` in the `Level` class, however, must use loops to calculate how many blocks to use to create each platform.
|
||||
|
||||
If you intend to have one solid ground in your game world, the ground is simple. You just "clone" your ground tile across the whole window. For instance, you could create a list of X and Y values to dictate where each tile should be placed, and then use a loop to take each value and draw one tile. This is just an example, so don't add this to your code:
|
||||
|
||||
```
|
||||
# Do not add this to your code
|
||||
gloc = [0,656,64,656,128,656,192,656,256,656,320,656,384,656]
|
||||
```
|
||||
|
||||
If you look carefully, though, you can see all the Y values are always the same, and the X values increase steadily in increments of 64, which is the size of the tiles. That kind of repetition is exactly what computers are good at, so you can use a little bit of math logic to have the computer do all the calculations for you:
|
||||
|
||||
Add this to the setup part of your script:
|
||||
|
||||
```
|
||||
gloc = []
|
||||
tx = 64
|
||||
ty = 64
|
||||
|
||||
i=0
|
||||
while i <= (worldx/tx)+tx:
|
||||
gloc.append(i*tx)
|
||||
i=i+1
|
||||
|
||||
ground_list = Level.ground( 1,gloc,tx,ty )
|
||||
```
|
||||
|
||||
Now, regardless of the size of your window, Python divides the width of the game world by the width of the tile and creates an array listing each X value. This doesn't calculate the Y value, but that never changes on flat ground anyway.
|
||||
|
||||
To use the array in a function, use a `while` loop that looks at each entry and adds a ground tile at the appropriate location:
|
||||
|
||||
```
|
||||
def ground(lvl,gloc,tx,ty):
|
||||
ground_list = pygame.sprite.Group()
|
||||
i=0
|
||||
if lvl == 1:
|
||||
while i < len(gloc):
|
||||
ground = Platform(gloc[i],worldy-ty,tx,ty,'tile-ground.png')
|
||||
ground_list.add(ground)
|
||||
i=i+1
|
||||
|
||||
if lvl == 2:
|
||||
print("Level " + str(lvl) )
|
||||
|
||||
return ground_list
|
||||
```
|
||||
|
||||
This is nearly the same code as the `ground` function for the block-style platformer, provided in a previous section above, aside from the `while` loop.
|
||||
|
||||
For moving platforms, the principle is similar, but there are some tricks you can use to make your life easier.
|
||||
|
||||
Rather than mapping every platform by pixels, you can define a platform by its starting pixel (its X value), the height from the ground (its Y value), and how many tiles to draw. That way, you don't have to worry about the width and height of every platform.
|
||||
|
||||
The logic for this trick is a little more complex, so copy this code carefully. There is a `while` loop inside of another `while` loop because this function must look at all three values within each array entry to successfully construct a full platform. In this example, there are only three platforms defined as `ploc.append` statements, but your game probably needs more, so define as many as you need. Of course, some won't appear yet because they're far offscreen, but they'll come into view once you implement scrolling.
|
||||
|
||||
```
|
||||
def platform(lvl,tx,ty):
|
||||
plat_list = pygame.sprite.Group()
|
||||
ploc = []
|
||||
i=0
|
||||
if lvl == 1:
|
||||
ploc.append((200,worldy-ty-128,3))
|
||||
ploc.append((300,worldy-ty-256,3))
|
||||
ploc.append((500,worldy-ty-128,4))
|
||||
while i < len(ploc):
|
||||
j=0
|
||||
while j <= ploc[i][2]:
|
||||
plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'tile.png')
|
||||
plat_list.add(plat)
|
||||
j=j+1
|
||||
print('run' + str(i) + str(ploc[i]))
|
||||
i=i+1
|
||||
|
||||
if lvl == 2:
|
||||
print("Level " + str(lvl) )
|
||||
|
||||
return plat_list
|
||||
```
|
||||
|
||||
To get the platforms to appear in your game world, they must be in your main loop. If you haven't already done so, add these lines to your main loop (again, the first line is just for context):
|
||||
|
||||
```
|
||||
enemy_list.draw(world) # refresh enemies
|
||||
ground_list.draw(world) # refresh ground
|
||||
plat_list.draw(world) # refresh platforms
|
||||
```
|
||||
|
||||
Launch your game, and adjust the placement of your platforms as needed. Don't worry that you can't see the platforms that are spawned offscreen; you'll fix that soon.
|
||||
|
||||
Here is the game so far in a picture and in code:
|
||||
|
||||
![Pygame game][23]
|
||||
|
||||
Our Pygame platformer so far.
|
||||
|
||||
```
|
||||
#!/usr/bin/env python3
|
||||
# draw a world
|
||||
# add a player and player control
|
||||
# add player movement
|
||||
# add enemy and basic collision
|
||||
# add platform
|
||||
|
||||
# GNU All-Permissive License
|
||||
# Copying and distribution of this file, with or without modification,
|
||||
# are permitted in any medium without royalty provided the copyright
|
||||
# notice and this notice are preserved. This file is offered as-is,
|
||||
# without any warranty.
|
||||
|
||||
import pygame
|
||||
import sys
|
||||
import os
|
||||
|
||||
'''
|
||||
Objects
|
||||
'''
|
||||
|
||||
class Platform(pygame.sprite.Sprite):
|
||||
# x location, y location, img width, img height, img file
|
||||
def __init__(self,xloc,yloc,imgw,imgh,img):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.image = pygame.image.load(os.path.join('images',img)).convert()
|
||||
self.image.convert_alpha()
|
||||
self.rect = self.image.get_rect()
|
||||
self.rect.y = yloc
|
||||
self.rect.x = xloc
|
||||
|
||||
class Player(pygame.sprite.Sprite):
|
||||
'''
|
||||
Spawn a player
|
||||
'''
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.movex = 0
|
||||
self.movey = 0
|
||||
self.frame = 0
|
||||
self.health = 10
|
||||
self.score = 1
|
||||
self.images = []
|
||||
for i in range(1,9):
|
||||
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
|
||||
img.convert_alpha()
|
||||
img.set_colorkey(ALPHA)
|
||||
self.images.append(img)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect()
|
||||
|
||||
def control(self,x,y):
|
||||
'''
|
||||
control player movement
|
||||
'''
|
||||
self.movex += x
|
||||
self.movey += y
|
||||
|
||||
def update(self):
|
||||
'''
|
||||
Update sprite position
|
||||
'''
|
||||
|
||||
self.rect.x = self.rect.x + self.movex
|
||||
self.rect.y = self.rect.y + self.movey
|
||||
|
||||
# moving left
|
||||
if self.movex < 0:
|
||||
self.frame += 1
|
||||
if self.frame > ani*3:
|
||||
self.frame = 0
|
||||
self.image = self.images[self.frame//ani]
|
||||
|
||||
# moving right
|
||||
if self.movex > 0:
|
||||
self.frame += 1
|
||||
if self.frame > ani*3:
|
||||
self.frame = 0
|
||||
self.image = self.images[(self.frame//ani)+4]
|
||||
|
||||
# collisions
|
||||
enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
|
||||
for enemy in enemy_hit_list:
|
||||
self.health -= 1
|
||||
print(self.health)
|
||||
|
||||
ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
|
||||
for g in ground_hit_list:
|
||||
self.health -= 1
|
||||
print(self.health)
|
||||
|
||||
|
||||
class Enemy(pygame.sprite.Sprite):
|
||||
'''
|
||||
Spawn an enemy
|
||||
'''
|
||||
def __init__(self,x,y,img):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.image = pygame.image.load(os.path.join('images',img))
|
||||
#self.image.convert_alpha()
|
||||
#self.image.set_colorkey(ALPHA)
|
||||
self.rect = self.image.get_rect()
|
||||
self.rect.x = x
|
||||
self.rect.y = y
|
||||
self.counter = 0
|
||||
|
||||
def move(self):
|
||||
'''
|
||||
enemy movement
|
||||
'''
|
||||
distance = 80
|
||||
speed = 8
|
||||
|
||||
if self.counter >= 0 and self.counter <= distance:
|
||||
self.rect.x += speed
|
||||
elif self.counter >= distance and self.counter <= distance*2:
|
||||
self.rect.x -= speed
|
||||
else:
|
||||
self.counter = 0
|
||||
|
||||
self.counter += 1
|
||||
|
||||
class Level():
|
||||
def bad(lvl,eloc):
|
||||
if lvl == 1:
|
||||
enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
|
||||
enemy_list = pygame.sprite.Group() # create enemy group
|
||||
enemy_list.add(enemy) # add enemy to group
|
||||
|
||||
if lvl == 2:
|
||||
print("Level " + str(lvl) )
|
||||
|
||||
return enemy_list
|
||||
|
||||
def loot(lvl,lloc):
|
||||
print(lvl)
|
||||
|
||||
def ground(lvl,gloc,tx,ty):
|
||||
ground_list = pygame.sprite.Group()
|
||||
i=0
|
||||
if lvl == 1:
|
||||
while i < len(gloc):
|
||||
print("blockgen:" + str(i))
|
||||
ground = Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
|
||||
ground_list.add(ground)
|
||||
i=i+1
|
||||
|
||||
if lvl == 2:
|
||||
print("Level " + str(lvl) )
|
||||
|
||||
return ground_list
|
||||
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
worldx = 960
|
||||
worldy = 720
|
||||
|
||||
fps = 40 # frame rate
|
||||
ani = 4 # animation cycles
|
||||
clock = pygame.time.Clock()
|
||||
pygame.init()
|
||||
main = True
|
||||
|
||||
BLUE = (25,25,200)
|
||||
BLACK = (23,23,23 )
|
||||
WHITE = (254,254,254)
|
||||
ALPHA = (0,255,0)
|
||||
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
|
||||
backdropbox = world.get_rect()
|
||||
player = Player() # spawn player
|
||||
player.rect.x = 0
|
||||
player.rect.y = 0
|
||||
player_list = pygame.sprite.Group()
|
||||
player_list.add(player)
|
||||
steps = 10 # how fast to move
|
||||
|
||||
eloc = []
|
||||
eloc = [200,20]
|
||||
gloc = []
|
||||
#gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]
|
||||
tx = 64 #tile size
|
||||
ty = 64 #tile size
|
||||
|
||||
i=0
|
||||
while i <= (worldx/tx)+tx:
|
||||
gloc.append(i*tx)
|
||||
i=i+1
|
||||
print("block: " + str(i))
|
||||
|
||||
enemy_list = Level.bad( 1, eloc )
|
||||
ground_list = Level.ground( 1,gloc,tx,ty )
|
||||
|
||||
'''
|
||||
Main loop
|
||||
'''
|
||||
while main == True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit(); sys.exit()
|
||||
main = False
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
player.control(-steps,0)
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
player.control(steps,0)
|
||||
if event.key == pygame.K_UP or event.key == ord('w'):
|
||||
print('jump')
|
||||
|
||||
if event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
player.control(steps,0)
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
player.control(-steps,0)
|
||||
if event.key == ord('q'):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
main = False
|
||||
|
||||
# world.fill(BLACK)
|
||||
world.blit(backdrop, backdropbox)
|
||||
player.update()
|
||||
player_list.draw(world) #refresh player position
|
||||
enemy_list.draw(world) # refresh enemies
|
||||
ground_list.draw(world) # refresh enemies
|
||||
for e in enemy_list:
|
||||
e.move()
|
||||
pygame.display.flip()
|
||||
clock.tick(fps)
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/7/put-platforms-python-game
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.pygame.org/news
|
||||
[2]: https://opensource.com/article/17/12/game-python-add-a-player
|
||||
[3]: https://opensource.com/article/17/12/game-python-moving-player
|
||||
[4]: /file/403841
|
||||
[5]: https://opensource.com/sites/default/files/uploads/supertux.png (Supertux, a tile-based video game)
|
||||
[6]: https://www.supertux.org/
|
||||
[7]: https://www.python.org/
|
||||
[8]: /file/403861
|
||||
[9]: https://opensource.com/sites/default/files/uploads/layout.png (Example of a level map)
|
||||
[10]: https://en.wikipedia.org/wiki/Cartesian_coordinate_system
|
||||
[11]: /file/403871
|
||||
[12]: https://opensource.com/sites/default/files/uploads/pygame_coordinates.png (Example of coordinates in Pygame)
|
||||
[13]: https://krita.org/en/
|
||||
[14]: /file/403876
|
||||
[15]: https://opensource.com/sites/default/files/uploads/pygame_floating.png (One image file per object)
|
||||
[16]: /file/403881
|
||||
[17]: https://opensource.com/sites/default/files/uploads/pygame_flattened.png (Your level cannot be one image file)
|
||||
[18]: https://www.gimp.org/
|
||||
[19]: http://mypaint.org/about/
|
||||
[20]: https://inkscape.org/en/
|
||||
[21]: https://opengameart.org/content/simplified-platformer-pack
|
||||
[22]: /file/403886
|
||||
[23]: https://opensource.com/sites/default/files/uploads/pygame_platforms.jpg (Pygame game)
|
||||
[24]: Learn how to program in Python by building a simple dice game
|
||||
[25]: https://opensource.com/article/17/12/game-framework-python
|
||||
[26]: https://opensource.com/article/17/12/game-python-add-a-player
|
||||
[27]: https://opensource.com/article/17/12/game-python-moving-player
|
||||
[28]: https://opensource.com/article/18/5/pygame-enemy
|
||||
|
@ -0,0 +1,128 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Host your own cloud with Raspberry Pi NAS)
|
||||
[#]: via: (https://opensource.com/article/18/9/host-cloud-nas-raspberry-pi?extIdCarryOver=true)
|
||||
[#]: author: (Manuel Dewald https://opensource.com/users/ntlx)
|
||||
|
||||
Host your own cloud with Raspberry Pi NAS
|
||||
======
|
||||
|
||||
Protect and secure your data with a self-hosted cloud powered by your Raspberry Pi.
|
||||
|
||||
![Tree clouds][1]
|
||||
|
||||
In the first two parts of this series, we discussed the [hardware and software fundamentals][2] for building network-attached storage (NAS) on a Raspberry Pi. We also put a proper [backup strategy][3] in place to secure the data on the NAS. In this third part, we will talk about a convenient way to store, access, and share your data with [Nextcloud][4].
|
||||
|
||||
![Raspberry Pi NAS infrastructure with Nextcloud][6]
|
||||
|
||||
### Prerequisites
|
||||
|
||||
To use Nextcloud conveniently, you have to meet a few prerequisites. First, you should have a domain you can use for the Nextcloud instance. For the sake of simplicity in this how-to, we'll use **nextcloud.pi-nas.com**. This domain should be directed to your Raspberry Pi. If you want to run it on your home network, you probably need to set up dynamic DNS for this domain and enable port forwarding of ports 80 and 443 (if you go for an SSL setup, which is highly recommended; otherwise port 80 should be sufficient) from your router to the Raspberry Pi.
|
||||
|
||||
You can automate dynamic DNS updates from the Raspberry Pi using [ddclient][7].
|
||||
|
||||
### Install Nextcloud
|
||||
|
||||
To run Nextcloud on your Raspberry Pi (using the setup described in the [first part][2] of this series), install the following packages as dependencies to Nextcloud using **apt**.
|
||||
|
||||
```
|
||||
sudo apt install unzip wget php apache2 mysql-server php-zip php-mysql php-dom php-mbstring php-gd php-curl
|
||||
```
|
||||
|
||||
The next step is to download Nextcloud. [Get the latest release's URL][8] and copy it to download via **wget** on the Raspberry Pi. In the first article in this series, we attached two disk drives to the Raspberry Pi, one for current data and one for backups. Install Nextcloud on the data drive to make sure data is backed up automatically every night.
|
||||
```
|
||||
sudo mkdir -p /nas/data/nextcloud
|
||||
sudo chown pi /nas/data/nextcloud
|
||||
cd /nas/data/
|
||||
wget <https://download.nextcloud.com/server/releases/nextcloud-14.0.0.zip> -O /nas/data/nextcloud.zip
|
||||
unzip nextcloud.zip
|
||||
sudo ln -s /nas/data/nextcloud /var/www/nextcloud
|
||||
sudo chown -R www-data:www-data /nas/data/nextcloud
|
||||
```
|
||||
|
||||
When I wrote this, the latest release (as you see in the code above) was 14. Nextcloud is under heavy development, so you may find a newer version when installing your copy of Nextcloud onto your Raspberry Pi.
|
||||
|
||||
### Database setup
|
||||
|
||||
When we installed Nextcloud above, we also installed MySQL as a dependency to use it for all the metadata Nextcloud generates (for example, the users you create to access Nextcloud). If you would rather use a Postgres database, you'll need to adjust some of the modules installed above.
|
||||
|
||||
To access the MySQL database as root, start the MySQL client as root:
|
||||
|
||||
```
|
||||
sudo mysql
|
||||
```
|
||||
|
||||
This will open a SQL prompt where you can insert the following commands—substituting the placeholder with the password you want to use for the database connection—to create a database for Nextcloud.
|
||||
```
|
||||
CREATE USER nextcloud IDENTIFIED BY '<insert-password-here>';
|
||||
CREATE DATABASE nextcloud;
|
||||
GRANT ALL ON nextcloud.* TO nextcloud;
|
||||
```
|
||||
|
||||
|
||||
You can exit the SQL prompt by pressing **Ctrl+D** or entering **quit**.
|
||||
|
||||
### Web server configuration
|
||||
|
||||
Nextcloud can be configured to run using Nginx or other web servers, but for this how-to, I decided to go with the Apache web server on my Raspberry Pi NAS. (Feel free to try out another alternative and let me know if you think it performs better.)
|
||||
|
||||
To set it up, configure a virtual host for the domain you created for your Nextcloud instance **nextcloud.pi-nas.com**. To create a virtual host, create the file **/etc/apache2/sites-available/001-nextcloud.conf** with content similar to the following. Make sure to adjust the ServerName to your domain and paths, if you didn't use the ones suggested earlier in this series.
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerName nextcloud.pi-nas.com
|
||||
ServerAdmin [admin@pi-nas.com][9]
|
||||
DocumentRoot /var/www/nextcloud/
|
||||
|
||||
<Directory /var/www/nextcloud/>
|
||||
AllowOverride None
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
|
||||
To enable this virtual host, run the following two commands.
|
||||
```
|
||||
a2ensite 001-nextcloud
|
||||
sudo systemctl reload apache2
|
||||
```
|
||||
|
||||
|
||||
With this configuration, you should now be able to reach the web server with your domain via the web browser. To secure your data, I recommend using HTTPS instead of HTTP to access Nextcloud. A very easy (and free) way is to obtain a [Let's Encrypt][10] certificate with [Certbot][11] and have a cron job automatically refresh it. That way you don't have to mess around with self-signed or expiring certificates. Follow Certbot's simple how-to [instructions to install it on your Raspberry Pi][12]. During Certbot configuration, you can even decide to automatically forward HTTP to HTTPS, so visitors to **<http://nextcloud.pi-nas.com>** will be redirected to **<https://nextcloud.pi-nas.com>**. Please note, if your Raspberry Pi is running behind your home router, you must have port forwarding enabled for ports 443 and 80 to obtain Let's Encrypt certificates.
|
||||
|
||||
### Configure Nextcloud
|
||||
|
||||
The final step is to visit your fresh Nextcloud instance in a web browser to finish the configuration. To do so, open your domain in a browser and insert the database details from above. You can also set up your first Nextcloud user here, the one you can use for admin tasks. By default, the data directory should be inside the Nextcloud folder, so you don't need to change anything for the backup mechanisms from the [second part of this series][3] to pick up the data stored by users in Nextcloud.
|
||||
|
||||
Afterward, you will be directed to your Nextcloud and can log in with the admin user you created previously. To see a list of recommended steps to ensure a performant and secure Nextcloud installation, visit the Basic Settings tab in the Settings page (in our example: <https://nextcloud.pi-nas.com/>settings/admin) and see the Security & Setup Warnings section.
|
||||
|
||||
Congratulations! You've set up your own Nextcloud powered by a Raspberry Pi. Go ahead and [download a Nextcloud client][13] from the Nextcloud page to sync data with your client devices and access it offline. Mobile clients even provide features like instant upload of pictures you take, so they'll automatically sync to your desktop PC without wondering how to get them there.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/9/host-cloud-nas-raspberry-pi?extIdCarryOver=true
|
||||
|
||||
作者:[Manuel Dewald][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ntlx
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life_tree_clouds.png?itok=b_ftihhP (Tree clouds)
|
||||
[2]: https://opensource.com/article/18/7/network-attached-storage-Raspberry-Pi
|
||||
[3]: https://opensource.com/article/18/8/automate-backups-raspberry-pi
|
||||
[4]: https://nextcloud.com/
|
||||
[5]: /file/409336
|
||||
[6]: https://opensource.com/sites/default/files/uploads/nas_part3.png (Raspberry Pi NAS infrastructure with Nextcloud)
|
||||
[7]: https://sourceforge.net/p/ddclient/wiki/Home/
|
||||
[8]: https://nextcloud.com/install/#instructions-server
|
||||
[9]: mailto:admin@pi-nas.com
|
||||
[10]: https://letsencrypt.org/
|
||||
[11]: https://certbot.eff.org/
|
||||
[12]: https://certbot.eff.org/lets-encrypt/debianother-apache
|
||||
[13]: https://nextcloud.com/install/#install-clients
|
@ -0,0 +1,353 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Using Pygame to move your game character around)
|
||||
[#]: via: (https://opensource.com/article/17/12/game-python-moving-player)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
Using Pygame to move your game character around
|
||||
======
|
||||
In the fourth part of this series, learn how to code the controls needed to move a game character.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python4-game.png?itok=tXFHaLdt)
|
||||
|
||||
In the first article in this series, I explained how to use Python to create a simple, [text-based dice game][1]. In the second part, we began building a game from scratch, starting with [creating the game's environment][2]. And, in the third installment, we [created a player sprite][3] and made it spawn in your (rather empty) game world. As you've probably noticed, a game isn't much fun if you can't move your character around. In this article, we'll use Pygame to add keyboard controls so you can direct your character's movement.
|
||||
|
||||
There are functions in Pygame to add other kinds of controls, but since you certainly have a keyboard if you're typing out Python code, that's what we'll use. Once you understand keyboard controls, you can explore other options on your own.
|
||||
|
||||
You created a key to quit your game in the second article in this series, and the principle is the same for movement. However, getting your character to move is a little more complex.
|
||||
|
||||
Let's start with the easy part: setting up the controller keys.
|
||||
|
||||
### Setting up keys for controlling your player sprite
|
||||
|
||||
Open your Python game script in IDLE, Ninja-IDE, or a text editor.
|
||||
|
||||
Since the game must constantly "listen" for keyboard events, you'll be writing code that needs to run continuously. Can you figure out where to put code that needs to run constantly for the duration of the game?
|
||||
|
||||
If you answered "in the main loop," you're correct! Remember that unless code is in a loop, it will run (at most) only once—and it may not run at all if it's hidden away in a class or function that never gets used.
|
||||
|
||||
To make Python monitor for incoming key presses, add this code to the main loop. There's no code to make anything happen yet, so use `print` statements to signal success. This is a common debugging technique.
|
||||
|
||||
```
|
||||
while main == True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit(); sys.exit()
|
||||
main = False
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
print('left')
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
print('right')
|
||||
if event.key == pygame.K_UP or event.key == ord('w'):
|
||||
print('jump')
|
||||
|
||||
if event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
print('left stop')
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
print('right stop')
|
||||
if event.key == ord('q'):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
main = False
|
||||
```
|
||||
|
||||
Some people prefer to control player characters with the keyboard characters W, A, S, and D, and others prefer to use arrow keys. Be sure to include both options.
|
||||
|
||||
**Note: **It's vital that you consider all of your users when programming. If you write code that works only for you, it's very likely that you'll be the only one who uses your application. More importantly, if you seek out a job writing code for money, you are expected to write code that works for everyone. Giving your users choices, such as the option to use either arrow keys or WASD, is a sign of a good programmer.
|
||||
|
||||
Launch your game using Python, and watch the console window for output as you press the right, left, and up arrows, or the A, D, and W keys.
|
||||
|
||||
```
|
||||
$ python ./your-name_game.py
|
||||
left
|
||||
left stop
|
||||
right
|
||||
right stop
|
||||
jump
|
||||
```
|
||||
|
||||
This confirms that Pygame detects key presses correctly. Now it's time to do the hard work of making the sprite move.
|
||||
|
||||
### Coding the player movement function
|
||||
|
||||
To make your sprite move, you must create a property for your sprite that represents movement. When your sprite is not moving, this variable is set to `0`.
|
||||
|
||||
If you are animating your sprite, or should you decide to animate it in the future, you also must track frames to enable the walk cycle to stay on track.
|
||||
|
||||
Create the variables in the Player class. The first two lines are for context (you already have them in your code, if you've been following along), so add only the last three:
|
||||
|
||||
```
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.movex = 0 # move along X
|
||||
self.movey = 0 # move along Y
|
||||
self.frame = 0 # count frames
|
||||
```
|
||||
|
||||
With those variables set, it's time to code the sprite's movement.
|
||||
|
||||
The player sprite doesn't need to respond to control all the time; sometimes it will not be moving. The code that controls the sprite, therefore, is only one small part of all the things the player sprite will do. When you want to make an object in Python do something independent of the rest of its code, you place your new code in a function. Python functions start with the keyword `def`, which stands for define.
|
||||
|
||||
Make a function in your Player class to add some number of pixels to your sprite's position on screen. Don't worry about how many pixels you add yet; that will be decided in later code.
|
||||
|
||||
```
|
||||
def control(self,x,y):
|
||||
'''
|
||||
control player movement
|
||||
'''
|
||||
self.movex += x
|
||||
self.movey += y
|
||||
```
|
||||
|
||||
To move a sprite in Pygame, you have to tell Python to redraw the sprite in its new location—and where that new location is.
|
||||
|
||||
Since the Player sprite isn't always moving, the updates need to be only one function within the Player class. Add this function after the `control` function you created earlier.
|
||||
|
||||
To make it appear that the sprite is walking (or flying, or whatever it is your sprite is supposed to do), you need to change its position on screen when the appropriate key is pressed. To get it to move across the screen, you redefine its position, designated by the `self.rect.x` and `self.rect.y` properties, to its current position plus whatever amount of `movex` or `movey` is applied. (The number of pixels the move requires is set later.)
|
||||
|
||||
```
|
||||
def update(self):
|
||||
'''
|
||||
Update sprite position
|
||||
'''
|
||||
self.rect.x = self.rect.x + self.movex
|
||||
```
|
||||
|
||||
Do the same thing for the Y position:
|
||||
|
||||
```
|
||||
self.rect.y = self.rect.y + self.movey
|
||||
```
|
||||
|
||||
For animation, advance the animation frames whenever your sprite is moving, and use the corresponding animation frame as the player image:
|
||||
|
||||
```
|
||||
# moving left
|
||||
if self.movex < 0:
|
||||
self.frame += 1
|
||||
if self.frame > 3*ani:
|
||||
self.frame = 0
|
||||
self.image = self.images[self.frame//ani]
|
||||
|
||||
# moving right
|
||||
if self.movex > 0:
|
||||
self.frame += 1
|
||||
if self.frame > 3*ani:
|
||||
self.frame = 0
|
||||
self.image = self.images[(self.frame//ani)+4]
|
||||
```
|
||||
|
||||
Tell the code how many pixels to add to your sprite's position by setting a variable, then use that variable when triggering the functions of your Player sprite.
|
||||
|
||||
First, create the variable in your setup section. In this code, the first two lines are for context, so just add the third line to your script:
|
||||
|
||||
```
|
||||
player_list = pygame.sprite.Group()
|
||||
player_list.add(player)
|
||||
steps = 10 # how many pixels to move
|
||||
```
|
||||
|
||||
Now that you have the appropriate function and variable, use your key presses to trigger the function and send the variable to your sprite.
|
||||
|
||||
Do this by replacing the `print` statements in your main loop with the Player sprite's name (player), the function (.control), and how many steps along the X axis and Y axis you want the player sprite to move with each loop.
|
||||
|
||||
```
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
player.control(-steps,0)
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
player.control(steps,0)
|
||||
if event.key == pygame.K_UP or event.key == ord('w'):
|
||||
print('jump')
|
||||
|
||||
if event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
player.control(steps,0)
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
player.control(-steps,0)
|
||||
if event.key == ord('q'):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
main = False
|
||||
```
|
||||
|
||||
Remember, `steps` is a variable representing how many pixels your sprite moves when a key is pressed. If you add 10 pixels to the location of your player sprite when you press D or the right arrow, then when you stop pressing that key you must subtract 10 (`-steps`) to return your sprite's momentum back to 0.
|
||||
|
||||
Try your game now. Warning: it won't do what you expect.
|
||||
|
||||
Why doesn't your sprite move yet? Because the main loop doesn't call the `update` function.
|
||||
|
||||
Add code to your main loop to tell Python to update the position of your player sprite. Add the line with the comment:
|
||||
|
||||
```
|
||||
player.update() # update player position
|
||||
player_list.draw(world)
|
||||
pygame.display.flip()
|
||||
clock.tick(fps)
|
||||
```
|
||||
|
||||
Launch your game again to witness your player sprite move across the screen at your bidding. There's no vertical movement yet because those functions will be controlled by gravity, but that's another lesson for another article.
|
||||
|
||||
In the meantime, if you have access to a joystick, try reading Pygame's documentation for its [joystick][4] module and see if you can make your sprite move that way. Alternately, see if you can get the [mouse][5] to interact with your sprite.
|
||||
|
||||
Most importantly, have fun!
|
||||
|
||||
### All the code used in this tutorial
|
||||
|
||||
For your reference, here is all the code used in this series of articles so far.
|
||||
|
||||
```
|
||||
#!/usr/bin/env python3
|
||||
# draw a world
|
||||
# add a player and player control
|
||||
# add player movement
|
||||
|
||||
# GNU All-Permissive License
|
||||
# Copying and distribution of this file, with or without modification,
|
||||
# are permitted in any medium without royalty provided the copyright
|
||||
# notice and this notice are preserved. This file is offered as-is,
|
||||
# without any warranty.
|
||||
|
||||
import pygame
|
||||
import sys
|
||||
import os
|
||||
|
||||
'''
|
||||
Objects
|
||||
'''
|
||||
|
||||
class Player(pygame.sprite.Sprite):
|
||||
'''
|
||||
Spawn a player
|
||||
'''
|
||||
def __init__(self):
|
||||
pygame.sprite.Sprite.__init__(self)
|
||||
self.movex = 0
|
||||
self.movey = 0
|
||||
self.frame = 0
|
||||
self.images = []
|
||||
for i in range(1,5):
|
||||
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
|
||||
img.convert_alpha()
|
||||
img.set_colorkey(ALPHA)
|
||||
self.images.append(img)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect()
|
||||
|
||||
def control(self,x,y):
|
||||
'''
|
||||
control player movement
|
||||
'''
|
||||
self.movex += x
|
||||
self.movey += y
|
||||
|
||||
def update(self):
|
||||
'''
|
||||
Update sprite position
|
||||
'''
|
||||
|
||||
self.rect.x = self.rect.x + self.movex
|
||||
self.rect.y = self.rect.y + self.movey
|
||||
|
||||
# moving left
|
||||
if self.movex < 0:
|
||||
self.frame += 1
|
||||
if self.frame > 3*ani:
|
||||
self.frame = 0
|
||||
self.image = self.images[self.frame//ani]
|
||||
|
||||
# moving right
|
||||
if self.movex > 0:
|
||||
self.frame += 1
|
||||
if self.frame > 3*ani:
|
||||
self.frame = 0
|
||||
self.image = self.images[(self.frame//ani)+4]
|
||||
|
||||
|
||||
'''
|
||||
Setup
|
||||
'''
|
||||
worldx = 960
|
||||
worldy = 720
|
||||
|
||||
fps = 40 # frame rate
|
||||
ani = 4 # animation cycles
|
||||
clock = pygame.time.Clock()
|
||||
pygame.init()
|
||||
main = True
|
||||
|
||||
BLUE = (25,25,200)
|
||||
BLACK = (23,23,23 )
|
||||
WHITE = (254,254,254)
|
||||
ALPHA = (0,255,0)
|
||||
|
||||
world = pygame.display.set_mode([worldx,worldy])
|
||||
backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
|
||||
backdropbox = world.get_rect()
|
||||
player = Player() # spawn player
|
||||
player.rect.x = 0
|
||||
player.rect.y = 0
|
||||
player_list = pygame.sprite.Group()
|
||||
player_list.add(player)
|
||||
steps = 10 # how fast to move
|
||||
|
||||
'''
|
||||
Main loop
|
||||
'''
|
||||
while main == True:
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit(); sys.exit()
|
||||
main = False
|
||||
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
player.control(-steps,0)
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
player.control(steps,0)
|
||||
if event.key == pygame.K_UP or event.key == ord('w'):
|
||||
print('jump')
|
||||
|
||||
if event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_LEFT or event.key == ord('a'):
|
||||
player.control(steps,0)
|
||||
if event.key == pygame.K_RIGHT or event.key == ord('d'):
|
||||
player.control(-steps,0)
|
||||
if event.key == ord('q'):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
main = False
|
||||
|
||||
# world.fill(BLACK)
|
||||
world.blit(backdrop, backdropbox)
|
||||
player.update()
|
||||
player_list.draw(world) #refresh player position
|
||||
pygame.display.flip()
|
||||
clock.tick(fps)
|
||||
```
|
||||
|
||||
You've come far and learned much, but there's a lot more to do. In the next few articles, you'll add enemy sprites, emulated gravity, and lots more. In the mean time, practice with Python!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/12/game-python-moving-player
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/17/10/python-101
|
||||
[2]: https://opensource.com/article/17/12/program-game-python-part-2-creating-game-world
|
||||
[3]: https://opensource.com/article/17/12/program-game-python-part-3-spawning-player
|
||||
[4]: http://pygame.org/docs/ref/joystick.html
|
||||
[5]: http://pygame.org/docs/ref/mouse.html#module-pygame.mouse
|
@ -1,127 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (ODrive (Open Drive) – Google Drive GUI Client For Linux)
|
||||
[#]: via: (https://www.2daygeek.com/odrive-open-drive-google-drive-gui-client-for-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
ODrive (Open Drive) – Google Drive GUI Client For Linux
|
||||
======
|
||||
|
||||
This we had discussed in so many times. However, i will give a small introduction about it.
|
||||
|
||||
As of now there is no official Google Drive Client for Linux and we need to use unofficial clients.
|
||||
|
||||
There are many applications available in Linux for Google Drive integration.
|
||||
|
||||
Each application has came out with set of features.
|
||||
|
||||
We had written few articles about this in our website in the past.
|
||||
|
||||
Those are **[DriveSync][1]** , **[Google Drive Ocamlfuse Client][2]** and **[Mount Google Drive in Linux Using Nautilus File Manager][3]**.
|
||||
|
||||
Today also we are going to discuss about the same topic and the utility name is ODrive.
|
||||
|
||||
### What’s ODrive?
|
||||
|
||||
ODrive stands for Open Drive. It’s a GUI client for Google Drive which was written in electron framework.
|
||||
|
||||
It’s simple GUI which allow users to integrate the Google Drive with few steps.
|
||||
|
||||
### How To Install & Setup ODrive on Linux?
|
||||
|
||||
Since the developer is offering the AppImage package and there is no difficulty for installing the ODrive on Linux.
|
||||
|
||||
Simple download the latest ODrive AppImage package from developer github page using **wget Command**.
|
||||
|
||||
```
|
||||
$ wget https://github.com/liberodark/ODrive/releases/download/0.1.3/odrive-0.1.3-x86_64.AppImage
|
||||
```
|
||||
|
||||
You have to set executable file permission to the ODrive AppImage file.
|
||||
|
||||
```
|
||||
$ chmod +x odrive-0.1.3-x86_64.AppImage
|
||||
```
|
||||
|
||||
Simple run the following ODrive AppImage file to launch the ODrive GUI for further setup.
|
||||
|
||||
```
|
||||
$ ./odrive-0.1.3-x86_64.AppImage
|
||||
```
|
||||
|
||||
You might get the same window like below when you ran the above command. Just hit the **`Next`** button for further setup.
|
||||
![][5]
|
||||
|
||||
Click **`Connect`** link to add a Google drive account.
|
||||
![][6]
|
||||
|
||||
Enter your email id which you want to setup a Google Drive account.
|
||||
![][7]
|
||||
|
||||
Enter your password for the given email id.
|
||||
![][8]
|
||||
|
||||
Allow ODrive (Open Drive) to access your Google account.
|
||||
![][9]
|
||||
|
||||
By default, it will choose the folder location. You can change if you want to use the specific one.
|
||||
![][10]
|
||||
|
||||
Finally hit **`Synchronize`** button to start download the files from Google Drive to your local system.
|
||||
![][11]
|
||||
|
||||
Synchronizing is in progress.
|
||||
![][12]
|
||||
|
||||
Once synchronizing is completed. It will show you all files downloaded.
|
||||
Once synchronizing is completed. It’s shows you that all the files has been downloaded.
|
||||
![][13]
|
||||
|
||||
I have seen all the files were downloaded in the mentioned directory.
|
||||
![][14]
|
||||
|
||||
If you want to sync any new files from local system to Google Drive. Just start the `ODrive` from the application menu but it won’t actual launch the application. But it will be running in the background that we can able to see by using the ps command.
|
||||
|
||||
```
|
||||
$ ps -df | grep odrive
|
||||
```
|
||||
|
||||
![][15]
|
||||
|
||||
It will automatically sync once you add a new file into the google drive folder. The same has been checked through notification menu. Yes, i can see one file was synced to Google Drive.
|
||||
![][16]
|
||||
|
||||
GUI is not loading after sync, and i’m not sure this functionality. I will check with developer and will add update based on his input.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/odrive-open-drive-google-drive-gui-client-for-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/drivesync-google-drive-sync-client-for-linux/
|
||||
[2]: https://www.2daygeek.com/mount-access-google-drive-on-linux-with-google-drive-ocamlfuse-client/
|
||||
[3]: https://www.2daygeek.com/mount-access-setup-google-drive-in-linux/
|
||||
[4]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[5]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-1.png
|
||||
[6]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-2.png
|
||||
[7]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-3.png
|
||||
[8]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-4.png
|
||||
[9]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-5.png
|
||||
[10]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-6.png
|
||||
[11]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-7.png
|
||||
[12]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-8a.png
|
||||
[13]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-9.png
|
||||
[14]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-11.png
|
||||
[15]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-9b.png
|
||||
[16]: https://www.2daygeek.com/wp-content/uploads/2019/01/odrive-open-drive-google-drive-gui-client-for-linux-10.png
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (MZqk)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -0,0 +1,61 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Get started with Freeplane, an open source mind mapping application)
|
||||
[#]: via: (https://opensource.com/article/19/1/productivity-tool-freeplane)
|
||||
[#]: author: (Kevin Sonney https://opensource.com/users/ksonney (Kevin Sonney))
|
||||
|
||||
Get started with Freeplane, an open source mind mapping application
|
||||
======
|
||||
|
||||
Map your brainstorming sessions with Freeplane, the 13th in our series on open source tools that will make you more productive in 2019.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X)
|
||||
|
||||
There seems to be a mad rush at the beginning of every year to find ways to be more productive. New Year's resolutions, the itch to start the year off right, and of course, an "out with the old, in with the new" attitude all contribute to this. And the usual round of recommendations is heavily biased towards closed source and proprietary software. It doesn't have to be that way.
|
||||
|
||||
Here's the 13th of my picks for 19 new (or new-to-you) open source tools to help you be more productive in 2019.
|
||||
|
||||
### Freeplane
|
||||
|
||||
[Mind maps][1] are one of the more valuable tools I've used for quickly brainstorming ideas and capturing data. Mind mapping is a versatile process that helps show how things are related and can be used to quickly organize interrelated information. From a planning perspective, mind mapping allows you to quickly perform a brain dump around a single concept, idea, or technology.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/freeplane-1.png)
|
||||
|
||||
[Freeplane][2] is a desktop application that makes it easy to create, view, edit, and share mind maps. It is a redesign of [FreeMind][3], which was the go-to mind-mapping application for quite some time.
|
||||
|
||||
Installing Freeplane is pretty easy. It is a [Java][4] application and distributed as a ZIP file with scripts to start the application on Linux, Windows, and MacOS. At its first startup, its main window includes an example mind map with links to documentation about all the different things you can do with Freeplane.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/freeplane-2.png)
|
||||
|
||||
You have a choice of templates when you create a new mind map. The standard template (likely at the bottom of the list) works for most cases. Just start typing the idea or phrase you want to start with, and your text will replace the center text. Pressing the Insert key will add a branch (or node) off the center with a blank field where you can fill in something associated with the idea. Pressing Insert again will add another node connected to the first one. Pressing Enter on a node will add a node parallel to that one.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/freeplane-3.png)
|
||||
|
||||
As you add nodes, you may come up with another thought or idea related to the main topic. Using either the mouse or the Arrow keys, go back to the center of the map and press Insert. A new node will be created off the main topic.
|
||||
|
||||
If you want to go beyond Freeplane's base functionality, right-click on any of the nodes to bring up a Properties menu for that node. The Tool pane (activated under the View–>Controls menu) contains customization options galore, including line shape and thickness, border shapes, colors, and much, much more. The Calendar tab allows you to insert dates into the nodes and set reminders for when nodes are due. (Note that reminders work only when Freeplane is running.) Mind maps can be exported to several formats, including common images, XML, Microsoft Project, Markdown, and OPML.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/freeplane-4.png)
|
||||
|
||||
Freeplane gives you all the tools you'll need to create vibrant and useful mind maps, getting your ideas out of your head and into a place where you can take action on them.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/1/productivity-tool-freeplane
|
||||
|
||||
作者:[Kevin Sonney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ksonney (Kevin Sonney)
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Mind_map
|
||||
[2]: https://www.freeplane.org/wiki/index.php/Home
|
||||
[3]: https://sourceforge.net/projects/freemind/
|
||||
[4]: https://java.com
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (ustblixin)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
|
@ -1,192 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( pityonline )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Remove/Delete The Empty Lines In A File In Linux)
|
||||
[#]: via: (https://www.2daygeek.com/remove-delete-empty-lines-in-a-file-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
How To Remove/Delete The Empty Lines In A File In Linux
|
||||
======
|
||||
|
||||
Some times you may wants to remove or delete the empty lines in a file in Linux.
|
||||
|
||||
If so, you can use the one of the below method to achieve it.
|
||||
|
||||
It can be done in many ways but i have listed simple methods in the article.
|
||||
|
||||
You may aware of that grep, awk and sed commands are specialized for textual data manipulation.
|
||||
|
||||
Navigate to the following URL, if you would like to read more about these kind of topics. For **[creating a file in specific size in Linux][1]** multiple ways, for **[creating a file in Linux][2]** multiple ways and for **[removing a matching string from a file in Linux][3]**.
|
||||
|
||||
These are fall in advanced commands category because these are used in most of the shell script to do required things.
|
||||
|
||||
It can be done using the following 5 methods.
|
||||
|
||||
* **`sed Command:`** Stream editor for filtering and transforming text.
|
||||
* **`grep Command:`** Print lines that match patterns.
|
||||
* **`cat Command:`** It concatenate files and print on the standard output.
|
||||
* **`tr Command:`** Translate or delete characters.
|
||||
* **`awk Command:`** The awk utility shall execute programs written in the awk programming language, which is specialized for textual data manipulation.
|
||||
* **`perl Command:`** Perl is a programming language specially designed for text editing.
|
||||
|
||||
|
||||
|
||||
To test this, i had already created the file called `2daygeek.txt` with some texts and empty lines. The details are below.
|
||||
|
||||
```
|
||||
$ 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.
|
||||
```
|
||||
|
||||
Now everything is ready and i’m going to test this in multiple ways.
|
||||
|
||||
### How To Remove/Delete The Empty Lines In A File In Linux Using sed Command?
|
||||
|
||||
Sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline).
|
||||
|
||||
```
|
||||
$ 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.
|
||||
```
|
||||
|
||||
Details are follow:
|
||||
|
||||
* **`sed:`** It’s a command
|
||||
* **`//:`** It holds the searching string.
|
||||
* **`^:`** Matches start of string.
|
||||
* **`$:`** Matches end of string.
|
||||
* **`d:`** Delete the matched string.
|
||||
* **`2daygeek.txt:`** Source file name.
|
||||
|
||||
|
||||
|
||||
### How To Remove/Delete The Empty Lines In A File In Linux Using grep Command?
|
||||
|
||||
grep searches for PATTERNS in each FILE. PATTERNS is one or patterns separated by newline characters, and grep prints each line that matches a pattern.
|
||||
|
||||
```
|
||||
$ 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.
|
||||
```
|
||||
|
||||
Details are follow:
|
||||
|
||||
* **`grep:`** It’s a command
|
||||
* **`.:`** Replaces any character.
|
||||
* **`^:`** matches start of string.
|
||||
* **`$:`** matches end of string.
|
||||
* **`E:`** For extended regular expressions pattern matching.
|
||||
* **`e:`** For regular expressions pattern matching.
|
||||
* **`v:`** To select non-matching lines from the file.
|
||||
* **`2daygeek.txt:`** Source file name.
|
||||
|
||||
|
||||
|
||||
### How To Remove/Delete The Empty Lines In A File In Linux Using awk Command?
|
||||
|
||||
The awk utility shall execute programs written in the awk programming language, which is specialized for textual data manipulation. An awk program is a sequence of patterns and corresponding actions.
|
||||
|
||||
```
|
||||
$ 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.
|
||||
```
|
||||
|
||||
Details are follow:
|
||||
|
||||
* **`awk:`** It’s a command
|
||||
* **`//:`** It holds the searching string.
|
||||
* **`^:`** matches start of string.
|
||||
* **`$:`** matches end of string.
|
||||
* **`.:`** Replaces any character.
|
||||
* **`!:`** Delete the matched string.
|
||||
* **`2daygeek.txt:`** Source file name.
|
||||
|
||||
|
||||
|
||||
### How To Delete The Empty Lines In A File In Linux using Combination of cat And tr Command?
|
||||
|
||||
cat stands for concatenate. It is very frequently used in Linux to reads data from a file.
|
||||
|
||||
cat is one of the most frequently used commands on Unix-like operating systems. It’s offer three functions which is related to text file such as display content of a file, combine multiple files into the single output and create a new file.
|
||||
|
||||
Translate, squeeze, and/or delete characters from standard input, writing to standard output.
|
||||
|
||||
```
|
||||
$ 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.
|
||||
```
|
||||
|
||||
Details are follow:
|
||||
|
||||
* **`cat:`** It’s a command
|
||||
* **`tr:`** It’s a command
|
||||
* **`|:`** Pipe symbol. It pass first command output as a input to another command.
|
||||
* **`s:`** Replace each sequence of a repeated character that is listed in the last specified SET.
|
||||
* **`\n:`** To add a new line.
|
||||
* **`2daygeek.txt:`** Source file name.
|
||||
|
||||
|
||||
|
||||
### How To Remove/Delete The Empty Lines In A File In Linux Using perl Command?
|
||||
|
||||
Perl stands in for “Practical Extraction and Reporting Language”. Perl is a programming language specially designed for text editing. It is now widely used for a variety of purposes including Linux system administration, network programming, web development, etc.
|
||||
|
||||
```
|
||||
$ 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.
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/remove-delete-empty-lines-in-a-file-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[pityonline](https://github.com/pityonline)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/create-a-file-in-specific-certain-size-linux/
|
||||
[2]: https://www.2daygeek.com/linux-command-to-create-a-file/
|
||||
[3]: https://www.2daygeek.com/empty-a-file-delete-contents-lines-from-a-file-remove-matching-string-from-a-file-remove-empty-blank-lines-from-a-file/
|
@ -1,264 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Install, Configure And Use Fish Shell In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/linux-fish-shell-friendly-interactive-shell/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
How To Install, Configure And Use Fish Shell In Linux?
|
||||
======
|
||||
|
||||
Every Linux administrator might heard the word called shell.
|
||||
|
||||
Do you know what is shell? Do you know what is the role for shell in Linux? How many shell is available in Linux?
|
||||
|
||||
A shell is a program that provides an interface between a user and kernel.
|
||||
|
||||
kernel is a heart of the Linux operating system that manage everything between user and operating system (OS).
|
||||
|
||||
Shell is available for all the users when they launch the terminal.
|
||||
|
||||
Once the terminal launched then user can run any commands which is available for him.
|
||||
|
||||
When shell completes the command execution then you will be getting the output on the terminal window.
|
||||
|
||||
Bash stands for Bourne Again Shell is the default shell which is running on most of the Linux distribution on today’s.
|
||||
|
||||
It’s very popular and has a lot of features. Today we are going to discuss about the fish shell.
|
||||
|
||||
### What Is Fish Shell?
|
||||
|
||||
[Fish][1] stands for friendly interactive shell, is a fully-equipped, smart and user-friendly command line shell for Linux which comes with some handy features that is not available in most of the shell.
|
||||
|
||||
The features are Autosuggestion, Sane Scripting, Man Page Completions, Web Based configuration and Glorious VGA Color. Are you curious to test it? if so, go ahead and install it by following the below installation steps.
|
||||
|
||||
### How To Install Fish Shell In Linux?
|
||||
|
||||
It’s very simple to install but it doesn’t available in most of the distributions except few. However, it can be easily installed by using the following [fish repository][2].
|
||||
|
||||
For **`Arch Linux`** based systems, use **[Pacman Command][3]** to install fish shell.
|
||||
|
||||
```
|
||||
$ sudo pacman -S fish
|
||||
```
|
||||
|
||||
For **`Ubuntu 16.04/18.04`** systems, use **[APT-GET Command][4]** or **[APT Command][5]** to install fish shell.
|
||||
|
||||
```
|
||||
$ sudo apt-add-repository ppa:fish-shell/release-3
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install fish
|
||||
```
|
||||
|
||||
For **`Fedora`** system, use **[DNF Command][6]** to install fish shell.
|
||||
|
||||
For Fedora 29 System:
|
||||
|
||||
```
|
||||
$ sudo dnf config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/Fedora_29/shells:fish:release:3.repo
|
||||
$ sudo dnf install fish
|
||||
```
|
||||
|
||||
For Fedora 28 System:
|
||||
|
||||
```
|
||||
$ sudo dnf config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/Fedora_28/shells:fish:release:3.repo
|
||||
$ sudo dnf install fish
|
||||
```
|
||||
|
||||
For **`Debian`** systems, use **[APT-GET Command][4]** or **[APT Command][5]** to install fish shell.
|
||||
|
||||
For Debian 9 System:
|
||||
|
||||
```
|
||||
$ sudo wget -nv https://download.opensuse.org/repositories/shells:fish:release:3/Debian_9.0/Release.key -O Release.key
|
||||
$ sudo apt-key add - < Release.key
|
||||
$ sudo echo 'deb http://download.opensuse.org/repositories/shells:/fish:/release:/3/Debian_9.0/ /' > /etc/apt/sources.list.d/shells:fish:release:3.list
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install fish
|
||||
```
|
||||
|
||||
For Debian 8 System:
|
||||
|
||||
```
|
||||
$ sudo wget -nv https://download.opensuse.org/repositories/shells:fish:release:3/Debian_8.0/Release.key -O Release.key
|
||||
$ sudo apt-key add - < Release.key
|
||||
$ sudo echo 'deb http://download.opensuse.org/repositories/shells:/fish:/release:/3/Debian_8.0/ /' > /etc/apt/sources.list.d/shells:fish:release:3.list
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install fish
|
||||
```
|
||||
|
||||
For **`RHEL/CentOS`** systems, use **[YUM Command][7]** to install fish shell.
|
||||
|
||||
For RHEL 7 System:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/RHEL_7/shells:fish:release:3.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
For RHEL 6 System:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:/fish:/release:/3/RedHat_RHEL-6/shells:fish:release:3.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
For CentOS 7 System:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:fish:release:2/CentOS_7/shells:fish:release:2.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
For CentOS 6 System:
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo https://download.opensuse.org/repositories/shells:fish:release:2/CentOS_6/shells:fish:release:2.repo
|
||||
$ sudo yum install fish
|
||||
```
|
||||
|
||||
For **`openSUSE Leap`** system, use **[Zypper Command][8]** to install fish shell.
|
||||
|
||||
```
|
||||
$ sudo zypper addrepo https://download.opensuse.org/repositories/shells:/fish:/release:/3/openSUSE_Leap_42.3/shells:fish:release:3.repo
|
||||
$ suod zypper refresh
|
||||
$ sudo zypper install fish
|
||||
```
|
||||
|
||||
### How To Use Fish Shell?
|
||||
|
||||
Once you have successfully installed the fish shell. Simply type `fish` on your terminal, which will automatically switch to the fish shell from your default bash shell.
|
||||
|
||||
```
|
||||
$ fish
|
||||
```
|
||||
|
||||
![][10]
|
||||
|
||||
### Auto Suggestions
|
||||
|
||||
When you type any commands in the fish shell, it will auto suggest a command in a light grey color after typing few letters.
|
||||
![][11]
|
||||
|
||||
Once you got a suggestion then simple hit the `Left Arrow Mark` to complete it instead of typing the full command.
|
||||
![][12]
|
||||
|
||||
Instantly you can access the previous history based on the command by pressing `Up Arrow Mark` after typing a few letters. It’s similar to bash shell `CTRL+r` option.
|
||||
|
||||
### Tab Completions
|
||||
|
||||
If you would like to see if there are any other possibilities for the given command then simple press the `Tab` button once after typing a few letters.
|
||||
![][13]
|
||||
|
||||
Press the `Tab` button one more time to see the full lists.
|
||||
![][14]
|
||||
|
||||
### Syntax highlighting
|
||||
|
||||
fish performs syntax highlighting, that you can see when you are typing any commands in the terminal. Invalid commands are colored by `RED color`.
|
||||
![][15]
|
||||
|
||||
The same way valid commands are shown in a different color. Also, fish will underline valid file paths when you type and it doesn’t show the underline if the path is not valid.
|
||||
![][16]
|
||||
|
||||
### Web based configuration
|
||||
|
||||
There is a cool feature is available in the fish shell, that allow us to set colors, prompt, functions, variables, history and bindings via web browser.
|
||||
|
||||
Run the following command on your terminal to start the web configuration interface. Simply press `Ctrl+c` to exit it.
|
||||
|
||||
```
|
||||
$ fish_config
|
||||
Web config started at 'file:///home/daygeek/.cache/fish/web_config-86ZF5P.html'. Hit enter to stop.
|
||||
qt5ct: using qt5ct plugin
|
||||
^C
|
||||
Shutting down.
|
||||
```
|
||||
|
||||
![][17]
|
||||
|
||||
### Man Page Completions
|
||||
|
||||
Other shells support programmable completions, but only fish generates them automatically by parsing your installed man pages.
|
||||
|
||||
To do so, run the below command.
|
||||
|
||||
```
|
||||
$ fish_update_completions
|
||||
Parsing man pages and writing completions to /home/daygeek/.local/share/fish/generated_completions/
|
||||
3466 / 3466 : zramctl.8.gz
|
||||
```
|
||||
|
||||
### How To Set Fish as default shell
|
||||
|
||||
If you would like to test the fish shell for some times then you can set the fish shell as your default shell instead of switching it every time.
|
||||
|
||||
If so, first get the fish shell location by using the below command.
|
||||
|
||||
```
|
||||
$ whereis fish
|
||||
fish: /usr/bin/fish /etc/fish /usr/share/fish /usr/share/man/man1/fish.1.gz
|
||||
```
|
||||
|
||||
Change your default shell as a fish shell by running the following command.
|
||||
|
||||
```
|
||||
$ chsh -s /usr/bin/fish
|
||||
```
|
||||
|
||||
![][18]
|
||||
|
||||
`Make note:` Just verify whether the fish shell is added into `/etc/shells` directory or not. If no, then run the following command to append it.
|
||||
|
||||
```
|
||||
$ echo /usr/bin/fish | sudo tee -a /etc/shells
|
||||
```
|
||||
|
||||
Once you have done the testing and if you would like to come back to the bash shell permanently then use the following command.
|
||||
|
||||
For temporary:
|
||||
|
||||
```
|
||||
$ bash
|
||||
```
|
||||
|
||||
For permanent:
|
||||
|
||||
```
|
||||
$ chsh -s /bin/bash
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/linux-fish-shell-friendly-interactive-shell/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fishshell.com/
|
||||
[2]: https://download.opensuse.org/repositories/shells:/fish:/release:/
|
||||
[3]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[4]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[5]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[6]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[7]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[8]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
||||
[9]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[10]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-1.png
|
||||
[11]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-2.png
|
||||
[12]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-5.png
|
||||
[13]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-3.png
|
||||
[14]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-4.png
|
||||
[15]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-6.png
|
||||
[16]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-8.png
|
||||
[17]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-9.png
|
||||
[18]: https://www.2daygeek.com/wp-content/uploads/2019/02/linux-fish-shell-friendly-interactive-shell-7.png
|
@ -1,157 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Run Particular Commands Without Sudo Password In Linux)
|
||||
[#]: via: (https://www.ostechnix.com/run-particular-commands-without-sudo-password-linux/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
Run Particular Commands Without Sudo Password In Linux
|
||||
======
|
||||
|
||||
I had a script on my Ubuntu system deployed on AWS. The primary purpose of this script is to check if a specific service is running at regular interval (every one minute to be precise) and start that service automatically if it is stopped for any reason. But the problem is I need sudo privileges to start the service. As you may know already, we should provide password when we run something as sudo user. But I don’t want to do that. What I actually want to do is to run the service as sudo without password. If you’re ever in a situation like this, I know a small work around, Today, in this brief guide, I will teach you how to run particular commands without sudo password in Unix-like operating systems.
|
||||
|
||||
Have a look at the following example.
|
||||
|
||||
```
|
||||
$ sudo mkdir /ostechnix
|
||||
[sudo] password for sk:
|
||||
```
|
||||
|
||||
![][2]
|
||||
|
||||
As you can see in the above screenshot, I need to provide sudo password when creating a directory named ostechnix in root (/) folder. Whenever we try to execute a command with sudo privileges, we must enter the password. However, in my scenario, I don’t want to provide the sudo password. Here is what I did to run a sudo command without password on my Linux box.
|
||||
|
||||
### Run Particular Commands Without Sudo Password In Linux
|
||||
|
||||
For any reasons, if you want to allow a user to run a particular command without giving the sudo password, you need to add that command in **sudoers** file.
|
||||
|
||||
I want the user named **sk** to execute **mkdir** command without giving the sudo password. Let us see how to do it.
|
||||
|
||||
Edit sudoers file:
|
||||
|
||||
```
|
||||
$ sudo visudo
|
||||
```
|
||||
|
||||
Add the following line at the end of file.
|
||||
|
||||
```
|
||||
sk ALL=NOPASSWD:/bin/mkdir
|
||||
```
|
||||
|
||||
![][3]
|
||||
|
||||
Here, **sk** is the username. As per the above line, the user **sk** can run ‘mkdir’ command from any terminal, without sudo password.
|
||||
|
||||
You can add additional commands (for example **chmod** ) with comma-separated values as shown below.
|
||||
|
||||
```
|
||||
sk ALL=NOPASSWD:/bin/mkdir,/bin/chmod
|
||||
```
|
||||
|
||||
Save and close the file. Log out (or reboot) your system. Now, log in as normal user ‘sk’ and try to run those commands with sudo and see what happens.
|
||||
|
||||
```
|
||||
$ sudo mkdir /dir1
|
||||
```
|
||||
|
||||
![][4]
|
||||
|
||||
See? Even though I ran ‘mkdir’ command with sudo privileges, there was no password prompt. From now on, the user **sk** need not to enter the sudo password while running ‘mkdir’ command.
|
||||
|
||||
When running all other commands except those commands added in sudoers files, you will be prompted to enter the sudo password.
|
||||
|
||||
Let us run another command with sudo.
|
||||
|
||||
```
|
||||
$ sudo apt update
|
||||
```
|
||||
|
||||
![][5]
|
||||
|
||||
See? This command prompts me to enter the sudo password.
|
||||
|
||||
If you don’t want this command to prompt you to ask sudo password, edit sudoers file:
|
||||
|
||||
```
|
||||
$ sudo visudo
|
||||
```
|
||||
|
||||
Add the ‘apt’ command in visudo file like below:
|
||||
|
||||
```
|
||||
sk ALL=NOPASSWD: /bin/mkdir,/usr/bin/apt
|
||||
```
|
||||
|
||||
Did you notice that the apt binary executable file path is different from mkdir? Yes, you must provide the correct executable file path. To find executable file path of any command, for example ‘apt’, use ‘whereis’ command like below.
|
||||
|
||||
```
|
||||
$ whereis apt
|
||||
apt: /usr/bin/apt /usr/lib/apt /etc/apt /usr/share/man/man8/apt.8.gz
|
||||
```
|
||||
|
||||
As you see, the executable file for apt command is **/usr/bin/apt** , hence I added it in sudoers file.
|
||||
|
||||
Like I already mentioned, you can add any number of commands with comma-separated values. Save and close your sudoers file once you’re done. Log out and log in again to your system.
|
||||
|
||||
Now, check if you can be able to run the command with sudo prefix without using the password:
|
||||
|
||||
```
|
||||
$ sudo apt update
|
||||
```
|
||||
|
||||
![][6]
|
||||
|
||||
See? The apt command didn’t ask me the password even though I ran it with sudo.
|
||||
|
||||
Here is yet another example. If you want to run a specific service, for example apache2, add it as shown below.
|
||||
|
||||
```
|
||||
sk ALL=NOPASSWD:/bin/mkdir,/usr/bin/apt,/bin systemctl restart apache2
|
||||
```
|
||||
|
||||
Now, the user can run ‘sudo systemctl restart apache2’ command without sudo password.
|
||||
|
||||
Can I re-authenticate to a particular command in the above case? Of course, yes! Just remove the added command. Log out and log in back.
|
||||
|
||||
Alternatively, you can add **‘PASSWD:’** directive in-front of the command. Look at the following example.
|
||||
|
||||
Add/modify the following line as shown below.
|
||||
|
||||
```
|
||||
sk ALL=NOPASSWD:/bin/mkdir,/bin/chmod,PASSWD:/usr/bin/apt
|
||||
```
|
||||
|
||||
In this case, the user **sk** can run ‘mkdir’ and ‘chmod’ commands without entering the sudo password. However, he must provide sudo password when running ‘apt’ command.
|
||||
|
||||
**Disclaimer:** This is for educational-purpose only. You should be very careful while applying this method. This method might be both productive and destructive. Say for example, if you allow users to execute ‘rm’ command without sudo password, they could accidentally or intentionally delete important stuffs. You have been warned!
|
||||
|
||||
**Suggested read:**
|
||||
|
||||
And, that’s all for now. Hope this was useful. More good stuffs to come. Stay tuned!
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/run-particular-commands-without-sudo-password-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: http://www.ostechnix.com/wp-content/uploads/2017/05/sudo-password-1.png
|
||||
[3]: http://www.ostechnix.com/wp-content/uploads/2017/05/sudo-password-7.png
|
||||
[4]: http://www.ostechnix.com/wp-content/uploads/2017/05/sudo-password-6.png
|
||||
[5]: http://www.ostechnix.com/wp-content/uploads/2017/05/sudo-password-4.png
|
||||
[6]: http://www.ostechnix.com/wp-content/uploads/2017/05/sudo-password-5.png
|
@ -1,5 +1,5 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: translator: (FSSlc)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
@ -211,7 +211,7 @@ via: https://www.2daygeek.com/four-methods-to-change-the-hostname-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
译者:[FSSlc](https://github.com/FSSlc)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,176 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (MjSeven)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Emoji-Log: A new way to write Git commit messages)
|
||||
[#]: via: (https://opensource.com/article/19/2/emoji-log-git-commit-messages)
|
||||
[#]: author: (Ahmad Awais https://opensource.com/users/mrahmadawais)
|
||||
|
||||
Emoji-Log: A new way to write Git commit messages
|
||||
======
|
||||
Add context to your commits with Emoji-Log.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/emoji_tech_keyboard.jpg?itok=ncBNKZFl)
|
||||
|
||||
I'm a full-time open source developer—or, as I like to call it, an 🎩 open sourcerer. I've been working with open source software for over a decade and [built hundreds][1] of open source software applications.
|
||||
|
||||
I also am a big fan of the Don't Repeat Yourself (DRY) philosophy and believe writing better Git commit messages—ones that are contextual enough to serve as a changelog for your open source software—is an important component of DRY. One of the many workflows I've written is [Emoji-Log][2], a straightforward, open source Git commit log standard. It improves the developer experience (DX) by using emoji to create better Git commit messages.
|
||||
|
||||
I've used Emoji-Log while building the [VSCode Tips & Tricks repo][3], my 🦄 [Shades of Purple VSCode theme repo][4], and even an [automatic changelog][5] that looks beautiful.
|
||||
|
||||
### Emoji-Log's philosophy
|
||||
|
||||
I like emoji (which is, in fact, the plural of emoji). I like 'em a lot. Programming, code, geeks/nerds, open source… all of that is inherently dull and sometimes boring. Emoji help me add colors and emotions to the mix. There's nothing wrong with wanting to attach feelings to the 2D, flat, text-based world of code.
|
||||
|
||||
Instead of memorizing [hundreds of emoji][6], I've learned it's better to keep the categories small and general. Here's the philosophy that guides writing commit messages with Emoji-Log:
|
||||
|
||||
1. **Imperative**
|
||||
* Make your Git commit messages imperative.
|
||||
* Write commit message like you're giving an order.
|
||||
* e.g., Use ✅ **Add** instead of ❌ **Added**
|
||||
* e.g., Use ✅ **Create** instead of ❌ **Creating**
|
||||
2. **Rules**
|
||||
* A small number of categories are easy to memorize.
|
||||
* Nothing more, nothing less
|
||||
* e.g. **📦 NEW** , **👌 IMPROVE** , **🐛 FIX** , **📖 DOC** , **🚀 RELEASE** , and **✅ TEST**
|
||||
3. **Actions**
|
||||
* Make Git commits based on actions you take.
|
||||
* Use a good editor like [VSCode][7] to commit the right files with commit messages.
|
||||
|
||||
|
||||
|
||||
### Writing commit messages
|
||||
|
||||
Use only the following Git commit messages. The simple and small footprint is the key to Emoji-Logo.
|
||||
|
||||
1. **📦 NEW: IMPERATIVE_MESSAGE**
|
||||
* Use when you add something entirely new.
|
||||
* e.g., **📦 NEW: Add Git ignore file**
|
||||
2. **👌 IMPROVE: IMPERATIVE_MESSAGE**
|
||||
* Use when you improve/enhance piece of code like refactoring etc.
|
||||
* e.g., **👌 IMPROVE: Remote IP API Function**
|
||||
3. **🐛 FIX: IMPERATIVE_MESSAGE**
|
||||
* Use when you fix a bug. Need I say more?
|
||||
* e.g., **🐛 FIX: Case converter**
|
||||
4. **📖 DOC: IMPERATIVE_MESSAGE**
|
||||
* Use when you add documentation, like README.md or even inline docs.
|
||||
* e.g., **📖 DOC: API Interface Tutorial**
|
||||
5. **🚀 RELEASE: IMPERATIVE_MESSAGE**
|
||||
* Use when you release a new version. e.g., **🚀 RELEASE: Version 2.0.0**
|
||||
6. **✅ TEST: IMPERATIVE_MESSAGE**
|
||||
* Use when you release a new version.
|
||||
* e.g., **✅ TEST: Mock User Login/Logout**
|
||||
|
||||
|
||||
|
||||
That's it for now. Nothing more, nothing less.
|
||||
|
||||
### Emoji-Log functions
|
||||
|
||||
For quick prototyping, I have made the following functions that you can add to your **.bashrc** / **.zshrc** files to use Emoji-Log quickly.
|
||||
|
||||
```
|
||||
#.# 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: $@"
|
||||
}
|
||||
```
|
||||
|
||||
To install these functions for the [fish shell][8], run the following commands:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
If you prefer, you can paste these aliases directly in your **~/.gitconfig** file:
|
||||
|
||||
```
|
||||
# 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"
|
||||
```
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/2/emoji-log-git-commit-messages
|
||||
|
||||
作者:[Ahmad Awais][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/mrahmadawais
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/ahmadawais
|
||||
[2]: https://github.com/ahmadawais/Emoji-Log/
|
||||
[3]: https://github.com/ahmadawais/VSCode-Tips-Tricks
|
||||
[4]: https://github.com/ahmadawais/shades-of-purple-vscode/commits/master
|
||||
[5]: https://github.com/ahmadawais/shades-of-purple-vscode/blob/master/CHANGELOG.md
|
||||
[6]: https://gitmoji.carloscuesta.me/
|
||||
[7]: https://VSCode.pro
|
||||
[8]: https://en.wikipedia.org/wiki/Friendly_interactive_shell
|
@ -1,170 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Set up two-factor authentication for SSH on Fedora)
|
||||
[#]: via: (https://fedoramagazine.org/two-factor-authentication-ssh-fedora/)
|
||||
[#]: author: (Curt Warfield https://fedoramagazine.org/author/rcurtiswarfield/)
|
||||
|
||||
Set up two-factor authentication for SSH on Fedora
|
||||
======
|
||||
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2019/02/twofactor-auth-ssh-816x345.png)
|
||||
|
||||
Every day there seems to be a security breach reported in the news where our data is at risk. Despite the fact that SSH is a secure way to connect remotely to a system, you can still make it even more secure. This article will show you how.
|
||||
|
||||
That’s where two-factor authentication (2FA) comes in. Even if you disable passwords and only allow SSH connections using public and private keys, an unauthorized user could still gain access to your system if they steal your keys.
|
||||
|
||||
With two-factor authentication, you can’t connect to a server with just your SSH keys. You also need to provide the randomly generated number displayed by an authenticator application on a mobile phone.
|
||||
|
||||
The Time-based One-time Password algorithm (TOTP) is the method shown in this article. [Google Authenticator][1] is used as the server application. Google Authenticator is available by default in Fedora.
|
||||
|
||||
For your mobile phone, you can use any two-way authentication application that is compatible with TOTP. There are numerous free applications for Android or IOS that work with TOTP and Google Authenticator. This article uses [FreeOTP][2] as an example.
|
||||
|
||||
### Install and set up Google Authenticator
|
||||
|
||||
First, install the Google Authenticator package on your server.
|
||||
|
||||
```
|
||||
$ sudo dnf install -y google-authenticator
|
||||
```
|
||||
|
||||
Run the application.
|
||||
|
||||
```
|
||||
$ google-authenticator
|
||||
```
|
||||
|
||||
The application presents you with a series of questions. The snippets below show you how to answer for a reasonably secure setup.
|
||||
|
||||
```
|
||||
Do you want authentication tokens to be time-based (y/n) y
|
||||
Do you want me to update your "/home/user/.google_authenticator" file (y/n)? y
|
||||
```
|
||||
|
||||
The app provides you with a secret key, verification code, and recovery codes. Keep these in a secure, safe location. The recovery codes are the **only** way to access your server if you lose your mobile phone.
|
||||
|
||||
### Set up mobile phone authentication
|
||||
|
||||
Install the authenticator application (FreeOTP) on your mobile phone. You can find it in Google Play if you have an Android phone, or in the iTunes store for an Apple iPhone.
|
||||
|
||||
A QR code is displayed on the screen. Open up the FreeOTP app on your mobile phone. To add a new account, select the QR code shaped tool at the top on the app, and then scan the QR code. After the setup is complete, you’ll have to provide the random number generated by the authenticator application every time you connect to your server remotely.
|
||||
|
||||
### Finish configuration
|
||||
|
||||
The application asks further questions. The example below shows you how to answer to set up a reasonably secure configuration.
|
||||
|
||||
```
|
||||
Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y
|
||||
By default, tokens are good for 30 seconds. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of +-1min (window size of 3) to about +-4min (window size of 17 acceptable tokens).
|
||||
Do you want to do so? (y/n) n
|
||||
If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s.
|
||||
Do you want to enable rate-limiting (y/n) y
|
||||
```
|
||||
|
||||
Now you have to set up SSH to take advantage of the new two-way authentication.
|
||||
|
||||
### Configure SSH
|
||||
|
||||
Before completing this step, **make sure you’ve already established a working SSH connection** using public SSH keys, since we’ll be disabling password connections. If there is a problem or mistake, having a connection will allow you to fix the problem.
|
||||
|
||||
On your server, use [sudo][3] to edit the /etc/pam.d/sshd file.
|
||||
|
||||
```
|
||||
$ sudo vi /etc/pam.d/ssh
|
||||
```
|
||||
|
||||
Comment out the auth substack password-auth line:
|
||||
|
||||
```
|
||||
#auth substack password-auth
|
||||
```
|
||||
|
||||
Add the following line to the bottom of the file.
|
||||
|
||||
```
|
||||
auth sufficient pam_google_authenticator.so
|
||||
```
|
||||
|
||||
Save and close the file. Next, edit the /etc/ssh/sshd_config file.
|
||||
|
||||
```
|
||||
$ sudo vi /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
Look for the ChallengeResponseAuthentication line and change it to yes.
|
||||
|
||||
```
|
||||
ChallengeResponseAuthentication yes
|
||||
```
|
||||
|
||||
Look for the PasswordAuthentication line and change it to no.
|
||||
|
||||
```
|
||||
PasswordAuthentication no
|
||||
```
|
||||
|
||||
Add the following line to the bottom of the file.
|
||||
|
||||
```
|
||||
AuthenticationMethods publickey,password publickey,keyboard-interactive
|
||||
```
|
||||
|
||||
Save and close the file, and then restart SSH.
|
||||
|
||||
```
|
||||
$ sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
### Testing your two-factor authentication
|
||||
|
||||
When you attempt to connect to your server you’re now prompted for a verification code.
|
||||
|
||||
```
|
||||
[user@client ~]$ ssh user@example.com
|
||||
Verification code:
|
||||
```
|
||||
|
||||
The verification code is randomly generated by your authenticator application on your mobile phone. Since this number changes every few seconds, you need to enter it before it changes.
|
||||
|
||||
![][4]
|
||||
|
||||
If you do not enter the verification code, you won’t be able to access the system, and you’ll get a permission denied error:
|
||||
|
||||
```
|
||||
[user@client ~]$ ssh user@example.com
|
||||
|
||||
Verification code:
|
||||
|
||||
Verification code:
|
||||
|
||||
Verification code:
|
||||
|
||||
Permission denied (keyboard-interactive).
|
||||
|
||||
[user@client ~]$
|
||||
```
|
||||
|
||||
### Conclusion
|
||||
|
||||
By adding this simple two-way authentication, you’ve now made it much more difficult for an unauthorized user to gain access to your server.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/two-factor-authentication-ssh-fedora/
|
||||
|
||||
作者:[Curt Warfield][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/author/rcurtiswarfield/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Google_Authenticator
|
||||
[2]: https://freeotp.github.io/
|
||||
[3]: https://fedoramagazine.org/howto-use-sudo/
|
||||
[4]: https://fedoramagazine.org/wp-content/uploads/2019/02/freeotp-1.png
|
@ -1,239 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (All about {Curly Braces} in Bash)
|
||||
[#]: via: (https://www.linux.com/blog/learn/2019/2/all-about-curly-braces-bash)
|
||||
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
|
||||
|
||||
All about {Curly Braces} in Bash
|
||||
======
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/curly-braces-1920.jpg?itok=cScRhWrX)
|
||||
|
||||
At this stage of our Bash basics series, it would be hard not to see some crossover between topics. For example, you have already seen a lot of brackets in the examples we have shown over the past several weeks, but the focus has been elsewhere.
|
||||
|
||||
For the next phase of the series, we’ll take a closer look at brackets, curly, curvy, or straight, how to use them, and what they do depending on where you use them. We will also tackle other ways of enclosing things, like when to use quotes, double-quotes, and backquotes.
|
||||
|
||||
This week, we're looking at curly brackets or _braces_ : `{}`.
|
||||
|
||||
### Array Builder
|
||||
|
||||
You have already encountered curly brackets before in [The Meaning of Dot][1]. There, the focus was on the use of the dot/period (`.`), but using braces to build a sequence was equally important.
|
||||
|
||||
As we saw then:
|
||||
|
||||
```
|
||||
echo {0..10}
|
||||
```
|
||||
|
||||
prints out the numbers from 0 to 10. Using:
|
||||
|
||||
```
|
||||
echo {10..0}
|
||||
```
|
||||
|
||||
prints out the same numbers, but in reverse order. And,
|
||||
|
||||
```
|
||||
echo {10..0..2}
|
||||
```
|
||||
|
||||
prints every second number, starting with 10 and making its way backwards to 0.
|
||||
|
||||
Then,
|
||||
|
||||
```
|
||||
echo {z..a..2}
|
||||
```
|
||||
|
||||
prints every second letter, starting with _z_ and working its way backwards until _a_.
|
||||
|
||||
And so on and so forth.
|
||||
|
||||
Another thing you can do is combine two or more sequences:
|
||||
|
||||
```
|
||||
echo {a..z}{a..z}
|
||||
```
|
||||
|
||||
This prints out all the two letter combinations of the alphabet, from _aa_ to _zz_.
|
||||
|
||||
Is this useful? Well, actually it is. You see, arrays in Bash are defined by putting elements between parenthesis `()` and separating each element using a space, like this:
|
||||
|
||||
```
|
||||
month=("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")
|
||||
```
|
||||
|
||||
To access an element within the array, you use its index within brackets `[]`:
|
||||
|
||||
```
|
||||
$ echo ${month[3]} # Array indexes start at [0], so [3] points to the fourth item
|
||||
|
||||
Apr
|
||||
```
|
||||
|
||||
You can accept all those brackets, parentheses, and braces on faith for a moment. We'll talk about them presently.
|
||||
|
||||
Notice that, all things being equal, you can create an array with something like this:
|
||||
|
||||
```
|
||||
letter_combos=({a..z}{a..z})
|
||||
```
|
||||
|
||||
and `letter_combos` points to an array that contains all the 2-letter combinations of the entire alphabet.
|
||||
|
||||
You can also do this:
|
||||
|
||||
```
|
||||
dec2bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
|
||||
```
|
||||
|
||||
This last one is particularly interesting because `dec2bin` now contains all the binary numbers for an 8-bit register, in ascending order, starting with 00000000, 00000001, 00000010, etc., until reaching 11111111. You can use this to build yourself an 8-bit decimal-to-binary converter. Say you want to know what 25 is in binary. You can do this:
|
||||
|
||||
```
|
||||
$ echo ${dec2bin[25]}
|
||||
|
||||
00011001
|
||||
```
|
||||
|
||||
Yes, there are better ways of converting decimal to binary as we saw in [the article where we discussed & as a logical operator][2], but it is still interesting, right?
|
||||
|
||||
### Parameter expansion
|
||||
|
||||
Getting back to
|
||||
|
||||
```
|
||||
echo ${month[3]}
|
||||
```
|
||||
|
||||
Here the braces `{}` are not being used as apart of a sequence builder, but as a way of generating _parameter expansion_. Parameter expansion involves what it says on the box: it takes the variable or expression within the braces and expands it to whatever it represents.
|
||||
|
||||
In this case, `month` is the array we defined earlier, that is:
|
||||
|
||||
```
|
||||
month=("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")
|
||||
```
|
||||
|
||||
And, item 3 within the array points to `"Apr"` (remember: the first index in an array in Bash is `[0]`). That means that `echo ${month[3]}`, after the expansion, translates to `echo "Apr"`.
|
||||
|
||||
Interpreting a variable as its value is one way of expanding it, but there are a few more you can leverage. You can use parameter expansion to manipulate what you read from variable, say, by cutting a chunk off the end.
|
||||
|
||||
Suppose you have a variable like:
|
||||
|
||||
```
|
||||
a="Too longgg"
|
||||
```
|
||||
|
||||
The command:
|
||||
|
||||
```
|
||||
echo ${a%gg}
|
||||
```
|
||||
|
||||
chops off the last two gs and prints " _Too long_ ".
|
||||
|
||||
Breaking this down,
|
||||
|
||||
* `${...}` tells the shell to expand whatever is inside it
|
||||
* `a` is the variable you are working with
|
||||
* `%` tells the shell you want to chop something off the end of the expanded variable ("Too longgg")
|
||||
* and `gg` is what you want to chop off.
|
||||
|
||||
|
||||
|
||||
This can be useful for converting files from one format to another. Allow me to explain with a slight digression:
|
||||
|
||||
[ImageMagick][3] is a set of command line tools that lets you manipulate and modify images. One of its most useful tools ImageMagick comes with is `convert`. In its simplest form `convert` allows you to, given an image in a certain format, make a copy of it in another format.
|
||||
|
||||
The following command takes a JPEG image called _image.jpg_ and creates a PNG copy called _image.png_ :
|
||||
|
||||
```
|
||||
convert image.jpg image.png
|
||||
```
|
||||
|
||||
ImageMagick is often pre-installed on most Linux distros. If you can't find it, look for it in your distro's software manager.
|
||||
|
||||
Okay, end of digression. On to the example:
|
||||
|
||||
With variable expansion, you can do the same as shown above like this:
|
||||
|
||||
```
|
||||
i=image.jpg
|
||||
|
||||
convert $i ${i%jpg}png
|
||||
```
|
||||
|
||||
What you are doing here is chopping off the extension `jpg` from `i` and then adding `png`, making the command `convert image.jpg image.png`.
|
||||
|
||||
You may be wondering how this is more useful than just writing in the name of the file. Well, when you have a directory containing hundreds of JPEG images, you need to convert to PNG, run the following in it:
|
||||
|
||||
```
|
||||
for i in *.jpg; do convert $i ${i%jpg}png; done
|
||||
```
|
||||
|
||||
... and, hey presto! All the pictures get converted automatically.
|
||||
|
||||
If you need to chop off a chunk from the beginning of a variable, instead of `%`, use `#`:
|
||||
|
||||
```
|
||||
$ a="Hello World!"
|
||||
|
||||
$ echo Goodbye${a#Hello}
|
||||
|
||||
Goodbye World!
|
||||
```
|
||||
|
||||
There's quite a bit more to parameter expansion, but a lot of it makes sense only when you are writing scripts. We'll explore more on that topic later in this series.
|
||||
|
||||
### Output Grouping
|
||||
|
||||
Meanwhile, let's finish up with something simple: you can also use `{ ... }` to group the output from several commands into one big blob. The command:
|
||||
|
||||
```
|
||||
echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls > PNGs.txt
|
||||
```
|
||||
|
||||
will execute all the commands but will only copy into the _PNGs.txt_ file the output from the last `ls` command in the list. However, doing
|
||||
|
||||
```
|
||||
{ echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls; } > PNGs.txt
|
||||
```
|
||||
|
||||
creates the file _PNGs.txt_ with everything, starting with the line " _I found all these PNGs:_ ", then the list of PNG files returned by `find`, then the line "Within this bunch of files:" and finishing up with the complete list of files and directories within the current directory.
|
||||
|
||||
Notice that there is space between the braces and the commands enclosed within them. That’s because `{` and `}` are _reserved words_ here, commands built into the shell. They would roughly translate to " _group the outputs of all these commands together_ " in plain English.
|
||||
|
||||
Also notice that the list of commands has to end with a semicolon (`;`) or the whole thing will bork.
|
||||
|
||||
### Next Time
|
||||
|
||||
In our next installment, we'll be looking at more things that enclose other things, but of different shapes. Until then, have fun!
|
||||
|
||||
Read more:
|
||||
|
||||
[And, Ampersand, and & in Linux][4]
|
||||
|
||||
[Ampersands and File Descriptors in Bash][5]
|
||||
|
||||
[Logical & in Bash][2]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/2019/2/all-about-curly-braces-bash
|
||||
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.linux.com/blog/learn/2019/1/linux-tools-meaning-dot
|
||||
[2]: https://www.linux.com/blog/learn/2019/2/logical-ampersand-bash
|
||||
[3]: http://www.imagemagick.org/
|
||||
[4]: https://www.linux.com/blog/learn/2019/2/and-ampersand-and-linux
|
||||
[5]: https://www.linux.com/blog/learn/2019/2/ampersands-and-file-descriptors-bash
|
@ -1,114 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To SSH Into A Particular Directory On Linux)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-ssh-into-a-particular-directory-on-linux/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
How To SSH Into A Particular Directory On Linux
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/SSH-Into-A-Particular-Directory-720x340.png)
|
||||
|
||||
Have you ever been in a situation where you want to SSH to a remote server and immediately cd into a directory and continue work interactively? You’re on the right track! This brief tutorial describes how to directly SSH into a particular directory of a remote Linux system. Not just SSH into a specific directory, you can run any command immediately right after connecting to an SSH server as described in this guide. It is not that difficult as you might think. Read on.
|
||||
|
||||
### SSH Into A Particular Directory Of A Remote System
|
||||
|
||||
Before I knew this method, I would usually first SSH to the remote remote system using command:
|
||||
|
||||
```
|
||||
$ ssh user@remote-system
|
||||
```
|
||||
|
||||
And then cd into a directory like below:
|
||||
|
||||
```
|
||||
$ cd <some-directory>
|
||||
```
|
||||
|
||||
However, you need not to use two separate commands. You can combine these commands and simplify the task with one command.
|
||||
|
||||
Have a look at the following example.
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix ; bash'
|
||||
```
|
||||
|
||||
The above command will SSH into a remote system (192.168.225.22) and immediately cd into a directory named **‘/home/sk/ostechnix/’** directory and leave yourself at the prompt.
|
||||
|
||||
Here, the **-t** flag is used to force pseudo-terminal allocation, which is necessary or an interactive shell.
|
||||
|
||||
Here is the sample output of the above command:
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/ssh-1.gif)
|
||||
|
||||
You can also use this command as well.
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix ; exec bash'
|
||||
```
|
||||
|
||||
Or,
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix && exec bash -l'
|
||||
```
|
||||
|
||||
Here, the **-l** flag sets the bash as login shell.
|
||||
|
||||
In the above example, I have used **bash** in the last argument. It is the default shell in my remote system. If you don’t know the shell type on the remote system, use the following command:
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix && exec $SHELL'
|
||||
```
|
||||
|
||||
Like I already said, this is not just for cd into directory after connecting to an remote system. You can use this trick to run other commands as well. For example, the following command will land you inside ‘/home/sk/ostechnix/’ directory and then execute ‘uname -a’ command.
|
||||
|
||||
```
|
||||
$ ssh -t sk@192.168.225.22 'cd /home/sk/ostechnix && uname -a && exec $SHELL'
|
||||
```
|
||||
|
||||
Alternatively, you can add the command(s) you wanted to run after connecting to an SSH server on the remote system’s **.bash_profile** file.
|
||||
|
||||
Edit **.bash_profile** file:
|
||||
|
||||
```
|
||||
$ nano ~/.bash_profile
|
||||
```
|
||||
|
||||
Add the command(s) one by one. In my case, I am adding the following line:
|
||||
|
||||
```
|
||||
cd /home/sk/ostechnix >& /dev/null
|
||||
```
|
||||
|
||||
Save and close the file. Finally, run the following command to update the changes.
|
||||
|
||||
```
|
||||
$ source ~/.bash_profile
|
||||
```
|
||||
|
||||
Please note that you should add this line on the remote system’s **.bash_profile** or **.bashrc** file, not in your local system’s. From now on, whenever you login (whether by SSH or direct), the cd command will execute and you will be automatically landed inside “/home/sk/ostechnix/” directory.
|
||||
|
||||
|
||||
And, that’s all for now. Hope this was useful. More good stuffs to come. Stay tuned!
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-ssh-into-a-particular-directory-on-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
@ -1,86 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Linux security: Cmd provides visibility, control over user activity)
|
||||
[#]: via: (https://www.networkworld.com/article/3342454/linux-security-cmd-provides-visibility-control-over-user-activity.html)
|
||||
[#]: author: (Sandra Henry-Stocker https://www.networkworld.com/author/Sandra-Henry_Stocker/)
|
||||
|
||||
Linux security: Cmd provides visibility, control over user activity
|
||||
======
|
||||
|
||||
![](https://images.techhive.com/images/article/2017/01/background-1900329_1920-100705659-large.jpg)
|
||||
|
||||
There's a new Linux security tool you should be aware of — Cmd (pronounced "see em dee") dramatically modifies the kind of control that can be exercised over Linux users. It reaches way beyond the traditional configuration of user privileges and takes an active role in monitoring and controlling the commands that users are able to run on Linux systems.
|
||||
|
||||
Provided by a company of the same name, Cmd focuses on cloud usage. Given the increasing number of applications being migrated into cloud environments that rely on Linux, gaps in the available tools make it difficult to adequately enforce required security. However, Cmd can also be used to manage and protect on-premises systems.
|
||||
|
||||
### How Cmd differs from traditional Linux security controls
|
||||
|
||||
The leaders at Cmd — Milun Tesovic and Jake King — say organizations cannot confidently predict or control user behavior until they understand how users work routinely and what is considered “normal.” They seek to provide a tool that will granularly control, monitor, and authenticate user activity.
|
||||
|
||||
Cmd monitors user activity by forming user activity profiles (characterizing the activities these users generally perform), noticing abnormalities in their online behavior (login times, commands used, user locations, etc.), and preventing and reporting certain activities (e.g., downloading or modifying files and running privileged commands) that suggest some kind of system compromise might be underway. The product's behaviors are configurable and changes can be made rapidly.
|
||||
|
||||
The kind of tools most of us are using today to detect threats, identify vulnerabilities, and control user privileges have taken us a long way, but we are still fighting the battle to keep our systems and data safe. Cmd brings us a lot closer to identifying the intentions of hostile users whether those users are people who have managed to break into accounts or represent insider threats.
|
||||
|
||||
![1 sources live sessions][1]
|
||||
|
||||
View live Linux sessions
|
||||
|
||||
### How does Cmd work?
|
||||
|
||||
In monitoring and managing user activity, Cmd:
|
||||
|
||||
* Collects information that profiles user activity
|
||||
* Uses the baseline to determine what is considered normal
|
||||
* Detects and proactively prevents threats using specific indicators
|
||||
* Sends alerts to responsible people
|
||||
|
||||
|
||||
|
||||
![2 triggers][3]
|
||||
|
||||
Building custom policies in Cmd
|
||||
|
||||
Cmd goes beyond defining what sysadmins can control through traditional methods, such as configuring sudo privileges, providing much more granular and situation-specific controls.
|
||||
|
||||
Administrators can select escalation policies that can be managed separately from the user privilege controls managed by Linux sysadmins.
|
||||
|
||||
The Cmd agent provides real-time visibility (not after-the-fact log analysis) and can block actions, require additional authentication, or negotiate authorization as needed.
|
||||
|
||||
Also, Cmd supports custom rules based on geolocation if user locations are available. And new policies can be pushed to agents deployed on hosts within minutes.
|
||||
|
||||
![3 command blocked][4]
|
||||
|
||||
Building a trigger query in Cmd
|
||||
|
||||
### Funding news for Cmd
|
||||
|
||||
[Cmd][2] recently got a financial boost, having [completed of a $15 million round of funding][5] led by [GV][6] (formerly Google Ventures) with participation from Expa, Amplify Partners, and additional strategic investors. This brings the company's raised funding to $21.6 million and will help it continue to add new defensive capabilities to the product and grow its engineering teams.
|
||||
|
||||
In addition, the company appointed Karim Faris, general partner at GV, to its board of directors.
|
||||
|
||||
Join the Network World communities on [Facebook][7] and [LinkedIn][8] to comment on topics that are top of mind.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3342454/linux-security-cmd-provides-visibility-control-over-user-activity.html
|
||||
|
||||
作者:[Sandra Henry-Stocker][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://images.idgesg.net/images/article/2019/02/1-sources-live-sessions-100789431-large.jpg
|
||||
[2]: https://cmd.com
|
||||
[3]: https://images.idgesg.net/images/article/2019/02/2-triggers-100789432-large.jpg
|
||||
[4]: https://images.idgesg.net/images/article/2019/02/3-command-blocked-100789433-large.jpg
|
||||
[5]: https://www.linkedin.com/pulse/changing-cybersecurity-announcing-cmds-15-million-funding-jake-king/
|
||||
[6]: https://www.gv.com/
|
||||
[7]: https://www.facebook.com/NetworkWorld/
|
||||
[8]: https://www.linkedin.com/company/network-world
|
@ -1,165 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Check Password Complexity/Strength And Score In Linux?)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-check-password-complexity-strength-and-score-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
How To Check Password Complexity/Strength And Score In Linux?
|
||||
======
|
||||
|
||||
We all know the password importance. It’s a best practices to use hard and guess password.
|
||||
|
||||
Also, i advise you to use the different password for each services such as email, ftp, ssh, etc.,
|
||||
|
||||
In top of that i suggest you guys to change the password frequently to avoid an unnecessary hacking attempt.
|
||||
|
||||
By default RHEL and it’s clone uses `cracklib` module to check password strength.
|
||||
|
||||
We are going to teach you, how to check the password strength using cracklib module.
|
||||
|
||||
If you would like to check the password score which you have created then use the `pwscore` package.
|
||||
|
||||
If you would like to create a good password, basically it should have minimum 12-15 characters length.
|
||||
|
||||
It should be created in the following combinations like, Alphabets (Lower case & Upper case), Numbers and Special Characters.
|
||||
|
||||
There are many utilities are available in Linux to check a password complexity and we are going to discuss about `cracklib` module today.
|
||||
|
||||
### How To Install cracklib module In Linux?
|
||||
|
||||
The cracklib module is available in most of the distribution repository so, use the distribution official package manager to install it.
|
||||
|
||||
For **`Fedora`** system, use **[DNF Command][1]** to install cracklib.
|
||||
|
||||
```
|
||||
$ sudo dnf install cracklib
|
||||
```
|
||||
|
||||
For **`Debian/Ubuntu`** systems, use **[APT-GET Command][2]** or **[APT Command][3]** to install libcrack2.
|
||||
|
||||
```
|
||||
$ sudo apt install libcrack2
|
||||
```
|
||||
|
||||
For **`Arch Linux`** based systems, use **[Pacman Command][4]** to install cracklib.
|
||||
|
||||
```
|
||||
$ sudo pacman -S cracklib
|
||||
```
|
||||
|
||||
For **`RHEL/CentOS`** systems, use **[YUM Command][5]** to install cracklib.
|
||||
|
||||
```
|
||||
$ sudo yum install cracklib
|
||||
```
|
||||
|
||||
For **`openSUSE Leap`** system, use **[Zypper Command][6]** to install cracklib.
|
||||
|
||||
```
|
||||
$ sudo zypper install cracklib
|
||||
```
|
||||
|
||||
### How To Use The cracklib module In Linux To Check Password Complexity?
|
||||
|
||||
I have added few example in this article to make you understand better about this module.
|
||||
|
||||
If you are given any words like, person name or place name or common word then you will be getting an message “it is based on a dictionary word”.
|
||||
|
||||
```
|
||||
$ echo "password" | cracklib-check
|
||||
password: it is based on a dictionary word
|
||||
```
|
||||
|
||||
The default password length in Linux is `Seven` characters. If you give any password less than seven characters then you will be getting an message “it is WAY too short”.
|
||||
|
||||
```
|
||||
$ echo "123" | cracklib-check
|
||||
123: it is WAY too short
|
||||
```
|
||||
|
||||
You will be getting `OK` When you give good password like us.
|
||||
|
||||
```
|
||||
$ echo "ME$2w!@fgty6723" | cracklib-check
|
||||
ME!@fgty6723: OK
|
||||
```
|
||||
|
||||
### How To Install pwscore In Linux?
|
||||
|
||||
The pwscore package is available in most of the distribution official repository so, use the distribution package manager to install it.
|
||||
|
||||
For **`Fedora`** system, use **[DNF Command][1]** to install libpwquality.
|
||||
|
||||
```
|
||||
$ sudo dnf install libpwquality
|
||||
```
|
||||
|
||||
For **`Debian/Ubuntu`** systems, use **[APT-GET Command][2]** or **[APT Command][3]** to install libpwquality.
|
||||
|
||||
```
|
||||
$ sudo apt install libpwquality
|
||||
```
|
||||
|
||||
For **`Arch Linux`** based systems, use **[Pacman Command][4]** to install libpwquality.
|
||||
|
||||
```
|
||||
$ sudo pacman -S libpwquality
|
||||
```
|
||||
|
||||
For **`RHEL/CentOS`** systems, use **[YUM Command][5]** to install libpwquality.
|
||||
|
||||
```
|
||||
$ sudo yum install libpwquality
|
||||
```
|
||||
|
||||
For **`openSUSE Leap`** system, use **[Zypper Command][6]** to install libpwquality.
|
||||
|
||||
```
|
||||
$ sudo zypper install libpwquality
|
||||
```
|
||||
|
||||
If you are given any words like, person name or place name or common word then you will be getting a message “it is based on a dictionary word”.
|
||||
|
||||
```
|
||||
$ echo "password" | pwscore
|
||||
Password quality check failed:
|
||||
The password fails the dictionary check - it is based on a dictionary word
|
||||
```
|
||||
|
||||
The default password length in Linux is `Seven` characters. If you give any password less than seven characters then you will be getting an message “it is WAY too short”.
|
||||
|
||||
```
|
||||
$ echo "123" | pwscore
|
||||
Password quality check failed:
|
||||
The password is shorter than 8 characters
|
||||
```
|
||||
|
||||
You will be getting `password score` When you give good password like us.
|
||||
|
||||
```
|
||||
$ echo "ME!@fgty6723" | pwscore
|
||||
90
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-check-password-complexity-strength-and-score-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[2]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[3]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[4]: https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/
|
||||
[5]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[6]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
@ -1,202 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Find Available Network Interfaces On Linux)
|
||||
[#]: via: (https://www.ostechnix.com/how-to-find-available-network-interfaces-on-linux/)
|
||||
[#]: author: (SK https://www.ostechnix.com/author/sk/)
|
||||
|
||||
How To Find Available Network Interfaces On Linux
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/network-interface-720x340.jpeg)
|
||||
|
||||
One of the common task we do after installing a Linux system is network configuration. Of course, you can configure network interfaces during the installation time. But, some of you might prefer to do it after installation or change the existing settings. As you know already, you must first know how many interfaces are available on the system in-order to configure network settings from command line. This brief tutorial addresses all the possible ways to find available network interfaces on Linux and Unix operating systems.
|
||||
|
||||
### Find Available Network Interfaces On Linux
|
||||
|
||||
We can find the available network cards in couple ways.
|
||||
|
||||
**Method 1 – Using ‘ifconfig’ Command:**
|
||||
|
||||
The most commonly used method to find the network interface details is using **‘ifconfig’** command. I believe some of Linux users might still use this.
|
||||
|
||||
```
|
||||
$ ifconfig -a
|
||||
```
|
||||
|
||||
Sample output:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
As you see in the above output, I have two network interfaces namely **enp5s0** (on board wired ethernet adapter) and **wlp9s0** (wireless network adapter) on my Linux box. Here, **lo** is loopback interface, which is used to access all network services locally. It has an ip address of 127.0.0.1.
|
||||
|
||||
We can also use the same ‘ifconfig’ command in many UNIX variants, for example **FreeBSD** , to list available network cards.
|
||||
|
||||
**Method 2 – Using ‘ip’ Command:**
|
||||
|
||||
The ‘ifconfig’ command is deprecated in the latest Linux versions. So you can use **‘ip’** command to display the network interfaces as shown below.
|
||||
|
||||
```
|
||||
$ ip link show
|
||||
```
|
||||
|
||||
Sample output:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/02/ip-command.png)
|
||||
|
||||
You can also use the following commands as well.
|
||||
|
||||
```
|
||||
$ ip addr
|
||||
|
||||
$ ip -s link
|
||||
```
|
||||
|
||||
Did you notice that these command also shows the connected state of the network interfaces? If you closely look at the above output, you will notice that my Ethernet card is not connected with network cable (see the word **“DOWN”** in the above output). And wireless network card is connected (See the word **“UP”** ). For more details, check our previous guide to [**find the connected state of network interfaces on Linux**][1].
|
||||
|
||||
These two commands (ifconfig and ip) are just enough to find the available network cards on your Linux systems.
|
||||
|
||||
However, there are few other methods available to list network interfaces on Linux. Here you go.
|
||||
|
||||
**Method 3:**
|
||||
|
||||
The Linux Kernel saves the network interface details inside **/sys/class/net** directory. You can verify the list of available interfaces by looking into this directory.
|
||||
|
||||
```
|
||||
$ ls /sys/class/net
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
enp5s0 lo wlp9s0
|
||||
```
|
||||
|
||||
**Method 4:**
|
||||
|
||||
In Linux operating systems, **/proc/net/dev** file contains statistics about network interfaces.
|
||||
|
||||
To view the available network cards, just view its contents using command:
|
||||
|
||||
```
|
||||
$ cat /proc/net/dev
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
**Method 5: Using ‘netstat’ command**
|
||||
|
||||
The **netstat** command displays various details such as network connections, routing tables, interface statistics, masquerade connections, and multicast memberships.
|
||||
|
||||
```
|
||||
$ netstat -i
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Please be mindful that netstat is obsolete. The Replacement for “netstat -i” is “ip -s link”. Also note that this method will list only the active interfaces, not all available interfaces.
|
||||
|
||||
**Method 6: Using ‘nmcli’ command**
|
||||
|
||||
The nmcli is nmcli is a command-line tool for controlling NetworkManager and reporting network status. It is used to create, display, edit, delete, activate, and deactivate network connections and display network status.
|
||||
|
||||
If you have Linux system with Network Manager installed, you can list the available network interfaces using nmcli tool using the following commands:
|
||||
|
||||
```
|
||||
$ nmcli device status
|
||||
```
|
||||
|
||||
Or,
|
||||
|
||||
```
|
||||
$ nmcli connection show
|
||||
```
|
||||
|
||||
You know now how to find the available network interfaces on Linux. Next, check the following guides to know how to configure IP address on Linux.
|
||||
|
||||
[How To Configure Static IP Address In Linux And Unix][2]
|
||||
|
||||
[How To Configure IP Address In Ubuntu 18.04 LTS][3]
|
||||
|
||||
[How To Configure Static And Dynamic IP Address In Arch Linux][4]
|
||||
|
||||
[How To Assign Multiple IP Addresses To Single Network Card In Linux][5]
|
||||
|
||||
If you know any other quick ways to do it, please share them in the comment section below. I will check and update the guide with your inputs.
|
||||
|
||||
And, that’s all. More good stuffs to come. Stay tuned!
|
||||
|
||||
Cheers!
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-find-available-network-interfaces-on-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/how-to-find-out-the-connected-state-of-a-network-cable-in-linux/
|
||||
[2]: https://www.ostechnix.com/configure-static-ip-address-linux-unix/
|
||||
[3]: https://www.ostechnix.com/how-to-configure-ip-address-in-ubuntu-18-04-lts/
|
||||
[4]: https://www.ostechnix.com/configure-static-dynamic-ip-address-arch-linux/
|
||||
[5]: https://www.ostechnix.com/how-to-assign-multiple-ip-addresses-to-single-network-card-in-linux/
|
@ -1,75 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Connecting a VoIP phone directly to an Asterisk server)
|
||||
[#]: via: (https://feeding.cloud.geek.nz/posts/connecting-voip-phone-directly-to-asterisk-server/)
|
||||
[#]: author: (François Marier https://fmarier.org/)
|
||||
|
||||
Connecting a VoIP phone directly to an Asterisk server
|
||||
======
|
||||
|
||||
On my [Asterisk][1] server, I happen to have two on-board ethernet boards. Since I only used one of these, I decided to move my VoIP phone from the local network switch to being connected directly to the Asterisk server.
|
||||
|
||||
The main advantage is that this phone, running proprietary software of unknown quality, is no longer available on my general home network. Most importantly though, it no longer has access to the Internet, without my having to firewall it manually.
|
||||
|
||||
Here's how I configured everything.
|
||||
|
||||
### Private network configuration
|
||||
|
||||
On the server, I started by giving the second network interface a static IP address in `/etc/network/interfaces`:
|
||||
|
||||
```
|
||||
auto eth1
|
||||
iface eth1 inet static
|
||||
address 192.168.2.2
|
||||
netmask 255.255.255.0
|
||||
```
|
||||
|
||||
On the VoIP phone itself, I set the static IP address to `192.168.2.3` and the DNS server to `192.168.2.2`. I then updated the SIP registrar IP address to `192.168.2.2`.
|
||||
|
||||
The DNS server actually refers to an [unbound daemon][2] running on the Asterisk server. The only configuration change I had to make was to listen on the second interface and allow the VoIP phone in:
|
||||
|
||||
```
|
||||
server:
|
||||
interface: 127.0.0.1
|
||||
interface: 192.168.2.2
|
||||
access-control: 0.0.0.0/0 refuse
|
||||
access-control: 127.0.0.1/32 allow
|
||||
access-control: 192.168.2.3/32 allow
|
||||
```
|
||||
|
||||
Finally, I opened the right ports on the server's firewall in `/etc/network/iptables.up.rules`:
|
||||
|
||||
```
|
||||
-A INPUT -s 192.168.2.3/32 -p udp --dport 5060 -j ACCEPT
|
||||
-A INPUT -s 192.168.2.3/32 -p udp --dport 10000:20000 -j ACCEPT
|
||||
```
|
||||
|
||||
### Accessing the admin page
|
||||
|
||||
Now that the VoIP phone is no longer available on the local network, it's not possible to access its admin page. That's a good thing from a security point of view, but it's somewhat inconvenient.
|
||||
|
||||
Therefore I put the following in my `~/.ssh/config` to make the admin page available on `http://localhost:8081` after I connect to the Asterisk server via ssh:
|
||||
|
||||
```
|
||||
Host asterisk
|
||||
LocalForward 8081 192.168.2.3:80
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://feeding.cloud.geek.nz/posts/connecting-voip-phone-directly-to-asterisk-server/
|
||||
|
||||
作者:[François Marier][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fmarier.org/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.asterisk.org/
|
||||
[2]: https://feeding.cloud.geek.nz/posts/setting-up-your-own-dnssec-aware/
|
84
sources/tech/20190301 Emacs for (even more of) the win.md
Normal file
84
sources/tech/20190301 Emacs for (even more of) the win.md
Normal file
@ -0,0 +1,84 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Emacs for (even more of) the win)
|
||||
[#]: via: (https://so.nwalsh.com/2019/03/01/emacs)
|
||||
[#]: author: (Norman Walsh https://so.nwalsh.com)
|
||||
|
||||
Emacs for (even more of) the win
|
||||
======
|
||||
|
||||
I use Emacs every day. I rarely notice it. But when I do, it usually brings me joy.
|
||||
|
||||
>If you are a professional writer…Emacs outshines all other editing software in approximately the same way that the noonday sun does the stars. It is not just bigger and brighter; it simply makes everything else vanish.
|
||||
|
||||
I’ve been using [Emacs][1] for well over twenty years. I use it for writing almost anything and everything (I edit Scala and Java in [IntelliJ][2]). I read my email in it. If it can be done in Emacs, that’s where I prefer to do it.
|
||||
|
||||
Although I’ve used Emacs for literally decades, I realized around the new year that very little about my use of Emacs had changed in the past decade or more. New editing modes had come along, of course, I’d picked up a package or two, and I did adopt [Helm][3] a few years ago, but mostly it just did all the heavy lifting that I required of it, day in and day out without complaining or getting in my way. On the one hand, that’s a testament to how good it is. On the other hand, that’s an invitation to dig in and see what I’ve missed.
|
||||
|
||||
At about the same time, I resolved to improve several aspects of my work life:
|
||||
|
||||
* **Better meeting management.** I’m lead on a couple of projects at work and those projects have meetings, both regularly scheduled and ad hoc; some of them I run, some of them, I only attend.
|
||||
|
||||
I realized I’d become sloppy about my participation in meetings. It’s all too easy sit in a room where there’s a meeting going on but actually read email and work on other items. (I strongly oppose the “no laptops” rule in meetings, but that’s a topic for another day.)
|
||||
|
||||
There are a couple of problems with sloppy participation. First, it’s disrespectful to the person who convened the meeting and the other participants. That’s actually sufficient reason not to do it, but I think there’s another problem: it disguises the cost of meetings.
|
||||
|
||||
If you’re in a meeting but also answering your email and maybe fixing a bug, then that meeting didn’t cost anything (or as much). If meetings are cheap, then there will be more of them.
|
||||
|
||||
I want fewer, shorter meetings. I don’t want to disguise their cost, I want them to be perceived as damned expensive and to be avoided unless absolutely necessary.
|
||||
|
||||
Sometimes, they are absolutely necessary. And I appreciate that a quick meeting can sometimes resolve an issue quickly. But if I have ten short meetings a day, let’s not pretend that I’m getting anything else productive accomplished.
|
||||
|
||||
I resolved to take notes at all the meetings I attend. I’m not offering to take minutes, necessarily, but I am taking minutes of a sort. It keeps me focused on the meeting and not catching up on other things.
|
||||
|
||||
* **Better time management.** There are lots and lots of things that I need or want to do, both professionally and personally. I’ve historically kept track off some of them in issue lists, some in saved email threads (in Emacs and [Gmail][4], for slightly different types of reminders), in my calendar, on “todo lists” of various sorts on my phone, and on little scraps of paper. And probably other places as well.
|
||||
|
||||
I resolved to keep them all in one place. Not because I think there’s one place that’s uniformly best or better, but because I hope to accomplish two things. First, by having them all in one place, I hope to be able to develop a better and more holistic view of where I’m putting my energies. Second, because I want to develop a habitn. “A settled or regular tendency or practice, especially one that is hard to give up.” of recording, tracking, and preserving them.
|
||||
|
||||
* **Better accountability.** If you work in certain science or engineering disciplines, you will have developed the habit of keeping a [lab notebook][5]. Alas, I did not. But I resolved to do so.
|
||||
|
||||
I’m not interested in the legal aspects that encourage bound pages or scribing only in permanent marker. What I’m interested in is developing the habit of keeping a record. My goal is to have a place to jot down ideas and design sketches and the like. If I have sudden inspiration or if I think of an edge case that isn’t in the test suite, I want my instinct to be to write it in my journal instead of scribbling it on a scrap of paper or promising myself that I’ll remember it.
|
||||
|
||||
|
||||
|
||||
|
||||
This confluence of resolutions led me quickly and more-or-less directly to [Org][6]. There is a large, active, and loyal community of Org users. I’ve played with it in the past (I even [wrote about it][7], at least in passing, a couple of years ago) and I tinkered long enough to [integrate MarkLogic][8] into it. (Boy has that paid off in the last week or two!)
|
||||
|
||||
But I never used it.
|
||||
|
||||
I am now using it. I take minutes in it, I record all of my todo items in it, and I keep a journal in it. I’m not sure there’s much value in me attempting to wax eloquent about it or enumerate all its features, you’ll find plenty of either with a quick web search.
|
||||
|
||||
If you use Emacs, you should be using Org. If you don’t use Emacs, I’m confident you wouldn’t be the first person who started because of Org. It does a lot. It takes a little time to learn your way around and remember the shortcuts, but I think it’s worth it. (And if you carry an [iOS][9] device in your pocket, I recommend [beorg][10] for recording items while you’re on the go.)
|
||||
|
||||
Naturally, I worked out how to [get XML out of it][11]⊕“Worked out” sure is a funny way to spell “hacked together in elisp.”. And from there, how to turn it back into the markup my weblog expects (and do so at the push of a button in Emacs, of course). So this is the first posting written in Org. It won’t be the last.
|
||||
|
||||
P.S. Happy birthday [little weblog][12].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://so.nwalsh.com/2019/03/01/emacs
|
||||
|
||||
作者:[Norman Walsh][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://so.nwalsh.com
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Emacs
|
||||
[2]: https://en.wikipedia.org/wiki/IntelliJ_IDEA
|
||||
[3]: https://emacs-helm.github.io/helm/
|
||||
[4]: https://en.wikipedia.org/wiki/Gmail
|
||||
[5]: https://en.wikipedia.org/wiki/Lab_notebook
|
||||
[6]: https://en.wikipedia.org/wiki/Org-mode
|
||||
[7]: https://www.balisage.net/Proceedings/vol17/html/Walsh01/BalisageVol17-Walsh01.html
|
||||
[8]: https://github.com/ndw/ob-ml-marklogic/
|
||||
[9]: https://en.wikipedia.org/wiki/IOS
|
||||
[10]: https://beorgapp.com/
|
||||
[11]: https://github.com/ndw/org-to-xml
|
||||
[12]: https://so.nwalsh.com/2017/03/01/helloWorld
|
69
sources/tech/20190303 How to boot up a new Raspberry Pi.md
Normal file
69
sources/tech/20190303 How to boot up a new Raspberry Pi.md
Normal file
@ -0,0 +1,69 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to boot up a new Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/how-boot-new-raspberry-pi)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
How to boot up a new Raspberry Pi
|
||||
======
|
||||
Learn how to install a Linux operating system, in the third article in our guide to getting started with Raspberry Pi.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_code_keyboard_orange_hands.png?itok=G6tJ_64Y)
|
||||
|
||||
If you've been following along in this series, you've [chosen][1] and [bought][2] your Raspberry Pi board and peripherals and now you're ready to start using it. Here, in the third article, let's look at what you need to do to boot it up.
|
||||
|
||||
Unlike your laptop, desktop, smartphone, or tablet, the Raspberry Pi doesn't come with built-in storage. Instead, it uses a Micro SD card to store the operating system and your files. The great thing about this is it gives you the flexibility to carry your files (even if you don't have your Raspberry Pi with you). The downside is it may also increase the risk of losing or damaging the card—and thus losing your files. Just protect your Micro SD card, and you should be fine.
|
||||
|
||||
You should also know that SD cards aren't as fast as mechanical or solid state drives, so booting, reading, and writing from your Pi will not be as speedy as you would expect from other devices.
|
||||
|
||||
### How to install Raspbian
|
||||
|
||||
The first thing you need to do when you get a new Raspberry Pi is to install its operating system on a Micro SD card. Even though there are other operating systems (both Linux- and non-Linux-based) available for the Raspberry Pi, this series focuses on [Raspbian][3] , Raspberry Pi's official Linux version.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/raspbian.png)
|
||||
|
||||
The easiest way to install Raspbian is with [NOOBS][4], which stands for "New Out Of Box Software." Raspberry Pi offers great [documentation for NOOBS][5], so I won't repeat the installation instructions here.
|
||||
|
||||
NOOBS gives you the choice of installing the following operating systems:
|
||||
|
||||
+ [Raspbian][6]
|
||||
+ [LibreELEC][7]
|
||||
+ [OSMC][8]
|
||||
+ [Recalbox][9]
|
||||
+ [Lakka][10]
|
||||
+ [RISC OS][11]
|
||||
+ [Screenly OSE][12]
|
||||
+ [Windows 10 IoT Core][13]
|
||||
+ [TLXOS][14]
|
||||
|
||||
Again, Raspbian is the operating system we'll use in this series, so go ahead, grab your Micro SD and follow the NOOBS documentation to install it. I'll meet you in the fourth article in this series, where we'll look at how to use Linux, including some of the main commands you'll need to know.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/how-boot-new-raspberry-pi
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/3/which-raspberry-pi-choose
|
||||
[2]: https://opensource.com/article/19/2/how-buy-raspberry-pi
|
||||
[3]: https://www.raspbian.org/RaspbianFAQ
|
||||
[4]: https://www.raspberrypi.org/downloads/noobs/
|
||||
[5]: https://www.raspberrypi.org/documentation/installation/noobs.md
|
||||
[6]: https://www.raspbian.org/RaspbianFAQ
|
||||
[7]: https://libreelec.tv/
|
||||
[8]: https://osmc.tv/
|
||||
[9]: https://www.recalbox.com/
|
||||
[10]: http://www.lakka.tv/
|
||||
[11]: https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi
|
||||
[12]: https://www.screenly.io/ose/
|
||||
[13]: https://developer.microsoft.com/en-us/windows/iot
|
||||
[14]: https://thinlinx.com/
|
@ -0,0 +1,133 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How rootless Buildah works: Building containers in unprivileged environments)
|
||||
[#]: via: (https://opensource.com/article/19/3/tips-tricks-rootless-buildah)
|
||||
[#]: author: (Daniel J Walsh https://opensource.com/users/rhatdan)
|
||||
|
||||
How rootless Buildah works: Building containers in unprivileged environments
|
||||
======
|
||||
Buildah is a tool and library for building Open Container Initiative (OCI) container images.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/containers_2015-1-osdc-lead.png?itok=VEB4zwza)
|
||||
|
||||
In previous articles, including [How does rootless Podman work?][1], I talked about [Podman][2], a tool that enables users to manage pods, containers, and container images.
|
||||
|
||||
[Buildah][3] is a tool and library for building Open Container Initiative ([OCI][4]) container images that is complementary to Podman. (Both projects are maintained by the [containers][5] organization, of which I'm a member.) In this article, I will talk about rootless Buildah, including the differences between it and Podman.
|
||||
|
||||
Our goal with Buildah was to build a low-level tool that could be used either directly or vendored into other tools to build container images.
|
||||
|
||||
### Why Buildah?
|
||||
|
||||
Here is how I describe a container image: It is basically a rootfs directory that contains the code needed to run your container. This directory is called a rootfs because it usually looks like **/ (root)** on a Linux machine, meaning you are likely to find directories in a rootfs like **/etc** , **/usr** , **/bin** , etc.
|
||||
|
||||
The second part of a container image is a JSON file that describes the contents of the rootfs. It contains fields like the command to run the container, the entrypoint, the environment variables required to run the container, the working directory of the container, etc. Basically this JSON file allows the developer of the container image to describe how the container image is expected to be used. The fields in this JSON file have been standardized in the [OCI Image Format specification][6]
|
||||
|
||||
The rootfs and the JSON file then get tar'd together to create an image bundle that is stored in a container registry. To create a layered image, you install more software into the rootfs and modify the JSON file. Then you tar up the differences of the new and the old rootfs and store that in another image tarball. The second JSON file refers back to the first JSON file via a checksum.
|
||||
|
||||
Many years ago, Docker introduced Dockerfile, a simplified scripting language for building container images. Dockerfile was great and really took off, but it has many shortcomings that users have complained about. For example:
|
||||
|
||||
* Dockerfile encourages the inclusion of tools used to build containers inside the container image. Container images do not need to include yum/dnf/apt, but most contain one of them and all their dependencies.
|
||||
|
||||
* Each line causes a layer to be created. Because of this, secrets can mistakenly get added to container images. If you create a secret in one line of the Dockerfile and delete it in the next, the secret is still in the image.
|
||||
|
||||
|
||||
|
||||
|
||||
One of my biggest complaints about the "container revolution" is that six years since it started, the only way to build a container image was still with Dockerfiles. Lots of tools other than **docker build** have appeared besides Buildah, but most still deal only with Dockerfile. So users continue hacking around the problems with Dockerfile.
|
||||
|
||||
Note that [umoci][7] is an alternative to **docker build** that allows you to build container images without Dockerfile.
|
||||
|
||||
Our goal with Buildah was to build a simple tool that could just create a rootfs directory on disk and allow other tools to populate the directory, then create the JSON file. Finally, Buildah would create the OCI image and push it to a container registry where it could be used by any container engine, like [Docker][8], Podman, [CRI-O][9], or another Buildah.
|
||||
|
||||
Buildah also supports Dockerfile, since we know the bulk of people building containers have created Dockerfiles.
|
||||
|
||||
### Using Buildah directly
|
||||
|
||||
Lots of people use Buildah directly. A cool feature of Buildah is that you can script up the container build directly in Bash.
|
||||
|
||||
The example below creates a Bash script called **myapp.sh** , which uses Buildah to pull down the Fedora image, and then uses **dnf** and **make** on a machine to install software into the container image rootfs, **$mnt**. It then adds some fields to the JSON file using **buildah config** and commits the container to a container image **myapp**. Finally, it pushes the container image to a container registry, **quay.io**. (It could push it to any container registry.) Now this OCI image can be used by any container engine or Kubernetes.
|
||||
|
||||
```
|
||||
cat myapp.sh
|
||||
#!/bin/sh
|
||||
ctr=$(buildah from fedora)
|
||||
mnt=($buildah mount $ctr)
|
||||
dnf -y install --installroot $mnt httpd
|
||||
make install DESTDIR=$mnt myapp
|
||||
rm -rf $mnt/var/cache $mnt/var/log/*
|
||||
buildah config --command /usr/bin/myapp -env foo=bar --working-dir=/root $ctr
|
||||
buildah commit $ctr myapp
|
||||
buildah push myapp http://quay.io/username/myapp
|
||||
```
|
||||
|
||||
To create really small images, you could replace **fedora** in the script above with **scratch** , and Buildah will build a container image that only has the requirements for the **httpd** package inside the container image. No need for Python or DNF.
|
||||
|
||||
### Podman's relationship to Buildah
|
||||
|
||||
With Buildah, we have a low-level tool for building container images. Buildah also provides a library for other tools to build container images. Podman was designed to replace the Docker command line interface (CLI). One of the Docker CLI commands is **docker build**. We needed to have **podman build** to support building container images with Dockerfiles. Podman vendored in the Buildah library to allow it to do **podman build**. Any time you do a **podman build** , you are executing Buildah code to build your container images. If you are only going to use Dockerfiles to build container images, we recommend you only use Podman; there's no need for Buildah at all.
|
||||
|
||||
### Other tools using the Buildah library
|
||||
|
||||
Podman is not the only tool to take advantage of the Buildah library. [OpenShift 4 Source-to-Image][10] (S2I) will also use Buildah to build container images. OpenShift S2I allows developers using OpenShift to use Git commands to modify source code; when they push the changes for their source code to the Git repository, OpenShift kicks off a job to compile the source changes and create a container image. It also uses Buildah under the covers to build this image.
|
||||
|
||||
[Ansible-Bender][11] is a new project to build container images via an Ansible playbook. For those familiar with Ansible, Ansible-Bender makes it easy to describe the contents of the container image and then uses Buildah to package up the container image and send it to a container registry.
|
||||
|
||||
We would love to see other tools and languages for describing and building a container image and would welcome others use Buildah to do the conversion.
|
||||
|
||||
### Problems with rootless
|
||||
|
||||
Buildah works fine in rootless mode. It uses user namespace the same way Podman does. If you execute
|
||||
|
||||
```
|
||||
$ buildah bud --tag myapp -f Dockerfile .
|
||||
$ buildah push myapp http://quay.io/username/myapp
|
||||
```
|
||||
|
||||
in your home directory, everything works great.
|
||||
|
||||
However, if you execute the script described above, it will fail!
|
||||
|
||||
The problem is that, when running the **buildah mount** command in rootless mode, the **buildah** command must put itself inside the user namespace and create a new mount namespace. Rootless users are not allowed to mount filesystems when not running in a user namespace.
|
||||
|
||||
When the Buildah executable exits, the user namespace and mount namespace disappear, so the mount point no longer exists. This means the commands after **buildah mount** that attempt to write to **$mnt** will fail since **$mnt** is no longer mounted.
|
||||
|
||||
How can we make the script work in rootless mode?
|
||||
|
||||
#### Buildah unshare
|
||||
|
||||
Buildah has a special command, **buildah unshare** , that allows you to enter the user namespace. If you execute it with no commands, it will launch a shell in the user namespace, and your shell will seem like it is running as root and all the contents of the home directory will seem like they are owned by root. If you look at the owner or files in **/usr** , it will list them as owned by **nfsnobody** (or nobody). This is because your user ID (UID) is now root inside the user namespace and real root (UID=0) is not mapped into the user namespace. The kernel represents all files owned by UIDs not mapped into the user namespace as the NFSNOBODY user. When you exit the shell, you will exit the user namespace, you will be back to your normal UID, and the home directory will be owned by your UID again.
|
||||
|
||||
If you want to execute the **myapp.sh** command defined above, you can execute **buildah unshare myapp.sh** and the script will now run correctly.
|
||||
|
||||
#### Conclusion
|
||||
|
||||
Building and running containers in unprivileged environments is now possible and quite useable. There is little reason for developers to develop containers as root.
|
||||
|
||||
If you want to use a traditional container engine, and use Dockerfile's for builds, then you should probably just use Podman. But if you want to experiment with building container images in new ways without using Dockerfile, then you should really take a look at Buildah.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/tips-tricks-rootless-buildah
|
||||
|
||||
作者:[Daniel J Walsh][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/rhatdan
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/2/how-does-rootless-podman-work
|
||||
[2]: https://podman.io/
|
||||
[3]: https://github.com/containers/buildah
|
||||
[4]: https://www.opencontainers.org/
|
||||
[5]: https://github.com/containers
|
||||
[6]: https://github.com/opencontainers/image-spec
|
||||
[7]: https://github.com/openSUSE/umoci
|
||||
[8]: https://github.com/docker
|
||||
[9]: https://cri-o.io/
|
||||
[10]: https://github.com/openshift/source-to-image
|
||||
[11]: https://github.com/TomasTomecek/ansible-bender
|
@ -0,0 +1,65 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (3 popular programming languages you can learn with Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/programming-languages-raspberry-pi)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
3 popular programming languages you can learn with Raspberry Pi
|
||||
======
|
||||
Become more valuable on the job market by learning to program with the Raspberry Pi.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_language_c.png?itok=mPwqDAD9)
|
||||
|
||||
In the last article in this series, I shared some ways to [teach kids to program with Raspberry Pi][1]. In theory, there is absolutely nothing stopping an adult from using resources designed for kids, but you might be better served by learning the programming languages that are in demand in the job market.
|
||||
|
||||
Here are three programming languages you can learn with the Raspberry Pi.
|
||||
|
||||
### Python
|
||||
|
||||
[Python][2] has become one of the [most popular programming languages][3] in the open source world. Its interpreter has been packaged and made available in every popular Linux distribution. If you install Raspbian on your Raspberry Pi, you will see an app called [Thonny][4], which is a Python integrated development environment (IDE) for beginners. In a nutshell, an IDE is an application that provides all you need to get your code executed, often including things like debuggers, documentation, auto-completion, and emulators. Here is a [great little tutorial][5] to get you started using Thonny and Python on the Raspberry Pi.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/thonny.png)
|
||||
|
||||
### Java
|
||||
|
||||
Although arguably not as attractive as it once was, [Java][6] remains heavily used in universities around the world and deeply embedded in the enterprise. So, even though some will disagree that I'm recommending it as a beginner's language, I am compelled to do so; for one thing, it still very popular, and for another, there are a lot of books, classes, and other information available for you to learn Java. Get started on the Raspberry Pi by using the [BlueJ][7] Java IDE.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/bluejayide.png)
|
||||
|
||||
### JavaScript
|
||||
|
||||
"Back in my day…" [JavaScript][8] was a client-side language that basically allowed people to streamline and automate user events in a browser and modify HTML elements. Today, JavaScript has escaped the browser and is available for other types of clients like mobile apps and even server-side programming. [Node.js][9] is a popular runtime environment that allows developers to code beyond the client-browser paradigm. To learn more about running Node.js on the Raspberry Pi, check out [W3Schools tutorial][10].
|
||||
|
||||
### Other languages
|
||||
|
||||
If there's another language you want to learn, don't despair. There's a high likelihood that you can use your Raspberry Pi to compile or interpret any language of choice, including C, C++, PHP, and Ruby.
|
||||
|
||||
Microsoft's [Visual Studio Code][11] also [runs on the Raspberry Pi][12]. It's an open source code editor from Microsoft that supports several markup and programming languages.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/programming-languages-raspberry-pi
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/2/teach-kids-program-raspberry-pi
|
||||
[2]: https://opensource.com/resources/python
|
||||
[3]: https://www.economist.com/graphic-detail/2018/07/26/python-is-becoming-the-worlds-most-popular-coding-language
|
||||
[4]: https://thonny.org/
|
||||
[5]: https://raspberrypihq.com/getting-started-with-python-programming-and-the-raspberry-pi/
|
||||
[6]: https://opensource.com/resources/java
|
||||
[7]: https://www.bluej.org/raspberrypi/
|
||||
[8]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
|
||||
[9]: https://nodejs.org/en/
|
||||
[10]: https://www.w3schools.com/nodejs/nodejs_raspberrypi.asp
|
||||
[11]: https://code.visualstudio.com/
|
||||
[12]: https://pimylifeup.com/raspberry-pi-visual-studio-code/
|
@ -0,0 +1,52 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Blockchain 2.0: Revolutionizing The Financial System [Part 2])
|
||||
[#]: via: (https://www.ostechnix.com/blockchain-2-0-revolutionizing-the-financial-system/)
|
||||
[#]: author: (EDITOR https://www.ostechnix.com/author/editor/)
|
||||
|
||||
Blockchain 2.0: Revolutionizing The Financial System [Part 2]
|
||||
======
|
||||
|
||||
This is the second part of our [**Blockchain 2.0**][1] series. The blockchain can transform how individuals and institutions deal with their finances. This post looks at how the existing monetary system evolved and how new blockchain systems are bringing in change as the next crucial step in the evolution of money.
|
||||
|
||||
Two key ideas will lay the foundation for this article. **PayPal** , when it was launched, was revolutionary in terms of its operation. The company would gather, process and confirm massive amounts of consumer data to facilitate online transactions of all kinds, virtually allowing platforms such as eBay to grow into trustful sources for commerce, and laying the benchmark for digital payment systems worldwide. The second, albeit much more important key idea to be highlighted here, is a somewhat existential question. We all use money or rather currency for our day-to-day needs. A ten-dollar bill will get you a cup or two from your favorite coffee shop and get you a head start on your day for instance. We depend on our respective national currencies for virtually everything.
|
||||
|
||||
Sure, mankind has come a long way since the **barter system** ruled what you ate for breakfast, but still, what exactly is currency? Who or what gives it it’s a value? And as the popular rumor suggests, does going to a bank and giving them a dollar bill actually get you the true value of whatever that currency “token” stands for?
|
||||
|
||||
The answer to most of those questions doesn’t exist. If they do, they’ll to be undependably vague and subjective at best. Back in the day when civilization started off establishing small cities and towns, the local currency deemed legal by the guy who ruled over them, was almost always made of something precious to that community. Indians are thought to have transacted in peppercorns while ancient Greeks and Romans in **salt** [1]. Gradually most of these little prehistoric civilizations adopted precious metals and stones as their tokens to transact. Gold coins, silver heirlooms, and rubies became eponymous with “value”. With the industrial revolution, people started printing these tokens of transaction and we finally seemed to have found our calling in paper currencies. They were dependable and cheap to produce and as long as a nation-state guaranteed its users that the piece of paper, they were holding was just a token for an amount of “value” they had and as long as they were able to show them that this value when demanded could be supported with precious substances such as gold or hard assets, people were happy to use them. However, if you still believe that the currency note you hold in your hand right now has the same guarantee, you’re wrong. We currently live in an age where almost all the major currencies in circulation around the globe are what economists would call a **fiat currency** [2]. Value-less pieces of paper that are only backed by the guarantees of the nation-state you’re residing in. The exact nature of fiat currencies and why they may possibly be a flawed system falls into the domain of economics and we won’t get into that now.
|
||||
|
||||
In fact, the only takeaway from all of this history that is relevant to this post is that civilizations started using tokens that hinted or represented value for trading goods and services rather than the non-practical barter system. Tokens. Naturally, this is the crucial concept behind cryptocurrencies as well. They don’t have any inherent value attached to them. Their value is tied to the number of people adopting that particular platform, the trust the adopters have on the system, and of course if released by a supervising entity, the background of the entity itself. The high price and market cap of **Bitcoin (BTC)** isn’t a coincidence, they were among the first in business and had a lot of early adopters. This ultimate truth behind cryptocurrencies is what makes it so important yet so unforgivingly complex to understand. It’s the natural next step in the evolution of “money”. Some understand this and some still like to think of the solid currency concept where “real” money is always backed by something of inherent value.[3] Though there have been countless debates and studies on this dilemma, there is no looking back from a blockchain powered future.
|
||||
|
||||
For instance, the country of **Ecuador** made headlines in 2015 for its purported plans to develop and release **its own national cryptocurrency** [4]. Albeit the attempt officially was to aid and support their existing currency system. Since then other countries and their regulatory bodies have or are drafting up papers to control the “epidemic” that is cryptocurrency with some already having published frameworks to the extent of creating a roadmap for blockchain and crypto development. **Germany** is thought to be investing in a long term blockchain project to streamline its taxation and financial systems[5]. Banks in developing countries are joining in on something called a Bank chain, cooperating in creating a **private blockchain** to increase efficiency in and optimize their operations
|
||||
|
||||
Now is when we tie both the ends of the stories together, remember the first mention of PayPal before the casual history lesson? Experts have compared Bitcoin’s (BTC) adoption rate with that of PayPal when it was launched. Initial consumer hesitation, where only a few early adopters are ready to jump into using the said product and then all a wider adoption gradually becoming a benchmark for similar platforms. Bitcoin (BTC) is already a benchmark for similar cryptocurrency platforms with major coins such as **Ethereum (ETH)** and **Ripple (XRP)** [6]. Adoption is steadily increasing, legal and regulatory frameworks being made to support it, and active research and development being done on the front as well. And not unlike PayPal, experts believe that cryptocurrencies and platforms utilizing blockchain tech for their digital infrastructure will soon become the standard norm rather than the exception.
|
||||
|
||||
Although the rise in cryptocurrency prices in 2018 can be termed as an economic bubble, companies and governments have continued to invest as much or more into the development of their own blockchain platforms and financial tokens. To counteract and prevent such an incident in the future while still looking forward to investing in the area, an alternative to traditional cryptocurrencies called **stablecoins** have made the rounds recently.
|
||||
|
||||
Financial behemoth **JP Morgan** came out with their own enterprise ready blockchain solution called **Quorum** handling their stablecoin called **JPM Coin** [7]. Each such JPM coin is tied to 1 USD and their value is guaranteed by the parent organization under supporting legal frameworks, in this case, JP Morgan. Platforms such as this one make it easier for large financial transactions to the tunes of millions or billions of dollars to be transferred instantaneously over the internet without having to rely on conventional banking systems such as SWIFT which involve lengthy procedures and are themselves decades old.
|
||||
|
||||
In the same spirit of making the niceties of the blockchain available for everyone, The Ethereum platform allows 3rd parties to utilize their blockchain or derive from it to create and administer their own takes on the triad of the **Blockchain-protocol-token** system thereby leading to wider adoption of the standard with lesser work on its foundations.
|
||||
|
||||
The blockchain allows for digital versions of existing financial instruments to be created, recorded, and traded quickly over a network without the need for third-party monitoring. The inherent safety and security features of the system makes the entire process totally safe and immune to fraud and tampering, basically the only reason why third-party monitoring was required in the sector. Another area where governmental and regulatory bodies presided over when it came to financial services and instruments were in regards to transparency and auditing. With blockchain banks and other financial institutes will be able to maintain a fully transparent, layered, almost permanent and tamper-proof record of all their transactions rendering auditing tasks near useless. Much needed developments and changes to the current financial system and services industry can be made possible by exploiting blockchains. The platform being distributed, tamper-proof, near permanent, and quick to execute is highly valuable to bankers and government regulators alike and their investments in this regard seem to be well placed[8].
|
||||
|
||||
In the next article of the series, we see how companies are using blockchains to deliver the next generation of financial services. Looking at individual firms creating ripples in the industry, we explore how the future of a blockchain backed economy would look like.
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/blockchain-2-0-revolutionizing-the-financial-system/
|
||||
|
||||
作者:[EDITOR][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/editor/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/blockchain-2-0-an-introduction/
|
@ -0,0 +1,309 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (ClusterShell – A Nifty Tool To Run Commands On Cluster Nodes In Parallel)
|
||||
[#]: via: (https://www.2daygeek.com/clustershell-clush-run-commands-on-cluster-nodes-remote-system-in-parallel-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
ClusterShell – A Nifty Tool To Run Commands On Cluster Nodes In Parallel
|
||||
======
|
||||
|
||||
We had written two articles in the past to run commands on multiple remote server in parallel.
|
||||
|
||||
These are **[Parallel SSH (PSSH)][1]** or **[Distributed Shell (DSH)][2]**.
|
||||
|
||||
Today also, we are going to discuss about the same kind of topic but it allows us to perform the same on cluster nodes as well.
|
||||
|
||||
You may think, i can write a small shell script to archive this instead of installing these third party packages.
|
||||
|
||||
Of course you are right and if you are going to run some commands in 10-15 remote systems then you don’t need to use this.
|
||||
|
||||
However, the scripts take some time to complete this task as it’s running in a sequential order.
|
||||
|
||||
Think about if you would like to run some commands on 1000+ servers what will be the options?
|
||||
|
||||
In this case your script won’t help you. Also, it would take good amount of time to complete a task.
|
||||
|
||||
So, to overcome this kind of issue and situation. We need to run the command in parallel on remote machines.
|
||||
|
||||
For that, we need use in one of the Parallel applications. I hope this explanation might fulfilled your doubts about parallel utilities.
|
||||
|
||||
### What Is ClusterShell?
|
||||
|
||||
clush stands for [ClusterShell][3]. ClusterShell is an event-driven open source Python library, designed to run local or distant commands in parallel on server farms or on large Linux clusters.
|
||||
|
||||
It will take care of common issues encountered on HPC clusters, such as operating on groups of nodes, running distributed commands using optimized execution algorithms, as well as gathering results and merging identical outputs, or retrieving return codes.
|
||||
|
||||
ClusterShell takes advantage of existing remote shell facilities already installed on your systems, like SSH.
|
||||
|
||||
ClusterShell’s primary goal is to improve the administration of high- performance clusters by providing a lightweight but scalable Python API for developers. It also provides clush, clubak and cluset/nodeset, convenient command-line tools that allow traditional shell scripts to benefit from some of the library features.
|
||||
|
||||
ClusterShell’s written in Python and it requires Python (v2.6+ or v3.4+) to run on your system.
|
||||
|
||||
### How To Install ClusterShell On Linux?
|
||||
|
||||
ClusterShell package is available in most of the distribution official package manager. So, use the distribution package manager tool to install it.
|
||||
|
||||
For **`Fedora`** system, use **[DNF Command][4]** to install clustershell.
|
||||
|
||||
```
|
||||
$ sudo dnf install clustershell
|
||||
```
|
||||
|
||||
Python 2 module and tools are installed and if it’s default on your system then run the following command to install Python 3 development on Fedora System.
|
||||
|
||||
```
|
||||
$ sudo dnf install python3-clustershell
|
||||
```
|
||||
|
||||
Make sure you should have enabled the **[EPEL repository][5]** on your system before performing clustershell installation.
|
||||
|
||||
For **`RHEL/CentOS`** systems, use **[YUM Command][6]** to install clustershell.
|
||||
|
||||
```
|
||||
$ sudo yum install clustershell
|
||||
```
|
||||
|
||||
Python 2 module and tools are installed and if it’s default on your system then run the following command to install Python 3 development on CentOS/RHEL System.
|
||||
|
||||
```
|
||||
$ sudo yum install python34-clustershell
|
||||
```
|
||||
|
||||
For **`openSUSE Leap`** system, use **[Zypper Command][7]** to install clustershell.
|
||||
|
||||
```
|
||||
$ sudo zypper install clustershell
|
||||
```
|
||||
|
||||
Python 2 module and tools are installed and if it’s default on your system then run the following command to install Python 3 development on OpenSUSE System.
|
||||
|
||||
```
|
||||
$ sudo zypper install python3-clustershell
|
||||
```
|
||||
|
||||
For **`Debian/Ubuntu`** systems, use **[APT-GET Command][8]** or **[APT Command][9]** to install clustershell.
|
||||
|
||||
```
|
||||
$ sudo apt install clustershell
|
||||
```
|
||||
|
||||
### How To Install ClusterShell In Linux Using PIP?
|
||||
|
||||
Use PIP to install ClusterShell because it’s written in Python.
|
||||
|
||||
Make sure you should have enabled the **[Python][10]** and **[PIP][11]** on your system before performing clustershell installation.
|
||||
|
||||
```
|
||||
$ sudo pip install ClusterShell
|
||||
```
|
||||
|
||||
### How To Use ClusterShell On Linux?
|
||||
|
||||
It’s straight forward and awesome tool compared with other utilities such as pssh and dsh. It has so many options to perform the remote execution in parallel.
|
||||
|
||||
Make sure you should have enabled the **[password less login][12]** on your system before start using clustershell.
|
||||
|
||||
The following configuration file defines system-wide default values. You no need to modify anything here.
|
||||
|
||||
```
|
||||
$ cat /etc/clustershell/clush.conf
|
||||
```
|
||||
|
||||
If you would like to create a servers group. Here you can go. By default some examples were available so, do the same for your requirements.
|
||||
|
||||
```
|
||||
$ cat /etc/clustershell/groups.d/local.cfg
|
||||
```
|
||||
|
||||
Just run the clustershell command in the following format to get the information from the given nodes.
|
||||
|
||||
```
|
||||
$ clush -w 192.168.1.4,192.168.1.9 cat /proc/version
|
||||
192.168.1.9: Linux version 4.15.0-45-generic ([email protected]) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #48-Ubuntu SMP Tue Jan 29 16:28:13 UTC 2019
|
||||
192.168.1.4: Linux version 3.10.0-957.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 8 23:39:32 UTC 2018
|
||||
```
|
||||
|
||||
**Option:**
|
||||
|
||||
* **`-w:`** nodes where to run the command.
|
||||
|
||||
|
||||
|
||||
You can use the regular expressions instead of using full hostname and IPs.
|
||||
|
||||
```
|
||||
$ clush -w 192.168.1.[4,9] uname -r
|
||||
192.168.1.9: 4.15.0-45-generic
|
||||
192.168.1.4: 3.10.0-957.el7.x86_64
|
||||
```
|
||||
|
||||
Alternatively you can use the following format if you have the servers in the same IP series.
|
||||
|
||||
```
|
||||
$ clush -w 192.168.1.[4-9] date
|
||||
192.168.1.6: Mon Mar 4 21:08:29 IST 2019
|
||||
192.168.1.7: Mon Mar 4 21:08:29 IST 2019
|
||||
192.168.1.8: Mon Mar 4 21:08:29 IST 2019
|
||||
192.168.1.5: Mon Mar 4 09:16:30 CST 2019
|
||||
192.168.1.9: Mon Mar 4 21:08:29 IST 2019
|
||||
192.168.1.4: Mon Mar 4 09:16:30 CST 2019
|
||||
```
|
||||
|
||||
clustershell allow us to run the command in batch mode. Use the following format to achieve this.
|
||||
|
||||
```
|
||||
$ clush -w 192.168.1.4,192.168.1.9 -b
|
||||
Enter 'quit' to leave this interactive mode
|
||||
Working with nodes: 192.168.1.[4,9]
|
||||
clush> hostnamectl
|
||||
---------------
|
||||
192.168.1.4
|
||||
---------------
|
||||
Static hostname: CentOS7.2daygeek.com
|
||||
Icon name: computer-vm
|
||||
Chassis: vm
|
||||
Machine ID: 002f47b82af248f5be1d67b67e03514c
|
||||
Boot ID: f9b37a073c534dec8b236885e754cb56
|
||||
Virtualization: kvm
|
||||
Operating System: CentOS Linux 7 (Core)
|
||||
CPE OS Name: cpe:/o:centos:centos:7
|
||||
Kernel: Linux 3.10.0-957.el7.x86_64
|
||||
Architecture: x86-64
|
||||
---------------
|
||||
192.168.1.9
|
||||
---------------
|
||||
Static hostname: Ubuntu18
|
||||
Icon name: computer-vm
|
||||
Chassis: vm
|
||||
Machine ID: 27f6c2febda84dc881f28fd145077187
|
||||
Boot ID: f176f2eb45524d4f906d12e2b5716649
|
||||
Virtualization: oracle
|
||||
Operating System: Ubuntu 18.04.2 LTS
|
||||
Kernel: Linux 4.15.0-45-generic
|
||||
Architecture: x86-64
|
||||
clush> free -m
|
||||
---------------
|
||||
192.168.1.4
|
||||
---------------
|
||||
total used free shared buff/cache available
|
||||
Mem: 1838 641 217 19 978 969
|
||||
Swap: 2047 0 2047
|
||||
---------------
|
||||
192.168.1.9
|
||||
---------------
|
||||
total used free shared buff/cache available
|
||||
Mem: 1993 352 1067 1 573 1473
|
||||
Swap: 1425 0 1425
|
||||
clush> w
|
||||
---------------
|
||||
192.168.1.4
|
||||
---------------
|
||||
09:21:14 up 3:21, 3 users, load average: 0.00, 0.01, 0.05
|
||||
USER TTY FROM [email protected] IDLE JCPU PCPU WHAT
|
||||
daygeek :0 :0 06:02 ?xdm? 1:28 0.30s /usr/libexec/gnome-session-binary --session gnome-classic
|
||||
daygeek pts/0 :0 06:03 3:17m 0.06s 0.06s bash
|
||||
daygeek pts/1 192.168.1.6 06:03 52:26 0.10s 0.10s -bash
|
||||
---------------
|
||||
192.168.1.9
|
||||
---------------
|
||||
21:13:12 up 3:12, 1 user, load average: 0.08, 0.03, 0.00
|
||||
USER TTY FROM [email protected] IDLE JCPU PCPU WHAT
|
||||
daygeek pts/0 192.168.1.6 20:42 29:41 0.05s 0.05s -bash
|
||||
clush> quit
|
||||
```
|
||||
|
||||
If you would like to run the command on a group of nodes then use the following format.
|
||||
|
||||
```
|
||||
$ clush -w @dev uptime
|
||||
or
|
||||
$ clush -g dev uptime
|
||||
or
|
||||
$ clush --group=dev uptime
|
||||
|
||||
192.168.1.9: 21:10:10 up 3:09, 1 user, load average: 0.09, 0.03, 0.01
|
||||
192.168.1.4: 09:18:12 up 3:18, 3 users, load average: 0.01, 0.02, 0.05
|
||||
```
|
||||
|
||||
If you would like to run the command on more than one group of nodes then use the following format.
|
||||
|
||||
```
|
||||
$ clush -w @dev,@uat uptime
|
||||
or
|
||||
$ clush -g dev,uat uptime
|
||||
or
|
||||
$ clush --group=dev,uat uptime
|
||||
|
||||
192.168.1.7: 07:57:19 up 59 min, 1 user, load average: 0.08, 0.03, 0.00
|
||||
192.168.1.9: 20:27:20 up 1:00, 1 user, load average: 0.00, 0.00, 0.00
|
||||
192.168.1.5: 08:57:21 up 59 min, 1 user, load average: 0.00, 0.01, 0.05
|
||||
```
|
||||
|
||||
clustershell allow us to copy a file to remote machines. To copy local file or directory to the remote nodes in the same location.
|
||||
|
||||
```
|
||||
$ clush -w 192.168.1.[4,9] --copy /home/daygeek/passwd-up.sh
|
||||
```
|
||||
|
||||
We can verify the same by running the following command.
|
||||
|
||||
```
|
||||
$ clush -w 192.168.1.[4,9] ls -lh /home/daygeek/passwd-up.sh
|
||||
192.168.1.4: -rwxr-xr-x. 1 daygeek daygeek 159 Mar 4 09:00 /home/daygeek/passwd-up.sh
|
||||
192.168.1.9: -rwxr-xr-x 1 daygeek daygeek 159 Mar 4 20:52 /home/daygeek/passwd-up.sh
|
||||
```
|
||||
|
||||
To copy local file or directory to the remote nodes in the different location.
|
||||
|
||||
```
|
||||
$ clush -g uat --copy /home/daygeek/passwd-up.sh --dest /tmp
|
||||
```
|
||||
|
||||
We can verify the same by running the following command.
|
||||
|
||||
```
|
||||
$ clush --group=uat ls -lh /tmp/passwd-up.sh
|
||||
192.168.1.7: -rwxr-xr-x. 1 daygeek daygeek 159 Mar 6 07:44 /tmp/passwd-up.sh
|
||||
```
|
||||
|
||||
To copy file or directory from remote nodes to local system.
|
||||
|
||||
```
|
||||
$ clush -w 192.168.1.7 --rcopy /home/daygeek/Documents/magi.txt --dest /tmp
|
||||
```
|
||||
|
||||
We can verify the same by running the following command.
|
||||
|
||||
```
|
||||
$ ls -lh /tmp/magi.txt.192.168.1.7
|
||||
-rw-r--r-- 1 daygeek daygeek 35 Mar 6 20:24 /tmp/magi.txt.192.168.1.7
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/clustershell-clush-run-commands-on-cluster-nodes-remote-system-in-parallel-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.2daygeek.com/pssh-parallel-ssh-run-execute-commands-on-multiple-linux-servers/
|
||||
[2]: https://www.2daygeek.com/dsh-run-execute-shell-commands-on-multiple-linux-servers-at-once/
|
||||
[3]: https://cea-hpc.github.io/clustershell/
|
||||
[4]: https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
|
||||
[5]: https://www.2daygeek.com/install-enable-epel-repository-on-rhel-centos-scientific-linux-oracle-linux/
|
||||
[6]: https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/
|
||||
[7]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/
|
||||
[8]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[9]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
|
||||
[10]: https://www.2daygeek.com/3-methods-to-install-latest-python3-package-on-centos-6-system/
|
||||
[11]: https://www.2daygeek.com/install-pip-manage-python-packages-linux/
|
||||
[12]: https://www.2daygeek.com/linux-passwordless-ssh-login-using-ssh-keygen/
|
@ -0,0 +1,64 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Get cooking with GNOME Recipes on Fedora)
|
||||
[#]: via: (https://fedoramagazine.org/get-cooking-with-gnome-recipes-on-fedora/)
|
||||
[#]: author: (Ryan Lerch https://fedoramagazine.org/introducing-flatpak/)
|
||||
|
||||
Get cooking with GNOME Recipes on Fedora
|
||||
======
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2019/03/gnome-recipes-816x345.jpg)
|
||||
|
||||
Do you love to cook? Looking for a better way to manage your recipes using Fedora? GNOME Recipes is an awesome application available to install in Fedora to store and organize your recipe collection.
|
||||
|
||||
![][1]
|
||||
|
||||
GNOME Recipes is an recipe management tool from the GNOME project. It has the visual style of a modern GNOME style application, and feels similar to GNOME Software, but for food.
|
||||
|
||||
### Installing GNOME Recipes
|
||||
|
||||
Recipes is available to install from the 3rd party Flathub repositories. If you have never installed an application from Flathub before, set it up using the following guide:
|
||||
|
||||
[Install Flathub apps on Fedora](https://fedoramagazine.org/install-flathub-apps-fedora/)
|
||||
|
||||
After correctly setting up Flathub as a software source, you will be able to search for and install Recipes via GNOME Software.
|
||||
|
||||
### Recipe management
|
||||
|
||||
Recipes allows you to manually add your own collection of recipes, including photos, ingredients, directions, as well as extra metadata like preparation time, cuisine style, and spiciness.
|
||||
|
||||
![][2]
|
||||
|
||||
When entering in a new item, GNOME Recipes there are a range of different measurement units to choose from, as well as special tags for items like temperature, allowing you to easily switch units.
|
||||
|
||||
### Community recipes
|
||||
|
||||
In addition to manually entering in your favourite dishes for your own use, it also allows you to find, use, and contribute recipes to the community. Additionally, you can mark your favourites, and search the collection by the myriad of metadata available for each recipe.
|
||||
|
||||
![][3]
|
||||
|
||||
### Step by step guidance
|
||||
|
||||
One of the awesome little features in GNOME Recipes is the step by step fullscreen mode. When you are ready to cook, simply activate this mode, move you laptop to the kitchen, and you will have a full screen display of the current step in the cooking method. Futhermore, you can set up the recipes to have timers displayed on this mode when something is in the oven.
|
||||
|
||||
![][4]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/get-cooking-with-gnome-recipes-on-fedora/
|
||||
|
||||
作者:[Ryan Lerch][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://fedoramagazine.org/introducing-flatpak/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://fedoramagazine.org/wp-content/uploads/2019/03/Screenshot-from-2019-03-06-19-45-06-1024x727.png
|
||||
[2]: https://fedoramagazine.org/wp-content/uploads/2019/03/gnome-recipes1-1024x727.png
|
||||
[3]: https://fedoramagazine.org/wp-content/uploads/2019/03/Screenshot-from-2019-03-06-20-08-45-1024x725.png
|
||||
[4]: https://fedoramagazine.org/wp-content/uploads/2019/03/Screenshot-from-2019-03-06-20-39-44-1024x640.png
|
@ -0,0 +1,141 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Getting started with the Geany text editor)
|
||||
[#]: via: (https://opensource.com/article/19/3/getting-started-geany-text-editor)
|
||||
[#]: author: (James Mawson https://opensource.com/users/dxmjames)
|
||||
|
||||
Getting started with the Geany text editor
|
||||
======
|
||||
Geany is a light and swift text editor with IDE features.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/web_browser_desktop_devlopment_design_system_computer.jpg?itok=pfqRrJgh)
|
||||
|
||||
I have to admit, it took me a rather embarrassingly long time to really get into Linux as a daily driver. One thing I recall from these years in the wilderness was how strange it was to watch open source types get so worked up about text editors.
|
||||
|
||||
It wasn't just that opinions differed. Disagreements were intense. And you'd see them again and again.
|
||||
|
||||
I mean, I suppose it makes some sense. Doing dev or admin work means you're spending a lot of time with a text editor. And when it gets in the way or won't do quite what you want? In that exact moment, that's the most frustrating thing in the world.
|
||||
|
||||
And I know what it means to really hate a text editor. I learned this many years ago in the computer labs at university trying to figure out Emacs. I was quite shocked that a piece of software could have so many sadomasochistic overtones. People were doing that to each other deliberately!
|
||||
|
||||
So perhaps it's a rite of passage that now I have one I very much like. It's called [Geany][1], it's on GPL, and it's [in the repositories][2] of most popular distributions.
|
||||
|
||||
Here's why it works for me.
|
||||
|
||||
### I'm into simplicity
|
||||
|
||||
The main thing I want from a text editor is just to edit text. I don't think there should be any kind of learning curve in the way. I should be able to open it and use it.
|
||||
|
||||
For that reason, I've generally used whatever is included with an operating system. On Windows 10, I used Notepad far longer than I should have. When I finally replaced it, it was with Notepad++. In the Linux terminal, I like Nano.
|
||||
|
||||
I was perfectly aware I was missing out on a lot of useful functionality. But it was never enough of a pain point to make a change. And it's not that I've never tried anything more elaborate. I did some of my first real programming on Visual Basic and Borland Delphi.
|
||||
|
||||
These development environments gave you a graphical interface to design your windows visually, various windows where you could configure properties and settings, a text interface to write your functions, and various odds and ends for debugging. This was a great way to build desktop applications, so long as you used it the way it was intended.
|
||||
|
||||
But if you wanted to do something the authors didn't anticipate, all these extra moving parts suddenly got in the way. As software became more and more about the web and the internet, this situation started happening all the time.
|
||||
|
||||
In the past, I used HTML editing suites like Macromedia Dreamweaver (as it was back then) and FirstPage for static websites. Again, I found the features could get in the way as much as they helped. These applications had their own ideas about how to organize your project, and if you had a different view, it was an awful bother.
|
||||
|
||||
More recently, after a long break from programming, I started learning the people's language: [Python][3]. I bought a book of introductory tutorials, which said to install [IDLE][4], so I did. I think I got about five minutes into it before ditching it to run the interpreter from the command line. It had way too many moving parts to deal with. Especially for HelloWorld.py.
|
||||
|
||||
But I always went back to Notepad++ and Nano whenever I could get away with it.
|
||||
|
||||
So what changed? Well, a few months ago I [ditched Windows 10][5] completely (hooray!). Sticking with what I knew, I used Nano as my main text editor for a few weeks.
|
||||
|
||||
I learned that Nano is great when you're already on the command line and you need to launch a Navy SEAL mission. You know what I mean. A lightning-fast raid. Get in, complete the objective, and get out.
|
||||
|
||||
It's less ideal for long campaigns—or even moderately short ones. Even just adding a new page to a static website turns out to involve many repetitive keystrokes. As much as anything else, I really missed being able to navigate and select text with the mouse.
|
||||
|
||||
### Introducing Geany
|
||||
|
||||
The Geany project began in 2005 and is still actively developed.
|
||||
|
||||
It has minimal dependencies: just the [GTK Toolkit][6] and the libraries that GTK depends on. If you have any kind of desktop environment installed, you almost certainly have GTK on your machine.
|
||||
|
||||
I'm using it on Xfce, but thanks to these minimal dependencies, Geany is portable across desktop environments.
|
||||
|
||||
Geany is fast and light. Installing Geany from the package manager took mere moments, and it uses only 3.1MB of space on my machine.
|
||||
|
||||
So far, I've used it for HTML, CSS, and Python and to edit configuration files. It also recognizes C, Java, JavaScript, Perl, and [more][7].
|
||||
|
||||
### No-compromise simplicity
|
||||
|
||||
Geany has a lot of great features that make life easier. Just listing them would miss the best bit, which is this: Geany makes sense right out of the box. As soon as it's installed, you can start editing files straightaway, and it just works.
|
||||
|
||||
For all the IDE functionality, none of it gets in the way. The default settings are set intelligently, and the menus are laid out nicely enough that it's no hassle to change them.
|
||||
|
||||
It doesn't try to organize your project for you, and it doesn't have strong opinions about how you should do anything.
|
||||
|
||||
### Handles whitespace beautifully
|
||||
|
||||
By default, every time you press Enter, Geany preserves the indentation on the new line. In addition to saving a few tedious keystrokes, it avoids the inconsistent use of tabs and spaces, which can sometimes sneak in when your mind's elsewhere and make your code hard to follow for anyone with a different text editor.
|
||||
|
||||
But what if you're editing a file that's already suffered this treatment? For example, I needed to edit an HTML file that was indented with a mix of tabs and spaces, making it a nightmare to figure out how the tags were nested.
|
||||
|
||||
With Geany, it took just seconds to hunt through the menus to change the tab length from four spaces to eight. Even better was the option to convert those tabs to spaces. Problem solved!
|
||||
|
||||
### Clever shortcuts and automation
|
||||
|
||||
How often do you write the correct code on the wrong line? I do it all the time.
|
||||
|
||||
Geany makes it easy to move lines of code up and down using Alt+PgUp and Alt+PgDn. This is a little nicer than just a regular cut and paste—instead of needing four or five key presses, you only need one.
|
||||
|
||||
When coding HTML, Geany automatically closes tags for you. As well as saving time, this avoids a lot of annoying bugs. When you forget to close a tag, you can spend ages scouring the document looking for something far more complex.
|
||||
|
||||
It gets even better in Python, where indentation is crucial. Whenever you end a line with a colon, Geany automatically indents it for you.
|
||||
|
||||
One nice little side effect is that when you forget to include the colon—something I do with embarrassing regularity—you realize it immediately when you don't get the automatic indentation you expected.
|
||||
|
||||
The default indentation is a single tab, while I prefer two spaces. Because Geany's menus are very well laid out, it took me only a few seconds to figure out how to change it.
|
||||
|
||||
You, of course, get syntax highlighting too. In addition, it tracks your [variable scope][8] and offers useful autocompletion.
|
||||
|
||||
### Large plugin library
|
||||
|
||||
Geany has a [big library of plugins][9], but so far I haven't needed to try any. Even so, I still feel like I benefit from them. How? Well, it means that my editor isn't crammed with functionality I don't use.
|
||||
|
||||
I reckon this attitude of adding extra functionality into a big library of plugins is a great ethos—no matter your specific needs, you get to have all the stuff you want and none of what you don't.
|
||||
|
||||
### Remote file editing
|
||||
|
||||
One thing that's really nice about terminal text editors is that it's no problem to use them in a remote shell.
|
||||
|
||||
Geany handles this beautifully, as well. You can open remote files anywhere you have SSH access as easily as you can open files on your own machine.
|
||||
|
||||
One frustration I had at first was I only seemed to be able to authenticate with a username and password, which was annoying, because certificates are so much nicer. It turned out that this was just me being a noob by keeping certificates in my home directory rather than in ~/.ssh.
|
||||
|
||||
When editing Python scripts remotely, autocompletion doesn't work when you use packages installed on the server and not on your local machine. This isn't really that big a deal for me, but it's there.
|
||||
|
||||
### In summary
|
||||
|
||||
Text editors are such a personal preference that the right one will be different for different people.
|
||||
|
||||
Geany is excellent if you already know what you want to write and want to just get on with it while enjoying plenty of useful shortcuts to speed up the menial parts.
|
||||
|
||||
Geany is a great way to have your cake and eat it too.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/getting-started-geany-text-editor
|
||||
|
||||
作者:[James Mawson][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/dxmjames
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.geany.org/
|
||||
[2]: https://www.geany.org/Download/ThirdPartyPackages
|
||||
[3]: https://opensource.com/resources/python
|
||||
[4]: https://en.wikipedia.org/wiki/IDLE
|
||||
[5]: https://blog.dxmtechsupport.com.au/linux-on-the-desktop-are-we-nearly-there-yet/
|
||||
[6]: https://www.gtk.org/
|
||||
[7]: https://www.geany.org/Main/AllFiletypes
|
||||
[8]: https://cscircles.cemc.uwaterloo.ca/11b-how-functions-work/
|
||||
[9]: https://plugins.geany.org/
|
72
sources/tech/20190307 13 open source backup solutions.md
Normal file
72
sources/tech/20190307 13 open source backup solutions.md
Normal file
@ -0,0 +1,72 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (13 open source backup solutions)
|
||||
[#]: via: (https://opensource.com/article/19/3/backup-solutions)
|
||||
[#]: author: (Don Watkins https://opensource.com/users/don-watkins)
|
||||
|
||||
13 open source backup solutions
|
||||
======
|
||||
Readers suggest more than a dozen of their favorite solutions for protecting data.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/server_data_system_admin.png?itok=q6HCfNQ8)
|
||||
|
||||
Recently, we published a [poll][1] that asked readers to vote on their favorite open source backup solution. We offered six solutions recommended by our [moderator community][2]—Cronopete, Deja Dup, Rclone, Rdiff-backup, Restic, and Rsync—and invited readers to share other options in the comments. And you came through, offering 13 other solutions (so far) that we either hadn't considered or hadn't even heard of.
|
||||
|
||||
By far the most popular suggestion was [BorgBackup][3]. It is a deduplicating backup solution that features compression and encryption. It is supported on Linux, MacOS, and BSD and has a BSD License.
|
||||
|
||||
Second was [UrBackup][4], which does full and incremental image and file backups; you can save whole partitions or single directories. It has clients for Windows, Linux, and MacOS and has a GNU Affero Public License.
|
||||
|
||||
Third was [LuckyBackup][5]; according to its website, "it is simple to use, fast (transfers over only changes made and not all data), safe (keeps your data safe by checking all declared directories before proceeding in any data manipulation), reliable, and fully customizable." It carries a GNU Public License.
|
||||
|
||||
[Casync][6] is content-addressable synchronization—it's designed for backup and synchronizing and stores and retrieves multiple related versions of large file systems. It is licensed with the GNU Lesser Public License.
|
||||
|
||||
[Syncthing][7] synchronizes files between two computers. It is licensed with the Mozilla Public License and, according to its website, is secure and private. It works on MacOS, Windows, Linux, FreeBSD, Solaris, and OpenBSD.
|
||||
|
||||
[Duplicati][8] is a free backup solution that works on Windows, MacOS, and Linux and a variety of standard protocols, such as FTP, SSH, and WebDAV, and cloud services. It features strong encryption and is licensed with the GPL.
|
||||
|
||||
[Dirvish][9] is a disk-based virtual image backup system licensed under OSL-3.0. It also requires Rsync, Perl5, and SSH to be installed.
|
||||
|
||||
[Bacula][10]'s website says it "is a set of computer programs that permits the system administrator to manage backup, recovery, and verification of computer data across a network of computers of different kinds." It is supported on Linux, FreeBSD, Windows, MacOS, OpenBSD, and Solaris and the bulk of its source code is licensed under AGPLv3.
|
||||
|
||||
[BackupPC][11] "is a high-performance, enterprise-grade system for backing up Linux, Windows, and MacOS PCs and laptops to a server's disk," according to its website. It is licensed under the GPLv3.
|
||||
|
||||
[Amanda][12] is a backup system written in C and Perl that allows a system administrator to back up an entire network of client machines to a single server using tape, disk, or cloud-based systems. It was developed and copyrighted in 1991 at the University of Maryland and has a BSD-style license.
|
||||
|
||||
[Back in Time][13] is a simple backup utility designed for Linux. It provides a command line client and a GUI, both written in Python. To do a backup, just specify where to store snapshots, what folders to back up, and the frequency of the backups. BackInTime is licensed with GPLv2.
|
||||
|
||||
[Timeshift][14] is a backup utility for Linux that is similar to System Restore for Windows and Time Capsule for MacOS. According to its GitHub repository, "Timeshift protects your system by taking incremental snapshots of the file system at regular intervals. These snapshots can be restored at a later date to undo all changes to the system."
|
||||
|
||||
[Kup][15] is a backup solution that was created to help users back up their files to a USB drive, but it can also be used to perform network backups. According to its GitHub repository, "When you plug in your external hard drive, Kup will automatically start copying your latest changes."
|
||||
|
||||
Thanks for sharing your favorite open source backup solutions in our poll! If there are still others that haven't been mentioned yet, please share them in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/backup-solutions
|
||||
|
||||
作者:[Don Watkins][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/don-watkins
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/2/linux-backup-solutions
|
||||
[2]: https://opensource.com/opensourcecom-team
|
||||
[3]: https://www.borgbackup.org/
|
||||
[4]: https://www.urbackup.org/
|
||||
[5]: http://luckybackup.sourceforge.net/
|
||||
[6]: http://0pointer.net/blog/casync-a-tool-for-distributing-file-system-images.html
|
||||
[7]: https://syncthing.net/
|
||||
[8]: https://www.duplicati.com/
|
||||
[9]: http://dirvish.org/
|
||||
[10]: https://www.bacula.org/
|
||||
[11]: https://backuppc.github.io/backuppc/
|
||||
[12]: http://www.amanda.org/
|
||||
[13]: https://github.com/bit-team/backintime
|
||||
[14]: https://github.com/teejee2008/timeshift
|
||||
[15]: https://github.com/spersson/Kup
|
@ -0,0 +1,208 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to Restart a Network in Ubuntu [Beginner’s Tip])
|
||||
[#]: via: (https://itsfoss.com/restart-network-ubuntu)
|
||||
[#]: author: (Sergiu https://itsfoss.com/author/sergiu/)
|
||||
|
||||
How to Restart a Network in Ubuntu [Beginner’s Tip]
|
||||
======
|
||||
|
||||
You’re [using an Ubuntu-based system and you just can’t seem to connect to your network][1]? You’d be surprised how many problems can a simple restart fix.
|
||||
|
||||
In this article, I’ll go over multiple ways you can restart network in Ubuntu and other Linux distributions, so you can use whatever suits your needs. The methods are basically divided into two parts:
|
||||
|
||||
![Ubuntu Restart Network][2]
|
||||
|
||||
### Restart network in Ubuntu using command line
|
||||
|
||||
If you are using Ubuntu server edition, you are already in the terminal. If you are using the desktop edition, you can access the terminal using Ctrl+Alt+T [keyboard shortcut in Ubuntu][3].
|
||||
|
||||
Now you have several commands at your disposal to restart network in Ubuntu. Some (or perhaps most) commands mentioned here should be applicable for restarting network in Debian and other Linux distributions as well.
|
||||
|
||||
#### 1\. network manager service
|
||||
|
||||
This is the easiest way to restart your network using the command line. It’s equivalent to the graphical way of doing it (restarts the Network-Manager service).
|
||||
|
||||
```
|
||||
sudo service network-manager restart
|
||||
```
|
||||
|
||||
The network icon should disappear for a moment and then reappear.
|
||||
|
||||
#### 2\. systemd
|
||||
|
||||
The **service** command is just a wrapper for this method (and also for init.d scripts and Upstart commands). The **systemctl** command is much more versatile than **service**. This is what I usually prefer.
|
||||
|
||||
```
|
||||
sudo systemctl restart NetworkManager.service
|
||||
```
|
||||
|
||||
The network icon (again) should disappear for a moment. To check out other **systemctl** options, you can refer to its man page.
|
||||
|
||||
#### 3\. nmcli
|
||||
|
||||
This is yet another tool for handling networks on a Linux machine. It is a pretty powerful tool that I find very practical. Many sysadmins prefer it since it is easy to use.
|
||||
|
||||
There are two steps to this method: turning the network off, and then turning it back on.
|
||||
|
||||
```
|
||||
sudo nmcli networking off
|
||||
```
|
||||
|
||||
The network will shut down and the icon will disappear. To turn it back on:
|
||||
|
||||
```
|
||||
sudo nmcli networking on
|
||||
```
|
||||
|
||||
You can check out the man page of nmcli for more options.
|
||||
|
||||
#### 4\. ifup & ifdown
|
||||
|
||||
This commands handle a network interface directly, changing it’s state to one in which it either can or can not transmit and receive data. It’s one of the [must know networking commands in Linux][4].
|
||||
|
||||
To shut down all network interfaces, use ifdown and then use ifup to turn all network interfaces back on.
|
||||
|
||||
A good practice would be to combine both of these commands:
|
||||
|
||||
```
|
||||
sudo ifdown -a && sudo ifup -a
|
||||
```
|
||||
|
||||
**Note:** This method will not make the network icon in your systray disappear, and yet you won’t be able to have a connection of any sort.
|
||||
|
||||
**Bonus tool: nmtui (click to expand)**
|
||||
|
||||
This is another method often used by system administrators. It is a text menu for managing networks right in your terminal.
|
||||
|
||||
```
|
||||
nmtui
|
||||
```
|
||||
|
||||
This should open up the following menu:
|
||||
|
||||
![nmtui Menu][5]
|
||||
|
||||
**Note** that in **nmtui** , you can select another option by using the **up** and **down arrow keys**.
|
||||
|
||||
Select **Activate a connection** :
|
||||
|
||||
![nmtui Menu Select "Activate a connection"][6]
|
||||
|
||||
Press **Enter**. This should now open the **connections** menu.
|
||||
|
||||
![nmtui Connections Menu][7]
|
||||
|
||||
Here, go ahead and select the network with a **star (*)** next to it. In my case, it’s MGEO72.
|
||||
|
||||
![Select your connection in the nmtui connections menu.][8]
|
||||
|
||||
Press **Enter**. This should **deactivate** your connection.
|
||||
|
||||
![nmtui Connections Menu with no active connection][9]
|
||||
|
||||
Select the connection you want to activate:
|
||||
|
||||
![Select the connection you want in the nmtui connections menu.][10]
|
||||
|
||||
Press **Enter**. This should reactivate the selected connection.
|
||||
|
||||
![nmtui Connections Menu][11]
|
||||
|
||||
Press **Tab** twice to select **Back** :
|
||||
|
||||
![Select "Back" in the nmtui connections menu.][12]
|
||||
|
||||
Press **Enter**. This should bring you back to the **nmtui** main menu.
|
||||
|
||||
![nmtui Main Menu][13]
|
||||
|
||||
Select **Quit** :
|
||||
|
||||
![nmtui Quit Main Menu][14]
|
||||
|
||||
This should exit the application and bring you back to your terminal.
|
||||
|
||||
That’s it! You have successfully restarted your network
|
||||
|
||||
### Restart network in Ubuntu graphically
|
||||
|
||||
This is, of course, the easiest way of restarting the network for Ubuntu desktop users. If this one doesn’t work, you can of course check the command line options mentioned in the previous section.
|
||||
|
||||
NM-applet is the system tray applet indicator for [NetworkManager][15]. That’s what we’re going to use to restart our network.
|
||||
|
||||
First of all, check out your top panel. You should find a network icon in your system tray (in my case, it is a Wi-Fi icon, since that’s what I use).
|
||||
|
||||
Go ahead and click on that icon (or the sound or battery icon). This will open up the menu. Select “Turn Off” here.
|
||||
|
||||
![Restart network in Ubuntu][16]Turn off your network
|
||||
|
||||
The network icon should now disappear from the top panel. This means the network has been successfully turned off.
|
||||
|
||||
Click again on your systray to reopen the menu. Select “Turn On”.
|
||||
|
||||
![Restarting network in Ubuntu][17]Turn the network back on
|
||||
|
||||
Congratulations! You have now restarted your network.
|
||||
|
||||
#### Bonus Tip: Refresh available network list
|
||||
|
||||
Suppose you are connected to a network already but you want to connect to another network. How do you refresh the WiFi to see what other networks are available? Let me show you that.
|
||||
|
||||
Ubuntu doesn’t have a ‘refresh wifi networks’ option directly. It’s sort of hidden.
|
||||
|
||||
You’ll have to open the setting menu again and this time, click on “Select Network”.
|
||||
|
||||
![Refresh wifi network list in Ubuntu][18]Select Network to change your WiFi connection
|
||||
|
||||
Now, you won’t see the list of available wireless networks immediately. When you open the networks list, it takes around 5 seconds to refresh and show up other available wireless networks.
|
||||
|
||||
![Select another wifi network in Ubuntu][19]Wait for around 5- seconds to see other available networks
|
||||
|
||||
And here, you can select the network of your choice and click connect. That’s it.
|
||||
|
||||
**Wrapping Up**
|
||||
|
||||
Restarting your network or connection is something that every Linux user has to go through at some point in their experience.
|
||||
|
||||
We hope that we helped you with plenty of methods for handling such issues!
|
||||
|
||||
What do you use to restart/handle your network? Is there something we missed? Leave us a comment below.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/restart-network-ubuntu
|
||||
|
||||
作者:[Sergiu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/sergiu/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/fix-no-wireless-network-ubuntu/
|
||||
[2]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/ubuntu-restart-network.png?resize=800%2C450&ssl=1
|
||||
[3]: https://itsfoss.com/ubuntu-shortcuts/
|
||||
[4]: https://itsfoss.com/basic-linux-networking-commands/
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmtui_menu.png?fit=800%2C602&ssl=1
|
||||
[6]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmtui_menu_select_option.png?fit=800%2C579&ssl=1
|
||||
[7]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_on.png?fit=800%2C585&ssl=1
|
||||
[8]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_select_connection_on.png?fit=800%2C576&ssl=1
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_off.png?fit=800%2C572&ssl=1
|
||||
[10]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_select_connection_off.png?fit=800%2C566&ssl=1
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_on-1.png?fit=800%2C585&ssl=1
|
||||
[12]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_connection_menu_back.png?fit=800%2C585&ssl=1
|
||||
[13]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmtui_menu_select_option-1.png?fit=800%2C579&ssl=1
|
||||
[14]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/nmui_menu_quit.png?fit=800%2C580&ssl=1
|
||||
[15]: https://wiki.gnome.org/Projects/NetworkManager
|
||||
[16]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/restart-network-ubuntu-1.jpg?resize=800%2C400&ssl=1
|
||||
[17]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/restart-network-ubuntu-2.jpg?resize=800%2C400&ssl=1
|
||||
[18]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/select-wifi-network-ubuntu.jpg?resize=800%2C400&ssl=1
|
||||
[19]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/select-wifi-network-ubuntu-1.jpg?resize=800%2C400&ssl=1
|
||||
[20]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/ubuntu-restart-network.png?fit=800%2C450&ssl=1
|
@ -0,0 +1,51 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to keep your Raspberry Pi updated)
|
||||
[#]: via: (https://opensource.com/article/19/3/how-raspberry-pi-update)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
How to keep your Raspberry Pi updated
|
||||
======
|
||||
Learn how to keep your Raspberry Pi patched and working well in the seventh article in our guide to getting started with the Raspberry Pi.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_happy_sad_developer_programming.png?itok=72nkfSQ_)
|
||||
|
||||
Just like your tablet, cellphone, and laptop, you need to keep your Raspberry Pi updated. Not only will the latest enhancements keep your Pi running smoothly, they will also keep you safer, especially if you are connected to a network. The seventh article in our guide to getting started with the Raspberry Pi shares two pieces of advice on keeping your Pi working well.
|
||||
|
||||
### Update Raspbian
|
||||
|
||||
Updating your Raspbian installation is a [two-step process][1]:
|
||||
|
||||
1. In your terminal type: **sudo apt-get update**
|
||||
The command **sudo** allows you to run **apt-get update** as admin (aka root). Note that **apt-get update** will not install anything new on your system; rather it will update the list of packages and dependencies that need to be updated.
|
||||
|
||||
|
||||
2. Then type: **sudo apt-get dist-upgrade**
|
||||
From the documentation: "Generally speaking, doing this regularly will keep your installation up to date, in that it will be equivalent to the latest released image available from [raspberrypi.org/downloads][2]."
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/update_sudo_rpi.png)
|
||||
|
||||
### Be careful with rpi-update
|
||||
|
||||
Raspbian comes with another little update utility called [rpi-update][3]. This utility can be used to upgrade your Pi to the latest firmware which may or may not be broken/buggy. You may find information explaining how to use it, but as of late it is recommended never to use this application unless you have a really good reason to do so.
|
||||
|
||||
Bottom line: Keep your systems updated!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/how-raspberry-pi-update
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.raspberrypi.org/documentation/raspbian/updating.md
|
||||
[2]: https://www.raspberrypi.org/downloads/
|
||||
[3]: https://github.com/Hexxeh/rpi-update
|
@ -0,0 +1,57 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to use your Raspberry Pi for entertainment)
|
||||
[#]: via: (https://opensource.com/article/19/3/raspberry-pi-entertainment)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
How to use your Raspberry Pi for entertainment
|
||||
======
|
||||
Learn how to watch Netflix and listen to music on your Raspberry Pi, in the eighth article in our guide to getting started with Raspberry Pi.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/video_editing_folder_music_wave_play.png?itok=-J9rs-My)
|
||||
|
||||
So far, this series has focused on more serious topics—how to [choose][1], [buy][2], [set up][3], and [update][4] your Raspberry Pi, and different things [kids][5] and [adults][6] can learn with it (including [Linux][7]). But now it's time to change up the subject and have some fun! Today we'll look at ways to use your Raspberry Pi for entertainment, and tomorrow we'll continue the fun with gaming.
|
||||
|
||||
### Watch TV and movies
|
||||
|
||||
You can use your Raspberry Pi and the [Open Source Media Center][8] (OSMC) to [watch Netflix][9]! The OSMC is a system based on the [Kodi][10] project that allows you to play back media from your local network, attached storage, and the internet. It's also known for having the best feature set and community among media center applications.
|
||||
|
||||
NOOBS (which we talked about in the [third article][11] in this series) allows you to [install OSMC][12] on your Raspberry Pi as easily as possible. NOOBS also offers another media center system based on Kodi called [LibreELEC][13].
|
||||
|
||||
### Listen to music
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/raspberrypi_8_pimusicbox.png)
|
||||
|
||||
You can also stream music on your network via attached storage or services like Spotify on your Raspberry Pi with the [Pi Music Box][14] project. I [wrote about it][15] a while ago, but you can find newer instructions, including how to's and DIY projects, on the [Pi Music Box website][16].
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/raspberry-pi-entertainment
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/3/which-raspberry-pi-choose
|
||||
[2]: https://opensource.com/article/19/2/how-buy-raspberry-pi
|
||||
[3]: https://opensource.com/article/19/2/how-boot-new-raspberry-pi
|
||||
[4]: https://opensource.com/article/19/2/how-keep-your-raspberry-pi-updated-and-patched
|
||||
[5]: https://opensource.com/article/19/3/teach-kids-program-raspberry-pi
|
||||
[6]: https://opensource.com/article/19/2/3-popular-programming-languages-you-can-learn-raspberry-pi
|
||||
[7]: https://opensource.com/article/19/2/learn-linux-raspberry-pi
|
||||
[8]: https://osmc.tv/
|
||||
[9]: https://www.dailydot.com/upstream/netflix-raspberry-pi/
|
||||
[10]: http://kodi.tv/
|
||||
[11]: https://opensource.com/article/19/3/how-boot-new-raspberry-pi
|
||||
[12]: https://www.raspberrypi.org/documentation/usage/kodi/
|
||||
[13]: https://libreelec.tv/
|
||||
[14]: https://github.com/pimusicbox/pimusicbox/tree/master
|
||||
[15]: https://opensource.com/life/15/3/pi-musicbox-guide
|
||||
[16]: https://www.pimusicbox.com/
|
@ -0,0 +1,196 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Virtual filesystems in Linux: Why we need them and how they work)
|
||||
[#]: via: (https://opensource.com/article/19/3/virtual-filesystems-linux)
|
||||
[#]: author: (Alison Chariken )
|
||||
|
||||
Virtual filesystems in Linux: Why we need them and how they work
|
||||
======
|
||||
Virtual filesystems are the magic abstraction that makes the "everything is a file" philosophy of Linux possible.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/documents_papers_file_storage_work.png?itok=YlXpAqAJ)
|
||||
|
||||
What is a filesystem? According to early Linux contributor and author [Robert Love][1], "A filesystem is a hierarchical storage of data adhering to a specific structure." However, this description applies equally well to VFAT (Virtual File Allocation Table), Git, and [Cassandra][2] (a [NoSQL database][3]). So what distinguishes a filesystem?
|
||||
|
||||
### Filesystem basics
|
||||
|
||||
The Linux kernel requires that for an entity to be a filesystem, it must also implement the **open()** , **read()** , and **write()** methods on persistent objects that have names associated with them. From the point of view of [object-oriented programming][4], the kernel treats the generic filesystem as an abstract interface, and these big-three functions are "virtual," with no default definition. Accordingly, the kernel's default filesystem implementation is called a virtual filesystem (VFS).
|
||||
|
||||
|
||||
![][5]
|
||||
If we can open(), read(), and write(), it is a file as this console session shows.
|
||||
|
||||
VFS underlies the famous observation that in Unix-like systems "everything is a file." Consider how weird it is that the tiny demo above featuring the character device /dev/console actually works. The image shows an interactive Bash session on a virtual teletype (tty). Sending a string into the virtual console device makes it appear on the virtual screen. VFS has other, even odder properties. For example, it's [possible to seek in them][6].
|
||||
|
||||
The familiar filesystems like ext4, NFS, and /proc all provide definitions of the big-three functions in a C-language data structure called [file_operations][7] . In addition, particular filesystems extend and override the VFS functions in the familiar object-oriented way. As Robert Love points out, the abstraction of VFS enables Linux users to blithely copy files to and from foreign operating systems or abstract entities like pipes without worrying about their internal data format. On behalf of userspace, via a system call, a process can copy from a file into the kernel's data structures with the read() method of one filesystem, then use the write() method of another kind of filesystem to output the data.
|
||||
|
||||
The function definitions that belong to the VFS base type itself are found in the [fs/*.c files][8] in kernel source, while the subdirectories of fs/ contain the specific filesystems. The kernel also contains filesystem-like entities such as cgroups, /dev, and tmpfs, which are needed early in the boot process and are therefore defined in the kernel's init/ subdirectory. Note that cgroups, /dev, and tmpfs do not call the file_operations big-three functions, but directly read from and write to memory instead.
|
||||
|
||||
The diagram below roughly illustrates how userspace accesses various types of filesystems commonly mounted on Linux systems. Not shown are constructs like pipes, dmesg, and POSIX clocks that also implement struct file_operations and whose accesses therefore pass through the VFS layer.
|
||||
|
||||
![How userspace accesses various types of filesystems][9]
|
||||
VFS are a "shim layer" between system calls and implementors of specific file_operations like ext4 and procfs. The file_operations functions can then communicate either with device-specific drivers or with memory accessors. tmpfs, devtmpfs and cgroups don't make use of file_operations but access memory directly.
|
||||
|
||||
VFS's existence promotes code reuse, as the basic methods associated with filesystems need not be re-implemented by every filesystem type. Code reuse is a widely accepted software engineering best practice! Alas, if the reused code [introduces serious bugs][10], then all the implementations that inherit the common methods suffer from them.
|
||||
|
||||
### /tmp: A simple tip
|
||||
|
||||
An easy way to find out what VFSes are present on a system is to type **mount | grep -v sd | grep -v :/** , which will list all mounted filesystems that are not resident on a disk and not NFS on most computers. One of the listed VFS mounts will assuredly be /tmp, right?
|
||||
|
||||
![Man with shocked expression][11]
|
||||
Everyone knows that keeping /tmp on a physical storage device is crazy! credit: <https://tinyurl.com/ybomxyfo>
|
||||
|
||||
Why is keeping /tmp on storage inadvisable? Because the files in /tmp are temporary(!), and storage devices are slower than memory, where tmpfs are created. Further, physical devices are more subject to wear from frequent writing than memory is. Last, files in /tmp may contain sensitive information, so having them disappear at every reboot is a feature.
|
||||
|
||||
Unfortunately, installation scripts for some Linux distros still create /tmp on a storage device by default. Do not despair should this be the case with your system. Follow simple instructions on the always excellent [Arch Wiki][12] to fix the problem, keeping in mind that memory allocated to tmpfs is not available for other purposes. In other words, a system with a gigantic tmpfs with large files in it can run out of memory and crash. Another tip: when editing the /etc/fstab file, be sure to end it with a newline, as your system will not boot otherwise. (Guess how I know.)
|
||||
|
||||
### /proc and /sys
|
||||
|
||||
Besides /tmp, the VFSes with which most Linux users are most familiar are /proc and /sys. (/dev relies on shared memory and has no file_operations). Why two flavors? Let's have a look in more detail.
|
||||
|
||||
The procfs offers a snapshot into the instantaneous state of the kernel and the processes that it controls for userspace. In /proc, the kernel publishes information about the facilities it provides, like interrupts, virtual memory, and the scheduler. In addition, /proc/sys is where the settings that are configurable via the [sysctl command][13] are accessible to userspace. Status and statistics on individual processes are reported in /proc/<PID> directories.
|
||||
|
||||
![Console][14]
|
||||
/proc/meminfo is an empty file that nonetheless contains valuable information.
|
||||
|
||||
The behavior of /proc files illustrates how unlike on-disk filesystems VFS can be. On the one hand, /proc/meminfo contains the information presented by the command **free**. On the other hand, it's also empty! How can this be? The situation is reminiscent of a famous article written by Cornell University physicist N. David Mermin in 1985 called "[Is the moon there when nobody looks?][15] Reality and the quantum theory." The truth is that the kernel gathers statistics about memory when a process requests them from /proc, and there actually is nothing in the files in /proc when no one is looking. As [Mermin said][16], "It is a fundamental quantum doctrine that a measurement does not, in general, reveal a preexisting value of the measured property." (The answer to the question about the moon is left as an exercise.)
|
||||
|
||||
![Full moon][17]
|
||||
The files in /proc are empty when no process accesses them. ([Source][18])
|
||||
|
||||
The apparent emptiness of procfs makes sense, as the information available there is dynamic. The situation with sysfs is different. Let's compare how many files of at least one byte in size there are in /proc versus /sys.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/virtualfilesystems_6-filesize.png)
|
||||
|
||||
Procfs has precisely one, namely the exported kernel configuration, which is an exception since it needs to be generated only once per boot. On the other hand, /sys has lots of larger files, most of which comprise one page of memory. Typically, sysfs files contain exactly one number or string, in contrast to the tables of information produced by reading files like /proc/meminfo.
|
||||
|
||||
The purpose of sysfs is to expose the readable and writable properties of what the kernel calls "kobjects" to userspace. The only purpose of kobjects is reference-counting: when the last reference to a kobject is deleted, the system will reclaim the resources associated with it. Yet, /sys constitutes most of the kernel's famous "[stable ABI to userspace][19]" which [no one may ever, under any circumstances, "break."][20] That doesn't mean the files in sysfs are static, which would be contrary to reference-counting of volatile objects.
|
||||
|
||||
The kernel's stable ABI instead constrains what can appear in /sys, not what is actually present at any given instant. Listing the permissions on files in sysfs gives an idea of how the configurable, tunable parameters of devices, modules, filesystems, etc. can be set or read. Logic compels the conclusion that procfs is also part of the kernel's stable ABI, although the kernel's [documentation][19] doesn't state so explicitly.
|
||||
|
||||
![Console][21]
|
||||
Files in sysfs describe exactly one property each for an entity and may be readable, writable or both. The "0" in the file reveals that the SSD is not removable.
|
||||
|
||||
### Snooping on VFS with eBPF and bcc tools
|
||||
|
||||
The easiest way to learn how the kernel manages sysfs files is to watch it in action, and the simplest way to watch on ARM64 or x86_64 is to use eBPF. eBPF (extended Berkeley Packet Filter) consists of a [virtual machine running inside the kernel][22] that privileged users can query from the command line. Kernel source tells the reader what the kernel can do; running eBPF tools on a booted system shows instead what the kernel actually does.
|
||||
|
||||
Happily, getting started with eBPF is pretty easy via the [bcc][23] tools, which are available as [packages from major Linux distros][24] and have been [amply documented][25] by Brendan Gregg. The bcc tools are Python scripts with small embedded snippets of C, meaning anyone who is comfortable with either language can readily modify them. At this count, [there are 80 Python scripts in bcc/tools][26], making it highly likely that a system administrator or developer will find an existing one relevant to her/his needs.
|
||||
|
||||
To get a very crude idea about what work VFSes are performing on a running system, try the simple [vfscount][27] or [vfsstat][28], which show that dozens of calls to vfs_open() and its friends occur every second.
|
||||
|
||||
![Console - vfsstat.py][29]
|
||||
vfsstat.py is a Python script with an embedded C snippet that simply counts VFS function calls.
|
||||
|
||||
For a less trivial example, let's watch what happens in sysfs when a USB stick is inserted on a running system.
|
||||
|
||||
![Console when USB is inserted][30]
|
||||
Watch with eBPF what happens in /sys when a USB stick is inserted, with simple and complex examples.
|
||||
|
||||
In the first simple example above, the [trace.py][31] bcc tools script prints out a message whenever the sysfs_create_files() command runs. We see that sysfs_create_files() was started by a kworker thread in response to the USB stick insertion, but what file was created? The second example illustrates the full power of eBPF. Here, trace.py is printing the kernel backtrace (-K option) plus the name of the file created by sysfs_create_files(). The snippet inside the single quotes is some C source code, including an easily recognizable format string, that the provided Python script [induces a LLVM just-in-time compiler][32] to compile and execute inside an in-kernel virtual machine. The full sysfs_create_files() function signature must be reproduced in the second command so that the format string can refer to one of the parameters. Making mistakes in this C snippet results in recognizable C-compiler errors. For example, if the **-I** parameter is omitted, the result is "Failed to compile BPF text." Developers who are conversant with either C or Python will find the bcc tools easy to extend and modify.
|
||||
|
||||
When the USB stick is inserted, the kernel backtrace appears showing that PID 7711 is a kworker thread that created a file called "events" in sysfs. A corresponding invocation with sysfs_remove_files() shows that removal of the USB stick results in removal of the events file, in keeping with the idea of reference counting. Watching sysfs_create_link() with eBPF during USB stick insertion (not shown) reveals that no fewer than 48 symbolic links are created.
|
||||
|
||||
What is the purpose of the events file anyway? Using [cscope][33] to find the function [__device_add_disk()][34] reveals that it calls disk_add_events(), and either "media_change" or "eject_request" may be written to the events file. Here, the kernel's block layer is informing userspace about the appearance and disappearance of the "disk." Consider how quickly informative this method of investigating how USB stick insertion works is compared to trying to figure out the process solely from the source.
|
||||
|
||||
### Read-only root filesystems make embedded devices possible
|
||||
|
||||
Assuredly, no one shuts down a server or desktop system by pulling out the power plug. Why? Because mounted filesystems on the physical storage devices may have pending writes, and the data structures that record their state may become out of sync with what is written on the storage. When that happens, system owners will have to wait at next boot for the [fsck filesystem-recovery tool][35] to run and, in the worst case, will actually lose data.
|
||||
|
||||
Yet, aficionados will have heard that many IoT and embedded devices like routers, thermostats, and automobiles now run Linux. Many of these devices almost entirely lack a user interface, and there's no way to "unboot" them cleanly. Consider jump-starting a car with a dead battery where the power to the [Linux-running head unit][36] goes up and down repeatedly. How is it that the system boots without a long fsck when the engine finally starts running? The answer is that embedded devices rely on [a read-only root fileystem][37] (ro-rootfs for short).
|
||||
|
||||
![Photograph of a console][38]
|
||||
ro-rootfs are why embedded systems don't frequently need to fsck. Credit (with permission): <https://tinyurl.com/yxoauoub>
|
||||
|
||||
A ro-rootfs offers many advantages that are less obvious than incorruptibility. One is that malware cannot write to /usr or /lib if no Linux process can write there. Another is that a largely immutable filesystem is critical for field support of remote devices, as support personnel possess local systems that are nominally identical to those in the field. Perhaps the most important (but also most subtle) advantage is that ro-rootfs forces developers to decide during a project's design phase which system objects will be immutable. Dealing with ro-rootfs may often be inconvenient or even painful, as [const variables in programming languages][39] often are, but the benefits easily repay the extra overhead.
|
||||
|
||||
Creating a read-only rootfs does require some additional amount of effort for embedded developers, and that's where VFS comes in. Linux needs files in /var to be writable, and in addition, many popular applications that embedded systems run will try to create configuration dot-files in $HOME. One solution for configuration files in the home directory is typically to pregenerate them and build them into the rootfs. For /var, one approach is to mount it on a separate writable partition while / itself is mounted as read-only. Using bind or overlay mounts is another popular alternative.
|
||||
|
||||
### Bind and overlay mounts and their use by containers
|
||||
|
||||
Running **[man mount][40]** is the best place to learn about bind and overlay mounts, which give embedded developers and system administrators the power to create a filesystem in one path location and then provide it to applications at a second one. For embedded systems, the implication is that it's possible to store the files in /var on an unwritable flash device but overlay- or bind-mount a path in a tmpfs onto the /var path at boot so that applications can scrawl there to their heart's delight. At next power-on, the changes in /var will be gone. Overlay mounts provide a union between the tmpfs and the underlying filesystem and allow apparent modification to an existing file in a ro-rootfs, while bind mounts can make new empty tmpfs directories show up as writable at ro-rootfs paths. While overlayfs is a proper filesystem type, bind mounts are implemented by the [VFS namespace facility][41].
|
||||
|
||||
Based on the description of overlay and bind mounts, no one will be surprised that [Linux containers][42] make heavy use of them. Let's spy on what happens when we employ [systemd-nspawn][43] to start up a container by running bcc's mountsnoop tool:
|
||||
|
||||
![Console - system-nspawn invocation][44]
|
||||
The system-nspawn invocation fires up the container while mountsnoop.py runs.
|
||||
|
||||
And let's see what happened:
|
||||
|
||||
![Console - Running mountsnoop][45]
|
||||
Running mountsnoop during the container "boot" reveals that the container runtime relies heavily on bind mounts. (Only the beginning of the lengthy output is displayed)
|
||||
|
||||
Here, systemd-nspawn is providing selected files in the host's procfs and sysfs to the container at paths in its rootfs. Besides the MS_BIND flag that sets bind-mounting, some of the other flags that the "mount" system call invokes determine the relationship between changes in the host namespace and in the container. For example, the bind-mount can either propagate changes in /proc and /sys to the container, or hide them, depending on the invocation.
|
||||
|
||||
### Summary
|
||||
|
||||
Understanding Linux internals can seem an impossible task, as the kernel itself contains a gigantic amount of code, leaving aside Linux userspace applications and the system-call interface in C libraries like glibc. One way to make progress is to read the source code of one kernel subsystem with an emphasis on understanding the userspace-facing system calls and headers plus major kernel internal interfaces, exemplified here by the file_operations table. The file operations are what makes "everything is a file" actually work, so getting a handle on them is particularly satisfying. The kernel C source files in the top-level fs/ directory constitute its implementation of virtual filesystems, which are the shim layer that enables broad and relatively straightforward interoperability of popular filesystems and storage devices. Bind and overlay mounts via Linux namespaces are the VFS magic that makes containers and read-only root filesystems possible. In combination with a study of source code, the eBPF kernel facility and its bcc interface makes probing the kernel simpler than ever before.
|
||||
|
||||
Much thanks to [Akkana Peck][46] and [Michael Eager][47] for comments and corrections.
|
||||
|
||||
Alison Chaiken will present [Virtual filesystems: why we need them and how they work][48] at the 17th annual Southern California Linux Expo ([SCaLE 17x][49]) March 7-10 in Pasadena, Calif.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/virtual-filesystems-linux
|
||||
|
||||
作者:[Alison Chariken][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.pearson.com/us/higher-education/program/Love-Linux-Kernel-Development-3rd-Edition/PGM202532.html
|
||||
[2]: http://cassandra.apache.org/
|
||||
[3]: https://en.wikipedia.org/wiki/NoSQL
|
||||
[4]: http://lwn.net/Articles/444910/
|
||||
[5]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_1-console.png (Console)
|
||||
[6]: https://lwn.net/Articles/22355/
|
||||
[7]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/fs.h
|
||||
[8]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs
|
||||
[9]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_2-shim-layer.png (How userspace accesses various types of filesystems)
|
||||
[10]: https://lwn.net/Articles/774114/
|
||||
[11]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_3-crazy.jpg (Man with shocked expression)
|
||||
[12]: https://wiki.archlinux.org/index.php/Tmpfs
|
||||
[13]: http://man7.org/linux/man-pages/man8/sysctl.8.html
|
||||
[14]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_4-proc-meminfo.png (Console)
|
||||
[15]: http://www-f1.ijs.si/~ramsak/km1/mermin.moon.pdf
|
||||
[16]: https://en.wikiquote.org/wiki/David_Mermin
|
||||
[17]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_5-moon.jpg (Full moon)
|
||||
[18]: https://commons.wikimedia.org/wiki/Moon#/media/File:Full_Moon_Luc_Viatour.jpg
|
||||
[19]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/ABI/stable
|
||||
[20]: https://lkml.org/lkml/2012/12/23/75
|
||||
[21]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_7-sysfs.png (Console)
|
||||
[22]: https://events.linuxfoundation.org/sites/events/files/slides/bpf_collabsummit_2015feb20.pdf
|
||||
[23]: https://github.com/iovisor/bcc
|
||||
[24]: https://github.com/iovisor/bcc/blob/master/INSTALL.md
|
||||
[25]: http://brendangregg.com/ebpf.html
|
||||
[26]: https://github.com/iovisor/bcc/tree/master/tools
|
||||
[27]: https://github.com/iovisor/bcc/blob/master/tools/vfscount_example.txt
|
||||
[28]: https://github.com/iovisor/bcc/blob/master/tools/vfsstat.py
|
||||
[29]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_8-vfsstat.png (Console - vfsstat.py)
|
||||
[30]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_9-ebpf.png (Console when USB is inserted)
|
||||
[31]: https://github.com/iovisor/bcc/blob/master/tools/trace_example.txt
|
||||
[32]: https://events.static.linuxfound.org/sites/events/files/slides/bpf_collabsummit_2015feb20.pdf
|
||||
[33]: http://northstar-www.dartmouth.edu/doc/solaris-forte/manuals/c/user_guide/cscope.html
|
||||
[34]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/block/genhd.c#n665
|
||||
[35]: http://www.man7.org/linux/man-pages/man8/fsck.8.html
|
||||
[36]: https://wiki.automotivelinux.org/_media/eg-rhsa/agl_referencehardwarespec_v0.1.0_20171018.pdf
|
||||
[37]: https://elinux.org/images/1/1f/Read-only_rootfs.pdf
|
||||
[38]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_10-code.jpg (Photograph of a console)
|
||||
[39]: https://www.meetup.com/ACCU-Bay-Area/events/drpmvfytlbqb/
|
||||
[40]: http://man7.org/linux/man-pages/man8/mount.8.html
|
||||
[41]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/sharedsubtree.txt
|
||||
[42]: https://coreos.com/os/docs/latest/kernel-modules.html
|
||||
[43]: https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html
|
||||
[44]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_11-system-nspawn.png (Console - system-nspawn invocation)
|
||||
[45]: https://opensource.com/sites/default/files/uploads/virtualfilesystems_12-mountsnoop.png (Console - Running mountsnoop)
|
||||
[46]: http://shallowsky.com/
|
||||
[47]: http://eagercon.com/
|
||||
[48]: https://www.socallinuxexpo.org/scale/17x/presentations/virtual-filesystems-why-we-need-them-and-how-they-work
|
||||
[49]: https://www.socallinuxexpo.org/
|
@ -0,0 +1,48 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Emulators and Native Linux games on the Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/play-games-raspberry-pi)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
Emulators and Native Linux games on the Raspberry Pi
|
||||
======
|
||||
The Raspberry Pi is a great platform for gaming; learn how in the ninth article in our series on getting started with the Raspberry Pi.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/getting_started_with_minecraft_copy.png?itok=iz4RF7f8)
|
||||
|
||||
Back in the [fifth article][1] in our series on getting started with the Raspberry Pi, I mentioned Minecraft as a way to teach kids to program using a gaming platform. Today we'll talk about other ways you can play games on your Raspberry Pi, as it's a great platform for gaming—with and without emulators.
|
||||
|
||||
### Gaming with emulators
|
||||
|
||||
Emulators are software that allow you to play games from different systems and different decades on your Raspberry Pi. Of the many emulators available today, the most popular for the Raspberry Pi is [RetroPi][2]. You can use it to play games from systems such as Apple II, Amiga, Atari 2600, Commodore 64, Game Boy Advance, and [many others][3].
|
||||
|
||||
If RetroPi sounds interesting, check out [these instructions][4] on how to get started, and start having fun today!
|
||||
|
||||
### Native Linux games
|
||||
|
||||
There are also plenty of native Linux games available on Raspbian, Raspberry Pi's operating system. Make Use Of has a great article on [how to play 10 old favorites][5] like Doom and Nuke Dukem 3D on the Raspberry Pi.
|
||||
|
||||
You can also use your Raspberry Pi as a [game server][6]. For example, you can set up Terraria, Minecraft, and QuakeWorld servers on the Raspberry Pi.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/play-games-raspberry-pi
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/article/19/3/teach-kids-program-raspberry-pi
|
||||
[2]: https://retropie.org.uk/
|
||||
[3]: https://retropie.org.uk/about/systems
|
||||
[4]: https://opensource.com/article/19/1/retropie
|
||||
[5]: https://www.makeuseof.com/tag/classic-games-raspberry-pi-without-emulators/
|
||||
[6]: https://www.makeuseof.com/tag/raspberry-pi-game-servers/
|
@ -0,0 +1,48 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Let's get physical: How to use GPIO pins on the Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/gpio-pins-raspberry-pi)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
Let's get physical: How to use GPIO pins on the Raspberry Pi
|
||||
======
|
||||
The 10th article in our series on getting started with Raspberry Pi explains how the GPIO pins work.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspbery_pi_zero_wireless_hardware.jpg?itok=9YFzdxFQ)
|
||||
|
||||
Until now, this series has focused on the Raspberry Pi's software side, but today we'll get into the hardware. The availability of [general-purpose input/output][1] (GPIO) pins was one of the main features that interested me in the Pi when it first came out. GPIO allows you to programmatically interact with the physical world by attaching sensors, relays, and other types of circuitry to the Raspberry Pi.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/raspberrypi_10_gpio-pins-pi2.jpg)
|
||||
|
||||
Each pin on the board either has a predefined function or is designated as general purpose. Also, different Raspberry Pi models have either 26 or 40 pins for you to use at your discretion. Wikipedia has a [good overview of each pin][2] and its functionality.
|
||||
|
||||
You can do many things with the Pi's GPIO pins. I've written some other articles about using the GPIOs, including a trio of articles ([Part I][3], [Part II][4], and [Part III][5]) about controlling holiday lights with the Raspberry Pi while using open source software to pair the lights with music.
|
||||
|
||||
The Raspberry Pi community has done a great job in creating libraries in different programming languages, so you should be able to interact with the pins using [C][6], [Python][7], [Scratch][8], and other languages.
|
||||
|
||||
Also, if you want the ultimate experience to interact with the physical world, pick up a [Raspberry Pi Sense Hat][9]. It is an affordable expansion board for the Pi that plugs into the GPIO pins so you can programmatically interact with LEDs, joysticks, and barometric pressure, temperature, humidity, gyroscope, accelerometer, and magnetometer sensors.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/gpio-pins-raspberry-pi
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.raspberrypi.org/documentation/usage/gpio/
|
||||
[2]: https://en.wikipedia.org/wiki/Raspberry_Pi#General_purpose_input-output_(GPIO)_connector
|
||||
[3]: https://opensource.com/life/15/2/music-light-show-with-raspberry-pi
|
||||
[4]: https://opensource.com/life/15/12/ssh-your-christmas-tree-raspberry-pi
|
||||
[5]: https://opensource.com/article/18/12/lightshowpi-raspberry-pi
|
||||
[6]: https://www.bigmessowires.com/2018/05/26/raspberry-pi-gpio-programming-in-c/
|
||||
[7]: https://www.raspberrypi.org/documentation/usage/gpio/python/README.md
|
||||
[8]: https://www.raspberrypi.org/documentation/usage/gpio/scratch2/README.md
|
||||
[9]: https://opensource.com/life/16/4/experimenting-raspberry-pi-sense-hat
|
@ -0,0 +1,80 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (7 resources for learning to use your Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/resources-raspberry-pi)
|
||||
[#]: author: (Manuel Dewald https://opensource.com/users/ntlx)
|
||||
|
||||
7 resources for learning to use your Raspberry Pi
|
||||
======
|
||||
Books, courses, and websites to shorten your Raspberry Pi learning curve.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/reading_book_stars_list.png?itok=Iwa1oBOl)
|
||||
|
||||
The [Raspberry Pi][1] is a small, single-board computer originally intended for teaching and learning programming and computer science. But today it's so much more. It is affordable, low-energy computing power that people can use for all kinds of things—from home entertainment over server applications to Internet of Things (IoT) projects.
|
||||
|
||||
There are so many resources on the topic and so many different projects you can do, it's hard to know where to begin. Following are some resources that will help you get started with the Raspberry Pi. Have fun browsing through it, but don't stop here. By looking left and right you will find a lot to discover and get deeper into the rabbit hole of the Raspberry Pi wonderland.
|
||||
|
||||
### Books
|
||||
|
||||
There are many books available in different languages about the Raspberry Pi. These two will help you start—then dive deep—into Raspberry Pi topics.
|
||||
|
||||
#### Raspberry Pi Cookbook: Software and Hardware Problems and Solutions by Simon Monk
|
||||
|
||||
Simon Monk is a software engineer and was a hobbyist maker for years. He was first attracted to the Arduino as an easy-to-use board for electronics development and later published a [book][2] about it. Later, he moved on to the Raspberry Pi and wrote [Raspberry Pi Cookbook: Software and Hardware Problems and Solutions][3]. In the book, you can find a lot of best practices for Raspberry Pi projects and solutions for all kinds of challenges you may face.
|
||||
|
||||
#### Programming the Raspberry Pi: Getting Started with Python by Simon Monk
|
||||
|
||||
Python has evolved as the go-to programming language for getting started with Raspberry Pi projects, as it is easy to learn and use, even if you don't have any programming experience. Also, a lot of its libraries help you focus on what makes your project special instead of implementing protocols to communicate with your sensors again and again. Monk wrote two chapters about Python programming in the Raspberry Pi Cookbook, but [Programming the Raspberry Pi: Getting Started with Python][4] is a more thorough quickstart. It introduces you to Python and shows you some projects you can create with it on the Raspberry Pi.
|
||||
|
||||
### Online course
|
||||
|
||||
There are many online courses and tutorials new Raspberry Pi users can choose from, including this introductory class.
|
||||
|
||||
#### Raspberry Pi Class
|
||||
|
||||
Instructables' free [Raspberry Pi Class][5] online course offers you an all-around introduction to the Raspberry Pi. It starts with Raspberry Pi and Linux operating basics, then gets into Python programming and GPIO communication. This makes it a good top-to-bottom Raspberry Pi guide if you are new to the topic and want to get started quickly.
|
||||
|
||||
### Websites
|
||||
|
||||
The web is rife with excellent information about Raspberry Pi, but these four sites should be on the top of any new user's list.
|
||||
|
||||
#### RaspberryPi.org
|
||||
|
||||
The official [Raspberry Pi][6] website is one of the best places to get started. Many articles about specific projects link to the site for the basics like installing Raspbian onto the Raspberry Pi. (This is what I tend to do, instead of repeating the instructions in every how-to.) You can also find [sample projects][7] and courses on [teaching][8] tech topics to students.
|
||||
|
||||
#### Opensource.com
|
||||
|
||||
On Opensource.com, you can find a number of different Raspberry Pi project how-to's, getting started guides, success stories, updates, and more. Take a look at the [Raspberry Pi topic page][9] to find out what people are doing with Raspberry Pi.
|
||||
|
||||
#### Instructables and Hackaday
|
||||
|
||||
Do you want to build your own retro arcade gaming console? Or for your mirror to display weather information, the time, and the first event on the day's calendar? Are you looking to create a word clock or maybe a photo booth for a party? Chances are good that you will find instructions on how to do all of this (and more!) with a Raspberry Pi on sites like [Instructables][10] and [Hackaday][11]. If you're not sure if you should get a Raspberry Pi, browse these sites, and you'll find plenty of reasons to buy one.
|
||||
|
||||
What are your favorite Raspberry Pi resources? Please share them in the comments!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/resources-raspberry-pi
|
||||
|
||||
作者:[Manuel Dewald][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ntlx
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/resources/raspberry-pi
|
||||
[2]: http://simonmonk.org/progardui2ed/
|
||||
[3]: http://simonmonk.org/raspberry-pi-cookbook-ed2/
|
||||
[4]: http://simonmonk.org/programming-raspberry-pi-ed2/
|
||||
[5]: https://www.instructables.com/class/Raspberry-Pi-Class/
|
||||
[6]: https://raspberrypi.org
|
||||
[7]: https://projects.raspberrypi.org/
|
||||
[8]: https://www.raspberrypi.org/training/online
|
||||
[9]: https://opensource.com/tags/raspberry-pi
|
||||
[10]: https://www.instructables.com/technology/raspberry-pi/
|
||||
[11]: https://hackaday.io/projects?tag=raspberry%20pi
|
@ -0,0 +1,63 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Blockchain 2.0: Redefining Financial Services [Part 3])
|
||||
[#]: via: (https://www.ostechnix.com/blockchain-2-0-redefining-financial-services/)
|
||||
[#]: author: (EDITOR https://www.ostechnix.com/author/editor/)
|
||||
|
||||
Blockchain 2.0: Redefining Financial Services [Part 3]
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/03/Financial-Services-1-720x340.png)
|
||||
|
||||
The [**previous article of this series**][1] focused on building context to bring forth why moving our existing monetary system to a futuristic [**blockchain**][2] system is the next natural step in the evolution of “money”. We looked at the features of a blockchain platform which would aid in such a move. However, the financial markets are far more complex and composed of numerous other instruments that people trade rather than just a currency.
|
||||
|
||||
This part will explore the features of blockchain which will enable institutions to transform and interlace traditional banking and financing systems with it. As previously discussed, and proved, if enough people participate in a given blockchain network and support the protocols for transactions, the nominal value that can be attributed to the “token” increases and becomes more stable. Take, for instance, Bitcoin (BTC). Like the simple paper currency, we’re all used to, cryptocurrencies such as Bitcoin and Ether can be utilized for all the former’s purposes from buying food to ships and from loaning money to insurance.
|
||||
|
||||
Chances are you are already involved with a bank or any other financial institution that makes use of blockchain ledger technology. The most significant uses of blockchain tech in the finance industry will be in setting up payments infrastructure, fund transfer technologies, and digital identity management. The latter two have traditionally been handled by legacy systems in the financial services industry. These systems are slowly being migrated to blockchain systems owing to their efficiency in handling work like this. The blockchain also offers high-quality data analytics solutions to these firms, an aspect that is quickly gaining prominence because of recent developments in data sciences.[1]
|
||||
|
||||
Considering the start-ups and projects at the cutting edge of innovation in this space first seems warranted due to their products or services already doing the rounds in the market today.
|
||||
|
||||
Starting with PayPal, an online payments company started in 1998, and now among the largest of such platforms, it is considered to be a benchmark in terms of operations and technical prowess. PayPal derives largely from the existing monetary system. Its contribution to innovation came by how it collected and leveraged consumer data to provide services online at instantaneous speeds. Online transactions are taken for granted today with minimal innovation in the industry in terms of the tech that it’s based on. Having a solid foundation is a good thing, but that won’t give anyone an edge over their competition in this fast-paced IT world with new standards and technology being pioneered every other day. In 2014 PayPal subsidiary, **Braintree** announced partnerships with popular cryptocurrency payment solutions including **Coinbase** and **GoCoin** , in a bid to gradually integrate Bitcoin and other popular cryptocurrencies into its service platform. This basically gave its consumers a chance to explore and experience the side of what’s to come under the familiar umbrella cover and reliability of PayPal. In fact, ride-hailing company **Uber** had an exclusive partnership with Braintree to allow customers to pay for rides using Bitcoin.[2][3]
|
||||
|
||||
**Ripple** is making it easier for people to operate between multiple blockchains. Ripple has been in the headlines for moving ahead with regional banks in the US, for instance, to facilitate transferring money bilaterally to other regional banks without the need for a 3rd party intermediary resulting in reduced cost and time overheads. Ripple’s **Codius platform** allows for interoperability between blockchains and opens the doors to smart contracts programmed into the system for minimal tampering and confusion. Built on technology that is highly advanced, secure and scalable to suit needs, Ripple’s platform currently has names such as UBS and Standard Chartered on their client’s list. Many more are expected to join in.[4][5]
|
||||
|
||||
**Kraken** , a US-based cryptocurrency exchange operating in locations around the globe is known for their reliable **crypto quant** estimates even providing Bitcoin pricing data real time to the Bloomberg terminal. In 2015, they partnered with **Fidor Bank** to form what was then the world’s first Cryptocurrency Bank offering customers banking services and products which dealt with cryptocurrencies.[6]
|
||||
|
||||
**Circle** , another FinTech company is currently among the largest of its sorts involved with allowing users to invest and trade in cryptocurrency derived assets, similar to traditional money market assets.[7]
|
||||
|
||||
Companies such as **Wyre** and **Stellar** today have managed to bring down the lead time involved in international wire transfers from an average of 3 days to under 6 hours. Claims have been made saying that once a proper regulatory system is in place the same 6 hours can be brought down to a matter of seconds.[8]
|
||||
|
||||
Now while all of the above have focused on the start-up projects involved, it has to be remembered that the reach and capabilities of the older more respectable financial institutions should not be ignored. Institutions that have existed for decades if not centuries moving billions of dollars worldwide are equally interested in leveraging the blockchain and its potential.
|
||||
|
||||
As we already mentioned in the previous article, **JP Morgan** recently unveiled their plans to exploit cryptocurrencies and the underlying ledger like the functionality of the blockchain for enterprises. The project, called **Quorum** , is defined as an **“Enterprise-ready distributed ledger and smart contract platform”**. The main goal being that gradually the bulk of the bank’s operations would one day be migrated to Quorum thus cutting significant investments that firms such as JP Morgan need to make in order to guarantee privacy, security, and transparency. They’re claimed to be the only player in the industry now to have complete ownership over the whole stack of the blockchain, protocol, and token system. They also released a cryptocurrency called **JPM Coin** meant to be used in transacting high volume settlements instantaneously. JPM coin is among the first “stable coins” to be backed by a major bank such as JP Morgan. A stable coin is a cryptocurrency whose price is linked to an existing major monetary system. Quorum is also touted for its capabilities to process almost 100 transactions a second which is leaps and bounds ahead of its contemporaries.[9]
|
||||
|
||||
**Barclay’s** , a British multinational financial giant is reported to have registered two blockchain-based patents supposedly with the aim of streamlining fund transfers and KYC procedures. Barclay’s proposals though are more aimed toward improving their banking operations’ efficiency. One of the application deals with creating a private blockchain network for storing KYC details of consumers. Once verified, stored and confirmed, these details are immutable and nullifies the need for further verifications down the line. If implemented the protocol will do away with the need for multiple verifications of KYC details. Developing and densely populated countries such as India where a bulk of the population is yet to be inducted into a formal banking system will find the innovative KYC system useful in reducing random errors and lead times involved in the process[10]. Barclay’s is also rumored to be exploring the capabilities of a blockchain system to address credit status ratings and insurance claims.
|
||||
|
||||
Such blockchain backed systems are designed to eliminate needless maintenance costs and leverage the power of smart contracts for enterprises which operate in industries where discretion, security, and speed determine competitive advantage. Being enterprise products, they’re built on protocols that ensure complete transaction and contract privacy along with a consensus mechanism which essentially nullifies corruption and bribery.
|
||||
|
||||
**PwC’s Global Fintech Report** from 2017 states that by 2020, an estimated 77% of all Fintech companies are estimated to switch to blockchain based technologies and processes concerning their operations. A whopping 90 percent of their respondents said that they were planning to adopt blockchain technology as part of an in-production system by 2020. Their judgments are not misplaced as significant cost savings and transparency gains from a regulatory point of view are guaranteed by moving to a blockchain based system.[11]
|
||||
|
||||
Since regulatory capabilities are built into the blockchain platform by default the migration of firms from legacy systems to modern networks running blockchain ledgers is a welcome move for industry regulators as well. Transactions and trade movements can be verified and tracked on the fly once and for all rather than after. This, in the long run, will likely result in better regulation and risk management. Not to mention improved accountability from the part of firms and individuals alike.[11]
|
||||
|
||||
While considerable investments in the space and leaping innovations are courtesy of large investments by established corporates it is misleading to think that such measures wouldn’t permeate the benefits to the end user. As banks and financial institutions start to adopt the blockchain, it will result in increased cost savings and efficiency for them which will ultimately mean good for the end consumer too. The added benefits of transparency and fraud protection will improve customer sentiments and more importantly improve the trust that people place on the banking and financial system. A much-needed revolution in the financial services industry is possible with blockchains and their integration into traditional services.
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/blockchain-2-0-redefining-financial-services/
|
||||
|
||||
作者:[EDITOR][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/editor/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/blockchain-2-0-revolutionizing-the-financial-system/
|
||||
[2]: https://www.ostechnix.com/blockchain-2-0-an-introduction/
|
@ -0,0 +1,76 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Building the virtualization stack of the future with rust-vmm)
|
||||
[#]: via: (https://opensource.com/article/19/3/rust-virtual-machine)
|
||||
[#]: author: (Andreea Florescu )
|
||||
|
||||
Building the virtualization stack of the future with rust-vmm
|
||||
======
|
||||
rust-vmm facilitates sharing core virtualization components between Rust Virtual Machine Monitors.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/data_stack_blue_disks.png?itok=3hKDtK20)
|
||||
|
||||
More than a year ago we started developing [Firecracker][1], a virtual machine monitor (VMM) that runs on top of KVM (the kernel-based virtual machine). We wanted to create a lightweight VMM that starts virtual machines (VMs) in a fraction of a second, with a low memory footprint, to enable high-density cloud environments.
|
||||
|
||||
We started out developing Firecracker by forking the Chrome OS VMM ([CrosVM][2]), but we diverged shortly after because we targeted different customer use cases. CrosVM provides Linux application isolation in ChromeOS, while Firecracker is used for running multi-tenant workloads at scale. Even though we now walk different paths, we still have common virtualization components, such as wrappers over KVM input/output controls (ioctls), a minimal kernel loader, and use of the [Virtio][3] device models.
|
||||
|
||||
With this in mind, we started thinking about the best approach for sharing the common code. Having a shared codebase raises the security and quality bar for both projects. Currently, fixing security bugs requires duplicated work in terms of porting the changes from one project to the other and going through different review processes for merging the changes. After open sourcing Firecracker, we've received requests for adding features including GPU support and booting [bzImage][4] files. Some of the requests didn't align with Firecracker's goals, but were otherwise valid use cases that just haven't found the right place for an implementation.
|
||||
|
||||
### The rust-vmm project
|
||||
|
||||
The [rust-vmm][5] project came to life in December 2018 when Amazon, Google, Intel, and Red Hat employees started talking about the best way of sharing virtualization packages. More contributors have joined this initiative along the way. We are still at the beginning of this journey, with only one component published to [Crates.io][6] (Rust's package registry) and several others (such as Virtio devices, Linux kernel loaders, and KVM ioctls wrappers) being developed. With two VMMs written in Rust under active development and growing interest in building other specialized VMMs, rust-vmm was born as the host for sharing core virtualization components.
|
||||
|
||||
The goal of rust-vmm is to enable the community to create custom VMMs that import just the required building blocks for their use case. We decided to organize rust-vmm as a multi-repository project, where each repository corresponds to an independent virtualization component. Each individual building block is published on Crates.io.
|
||||
|
||||
### Creating custom VMMs with rust-vmm
|
||||
|
||||
The components discussed below are currently under development.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/custom_vmm.png)
|
||||
|
||||
Each box on the right side of the diagram is a GitHub repository corresponding to one package, which in Rust is called a crate. The functionality of one crate can be further split into modules, for example virtio-devices. Let's have a look at these components and some of their potential use cases.
|
||||
|
||||
* **KVM interface:** Creating our VMM on top of KVM requires an interface that can invoke KVM functionality from Rust. The kvm-bindings crate represents the Rust Foreign Function Interface (FFI) to KVM kernel headers. Because headers only include structures and defines, we also have wrappers over the KVM ioctls (kvm-ioctls) that we use for opening dev/kvm, creating a VM, creating vCPUs, and so on.
|
||||
|
||||
* **Virtio devices and rate limiting:** Virtio has a frontend-backend architecture. Currently in rust-vmm, the frontend is implemented in the virtio-devices crate, and the backend lies in the vhost package. Vhost has support for both user-land and kernel-land drivers, but users can also plug virtio-devices to their custom backend. The virtio-bindings are the bindings for Virtio devices generated using the Virtio Linux headers. All devices in the virtio-devices crate are exported independently as modules using conditional compilation. Some devices, such as block, net, and vsock support rate limiting in terms of I/O per second and bandwidth. This can be achieved by using the functionality provided in the rate-limiter crate.
|
||||
|
||||
* The kernel-loader is responsible for loading the contents of an [ELF][7] kernel image in guest memory.
|
||||
|
||||
|
||||
|
||||
|
||||
For example, let's say we want to build a custom VMM that allows users to create and configure a single VM running on top of KVM. As part of the configuration, users will be able to specify the kernel image file, the root file system, the number of vCPUs, and the memory size. Creating and configuring the resources of the VM can be implemented using the kvm-ioctls crate. The kernel image can be loaded in guest memory with kernel-loader, and specifying a root filesystem can be achieved with the virtio-devices block module. The last thing needed for our VMM is writing VMM Glue, the code that takes care of integrating rust-vmm components with the VMM user interface, which allows users to create and manage VMs.
|
||||
|
||||
### How you can help
|
||||
|
||||
This is the beginning of an exciting journey, and we are looking forward to getting more people interested in VMMs, Rust, and the place where you can find both: [rust-vmm][5].
|
||||
|
||||
We currently have [sync meetings][8] every two weeks to discuss the future of the rust-vmm organization. The meetings are open to anyone willing to participate. If you have any questions, please open an issue in the [community repository][9] or send an email to the rust-vmm [mailing list][10] (you can also [subscribe][11]). We also have a [Slack channel][12] and encourage you to join, if you are interested.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/rust-virtual-machine
|
||||
|
||||
作者:[Andreea Florescu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://github.com/firecracker-microvm/firecracker
|
||||
[2]: https://chromium.googlesource.com/chromiumos/platform/crosvm/
|
||||
[3]: https://www.linux-kvm.org/page/Virtio
|
||||
[4]: https://en.wikipedia.org/wiki/Vmlinux#bzImage
|
||||
[5]: https://github.com/rust-vmm
|
||||
[6]: https://crates.io/
|
||||
[7]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||
[8]: http://lists.opendev.org/pipermail/rust-vmm/2019-January/000103.html
|
||||
[9]: https://github.com/rust-vmm/community
|
||||
[10]: mailto:rust-vmm@lists.opendev.org
|
||||
[11]: http://lists.opendev.org/cgi-bin/mailman/listinfo/rust-vmm
|
||||
[12]: https://join.slack.com/t/rust-vmm/shared_invite/enQtNTI3NDM2NjA5MzMzLTJiZjUxOGEwMTJkZDVkYTcxYjhjMWU3YzVhOGQ0M2Y5NmU5MzExMjg5NGE3NjlmNzNhZDlhMmY4ZjVhYTQ4ZmQ
|
@ -0,0 +1,62 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (hopefully2333)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Learn about computer security with the Raspberry Pi and Kali Linux)
|
||||
[#]: via: (https://opensource.com/article/19/3/computer-security-raspberry-pi)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
Learn about computer security with the Raspberry Pi and Kali Linux
|
||||
======
|
||||
Raspberry Pi is a great way to learn about computer security. Learn how in the 11th article in our getting-started series.
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security_privacy_lock.png?itok=ZWjrpFzx)
|
||||
|
||||
Is there a hotter topic in technology than securing your computer? Some experts will tell you that there is no such thing as perfect security. They joke that if you want your server or application to be truly secure, then turn off your server, unplug it from the network, and put it in a safe somewhere. The problem with that should be obvious: What good is an app or server that nobody can use?
|
||||
|
||||
That's the conundrum around security. How can we make something secure enough and still usable and valuable? I am not a security expert by any means, although I hope to be one day. With that in mind, I thought it would make sense to share some ideas about what you can do with a Raspberry Pi to learn more about security.
|
||||
|
||||
I should note that, like the other articles in this series dedicated to Raspberry Pi beginners, my goal is not to dive in deep, rather to light a fire of interest for you to learn more about these topics.
|
||||
|
||||
### Kali Linux
|
||||
|
||||
When it comes to "doing security things," one of the Linux distributions that comes to mind is [Kali Linux][1]. Kali's development is primarily focused on forensics and penetration testing. It has more than 600 preinstalled [penetration-testing programs][2] to test your computer's security, and a [forensics mode][3], which prevents it from touching the internal hard drive or swap space of the system being examined.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/raspberrypi_11_kali.png)
|
||||
|
||||
Like Raspbian, Kali Linux is based on the Debian distribution, and you can find directions on installing it on the Raspberry Pi in its main [documentation portal][4]. If you installed Raspbian or another Linux distribution on your Raspberry Pi, you should have no problem installing Kali. Kali Linux's creators have even put together [training, workshops, and certifications][5] to help boost your career in the security field.
|
||||
|
||||
### Other Linux distros
|
||||
|
||||
Most standard Linux distributions, like Raspbian, Ubuntu, and Fedora, also have [many security tools available][6] in their repositories. Some great tools to explore include [Nmap][7], [Wireshark][8], [auditctl][9], and [SELinux][10].
|
||||
|
||||
### Projects
|
||||
|
||||
There are many other security-related projects you can run on your Raspberry Pi, such as [Honeypots][11], [Ad blockers][12], and [USB sanitizers][13]. Take some time and learn about them!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/computer-security-raspberry-pi
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.kali.org/
|
||||
[2]: https://en.wikipedia.org/wiki/Kali_Linux#Development
|
||||
[3]: https://docs.kali.org/general-use/kali-linux-forensics-mode
|
||||
[4]: https://docs.kali.org/kali-on-arm/install-kali-linux-arm-raspberry-pi
|
||||
[5]: https://www.kali.org/penetration-testing-with-kali-linux/
|
||||
[6]: https://linuxblog.darkduck.com/2019/02/9-best-linux-based-security-tools.html
|
||||
[7]: https://nmap.org/
|
||||
[8]: https://www.wireshark.org/
|
||||
[9]: https://linux.die.net/man/8/auditctl
|
||||
[10]: https://opensource.com/article/18/7/sysadmin-guide-selinux
|
||||
[11]: https://trustfoundry.net/honeypi-easy-honeypot-raspberry-pi/
|
||||
[12]: https://pi-hole.net/
|
||||
[13]: https://www.circl.lu/projects/CIRCLean/
|
200
sources/tech/20190312 BackBox Linux for Penetration Testing.md
Normal file
200
sources/tech/20190312 BackBox Linux for Penetration Testing.md
Normal file
@ -0,0 +1,200 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (BackBox Linux for Penetration Testing)
|
||||
[#]: via: (https://www.linux.com/blog/learn/2019/3/backbox-linux-penetration-testing)
|
||||
[#]: author: (Jack Wallen https://www.linux.com/users/jlwallen)
|
||||
|
||||
BackBox Linux for Penetration Testing
|
||||
======
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/security-2688911_1920.jpg?itok=yZ9TjAXu)
|
||||
|
||||
Any given task can succeed or fail depending upon the tools at hand. For security engineers in particular, building just the right toolkit can make life exponentially easier. Luckily, with open source, you have a wide range of applications and environments at your disposal, ranging from simple commands to complicated and integrated tools.
|
||||
|
||||
The problem with the piecemeal approach, however, is that you might wind up missing out on something that can make or break a job… or you waste a lot of time hunting down the right tools for the job. To that end, it’s always good to consider an operating system geared specifically for penetration testing (aka pentesting).
|
||||
|
||||
Within the world of open source, the most popular pentesting distribution is [Kali Linux][1]. It is, however, not the only tool in the shop. In fact, there’s another flavor of Linux, aimed specifically at pentesting, called [BackBox][2]. BackBox is based on Ubuntu Linux, which also means you have easy access to a host of other outstanding applications besides those that are included, out of the box.
|
||||
|
||||
### What Makes BackBox Special?
|
||||
|
||||
BackBox includes a suite of ethical hacking tools, geared specifically toward pentesting. These testing tools include the likes of:
|
||||
|
||||
* Web application analysis
|
||||
|
||||
* Exploitation testing
|
||||
|
||||
* Network analysis
|
||||
|
||||
* Stress testing
|
||||
|
||||
* Privilege escalation
|
||||
|
||||
* Vulnerability assessment
|
||||
|
||||
* Computer forensic analysis and exploitation
|
||||
|
||||
* And much more
|
||||
|
||||
|
||||
|
||||
|
||||
Out of the box, one of the most significant differences between Kali Linux and BackBox is the number of installed tools. Whereas Kali Linux ships with hundreds of tools pre-installed, BackBox significantly limits that number to around 70. Nonetheless, BackBox includes many of the tools necessary to get the job done, such as:
|
||||
|
||||
* Ettercap
|
||||
|
||||
* Msfconsole
|
||||
|
||||
* Wireshark
|
||||
|
||||
* ZAP
|
||||
|
||||
* Zenmap
|
||||
|
||||
* BeEF Browser Exploitation
|
||||
|
||||
* Sqlmap
|
||||
|
||||
* Driftnet
|
||||
|
||||
* Tcpdump
|
||||
|
||||
* Cryptcat
|
||||
|
||||
* Weevely
|
||||
|
||||
* Siege
|
||||
|
||||
* Autopsy
|
||||
|
||||
|
||||
|
||||
|
||||
BackBox is in active development, the latest version (5.3) was released February 18, 2019. But how is BackBox as a usable tool? Let’s install and find out.
|
||||
|
||||
### Installation
|
||||
|
||||
If you’ve installed one Linux distribution, you’ve installed them all … with only slight variation. BackBox is pretty much the same as any other installation. [Download the ISO][3], burn the ISO onto a USB drive, boot from the USB drive, and click the Install icon.
|
||||
|
||||
The installer (Figure 1) will be instantly familiar to anyone who has installed a Ubuntu or Debian derivative. Just because BackBox is a distribution geared specifically toward security administrators, doesn’t mean the operating system is a challenge to get up and running. In fact, BackBox is a point-and-click affair that anyone, regardless of skills, can install.
|
||||
|
||||
![installation][5]
|
||||
|
||||
Figure 1: The installation of BackBox will be immediately familiar to anyone.
|
||||
|
||||
[Used with permission][6]
|
||||
|
||||
The trickiest section of the installation is the Installation Type. As you can see (Figure 2), even this step is quite simple.
|
||||
|
||||
![BackBox][8]
|
||||
|
||||
Figure 2: Selecting the type of installation for BackBox.
|
||||
|
||||
[Used with permission][6]
|
||||
|
||||
Once you’ve installed BackBox, reboot the system, remove the USB drive, and wait for it to land on the login screen. Log into the desktop and you’re ready to go (Figure 3).
|
||||
|
||||
![desktop][10]
|
||||
|
||||
Figure 3: The BackBox Linux desktop, running as a VirtualBox virtual machine.
|
||||
|
||||
[Used with permission][6]
|
||||
|
||||
### Using BackBox
|
||||
|
||||
Thanks to the [Xfce desktop environment][11], BackBox is easy enough for a Linux newbie to navigate. Click on the menu button in the top left corner to reveal the menu (Figure 4).
|
||||
|
||||
![desktop menu][13]
|
||||
|
||||
Figure 4: The BackBox desktop menu in action.
|
||||
|
||||
[Used with permission][6]
|
||||
|
||||
From the desktop menu, click on any one of the favorites (in the left pane) or click on a category to reveal the related tools (Figure 5).
|
||||
|
||||
![Auditing][15]
|
||||
|
||||
Figure 5: The Auditing category in the BackBox menu.
|
||||
|
||||
[Used with permission][6]
|
||||
|
||||
The menu entries you’ll most likely be interested in are:
|
||||
|
||||
* Anonymous - allows you to start an anonymous networking session.
|
||||
|
||||
* Auditing - the majority of the pentesting tools are found in here.
|
||||
|
||||
* Services - allows you to start/stop services such as Apache, Bluetooth, Logkeys, Networking, Polipo, SSH, and Tor.
|
||||
|
||||
|
||||
|
||||
|
||||
Before you run any of the testing tools, I would recommend you first making sure to update and upgrade BackBox. This can be done via a GUI or the command line. If you opt to go the GUI route, click on the desktop menu, click System, and click Software Updater. When the updater completes its check for updates, it will prompt you if any are available, or if (after an upgrade) a reboot is necessary (Figure 6).
|
||||
|
||||
![reboot][17]
|
||||
|
||||
Figure 6: Time to reboot after an upgrade.
|
||||
|
||||
[Used with permission][6]
|
||||
|
||||
Should you opt to go the manual route, open a terminal window and issue the following two commands:
|
||||
|
||||
```
|
||||
sudo apt-get update
|
||||
|
||||
sudo apt-get upgrade -y
|
||||
```
|
||||
|
||||
Many of the BackBox pentesting tools do require a solid understanding of how each tool works, so before you attempt to use any given tool, make sure you know how to use said tool. Some tools (such as Metasploit) are made a bit easier to work with, thanks to BackBox. To run Metasploit, click on the desktop menu button and click msfconsole from the favorites (left pane). When the tool opens for the first time, you’ll be asked to configure a few options. Simply select each default given by clicking your keyboard Enter key when prompted. Once you see the Metasploit prompt, you can run commands like:
|
||||
|
||||
```
|
||||
db_nmap 192.168.0/24
|
||||
```
|
||||
|
||||
The above command will list out all discovered ports on a 192.168.1.x network scheme (Figure 7).
|
||||
|
||||
![Metasploit][19]
|
||||
|
||||
Figure 7: Open port discovery made simple with Metasploit on BackBox.
|
||||
|
||||
[Used with permission][6]
|
||||
|
||||
Even often-challenging tools like Metasploit are made far easier than they are with other distributions (partially because you don’t have to bother with installing the tools). That alone is worth the price of entry for BackBox (which is, of course, free).
|
||||
|
||||
### The Conclusion
|
||||
|
||||
Although BackBox usage may not be as widespread as Kali Linux, it still deserves your attention. For anyone looking to do pentesting on their various environments, BackBox makes the task far easier than so many other operating systems. Give this Linux distribution a go and see if it doesn’t aid you in your journey to security nirvana.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/2019/3/backbox-linux-penetration-testing
|
||||
|
||||
作者:[Jack Wallen][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/jlwallen
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.kali.org/
|
||||
[2]: https://linux.backbox.org/
|
||||
[3]: https://www.backbox.org/download/
|
||||
[4]: /files/images/backbox1jpg
|
||||
[5]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/backbox_1.jpg?itok=pn4fQVp7 (installation)
|
||||
[6]: /licenses/category/used-permission
|
||||
[7]: /files/images/backbox2jpg
|
||||
[8]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/backbox_2.jpg?itok=tf-1zo8Z (BackBox)
|
||||
[9]: /files/images/backbox3jpg
|
||||
[10]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/backbox_3.jpg?itok=GLowoAUb (desktop)
|
||||
[11]: https://www.xfce.org/
|
||||
[12]: /files/images/backbox4jpg
|
||||
[13]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/backbox_4.jpg?itok=VmQXtuZL (desktop menu)
|
||||
[14]: /files/images/backbox5jpg
|
||||
[15]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/backbox_5.jpg?itok=UnfM_OxG (Auditing)
|
||||
[16]: /files/images/backbox6jpg
|
||||
[17]: https://www.linux.com/sites/lcom/files/styles/floated_images/public/backbox_6.jpg?itok=2t1BiKPn (reboot)
|
||||
[18]: /files/images/backbox7jpg
|
||||
[19]: https://www.linux.com/sites/lcom/files/styles/rendered_file/public/backbox_7.jpg?itok=Vw_GEub3 (Metasploit)
|
@ -0,0 +1,49 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Do advanced math with Mathematica on the Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/do-math-raspberry-pi)
|
||||
[#]: author: (Anderson Silva https://opensource.com/users/ansilva)
|
||||
|
||||
Do advanced math with Mathematica on the Raspberry Pi
|
||||
======
|
||||
Wolfram bundles a version of Mathematica with Raspbian. Learn how to use it in the 12th article in our series on getting started with Raspberry Pi.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/edu_math_formulas.png?itok=B59mYTG3)
|
||||
|
||||
In the mid-'90s, I started college as a math major, and, even though I graduated with a computer science degree, I had taken enough classes to graduate with a minor—and only two classes short of a double-major—in math. At the time, I was introduced to an application called [Mathematica][1] by [Wolfram][2], where we would take many of our algebraic and differential equations from the blackboard into the computer. I spent a few hours a month in the lab learning the Wolfram Language and solving integrals and such on Mathematica.
|
||||
|
||||
Mathematica was closed source and expensive for a college student, so it was a nice surprise to see almost 20 years later Wolfram bundling a version of Mathematica with Raspbian and the Raspberry Pi. If you decide to use another Debian-based distribution, you can [download it][3] on your Pi. Note that this version is free for non-commercial use only.
|
||||
|
||||
The Raspberry Pi Foundation's [introduction to Mathematica][4] covers some basic concepts such as variables and loops, solving some math problems, creating graphs, doing linear algebra, and even interacting with the GPIO pins through the application.
|
||||
|
||||
![](https://opensource.com/sites/default/files/uploads/raspberrypi_12_mathematica_batman-plot.png)
|
||||
|
||||
To dive deeper into Mathematica, check out the [Wolfram Language documentation][5]. If you just want to solve some basic calculus problems, [check out its functions][6]. And read this tutorial if you want to [plot some 2D and 3D graphs][7].
|
||||
|
||||
Or, if you want to stick with open source tools while doing math, check out the command-line tools **expr** , **factor** , and **bc**. (Remember to use the [**man** command][8] to read up on these utilities.) And if you want to graph something, [Gnuplot][9] is a great option.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/do-math-raspberry-pi
|
||||
|
||||
作者:[Anderson Silva][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ansilva
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://en.wikipedia.org/wiki/Wolfram_Mathematica
|
||||
[2]: https://wolfram.com/
|
||||
[3]: https://www.wolfram.com/raspberry-pi/
|
||||
[4]: https://projects.raspberrypi.org/en/projects/getting-started-with-mathematica/
|
||||
[5]: https://www.wolfram.com/language/
|
||||
[6]: https://reference.wolfram.com/language/guide/Calculus.html
|
||||
[7]: https://reference.wolfram.com/language/howto/PlotAGraph.html
|
||||
[8]: https://opensource.com/article/19/3/learn-linux-raspberry-pi
|
||||
[9]: http://gnuplot.info/
|
@ -0,0 +1,93 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Star LabTop Mk III Open Source Edition: An Interesting Laptop)
|
||||
[#]: via: (https://itsfoss.com/star-labtop-open-source-edition)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Star LabTop Mk III Open Source Edition: An Interesting Laptop
|
||||
======
|
||||
|
||||
[Star Labs Systems][1] have been producing Laptops tailored for Linux for some time. While you can purchase other variants available on their website, they have recently launched a [Kickstarter campaign][2] for their upcoming ‘Open Source Edition’ laptop that incorporates more features as per the requests by the users or reviewers.
|
||||
|
||||
It may not be the best laptop you’ve ever come across for around a **1000 Euros** – but it certainly is interesting for some specific features.
|
||||
|
||||
In this article, we will talk about what makes it an interesting deal and whether or not it’s worth investing for.
|
||||
|
||||
![star labtop mk III][3]
|
||||
|
||||
### Key Highlight: Open-source Coreboot Firmware
|
||||
|
||||
Normally, you will observe proprietary firmware (BIOS) on computers, American Megatrends Inc, for example.
|
||||
|
||||
But, here, Star Labs have tailored the [coreboot firmware][4] (a.k.a known as the LinuxBIOS) which is an open source alternative to proprietary solutions for this laptop.
|
||||
|
||||
Not just open source but it is also a lighter firmware for better control over your laptop. With [TianoCore EDK II][5], it ensures that you get the maximum compatibility for most of the major Operating Systems.
|
||||
|
||||
### Other Features of Star LabTop Mk III
|
||||
|
||||
![sat labtop mk III][6]
|
||||
|
||||
In addition to the open source firmware, the laptop features an **8th-gen i7 chipse** t ( **i7-8550u** ) coupled with **16 Gigs of LPDDR4 RAM** clocked at **2400 MHz**.
|
||||
|
||||
The GPU being the integrated **Intel UHD Graphics 620** should be enough for professional tasks – except video editing and gaming. It will be rocking a **Full HD 13.3-inch IPS** panel as the display.
|
||||
|
||||
The storage option includes **480 GB or 960 GB of PCIe SSD** – which is impressive as well. In addition to all this, it comes with the **USB Type-C** support.
|
||||
|
||||
Interestingly, the **BIOS, Embedded Controller and SSD** will be receiving automatic [firmware updates][7] via the [LVFS][8] (the Mk III standard edition has this feature already).
|
||||
|
||||
You should also check out a review video of [Star LabTob Mk III][9] to get an idea of how the open source edition could look like:
|
||||
|
||||
If you are curious about the detailed tech specs, you should check out the [Kickstarter page][2].
|
||||
|
||||
<https://youtu.be/_oxewz8ePv4>
|
||||
|
||||
### Our Opinion
|
||||
|
||||
![star labtop mk III][10]
|
||||
|
||||
The inclusion of coreboot firmware and being something tailored for various Linux distributions originally is the reason why it is being termed as the “ **Open Source Edition”**.
|
||||
|
||||
The price for the ultimate bundle on Kickstarter is **1087 Euros**.
|
||||
|
||||
Can you get better laptop deals at this price? **Yes** , definitely. But, it really comes down to your preference and your passion for open source – of what you require.
|
||||
|
||||
However, if you want a performance-driven laptop specifically tailored for Linux, yes, this is an option you might want to consider with something new to offer (and potentially considering your requests for their future builds).
|
||||
|
||||
Of course, you cannot consider this for video editing and gaming – for obvious reasons. So, they should considering adding a dedicated GPU to make it a complete package for computing, gaming, video editing and much more. Maybe even a bigger screen, say 15.6-inch?
|
||||
|
||||
### Wrapping Up
|
||||
|
||||
For what it is worth, if you are a Linux and open source enthusiast and want a performance-driven laptop, this could be an option to go with and back this up on Kickstarter right now.
|
||||
|
||||
What do you think about it? Will you be interested in a laptop like this? If not, why?
|
||||
|
||||
Let us know your thoughts in the comments below.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/star-labtop-open-source-edition
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://starlabs.systems
|
||||
[2]: https://www.kickstarter.com/projects/starlabs/star-labtop-mk-iii-open-source-edition
|
||||
[3]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/star-labtop-mkiii-2.jpg?resize=800%2C450&ssl=1
|
||||
[4]: https://en.wikipedia.org/wiki/Coreboot
|
||||
[5]: https://github.com/tianocore/tianocore.github.io/wiki/EDK-II
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/star-labtop-mkiii-1.jpg?ssl=1
|
||||
[7]: https://itsfoss.com/update-firmware-ubuntu/
|
||||
[8]: https://fwupd.org/
|
||||
[9]: https://starlabs.systems/pages/star-labtop
|
||||
[10]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/star-labtop-mkiii.jpg?resize=800%2C435&ssl=1
|
||||
[11]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/03/star-labtop-mkiii-2.jpg?fit=800%2C450&ssl=1
|
@ -0,0 +1,95 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Game Review: Steel Rats is an Enjoyable Bike-Combat Game)
|
||||
[#]: via: (https://itsfoss.com/steel-rats)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Game Review: Steel Rats is an Enjoyable Bike-Combat Game
|
||||
======
|
||||
|
||||
Steel Rats is a quite impressive 2.5D motorbike combat game with exciting stunts involved. It was already available for Windows on [Steam][1] – however, recently it has been made available for Linux and Mac as well.
|
||||
|
||||
In case you didn’t know, you can easily [install Steam on Ubuntu][2] or other distributions and [enable Steam Play feature to run some Windows games on Linux][3].
|
||||
|
||||
So, in this article, we shall take a look at what the game is all about and if it is a good purchase for you.
|
||||
|
||||
This game is neither free nor open source. We have covered it here because the game developers made an effort to port it to Linux.
|
||||
|
||||
### Story Overview
|
||||
|
||||
![steel rats][4]
|
||||
|
||||
You belong to a biker gang – “ **Steel Rats** ” – who stepped up to protect their city from alien robots invasion. The alien robots aren’t just any tiny toys that you can easily defeat but with deadly weapons and abilities.
|
||||
|
||||
The games features the setting as an alternative version of 1940’s USA – with the retro theme in place. You have to use your bike as the ultimate weapon to go against waves of alien robot and boss fights as well.
|
||||
|
||||
You will encounter 4 different characters with unique abilities to switch from after progressing through a couple of rounds.
|
||||
|
||||
You will start playing as “ **Toshi** ” and unlock other characters as you progress. **Toshi** is a genius and will be using a drone as his gadget to fight the alien robots. **James** – is the leader with the hammer attack as his special ability. **Lisa** would be the one utilizing fire to burn the junk robots. And, **Randall** will have his harpoon ready to destroy aerial robots with ease.
|
||||
|
||||
### Gameplay
|
||||
|
||||
![][5]
|
||||
|
||||
Honestly, I am not a fan of 2.5 D (or 2D games). But, games like [Unravel][6] will be the exception – which is still not available for Linux, such a shame – EA.
|
||||
|
||||
In this case, I did end up enjoying “ **Steel Rats** ” as one of the few 2D games I play.
|
||||
|
||||
There is really no rocket science for this game – you just have to get good with the controls. No matter whether you use a controller or a keyboard, it is definitely challenging to get comfortable with the controls.
|
||||
|
||||
You do not need to plan ahead in order to save your health or nitro boost because you will always have it when needed while also having checkpoints to resume your progress.
|
||||
|
||||
You just need to keep the right pace and the perfect jump while hitting every enemy to get the best score in the leader boards. Once you do that, the game ends up being an easy and fun experience.
|
||||
|
||||
If you’re curious about the gameplay, we recommend watching this video:
|
||||
|
||||
<https://www.youtube.com/embed/e2RhSKjLKf0?enablejsapi=1&autoplay=0&cc_load_policy=0&iv_load_policy=1&loop=0&modestbranding=1&rel=0&showinfo=0&fs=1&playsinline=0&autohide=2&theme=dark&color=red&controls=2&?
|
||||
|
||||
### Performance & Visuals
|
||||
|
||||
![][7]
|
||||
|
||||
The graphics or visuals do matter in a game. Even though the minimum system requirements is not something to worry about, you should be good with a processor similar to or better than **Intel Core 2 Duo** coupled with **4 Gigs of RAM** at least and a dedicated GPU ( **GeForce GT 630 / Radeon HD 7570)**.
|
||||
|
||||
I tried it on my system with **i5-7400** coupled with **8 Gigs of RAM** and a **GTX 1050** graphics card on board. With the highest settings, the game worked smooth and looked visually good as well. Of course, we will avoid talking about the frames I got – because anything above **25-30 FPS** for this kind of game is perfectly fine.
|
||||
|
||||
However, I did encounter multiple crashes – so had to restart the game. Maybe the [Nvidia driver][8] was at fault? Maybe the fact that I’m using Elementary OS?
|
||||
|
||||
I’m not so sure why I had issues – but just a heads up for you. Once the game launches successfully without a crash, it works well without any hiccups.
|
||||
|
||||
### Final Verdict
|
||||
|
||||
While this may not be the most challenging game you’ve come across but it surely is a fun experience. Along with a good gameplay and visuals – the background theme music of the game is also very good.
|
||||
|
||||
The music actually sets up the mood of a gamer while playing this – so thought of pointing this out as well.
|
||||
|
||||
Depending on your region – you will find this game listed on Steam for either **19.99 USD** or **529 INR**.
|
||||
|
||||
Is it worth it? **Yes** , if you want a exciting and fun motorbike-action game in a 2.5D experience. **No** , if you want an extremely challenging 2D game in your library.
|
||||
|
||||
What do you think about the game? Let us know in the comments below.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/steel-rats
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://store.steampowered.com/app/619700/Steel_Rats/
|
||||
[2]: https://itsfoss.com/install-steam-ubuntu-linux/
|
||||
[3]: https://itsfoss.com/steam-play/
|
||||
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/steel-rats-screenshot-1.jpg?fit=800%2C450&ssl=1
|
||||
[5]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/steel-rats-screenshot-2.jpg?fit=800%2C450&ssl=1
|
||||
[6]: https://en.wikipedia.org/wiki/Unravel_(video_game)
|
||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/steel-rats-screenshot-3.jpg?fit=800%2C450&ssl=1
|
||||
[8]: https://itsfoss.com/install-additional-drivers-ubuntu/
|
@ -0,0 +1,77 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (14 days of celebrating the Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/happy-pi-day)
|
||||
[#]: author: (Anderson Silva (Red Hat) https://opensource.com/users/ansilva)
|
||||
|
||||
14 days of celebrating the Raspberry Pi
|
||||
======
|
||||
|
||||
In the 14th and final article in our series on getting started with the Raspberry Pi, take a look back at all the things we've learned.
|
||||
|
||||
![][1]
|
||||
|
||||
**Happy Pi Day!**
|
||||
|
||||
Every year on March 14th, we geeks celebrate Pi Day. In the way we abbreviate dates—MMDD—March 14 is written 03/14, which numerically reminds us of 3.14, or the first three numbers of [pi][2]. What many Americans don't realize is that virtually no other country in the world uses this [date format][3], so Pi Day pretty much only works in the US, though it is celebrated globally.
|
||||
|
||||
Wherever you are in the world, let's celebrate the Raspberry Pi and wrap up this series by reviewing the topics we've covered in the past two weeks:
|
||||
|
||||
* Day 1: [Which Raspberry Pi should you choose?][4]
|
||||
* Day 2: [How to buy a Raspberry Pi][5]
|
||||
* Day 3: [How to boot up a new Raspberry Pi][6]
|
||||
* Day 4: [Learn Linux with the Raspberry Pi][7]
|
||||
* Day 5: [5 ways to teach kids to program with Raspberry Pi][8]
|
||||
* Day 6: [3 popular programming languages you can learn with Raspberry Pi][9]
|
||||
* Day 7: [How to keep your Raspberry Pi updated][10]
|
||||
* Day 8: [How to use your Raspberry Pi for entertainment][11]
|
||||
* Day 9: [Play games on the Raspberry Pi][12]
|
||||
* Day 10: [Let's get physical: How to use GPIO pins on the Raspberry Pi][13]
|
||||
* Day 11: [Learn about computer security with the Raspberry Pi][14]
|
||||
* Day 12: [Do advanced math with Mathematica on the Raspberry Pi][15]
|
||||
* Day 13: [Contribute to the Raspberry Pi community][16]
|
||||
|
||||
|
||||
|
||||
![Pi Day illustration][18]
|
||||
|
||||
I'll end this series by thanking everyone who was brave enough to follow along and especially those who learned something from it during these past 14 days! I also want to encourage everyone to keep expanding their knowledge about the Raspberry Pi and all of the open (and closed) source technology that has been built around it.
|
||||
|
||||
I also encourage you to learn about other cultures, philosophies, religions, and worldviews. What makes us human is this amazing (and sometimes amusing) ability that we have to adapt not only to external environmental circumstances—but also intellectual ones.
|
||||
|
||||
No matter what you do, keep learning!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/happy-pi-day
|
||||
|
||||
作者:[Anderson Silva (Red Hat)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberry-pi-juggle.png?itok=oTgGGSRA
|
||||
[2]: https://www.piday.org/million/
|
||||
[3]: https://en.wikipedia.org/wiki/Date_format_by_country
|
||||
[4]: https://opensource.com/article/19/3/which-raspberry-pi-choose
|
||||
[5]: https://opensource.com/article/19/3/how-buy-raspberry-pi
|
||||
[6]: https://opensource.com/article/19/3/how-boot-new-raspberry-pi
|
||||
[7]: https://opensource.com/article/19/3/learn-linux-raspberry-pi
|
||||
[8]: https://opensource.com/article/19/3/teach-kids-program-raspberry-pi
|
||||
[9]: https://opensource.com/article/19/3/programming-languages-raspberry-pi
|
||||
[10]: https://opensource.com/article/19/3/how-raspberry-pi-update
|
||||
[11]: https://opensource.com/article/19/3/raspberry-pi-entertainment
|
||||
[12]: https://opensource.com/article/19/3/play-games-raspberry-pi
|
||||
[13]: https://opensource.com/article/19/3/gpio-pins-raspberry-pi
|
||||
[14]: https://opensource.com/article/19/3/learn-about-computer-security-raspberry-pi
|
||||
[15]: https://opensource.com/article/19/3/do-math-raspberry-pi
|
||||
[16]: https://opensource.com/article/19/3/contribute-raspberry-pi-community
|
||||
[17]: /file/426561
|
||||
[18]: https://opensource.com/sites/default/files/uploads/raspberrypi_14_piday.jpg (Pi Day illustration)
|
@ -0,0 +1,182 @@
|
||||
[#]: collector: (oska874)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Getting started with PiFlash: Booting your Raspberry Pi on Linux)
|
||||
[#]: via: (https://opensource.com/article/19/3/piflash?utm_campaign=intrel)
|
||||
[#]: author: (Ian Kluft https://opensource.com/users/ikluft)
|
||||
|
||||
|
||||
Getting started with PiFlash: Booting your Raspberry Pi on Linux
|
||||
============================================================
|
||||
|
||||
### Linux users can say goodbye to manually creating bootable SD cards for Raspberry Pi with PiFlash.
|
||||
|
||||
![Vector, generic Raspberry Pi board](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/raspberrypi_board_vector_red.png?itok=yaqYjYqI "Vector, generic Raspberry Pi board")
|
||||
|
||||
Most people install some form of Linux when they set up a Raspberry Pi computer. Until recently, the installation tools for creating a bootable SD card were only available for Windows and MacOS desktops. If you were running Linux on your desktop, you got a page of instructions on doing it manually from the command line.
|
||||
|
||||
That works. But if you experiment with multiple Raspberry Pi boards, over time this gets tedious. As an engineer and a coder, I started thinking about automating it to make it easier and, in the usual way open source projects get started, I came away with [PiFlash][10].
|
||||
|
||||
I wrote PiFlash just for myself in 2016\. By February 2017, it had evolved far enough that I introduced it in a presentation at SVPerl (Silicon Valley Perl) about using Perl on the Raspberry Pi, then was invited to write two articles for Opensource.com: _[Getting Started with Perl on the Raspberry Pi][7]_ and _[How to Secure Your Raspberry Pi][8]._
|
||||
|
||||
### PiFlash features
|
||||
|
||||
PiFlash has features that appeal to beginners and experts.
|
||||
|
||||
Like most other open source software tools, you don't need to see the language it's written in, if you're not into that. But the source code is available for power users and participants.
|
||||
|
||||
For expert users, PiFlash simplifies the process of writing an SD card. When you download a bootable OS "image" file, it's usually in a ZIP archive or compressed. All the distributions package them a little differently. With PiFlash, you don't have to unpack or decompress the image. Just specify the downloaded file as the input and PiFlash will do the tedious part of extracting it.
|
||||
|
||||
For beginners, there's an important safety feature: PiFlash will write _only_ to an SD card and refuse to write to any other type of device. Since you have to use root permissions to write the card, the system will do anything you tell it to. Therefore, it's possible to accidentally erase the wrong device, maybe a hard drive you want to keep, when trying to flash an SD card manually for a new Raspberry Pi.
|
||||
|
||||
This is where PiFlash protects you from danger. Internally, it finds device attributes with the **lsblk** command from the **util-linux** package, which is part of all Linux distributions. It can recognize SD cards using various drivers. It will refuse to write to a block device if it isn't an SD card.
|
||||
|
||||
Fortunately, the Etcher GUI tool that Raspberry Pi Foundation uses in its instructions for Windows and MacOS users has been expanded to Linux, so there is now a GUI option on Linux for those who prefer one. But if you want to automate the process, or if you want power-user levels of customization, only a command-line tool will do the job.
|
||||
|
||||
The latest version of PiFlash adds plugin modules that can modify the SD card's filesystem after installing the OS image, so you can start to explore new options for automation.
|
||||
|
||||
### Installing PiFlash
|
||||
|
||||
[PiFlash is available][11] from [CPAN][12], the Comprehensive Perl Archive Network—but before you proceed, make sure you have all the dependency packages installed. To install the dependencies:
|
||||
|
||||
On RPM-based Linux systems (Red Hat Enterprise, Fedora, CentOS, etc.):
|
||||
|
||||
```
|
||||
sudo dnf install coreutils util-linux perl file-libs perl-File-LibMagic perl-IO perl-Exception-Class perl-Try-Tiny perl-Module-Pluggable perl-File-Path perl-YAML-LibYAML gzip unzip xz e2fsprogs dosfstools
|
||||
```
|
||||
|
||||
On Debian-based Linux systems (Debian, Ubuntu, Raspbian, etc.):
|
||||
|
||||
```
|
||||
sudo apt-get install coreutils util-linux klibc-utils perl-base libmagic1 libfile-libmagic-perl libio-all-perl libexception-class-perl libtry-tiny-perl libmodule-pluggable-perl libyaml-libyaml-perl gzip xz-utils e2fsprogs dosfstools
|
||||
```
|
||||
|
||||
For source-based distributions or other packaging systems, see the CPAN documentation for the dependency list.
|
||||
|
||||
Next, install PiFlash using the CPAN tool:
|
||||
|
||||
```
|
||||
cpan PiFlash
|
||||
```
|
||||
|
||||
I have the [Dist:][13][:Zilla][14]-based build set up to make DEB and RPM packages, but it isn't in any of the major package archives yet. That's possible in the future.
|
||||
|
||||
### Running PiFlash
|
||||
|
||||
If you just run the **piflash** command without any arguments, it will print usage information.
|
||||
|
||||
```
|
||||
usage: piflash [--verbose] [--resize] [--config conf-file] input-file output-device
|
||||
piflash [--verbose] [--config conf-file] --SDsearch
|
||||
piflash --version
|
||||
```
|
||||
|
||||
Scan the system for SD cards to get the exact device name, which you'll need for the Pi-Flash output-device parameter below.
|
||||
|
||||
```
|
||||
piflash --sdsearch
|
||||
```
|
||||
|
||||
If no SD cards are found, it says it can't find anything.
|
||||
|
||||
```
|
||||
no SD cards found on system
|
||||
```
|
||||
More on Raspberry Pi
|
||||
|
||||
* [What is Raspberry Pi?][1]
|
||||
|
||||
* [Getting started with Raspberry Pi][2]
|
||||
|
||||
* [Getting started with Raspberry Pi cheat sheet][3]
|
||||
|
||||
* [Our latest on Raspberry Pi][4]
|
||||
|
||||
* [Send us your Raspberry Pi projects and tutorials][5]
|
||||
|
||||
By the way, if you have an SD card writer that PiFlash doesn't know about, please let me know by filing a report on GitHub. For problem reports and troubleshooting, please collect the program's internal information by using the **--verbose** option so I can see what driver your system has that PiFlash didn't recognize.
|
||||
|
||||
Your exact device name may vary by drivers and the names used by other devices on your system. If you have a USB-based SD reader/writer, it may say something like this:
|
||||
|
||||
```
|
||||
SD cards found: /dev/sdb
|
||||
```
|
||||
|
||||
Or if you have a built-in SD card slot, it may use a different driver and have a name that indicates it’s an SD card using the MMC (MultiMediaCard) driver:
|
||||
|
||||
```
|
||||
SD cards found: /dev/mmcblk0
|
||||
```
|
||||
|
||||
Next, download a system image to install. The Raspberry Pi Foundation has an old [list of possibilities][15] that is no longer updated. Since Raspbian is the official Linux distribution for the Raspberry Pi, driver support goes there first. But others work: Ubuntu is on the list, but Fedora isn't because ARM and Raspberry Pi support came after the list was made, however, you can [download it][16].
|
||||
|
||||
The command to flash the SD card is **piflash <input-file> <output-device **. Here are some examples of commands to flash it, depending upon the system you downloaded and which block device has your SD card:
|
||||
|
||||
```
|
||||
piflash 2018-11-13-raspbian-stretch-full.zip /dev/mmcblk0
|
||||
piflash Fedora-LXDE-armhfp-29-1.2-sda.raw.xz /dev/sdb
|
||||
```
|
||||
|
||||
PiFlash now has a **--resize** option, which will resize the root partition on the SD card to fill the rest of the device. It only works if the root is a Linux ext2/3/4 filesystem. Most distributions make that available as an option you can do manually after installation, but this automates it to one step.
|
||||
|
||||
### Plugins, automation, and future development
|
||||
|
||||
PiFlash 0.3.1 is current at the time of this writing.
|
||||
|
||||
PiFlash 0.1.0 introduced plugin modules, which means Perl modules named like **PiFlash::Plugin::Something** will be available to the program. As a security precaution, because PiFlash can run commands as **sudo-root**, plugins are not automatically loaded. Instead, they have to be enabled via **--plugin** on the command line or in a configuration file. The name of the plugin is the Perl module name without the **PiFlash::Plugin:: prefix**. For more than one plugin, it's a comma-delimited list of names. Enabled plugins can use a hook that is called when the boot and root filesystems are mounted after writing the SD card. More on plugins can be found at the [**PiFlash::Plugin**][17] module documentation.
|
||||
|
||||
Here are some ideas on my own to-do list for upcoming plugin modules...
|
||||
|
||||
* Change the password of the user and root accounts on the SD card before it boots
|
||||
|
||||
* Set the network parameters and hostname
|
||||
|
||||
* Modify system configuration parameters that would usually require manually running **raspi-config** or editing **config.txt**
|
||||
|
||||
* Set up a custom Linux environment around ARM kernels you build
|
||||
|
||||
My ideas are, of course, influenced by what I want to do. You may want to go in other directions, so please consider contributing patches and plugins.
|
||||
|
||||
The source code repository for PiFlash is [on GitHub][18]. Please file problem reports and code/documentation contributions there, also.
|
||||
|
||||
### About the author
|
||||
|
||||
Ian Kluft - Ian has had parallel interests since grade school in computing and flight. He was coding on Unix before there was Linux, and started on Linux 6 months after the kernel was posted. He has a masters degree in Computer Science and is a CSSLP (Certified Secure Software Lifecycle Professional). On the side he's a pilot and a certified flight instructor. As a licensed Ham Radio operator for over 25 years, experimentation with electronics has evolved in recent years to include the Raspberry Pi and...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/piflash?utm_campaign=intrel
|
||||
|
||||
作者:[ Ian Kluft ][a]
|
||||
选题:[ezio][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/ikluft
|
||||
[b]:https://github.com/oska874
|
||||
[1]:https://opensource.com/resources/what-raspberry-pi?src=raspberry_pi_resource_menu1&intcmp=701f2000000h4RcAAI
|
||||
[2]:https://opensource.com/article/16/12/getting-started-raspberry-pi?src=raspberry_pi_resource_menu2&intcmp=701f2000000h4RcAAI
|
||||
[3]:https://opensource.com/downloads/getting-started-raspberry-pi-cheat-sheet?src=raspberry_pi_resource_menu3&intcmp=701f2000000h4RcAAI
|
||||
[4]:https://opensource.com/tags/raspberry-pi?src=raspberry_pi_resource_menu4&intcmp=701f2000000h4RcAAI
|
||||
[5]:https://opensource.com/article/17/2/raspberry-pi-submit-your-article?src=raspberry_pi_resource_menu5&intcmp=701f2000000h4RcAAI
|
||||
[6]:https://opensource.com/article/19/3/piflash?rate=uzXbDSgdiRC1mnuHSCo-WHnHP7-lSyoYkTjdfMcFcUI
|
||||
[7]:https://opensource.com/article/17/3/perl-raspberry-pi
|
||||
[8]:https://opensource.com/article/17/3/iot-security-raspberry-pi
|
||||
[9]:https://opensource.com/user/120171/feed
|
||||
[10]:https://github.com/ikluft/piflash
|
||||
[11]:https://metacpan.org/release/PiFlash
|
||||
[12]:http://www.cpan.org/
|
||||
[13]:https://metacpan.org/pod/Dist::Zilla
|
||||
[14]:https://metacpan.org/pod/Dist::Zilla
|
||||
[15]:https://www.raspberrypi.org/downloads/
|
||||
[16]:https://arm.fedoraproject.org/
|
||||
[17]:https://metacpan.org/pod/PiFlash::Plugin
|
||||
[18]:https://github.com/ikluft/piflash
|
||||
[19]:https://opensource.com/users/ikluft
|
||||
[20]:https://opensource.com/users/ikluft
|
||||
[21]:https://opensource.com/tags/raspberry-pi
|
||||
[22]:https://opensource.com/tags/linux
|
@ -0,0 +1,169 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How To Navigate Inside A Directory/Folder In Linux Without CD Command?)
|
||||
[#]: via: (https://www.2daygeek.com/navigate-switch-directory-without-using-cd-command-in-linux/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
How To Navigate Inside A Directory/Folder In Linux Without CD Command?
|
||||
======
|
||||
|
||||
As everybody know that we can’t navigate inside a directory in Linux without CD command.
|
||||
|
||||
Yes that’s true but we have the Linux built-in command called `shopt` that help us to solve this issue.
|
||||
|
||||
[shopt][1] is a shell builtin command to set and unset various bash shell options, which is installed so, we no need to install it again.
|
||||
|
||||
Yes we can navigate inside a directory without CD command after enabling this option.
|
||||
|
||||
We will show you, how to do this in this article. This is a small tweak but it’s very useful for newbies who all are moving from Windows to Linux.
|
||||
|
||||
This is not useful for Linux administrator because we won’t navigate to the directory without CD command, as we had a good practices on this.
|
||||
|
||||
If you are trying to navigate a directory/folder in Linux without cd command, you will be getting the following error message. This is common in Linux.
|
||||
|
||||
```
|
||||
$ Documents/
|
||||
bash: Documents/: Is a directory
|
||||
```
|
||||
|
||||
To achieve this, we need to append the following values in a user `.bashrc` file.
|
||||
|
||||
### What Is the .bashrc File?
|
||||
|
||||
The “.bashrc” file is a shell script which is run every time a user opens a new shell in interactive mode.
|
||||
|
||||
You can add any command in that file that you want to type at the command prompt.
|
||||
|
||||
The .bashrc file itself contains a series of configurations for the terminal session. This includes setting up or enabling: colouring, completion, the shell history, command aliases and more.
|
||||
|
||||
```
|
||||
$ vi ~/.bashrc
|
||||
|
||||
shopt -s autocd
|
||||
```
|
||||
|
||||
Run the following command to make the changes to take effect.
|
||||
|
||||
```
|
||||
$ source ~/.bashrc
|
||||
```
|
||||
|
||||
We have done all the configuration. Simple do the testing on this to confirm whether this working or not.
|
||||
|
||||
```
|
||||
$ Documents/
|
||||
cd -- Documents/
|
||||
|
||||
$ daygeek/
|
||||
cd -- daygeek/
|
||||
|
||||
$ /home/daygeek/Documents/daygeek
|
||||
cd -- /home/daygeek/Documents/daygeek
|
||||
|
||||
$ pwd
|
||||
/home/daygeek/Documents/daygeek
|
||||
```
|
||||
|
||||
![][3]
|
||||
Yes, it’s working fine as expected.
|
||||
|
||||
However, it’s working fine in `fish shell` without making any changes in the `.bashrc` file.
|
||||
![][4]
|
||||
|
||||
If you would like to perform this action for temporarily then use the following commands (set/unset). This will go away when you reboot the system.
|
||||
|
||||
```
|
||||
# shopt -s autocd
|
||||
|
||||
# shopt | grep autocd
|
||||
autocd on
|
||||
|
||||
# shopt -u autocd
|
||||
|
||||
# shopt | grep autocd
|
||||
autocd off
|
||||
```
|
||||
|
||||
shopt command is offering so many other options and if you want to verify those, run the following command.
|
||||
|
||||
```
|
||||
$ shopt
|
||||
autocd on
|
||||
assoc_expand_once off
|
||||
cdable_vars off
|
||||
cdspell on
|
||||
checkhash off
|
||||
checkjobs off
|
||||
checkwinsize on
|
||||
cmdhist on
|
||||
compat31 off
|
||||
compat32 off
|
||||
compat40 off
|
||||
compat41 off
|
||||
compat42 off
|
||||
compat43 off
|
||||
compat44 off
|
||||
complete_fullquote on
|
||||
direxpand off
|
||||
dirspell off
|
||||
dotglob off
|
||||
execfail off
|
||||
expand_aliases on
|
||||
extdebug off
|
||||
extglob off
|
||||
extquote on
|
||||
failglob off
|
||||
force_fignore on
|
||||
globasciiranges on
|
||||
globstar off
|
||||
gnu_errfmt off
|
||||
histappend on
|
||||
histreedit off
|
||||
histverify off
|
||||
hostcomplete on
|
||||
huponexit off
|
||||
inherit_errexit off
|
||||
interactive_comments on
|
||||
lastpipe off
|
||||
lithist off
|
||||
localvar_inherit off
|
||||
localvar_unset off
|
||||
login_shell off
|
||||
mailwarn off
|
||||
no_empty_cmd_completion off
|
||||
nocaseglob off
|
||||
nocasematch off
|
||||
nullglob off
|
||||
progcomp on
|
||||
progcomp_alias off
|
||||
promptvars on
|
||||
restricted_shell off
|
||||
shift_verbose off
|
||||
sourcepath on
|
||||
xpg_echo off
|
||||
```
|
||||
|
||||
I had found few other utilities, that are help us to navigate a directory faster in Linux compared with cd command.
|
||||
|
||||
Those are pushd, popd, up shell script and bd utility. We will cover these topics in the upcoming articles.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/navigate-switch-directory-without-using-cd-command-in-linux/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
|
||||
[2]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[3]: https://www.2daygeek.com/wp-content/uploads/2019/03/navigate-switch-directory-without-using-cd-command-in-linux-1.jpg
|
||||
[4]: https://www.2daygeek.com/wp-content/uploads/2019/03/navigate-switch-directory-without-using-cd-command-in-linux-2.jpg
|
@ -0,0 +1,264 @@
|
||||
[#]: collector: "lujun9972"
|
||||
[#]: translator: "zhangxiangping "
|
||||
[#]: reviewer: " "
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
[#]: subject: "How To Parse And Pretty Print JSON With Linux Commandline Tools"
|
||||
[#]: via: "https://www.ostechnix.com/how-to-parse-and-pretty-print-json-with-linux-commandline-tools/"
|
||||
[#]: author: "EDITOR https://www.ostechnix.com/author/editor/"
|
||||
|
||||
How To Parse And Pretty Print JSON With Linux Commandline Tools
|
||||
======
|
||||
|
||||
**JSON** is a lightweight and language independent data storage format, easy to integrate with most programming languages and also easy to understand by humans, of course when properly formatted. The word JSON stands for **J** ava **S** cript **O** bject **N** otation, though it starts with JavaScript, and primarily used to exchange data between server and browser, but now being used in many fields including embedded systems. Here we’re going to parse and pretty print JSON with command line tools on Linux. It’s extremely useful for handling large JSON data in a shell scripts, or manipulating JSON data in a shell script.
|
||||
|
||||
### What is pretty printing?
|
||||
|
||||
The JSON data is structured to be somewhat more human readable. However in most cases, JSON data is stored in a single line, even without a line ending character.
|
||||
|
||||
Obviously that’s not very convenient for reading and editing manually.
|
||||
|
||||
That’s when pretty print is useful. The name is quite self explanatory, re-formatting the JSON text to be more legible by humans. This is known as **JSON pretty printing**.
|
||||
|
||||
### Parse And Pretty Print JSON With Linux Commandline Tools
|
||||
|
||||
JSON data could be parsed with command line text processors like **awk** , **sed** and **gerp**. In fact JSON.awk is an awk script to do that. However there are some dedicated tools for the same purpose.
|
||||
|
||||
1. **jq** or **jshon** , JSON parser for shell, both of them are quite useful.
|
||||
|
||||
2. Shell scripts like **JSON.sh** or **jsonv.sh** to parse JSON in bash, zsh or dash shell.
|
||||
|
||||
3. **JSON.awk** , JSON parser awk script.
|
||||
|
||||
4. Python modules like **json.tool**.
|
||||
|
||||
5. **underscore-cli** , Node.js and javascript based.
|
||||
|
||||
|
||||
|
||||
|
||||
In this tutorial I’m focusing only on **jq** , which is quite powerful JSON parser for shells with advanced filtering and scripting capability.
|
||||
|
||||
### JSON pretty printing
|
||||
|
||||
JSON data could be in one and nearly illegible for humans, so to make it somewhat readable, JSON pretty printing is here.
|
||||
|
||||
**Example:** A data from **jsonip.com** , to get external IP address in JSON format, use **curl** or **wget** tools like below.
|
||||
|
||||
```
|
||||
$ wget -cq http://jsonip.com/ -O -
|
||||
```
|
||||
|
||||
The actual data looks like this:
|
||||
|
||||
```
|
||||
{"ip":"111.222.333.444","about":"/about","Pro!":"http://getjsonip.com"}
|
||||
```
|
||||
|
||||
Now pretty print it with jq:
|
||||
|
||||
```
|
||||
$ wget -cq http://jsonip.com/ -O - | jq '.'
|
||||
```
|
||||
|
||||
This should look like below, after filtering the result with jq.
|
||||
|
||||
```
|
||||
{
|
||||
|
||||
"ip": "111.222.333.444",
|
||||
|
||||
"about": "/about",
|
||||
|
||||
"Pro!": "http://getjsonip.com"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
The Same thing could be done with python **json.tool** module. Here is an example:
|
||||
|
||||
```
|
||||
$ cat anything.json | python -m json.tool
|
||||
```
|
||||
|
||||
This Python based solution should be fine for most users, but it’s not that useful where Python is not pre-installed or could not be installed, like on embedded systems.
|
||||
|
||||
However the json.tool python module has a distinct advantage, it’s cross platform. So, you can use it seamlessly on Windows, Linux or mac OS.
|
||||
|
||||
|
||||
### How to parse JSON with jq
|
||||
|
||||
First, you need to install jq, it’s already picked up by most GNU/Linux distributions, install it with their respective package installer commands.
|
||||
|
||||
On Arch Linux:
|
||||
|
||||
```
|
||||
$ sudo pacman -S jq
|
||||
```
|
||||
|
||||
On Debian, Ubuntu, Linux Mint:
|
||||
|
||||
```
|
||||
$ sudo apt-get install jq
|
||||
```
|
||||
|
||||
On Fedora:
|
||||
|
||||
```
|
||||
$ sudo dnf install jq
|
||||
```
|
||||
|
||||
On openSUSE:
|
||||
|
||||
```
|
||||
$ sudo zypper install jq
|
||||
```
|
||||
|
||||
For other OS or platforms, see the [official installation instructions][1].
|
||||
|
||||
**Basic filters and identifiers of jq**
|
||||
|
||||
jq could read the JSON data either from **stdin** or a **file**. You’ve to use both depending on the situation.
|
||||
|
||||
The single symbol of **.** is the most basic filter. These filters are also called as **object identifier-index**. Using a single **.** along with jq basically pretty prints the input JSON file.
|
||||
|
||||
**Single quotes** – You don’t have to use the single quote always. But if you’re combining several filters in a single line, then you must use them.
|
||||
|
||||
**Double quotes** – You’ve to enclose any special character like **@** , **#** , **$** within two double quotes, like this example, **jq .foo.”@bar”**
|
||||
|
||||
**Raw data print** – For any reason, if you need only the final parsed data, not enclosed within a double quote, use the -r flag with the jq command, like this. **– jq -r .foo.bar**.
|
||||
|
||||
**Parsing specific data**
|
||||
|
||||
To filter out a specific part of JSON, you’ve to look into the pretty printed JSON file’s data hierarchy.
|
||||
|
||||
An example of JSON data, from Wikipedia:
|
||||
|
||||
```
|
||||
{
|
||||
|
||||
"firstName": "John",
|
||||
|
||||
"lastName": "Smith",
|
||||
|
||||
"age": 25,
|
||||
|
||||
"address": {
|
||||
|
||||
"streetAddress": "21 2nd Street",
|
||||
|
||||
"city": "New York",
|
||||
|
||||
"state": "NY",
|
||||
|
||||
"postalCode": "10021"
|
||||
|
||||
},
|
||||
|
||||
"phoneNumber": [
|
||||
|
||||
{
|
||||
|
||||
"type": "home",
|
||||
|
||||
"number": "212 555-1234"
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"type": "fax",
|
||||
|
||||
"number": "646 555-4567"
|
||||
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
"gender": {
|
||||
|
||||
"type": "male"
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
I’m going to use this JSON data as an example in this tutorial, saved this as **sample.json**.
|
||||
|
||||
Let’s say I want to filter out the address from sample.json file. So the command should be like:
|
||||
|
||||
```
|
||||
$ jq .address sample.json
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
{
|
||||
|
||||
"streetAddress": "21 2nd Street",
|
||||
|
||||
"city": "New York",
|
||||
|
||||
"state": "NY",
|
||||
|
||||
"postalCode": "10021"
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Again let’s say I want the postal code, then I’ve to add another **object identifier-index** , i.e. another filter.
|
||||
|
||||
```
|
||||
$ cat sample.json | jq .address.postalCode
|
||||
```
|
||||
|
||||
Also note that the **filters are case sensitive** and you’ve to use the exact same string to get something meaningful output instead of null.
|
||||
|
||||
**Parsing elements from JSON array**
|
||||
|
||||
Elements of JSON array are enclosed within square brackets, undoubtedly quite versatile to use.
|
||||
|
||||
To parse elements from a array, you’ve to use the **[]identifier** along with other object identifier-index.
|
||||
|
||||
In this sample JSON data, the phone numbers are stored inside an array, to get all the contents from this array, you’ve to use only the brackets, like this example.
|
||||
|
||||
```
|
||||
$ jq .phoneNumber[] sample.json
|
||||
```
|
||||
|
||||
Let’s say you just want the first element of the array, then use the array object numbers starting for 0, for the first item, use **[0]** , for the next items, it should be incremented by one each step.
|
||||
|
||||
```
|
||||
$ jq .phoneNumber[0] sample.json
|
||||
```
|
||||
|
||||
**Scripting examples**
|
||||
|
||||
Let’s say I want only the the number for home, not entire JSON array data. Here’s when scripting within jq command comes handy.
|
||||
|
||||
```
|
||||
$ cat sample.json | jq -r '.phoneNumber[] | select(.type == "home") | .number'
|
||||
```
|
||||
|
||||
Here first I’m piping the results of one filer to another, then using the select attribute to select a particular type of data, again piping the result to another filter.
|
||||
|
||||
Explaining every type of jq filters and scripting is beyond the scope and purpose of this tutorial. It’s highly suggested to read the JQ manual for better understanding given below.
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/how-to-parse-and-pretty-print-json-with-linux-commandline-tools/
|
||||
|
||||
作者:[EDITOR][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/editor/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://stedolan.github.io/jq/download/
|
@ -0,0 +1,317 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to create portable documents with CBZ and DjVu)
|
||||
[#]: via: (https://opensource.com/article/19/3/comic-book-archive-djvu)
|
||||
[#]: author: (Seth Kenlon (Red Hat, Community Moderator) https://opensource.com/users/seth)
|
||||
|
||||
How to create portable documents with CBZ and DjVu
|
||||
======
|
||||
|
||||
Stop using PDFs with these two smart digital archive formats.
|
||||
|
||||
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/books_stack_library_reading.jpg?itok=uulcS8Sw)
|
||||
|
||||
Recently, I discovered that my great-great-grandfather wrote two books near the turn of the 20th century: one about sailing and the other about his career as [New York City's fire chief][1]. The books have a niche audience, but since they are part of my family history, I wanted to preserve a digital copy of each. But, I wondered, what portable document format is best suited for such an endeavor?
|
||||
|
||||
I decided early on that PDF was not an option. The format, while good for printing preflight, seems condemned to nonstop feature bloat, and it produces documents that are difficult to introspect and edit. I wanted a smarter format with similar features. Two came to mind: comic book archive and DjVu.
|
||||
|
||||
### Comic book archive
|
||||
|
||||
[Comic book archive][2] is a simple format most often used, as the name suggests, for comic books. You can see examples of comic book archives on sites like [Comic Book Plus][3] and [The Digital Comic Museum][4].
|
||||
|
||||
The greatest feature of a comic book archive is also its weakest: it's so simple, it's almost more of a convention than a format. In fact, a comic book archive is just a ZIP, TAR, 7Z, or RAR archive given the extension .cbz, .cbt, .cb7, or .cbr, respectively. It has no standard for storing metadata.
|
||||
|
||||
They are, however, very easy to create.
|
||||
|
||||
#### Creating comic book archives
|
||||
|
||||
1. Create a directory full of image files, and rename the images so that they have an inherent order:
|
||||
|
||||
```
|
||||
$ n=0 && for i in *.png ; do mv $i `printf %04d $n`.png ; done
|
||||
```
|
||||
|
||||
|
||||
|
||||
2. Archive the files using your favorite archive tool. In my experience, CBZ is best supported.
|
||||
|
||||
```
|
||||
$ zip comicbook.zip -r *.png
|
||||
```
|
||||
|
||||
|
||||
|
||||
3. Finally, rename the file with the appropriate extension.
|
||||
|
||||
```
|
||||
$ mv comicbook.zip comicbook.cbz
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
The resulting file should open on most of your devices. On Linux, both [Evince][5] and [Okular][6] can open CBZ files. On Android, [Document Viewer][7] and [Bubble][8] can open them.
|
||||
|
||||
#### Uncompressing comic book archives
|
||||
|
||||
Getting your data back out of a comic book archive is also easy: just unarchive the CBZ file.
|
||||
|
||||
Since your favorite archive tool may not recognize the .cbz extension as a valid archive, it's best to rename it back to its native extension:
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
$ mv comicbook.cbz comicbook.zip
|
||||
$ unzip comicbook.zip
|
||||
|
||||
### DjVu
|
||||
|
||||
A more advanced format, developed more than 20 years ago by AT&T, is [DjVu][9] (pronounced "déjà vu"). It's a digital document format with advanced compression technology and is viewable in more applications than you probably realize, including [Evince][5], [Okular][6], [DjVu.js][10] online, the [DjVu.js viewer][11] Firefox extension, [GNU Emacs][12], [Document Viewer][7] on Android, and the open source, cross-platform [DjView][13] viewer on Sourceforge.
|
||||
|
||||
You can read more about DjVu and find sample .djvu files, at [djvu.org][14].
|
||||
|
||||
DjVu has several appealing features, including image compression, outline (bookmark) structure, and support for embedded text. It's easy to introspect and edit using free and open source tools.
|
||||
|
||||
#### Installing DjVu
|
||||
|
||||
The open source toolchain is [DjVuLibre][15], which you can find in your distribution's software repository. For example, on Fedora:
|
||||
|
||||
```
|
||||
$ sudo dnf install dvjulibre
|
||||
```
|
||||
|
||||
#### Creating a DjVu file
|
||||
|
||||
A .djvu is an image that has been encoded as a DjVu file. A .djvu can contain one or more images (stored as "pages").
|
||||
|
||||
To manually produce a DjVu, you can use one of two encoders: **c44** for high-quality images or **cjb2** for simple bi-tonal images. Each encoder accepts a different image format: c44 can process .pnm or .jpeg files, while cjb2 can process .pbm or .tiff images.
|
||||
|
||||
If you need to preprocess an image, you can do that in a terminal with [Image Magick][16], using the **-density** option to define your desired resolution:
|
||||
|
||||
```
|
||||
$ convert -density 200 foo.png foo.pnm
|
||||
```
|
||||
|
||||
Then you can convert it to DjVu:
|
||||
|
||||
```
|
||||
$ c44 -dpi 200 foo.pnm foo.djvu
|
||||
```
|
||||
|
||||
If your image is simple, like black text on a white page, you can try to convert it using the simpler encoder. If necessary, use Image Magick first to convert it to a compatible intermediate format:
|
||||
|
||||
```
|
||||
$ convert -density 200 foo.png foo.pbm
|
||||
```
|
||||
|
||||
And then convert it to DjVu:
|
||||
|
||||
```
|
||||
$ cjb2 -dpi 200 foo.pbm foo.djvu
|
||||
```
|
||||
|
||||
You now have a simple, single-page .djvu document.
|
||||
|
||||
#### Creating a multi-page DjVu file
|
||||
|
||||
While a single-page DjVu can be useful, given DjVu's sometimes excellent compression, it's most commonly used as a multi-page format.
|
||||
|
||||
Assuming you have a directory of many .djvu files, you can bundle them together with the **djvm** command:
|
||||
|
||||
```
|
||||
$ djvm -c pg_1.djvu two.djvu 003.djvu mybook.djvu
|
||||
```
|
||||
|
||||
Unlike a CBZ archive, the names of the bundled images have no effect on their order in the DjVu document, rather it preserves the order you provide in the command. If you had the foresight to name them in a natural sorting order (001.djvu, 002.djvu, 003.djvu, 004.djvu, and so on), you can use a wildcard:
|
||||
|
||||
```
|
||||
$ djvm -c *.djvu mybook.djvu
|
||||
```
|
||||
|
||||
#### Manipulating a DjVu document
|
||||
|
||||
It's easy to edit DjVu documents with **djvm**. For instance, you can insert a page into an existing DjVu document:
|
||||
|
||||
```
|
||||
$ djvm -i mybook.djvu newpage.djvu 2
|
||||
```
|
||||
|
||||
In this example, the page _newpage.djvu_ becomes the new page 2 in the file _mybook.djvu_.
|
||||
|
||||
You can also delete a page. For example, to delete page 4 from _mybook.djvu_ :
|
||||
|
||||
```
|
||||
$ djvm -d mybook.djvu 4
|
||||
```
|
||||
|
||||
#### Setting an outline
|
||||
|
||||
You can add metadata to a DjVu file, such as an outline (commonly called "bookmarks"). To do this manually, create a plaintext file with the document's outline. A DjVu outline is expressed in a [Lisp][17]-like structure, with an opening **bookmarks** element followed by bookmark names and page numbers:
|
||||
```
|
||||
(bookmarks
|
||||
("Front cover" "#1")
|
||||
("Chapter 1" "#3")
|
||||
("Chapter 2" "#18")
|
||||
("Chapter 3" "#26")
|
||||
)
|
||||
```
|
||||
|
||||
The parentheses define levels in the outline. The outline currently has only top-level bookmarks, but any section can have a subsection by delaying its closing parenthesis. For example, to add a subsection to Chapter 1:
|
||||
```
|
||||
(bookmarks
|
||||
("Front cover" "#1")
|
||||
("Chapter 1" "#3"
|
||||
("Section 1" "#6"))
|
||||
("Chapter 2" "#18")
|
||||
("Chapter 3" "#26")
|
||||
)
|
||||
```
|
||||
|
||||
Once the outline is complete, save the file and apply it to your DjVu file using the **djvused** command:
|
||||
|
||||
```
|
||||
$ djvused -e 'set-outline outline.txt' -s mybook.djvu
|
||||
```
|
||||
|
||||
Open the DjVu file to see the outline.
|
||||
|
||||
![A DjVu with an outline as viewed in Okular][19]
|
||||
|
||||
#### Embedding text
|
||||
|
||||
If you want to store the text of a document you're creating, you can embed text elements ("hidden text" in **djvused** terminology) in your DjVu file so that applications like Okular or DjView can select and copy the text to a user's clipboard.
|
||||
|
||||
This is a complex operation because, in order to embed text, you must first have text. If you have access to a good OCR application (or the time and dedication to transcribe the printed page), you may have that data, but then you must map the text to the bitmap image.
|
||||
|
||||
Once you have the text and the coordinates for each line (or, if you prefer, for each word), you can write a **djvused** script with blocks for each page:
|
||||
```
|
||||
select; remove-ant; remove-txt
|
||||
# -------------------------
|
||||
select "p0004.djvu" # page 4
|
||||
set-txt
|
||||
(page 0 0 2550 3300
|
||||
(line 1661 2337 2235 2369 "Fires and Fire-fighters")
|
||||
(line 1761 2337 2235 2369 "by John Kenlon"))
|
||||
|
||||
.
|
||||
# -------------------------
|
||||
select "p0005.djvu" # page 5
|
||||
set-txt
|
||||
(page 0 0 2550 3300
|
||||
(line 294 2602 1206 2642 "Some more text here, blah blah blah."))
|
||||
```
|
||||
|
||||
The integers for each line represent the minimum and maximum locations for the X and Y coordinates of each line ( **xmin** , **ymin** , **xmax** , **ymax** ). Each line is a rectangle measured in pixels, with an origin at the _bottom-left_ corner of the page.
|
||||
|
||||
You can define embedded text elements as words, lines, and hyperlinks, and you can map complex regions with shapes other than just rectangles. You can also embed specially defined metadata, such as BibTex keys, which are expressed in lowercase (year, booktitle, editor, author, and so on), and DocInfo keys, borrowed from the PDF spec, always starting with an uppercase letter (Title, Author, Subject, Creator, Produced, CreationDate, ModDate, and so on).
|
||||
|
||||
#### Automating DjVu creation
|
||||
|
||||
While it's nice to be able to handcraft a finely detailed DjVu document, if you adopt DjVu as an everyday format, you'll notice that your applications lack some of the conveniences available in the more ubiquitous PDF. For instance, few (if any) applications offer a convenient _Print to DjVu_ or _Export to DjVu_ option, as they do for PDF.
|
||||
|
||||
However, you can still use DjVu by leveraging PDF as an intermediate format.
|
||||
|
||||
Unfortunately, the library required for easy, automated DjVu conversion is licensed under the CPL, which has requirements that cannot be satisfied by the GPL code in the toolchain. For this reason, it can't be distributed as a compiled library, but you're free to compile it yourself.
|
||||
|
||||
The process is relatively simple due to an excellent build script provided by the DjVuLibre team.
|
||||
|
||||
1. First, prepare your system with software development tools. On Fedora, the quick-and-easy way is with a DNF group:
|
||||
|
||||
```
|
||||
$ sudo dnf group install @c-development
|
||||
```
|
||||
|
||||
On Ubuntu:
|
||||
|
||||
```
|
||||
$ sudo apt-get install build-essential
|
||||
```
|
||||
|
||||
|
||||
|
||||
2. Next, download the [**GSDjVu** source code][20] from Sourceforge. Be sure to download **GSDjVu** , not **DjVuLibre** (in other words, don't click on the big green button at the top of the file listing, but on the latest file instead).
|
||||
|
||||
|
||||
3. Unarchive the file you just downloaded, and change directory into it:
|
||||
```
|
||||
$ cd ~/Downloads
|
||||
$ tar xvf gsdjvu-X.YY.tar.gz
|
||||
$ cd gsdjvu-X.YY
|
||||
```
|
||||
|
||||
|
||||
|
||||
4. Create a directory called **BUILD**. It must be called **BUILD** , so quell your creativity:
|
||||
```
|
||||
$ mkdir BUILD
|
||||
$ cd BUILD
|
||||
```
|
||||
|
||||
|
||||
|
||||
5. Download the additional source packages required to build the **GSDjVu **application. Specifically, you must download the source for **Ghostscript** (you almost certainly already have this installed, but you need its source to build against). Additionally, your system must have source packages for **jpeg** , **libpng** , **openjpeg** , and **zlib**. If you think your system already has the source packages for these projects, you can run the build script; if the sources are not found, the script will fail and let you correct the error before trying again.
|
||||
|
||||
|
||||
6. Run the interactive **build-gsdjvu** build script included in the download. This script unpacks the source files, patches Ghostscript with the **gdevdjvu** driver, compiles Ghostscript, and prunes unnecessary files from the build results.
|
||||
|
||||
|
||||
7. You can install **GSDjVu **anywhere in your path. If you don't know what your **PATH** variable is, you can see it with **echo $PATH**. For example, to install it to the **/usr/local** prefix:
|
||||
```
|
||||
$ sudo cp -r BUILD/INST/gsdjvu /usr/local/lib64
|
||||
$ cd /usr/local/bin
|
||||
$ sudo ln -s ../lib64/gsdjvu/gsdjvu gsdjvu
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### Converting a PDF to DjVu
|
||||
|
||||
Now that you've built the Ghostscript driver, converting a PDF to DjVu requires just one command:
|
||||
|
||||
```
|
||||
$ djvudigital --words mydocument.pdf mydocument.djvu
|
||||
```
|
||||
|
||||
This transforms all pages, bookmarks, and embedded text in a PDF into a DjVu file. The `--words` option maps all mapped embedded PDF text to the corresponding points in the DjVu file. If there is no embedded PDF, then no embedded text is carried over. Using this tool, you can use convenient PDF functions from your applications and end up with DjVu files.
|
||||
|
||||
### Why DjVu and CBZ?
|
||||
|
||||
DjVu and comic book archive are great additional document formats for your archival arsenal. It seems silly to stuff a series of images into a PostScript format, like PDF, or a format clearly meant mostly for text, like EPUB, so it's nice to have CBZ and DjVu as additional options. They might not be right for all of your documents, but it's good to get comfortable with them so you can use one when it makes the most sense.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/comic-book-archive-djvu
|
||||
|
||||
作者:[Seth Kenlon (Red Hat, Community Moderator)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.fireengineering.com/articles/print/volume-56/issue-27/features/chief-john-kenlon-of-new-york-city.html
|
||||
[2]: https://en.wikipedia.org/wiki/Comic_book_archive
|
||||
[3]: https://comicbookplus.com/
|
||||
[4]: https://digitalcomicmuseum.com/
|
||||
[5]: https://wiki.gnome.org/Apps/Evince
|
||||
[6]: https://okular.kde.org
|
||||
[7]: https://f-droid.org/en/packages/org.sufficientlysecure.viewer/
|
||||
[8]: https://f-droid.org/en/packages/com.nkanaev.comics/
|
||||
[9]: http://djvu.org/
|
||||
[10]: http://djvu.js.org/
|
||||
[11]: https://github.com/RussCoder/djvujs
|
||||
[12]: https://elpa.gnu.org/packages/djvu.html
|
||||
[13]: http://djvu.sourceforge.net/djview4.html
|
||||
[14]: http://djvu.org
|
||||
[15]: http://djvu.sourceforge.net
|
||||
[16]: https://www.imagemagick.org/
|
||||
[17]: https://en.wikipedia.org/wiki/Lisp_(programming_language)
|
||||
[18]: /file/426061
|
||||
[19]: https://opensource.com/sites/default/files/uploads/outline.png (A DjVu with an outline as viewed in Okular)
|
||||
[20]: https://sourceforge.net/projects/djvu/files/GSDjVu/1.10/
|
@ -0,0 +1,73 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Sweet Home 3D: An open source tool to help you decide on your dream home)
|
||||
[#]: via: (https://opensource.com/article/19/3/tool-find-home)
|
||||
[#]: author: (Jeff Macharyas (Community Moderator) )
|
||||
|
||||
Sweet Home 3D: An open source tool to help you decide on your dream home
|
||||
======
|
||||
|
||||
Interior design application makes it easy to render your favorite house—real or imaginary.
|
||||
|
||||
![Houses in a row][1]
|
||||
|
||||
I recently accepted a new job in Virginia. Since my wife was working and watching our house in New York until it sold, it was my responsibility to go out and find a new house for us and our cat. A house that she would not see until we moved into it!
|
||||
|
||||
I contracted with a real estate agent and looked at a few houses, taking many pictures and writing down illegible notes. At night, I would upload the photos into a Google Drive folder, and my wife and I would review them simultaneously over the phone while I tried to remember whether the room was on the right or the left, whether it had a fan, etc.
|
||||
|
||||
Since this was a rather tedious and not very accurate way to present my findings, I went in search of an open source solution to better illustrate what our future dream house would look like that wouldn't hinge on my fuzzy memory and blurry photos.
|
||||
|
||||
[Sweet Home 3D][2] did exactly what I wanted it to do. Sweet Home 3D is available on Sourceforge and released under the GNU General Public License. The [website][3] is very informative, and I was able to get it up and running in no time. Sweet Home 3D was developed by Paris-based Emmanuel Puybaret of eTeks.
|
||||
|
||||
### Hanging the drywall
|
||||
|
||||
I downloaded Sweet Home 3D onto my MacBook Pro and added a PNG version of a flat floorplan of a house to use as a background base map.
|
||||
|
||||
From there, it was a simple matter of using the Rooms palette to trace the pattern and set the "real life" dimensions. After I mapped the rooms, I added the walls, which I could customize by color, thickness, height, etc.
|
||||
|
||||
![Sweet Home 3D floorplan][5]
|
||||
|
||||
Now that I had the "drywall" built, I downloaded various pieces of "furniture" from a large array that includes actual furniture as well as doors, windows, shelves, and more. Each item downloads as a ZIP file, so I created a folder of all my uncompressed pieces. I could customize each piece of furniture, and repetitive items, such as doors, were easy to copy-and-paste into place.
|
||||
|
||||
Once I had all my walls and doors and windows in place, I used the application's 3D view to navigate through the house. Drawing upon my photos and memory, I made adjustments to all the objects until I had a close representation of the house. I could have spent more time modifying the house by adding textures, additional furniture, and objects, but I got it to the point I needed.
|
||||
|
||||
![Sweet Home 3D floorplan][7]
|
||||
|
||||
After I finished, I exported the plan as an OBJ file, which can be opened in a variety of programs, such as [Blender][8] and Preview on the Mac, to spin the house around and examine it from various angles. The Video function was most useful, as I could create a starting point, draw a path through the house, and record the "journey." I exported the video as a MOV file, which I opened and viewed on the Mac using QuickTime.
|
||||
|
||||
My wife was able to see (almost) exactly what I saw, and we could even start arranging furniture ahead of the move, too. Now, all I have to do is load up the moving truck and head south.
|
||||
|
||||
Sweet Home 3D will also prove useful at my new job. I was looking for a way to improve the map of the college's buildings and was planning to just re-draw it in [Inkscape][9] or Illustrator or something. However, since I have the flat map, I can use Sweet Home 3D to create a 3D version of the floorplan and upload it to our website to make finding the bathrooms so much easier!
|
||||
|
||||
### An open source crime scene?
|
||||
|
||||
An interesting aside: according to the [Sweet Home 3D blog][10], "the French Forensic Police Office (Scientific Police) recently chose Sweet Home 3D as a tool to design plans [to represent roads and crime scenes]. This is a concrete application of the recommendation of the French government to give the preference to free open source solutions."
|
||||
|
||||
This is one more bit of evidence of how open source solutions are being used by citizens and governments to create personal projects, solve crimes, and build worlds.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/tool-find-home
|
||||
|
||||
作者:[Jeff Macharyas (Community Moderator)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/house_home_colors_live_building.jpg?itok=HLpsIfIL (Houses in a row)
|
||||
[2]: https://sourceforge.net/projects/sweethome3d/
|
||||
[3]: http://www.sweethome3d.com/
|
||||
[4]: /file/426441
|
||||
[5]: https://opensource.com/sites/default/files/uploads/virginia-house-create-screenshot.png (Sweet Home 3D floorplan)
|
||||
[6]: /file/426451
|
||||
[7]: https://opensource.com/sites/default/files/uploads/virginia-house-3d-screenshot.png (Sweet Home 3D floorplan)
|
||||
[8]: https://opensource.com/article/18/5/blender-hotkey-cheat-sheet
|
||||
[9]: https://opensource.com/article/19/1/inkscape-cheat-sheet
|
||||
[10]: http://www.sweethome3d.com/blog/2018/12/10/customization_for_the_forensic_police.html
|
@ -0,0 +1,141 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Program the real world using Rust on Raspberry Pi)
|
||||
[#]: via: (https://opensource.com/article/19/3/physical-computing-rust-raspberry-pi)
|
||||
[#]: author: (Rahul Thakoor https://opensource.com/users/rahul27)
|
||||
|
||||
Program the real world using Rust on Raspberry Pi
|
||||
======
|
||||
|
||||
rust_gpizero uses the Rust programming language to do physical computing on the Raspberry Pi.
|
||||
|
||||
![][1]
|
||||
|
||||
If you own a Raspberry Pi, chances are you may already have experimented with physical computing—writing code to interact with the real, physical world, like blinking some LEDs or [controlling a servo motor][2]. You may also have used [GPIO Zero][3], a Python library that provides a simple interface to GPIO devices from Raspberry Pi with a friendly Python API. GPIO Zero is developed by [Opensource.com][4] community moderator [Ben Nuttall][5].
|
||||
|
||||
I am working on [**rust_gpiozero**][6], a port of the awesome GPIO Zero library that uses the Rust programming language. It is still a work in progress, but it already includes some useful components.
|
||||
|
||||
[Rust][7] is a systems programming language developed at Mozilla. It is focused on performance, reliability, and productivity. The Rust website has [great resources][8] if you'd like to learn more about it.
|
||||
|
||||
### Getting started
|
||||
|
||||
Before starting with rust_gpiozero, it's smart to have a basic grasp of the Rust programming language. I recommend working through at least the first three chapters in [The Rust Programming Language][9] book.
|
||||
|
||||
I recommend [installing Rust][10] on your Raspberry Pi using [**rustup**][11]. Alternatively, you can set up a cross-compilation environment using [cross][12] (which works only on an x86_64 Linux host) or [this how-to][13].
|
||||
|
||||
After you've installed Rust, create a new Rust project by entering:
|
||||
|
||||
```
|
||||
cargo new rust_gpiozero_demo
|
||||
```
|
||||
|
||||
Add **rust_gpiozero** as a dependency (currently in v0.2.0) by adding the following to the dependencies section in your **Cargo.toml** file
|
||||
|
||||
```
|
||||
rust_gpiozero = "0.2.0"
|
||||
```
|
||||
|
||||
Next, blink an LED—the "hello world" of physical computing by modifying the **main.rs** file with the following:
|
||||
```
|
||||
use rust_gpiozero::*;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
// Create a new LED attached to Pin 17
|
||||
let led = LED::new(17);
|
||||
|
||||
// Blink the LED 5 times
|
||||
for _ in 0.. 5{
|
||||
led.on();
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
led.off();
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
rust_gpiozero provides an easier interface for blinking an LED. You can use the blink method, providing the number of seconds it should stay on and off. This simplifies the code to the following:
|
||||
```
|
||||
use rust_gpiozero::*;
|
||||
fn main() {
|
||||
// Create a new LED attached to Pin 17
|
||||
let mut led = LED::new(17);
|
||||
|
||||
// on_time = 2 secs, off_time=3 secs
|
||||
led.blink(2.0,3.0);
|
||||
|
||||
// prevent program from exiting immediately
|
||||
led.wait();
|
||||
}
|
||||
```
|
||||
|
||||
### Other components
|
||||
|
||||
rust_gpiozero provides several components that are similar to GPIO Zero for controlling output and input devices. These include [LED][14], [Buzzer][15], [Motor][16], Pulse Width Modulation LED ([PWMLED][17]), [Servo][18], and [Button][19].
|
||||
|
||||
Support for other components, sensors, and devices will be added eventually. You can refer to the [documentation][20] for further usage information.
|
||||
|
||||
### More resources
|
||||
|
||||
rust_gpiozero is still a work in progress. If you need more resources for getting started with Rust on your Raspberry Pi, here are some useful links:
|
||||
|
||||
#### Raspberry Pi Peripheral Access Library (RPPAL)
|
||||
|
||||
Similar to GPIO Zero, which is based on the [RPi.GPIO][21] library, rust_gpiozero builds upon the awesome **[RPPAL][22]** library by [Rene van der Meer][23]. If you want more control for your projects using Rust, you should definitely try RPPAL. It has support for GPIO, Inter-Integrated Circuit (I 2C), hardware and software Pulse Width Modulation (PWM), and Serial Peripheral Interface (SPI). Universal asynchronous receiver-transmitter (UART) support is currently in development.
|
||||
|
||||
#### Sense HAT support
|
||||
|
||||
**[Sensehat-rs][24]** is a library by [Jonathan Pallant][25] ([@therealjpster][26]) that provides Rust support for the Raspberry Pi [Sense HAT][27] add-on board. Jonathan also has a [starter workshop][28] for using the library and he wrote a beginner's intro to use Rust on Raspberry Pi, "Read Sense HAT with Rust," in [Issue 73 of _The MagPi_][29] magazine.
|
||||
|
||||
### Wrap Up
|
||||
|
||||
Hopefully, this has inspired you to use the Rust programming language for physical computing on your Raspberry Pi. rust_gpiozero is a library which provides useful components such as LED, Buzzer, Motor, PWMLED, Servo, and Button. More features are planned and you can follow me on [twitter][30] or check out [my blog][31] to stay tuned.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/physical-computing-rust-raspberry-pi
|
||||
|
||||
作者:[Rahul Thakoor][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003784_02_os.comcareers_os_rh2x.png?itok=jbRfXinl
|
||||
[2]: https://projects.raspberrypi.org/en/projects/grandpa-scarer/4
|
||||
[3]: https://gpiozero.readthedocs.io/en/stable/#
|
||||
[4]: http://Opensource.com
|
||||
[5]: https://opensource.com/users/bennuttall
|
||||
[6]: https://crates.io/crates/rust_gpiozero
|
||||
[7]: https://www.rust-lang.org/
|
||||
[8]: https://www.rust-lang.org/learn
|
||||
[9]: https://doc.rust-lang.org/book/
|
||||
[10]: https://www.rust-lang.org/tools/install
|
||||
[11]: https://rustup.rs/
|
||||
[12]: https://github.com/rust-embedded/cross
|
||||
[13]: https://github.com/kunerd/clerk/wiki/How-to-use-HD44780-LCD-from-Rust#setting-up-the-cross-toolchain
|
||||
[14]: https://docs.rs/rust_gpiozero/0.2.0/rust_gpiozero/output_devices/struct.LED.html
|
||||
[15]: https://docs.rs/rust_gpiozero/0.2.0/rust_gpiozero/output_devices/struct.Buzzer.html
|
||||
[16]: https://docs.rs/rust_gpiozero/0.2.0/rust_gpiozero/output_devices/struct.Motor.html
|
||||
[17]: https://docs.rs/rust_gpiozero/0.2.0/rust_gpiozero/output_devices/struct.PWMLED.html
|
||||
[18]: https://docs.rs/rust_gpiozero/0.2.0/rust_gpiozero/output_devices/struct.Servo.html
|
||||
[19]: https://docs.rs/rust_gpiozero/0.2.0/rust_gpiozero/input_devices/struct.Button.html
|
||||
[20]: https://docs.rs/rust_gpiozero/
|
||||
[21]: https://pypi.org/project/RPi.GPIO/
|
||||
[22]: https://github.com/golemparts/rppal
|
||||
[23]: https://twitter.com/golemparts
|
||||
[24]: https://crates.io/crates/sensehat
|
||||
[25]: https://github.com/thejpster
|
||||
[26]: https://twitter.com/therealjpster
|
||||
[27]: https://www.raspberrypi.org/products/sense-hat/
|
||||
[28]: https://github.com/thejpster/pi-workshop-rs/
|
||||
[29]: https://www.raspberrypi.org/magpi/issues/73/
|
||||
[30]: https://twitter.com/rahulthakoor
|
||||
[31]: https://rahul-thakoor.github.io/
|
331
sources/tech/20190318 10 Python image manipulation tools.md
Normal file
331
sources/tech/20190318 10 Python image manipulation tools.md
Normal file
@ -0,0 +1,331 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (10 Python image manipulation tools)
|
||||
[#]: via: (https://opensource.com/article/19/3/python-image-manipulation-tools)
|
||||
[#]: author: (Parul Pandey https://opensource.com/users/parul-pandey)
|
||||
|
||||
10 Python image manipulation tools
|
||||
======
|
||||
|
||||
These Python libraries provide an easy and intuitive way to transform images and make sense of the underlying data.
|
||||
|
||||
![][1]
|
||||
|
||||
Today's world is full of data, and images form a significant part of this data. However, before they can be used, these digital images must be processed—analyzed and manipulated in order to improve their quality or extract some information that can be put to use.
|
||||
|
||||
Common image processing tasks include displays; basic manipulations like cropping, flipping, rotating, etc.; image segmentation, classification, and feature extractions; image restoration; and image recognition. Python is an excellent choice for these types of image processing tasks due to its growing popularity as a scientific programming language and the free availability of many state-of-the-art image processing tools in its ecosystem.
|
||||
|
||||
This article looks at 10 of the most commonly used Python libraries for image manipulation tasks. These libraries provide an easy and intuitive way to transform images and make sense of the underlying data.
|
||||
|
||||
### 1\. scikit-image
|
||||
|
||||
**[**scikit** -image][2]** is an open source Python package that works with [NumPy][3] arrays. It implements algorithms and utilities for use in research, education, and industry applications. It is a fairly simple and straightforward library, even for those who are new to Python's ecosystem. The code is high-quality, peer-reviewed, and written by an active community of volunteers.
|
||||
|
||||
#### Resources
|
||||
|
||||
scikit-image is very well [documented][4] with a lot of examples and practical use cases.
|
||||
|
||||
#### Usage
|
||||
|
||||
The package is imported as **skimage** , and most functions are found within the submodules.
|
||||
|
||||
Image filtering:
|
||||
|
||||
```
|
||||
import matplotlib.pyplot as plt
|
||||
%matplotlib inline
|
||||
|
||||
from skimage import data,filters
|
||||
|
||||
image = data.coins() # ... or any other NumPy array!
|
||||
edges = filters.sobel(image)
|
||||
plt.imshow(edges, cmap='gray')
|
||||
```
|
||||
|
||||
![Image filtering in scikit-image][6]
|
||||
|
||||
Template matching using the [match_template][7] function:
|
||||
|
||||
![Template matching in scikit-image][9]
|
||||
|
||||
You can find more examples in the [gallery][10].
|
||||
|
||||
### 2\. NumPy
|
||||
|
||||
[**NumPy**][11] is one of the core libraries in Python programming and provides support for arrays. An image is essentially a standard NumPy array containing pixels of data points. Therefore, by using basic NumPy operations, such as slicing, masking, and fancy indexing, you can modify the pixel values of an image. The image can be loaded using **skimage** and displayed using Matplotlib.
|
||||
|
||||
#### Resources
|
||||
|
||||
A complete list of resources and documentation is available on NumPy's [official documentation page][11].
|
||||
|
||||
#### Usage
|
||||
|
||||
Using Numpy to mask an image:
|
||||
|
||||
```
|
||||
import numpy as np
|
||||
from skimage import data
|
||||
import matplotlib.pyplot as plt
|
||||
%matplotlib inline
|
||||
|
||||
image = data.camera()
|
||||
type(image)
|
||||
numpy.ndarray #Image is a NumPy array:
|
||||
|
||||
mask = image < 87
|
||||
image[mask]=255
|
||||
plt.imshow(image, cmap='gray')
|
||||
```
|
||||
|
||||
![NumPy][13]
|
||||
|
||||
### 3\. SciPy
|
||||
|
||||
**[SciPy][14]** is another of Python's core scientific modules (like NumPy) and can be used for basic image manipulation and processing tasks. In particular, the submodule [**scipy.ndimage**][15] (in SciPy v1.1.0) provides functions operating on n-dimensional NumPy arrays. The package currently includes functions for linear and non-linear filtering, binary morphology, B-spline interpolation, and object measurements.
|
||||
|
||||
#### Resources
|
||||
|
||||
For a complete list of functions provided by the **scipy.ndimage** package, refer to the [documentation][16].
|
||||
|
||||
#### Usage
|
||||
|
||||
Using SciPy for blurring using a [Gaussian filter][17]:
|
||||
```
|
||||
from scipy import misc,ndimage
|
||||
|
||||
face = misc.face()
|
||||
blurred_face = ndimage.gaussian_filter(face, sigma=3)
|
||||
very_blurred = ndimage.gaussian_filter(face, sigma=5)
|
||||
|
||||
#Results
|
||||
plt.imshow(<image to be displayed>)
|
||||
```
|
||||
|
||||
![Using a Gaussian filter in SciPy][19]
|
||||
|
||||
### 4\. PIL/Pillow
|
||||
|
||||
**PIL** (Python Imaging Library) is a free library for the Python programming language that adds support for opening, manipulating, and saving many different image file formats. However, its development has stagnated, with its last release in 2009. Fortunately, there is [**Pillow**][20], an actively developed fork of PIL, that is easier to install, runs on all major operating systems, and supports Python 3. The library contains basic image processing functionality, including point operations, filtering with a set of built-in convolution kernels, and color-space conversions.
|
||||
|
||||
#### Resources
|
||||
|
||||
The [documentation][21] has instructions for installation as well as examples covering every module of the library.
|
||||
|
||||
#### Usage
|
||||
|
||||
Enhancing an image in Pillow using ImageFilter:
|
||||
|
||||
```
|
||||
from PIL import Image,ImageFilter
|
||||
#Read image
|
||||
im = Image.open('image.jpg')
|
||||
#Display image
|
||||
im.show()
|
||||
|
||||
from PIL import ImageEnhance
|
||||
enh = ImageEnhance.Contrast(im)
|
||||
enh.enhance(1.8).show("30% more contrast")
|
||||
```
|
||||
|
||||
![Enhancing an image in Pillow using ImageFilter][23]
|
||||
|
||||
[Image source code][24]
|
||||
|
||||
### 5\. OpenCV-Python
|
||||
|
||||
**OpenCV** (Open Source Computer Vision Library) is one of the most widely used libraries for computer vision applications. [**OpenCV-Python**][25] is the Python API for OpenCV. OpenCV-Python is not only fast, since the background consists of code written in C/C++, but it is also easy to code and deploy (due to the Python wrapper in the foreground). This makes it a great choice to perform computationally intensive computer vision programs.
|
||||
|
||||
#### Resources
|
||||
|
||||
The [OpenCV2-Python-Guide][26] makes it easy to get started with OpenCV-Python.
|
||||
|
||||
#### Usage
|
||||
|
||||
Using _Image Blending using Pyramids_ in OpenCV-Python to create an "Orapple":
|
||||
|
||||
|
||||
![Image blending using Pyramids in OpenCV-Python][28]
|
||||
|
||||
[Image source code][29]
|
||||
|
||||
### 6\. SimpleCV
|
||||
|
||||
[**SimpleCV**][30] is another open source framework for building computer vision applications. It offers access to several high-powered computer vision libraries such as OpenCV, but without having to know about bit depths, file formats, color spaces, etc. Its learning curve is substantially smaller than OpenCV's, and (as its tagline says), "it's computer vision made easy." Some points in favor of SimpleCV are:
|
||||
|
||||
* Even beginning programmers can write simple machine vision tests
|
||||
* Cameras, video files, images, and video streams are all interoperable
|
||||
|
||||
|
||||
|
||||
#### Resources
|
||||
|
||||
The official [documentation][31] is very easy to follow and has tons of examples and use cases to follow.
|
||||
|
||||
#### Usage
|
||||
|
||||
### [7-_simplecv.png][32]
|
||||
|
||||
![SimpleCV][33]
|
||||
|
||||
### 7\. Mahotas
|
||||
|
||||
**[Mahotas][34]** is another computer vision and image processing library for Python. It contains traditional image processing functions such as filtering and morphological operations, as well as more modern computer vision functions for feature computation, including interest point detection and local descriptors. The interface is in Python, which is appropriate for fast development, but the algorithms are implemented in C++ and tuned for speed. Mahotas' library is fast with minimalistic code and even minimum dependencies. Read its [official paper][35] for more insights.
|
||||
|
||||
#### Resources
|
||||
|
||||
The [documentation][36] contains installation instructions, examples, and even some tutorials to help you get started using Mahotas easily.
|
||||
|
||||
#### Usage
|
||||
|
||||
The Mahotas library relies on simple code to get things done. For example, it does a good job with the [Finding Wally][37] problem with a minimum amount of code.
|
||||
|
||||
Solving the Finding Wally problem:
|
||||
|
||||
![Finding Wally problem in Mahotas][39]
|
||||
|
||||
[Image source code][40]
|
||||
|
||||
![Finding Wally problem in Mahotas][42]
|
||||
|
||||
[Image source code][40]
|
||||
|
||||
### 8\. SimpleITK
|
||||
|
||||
[**ITK**][43] (Insight Segmentation and Registration Toolkit) is an "open source, cross-platform system that provides developers with an extensive suite of software tools for image analysis. **[SimpleITK][44]** is a simplified layer built on top of ITK, intended to facilitate its use in rapid prototyping, education, [and] interpreted languages." It's also an image analysis toolkit with a [large number of components][45] supporting general filtering operations, image segmentation, and registration. SimpleITK is written in C++, but it's available for a large number of programming languages including Python.
|
||||
|
||||
#### Resources
|
||||
|
||||
There are a large number of [Jupyter Notebooks][46] illustrating the use of SimpleITK for educational and research activities. The notebooks demonstrate using SimpleITK for interactive image analysis using the Python and R programming languages.
|
||||
|
||||
#### Usage
|
||||
|
||||
Visualization of a rigid CT/MR registration process created with SimpleITK and Python:
|
||||
|
||||
![SimpleITK animation][48]
|
||||
|
||||
[Image source code][49]
|
||||
|
||||
### 9\. pgmagick
|
||||
|
||||
[**pgmagick**][50] is a Python-based wrapper for the GraphicsMagick library. The [**GraphicsMagick**][51] image processing system is sometimes called the Swiss Army Knife of image processing. Its robust and efficient collection of tools and libraries supports reading, writing, and manipulating images in over 88 major formats including DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNM, and TIFF.
|
||||
|
||||
#### Resources
|
||||
|
||||
pgmagick's [GitHub repository][52] has installation instructions and requirements. There is also a detailed [user guide][53].
|
||||
|
||||
#### Usage
|
||||
|
||||
Image scaling:
|
||||
|
||||
![Image scaling in pgmagick][55]
|
||||
|
||||
[Image source code][56]
|
||||
|
||||
Edge extraction:
|
||||
|
||||
![Edge extraction in pgmagick][58]
|
||||
|
||||
[Image source code][59]
|
||||
|
||||
### 10\. Pycairo
|
||||
|
||||
[**Pycairo**][60] is a set of Python bindings for the [Cairo][61] graphics library. Cairo is a 2D graphics library for drawing vector graphics. Vector graphics are interesting because they don't lose clarity when resized or transformed. Pycairo can call Cairo commands from Python.
|
||||
|
||||
#### Resources
|
||||
|
||||
The Pycairo [GitHub repository][62] is a good resource with detailed instructions on installation and usage. There is also a [getting started guide][63], which has a brief tutorial on Pycairo.
|
||||
|
||||
#### Usage
|
||||
|
||||
Drawing lines, basic shapes, and radial gradients with Pycairo:
|
||||
|
||||
![Pycairo][65]
|
||||
|
||||
[Image source code][66]
|
||||
|
||||
### Conclusion
|
||||
|
||||
These are some of the useful and freely available image processing libraries in Python. Some are well known and others may be new to you. Try them out to get to know more about them!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/python-image-manipulation-tools
|
||||
|
||||
作者:[Parul Pandey][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/parul-pandey
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/daisy_gimp_art_design.jpg?itok=6kCxAKWO
|
||||
[2]: https://scikit-image.org/
|
||||
[3]: http://docs.scipy.org/doc/numpy/reference/index.html#module-numpy
|
||||
[4]: http://scikit-image.org/docs/stable/user_guide.html
|
||||
[5]: /file/426206
|
||||
[6]: https://opensource.com/sites/default/files/uploads/1-scikit-image.png (Image filtering in scikit-image)
|
||||
[7]: http://scikit-image.org/docs/dev/auto_examples/features_detection/plot_template.html#sphx-glr-auto-examples-features-detection-plot-template-py
|
||||
[8]: /file/426211
|
||||
[9]: https://opensource.com/sites/default/files/uploads/2-scikit-image.png (Template matching in scikit-image)
|
||||
[10]: https://scikit-image.org/docs/dev/auto_examples
|
||||
[11]: http://www.numpy.org/
|
||||
[12]: /file/426216
|
||||
[13]: https://opensource.com/sites/default/files/uploads/3-numpy.png (NumPy)
|
||||
[14]: https://www.scipy.org/
|
||||
[15]: https://docs.scipy.org/doc/scipy/reference/ndimage.html#module-scipy.ndimage
|
||||
[16]: https://docs.scipy.org/doc/scipy/reference/tutorial/ndimage.html#correlation-and-convolution
|
||||
[17]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.gaussian_filter.html
|
||||
[18]: /file/426221
|
||||
[19]: https://opensource.com/sites/default/files/uploads/4-scipy.png (Using a Gaussian filter in SciPy)
|
||||
[20]: https://python-pillow.org/
|
||||
[21]: https://pillow.readthedocs.io/en/3.1.x/index.html
|
||||
[22]: /file/426226
|
||||
[23]: https://opensource.com/sites/default/files/uploads/5-pillow.png (Enhancing an image in Pillow using ImageFilter)
|
||||
[24]: http://sipi.usc.edu/database/
|
||||
[25]: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_intro/py_intro.html
|
||||
[26]: https://github.com/abidrahmank/OpenCV2-Python-Tutorials
|
||||
[27]: /file/426236
|
||||
[28]: https://opensource.com/sites/default/files/uploads/6-opencv.jpeg (Image blending using Pyramids in OpenCV-Python)
|
||||
[29]: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_pyramids/py_pyramids.html#pyramids
|
||||
[30]: http://simplecv.org/
|
||||
[31]: http://examples.simplecv.org/en/latest/
|
||||
[32]: /file/426241
|
||||
[33]: https://opensource.com/sites/default/files/uploads/7-_simplecv.png (SimpleCV)
|
||||
[34]: https://mahotas.readthedocs.io/en/latest/
|
||||
[35]: https://openresearchsoftware.metajnl.com/articles/10.5334/jors.ac/
|
||||
[36]: https://mahotas.readthedocs.io/en/latest/install.html
|
||||
[37]: https://blog.clarifai.com/wheres-waldo-using-machine-learning-to-find-all-the-waldos
|
||||
[38]: /file/426246
|
||||
[39]: https://opensource.com/sites/default/files/uploads/8-mahotas.png (Finding Wally problem in Mahotas)
|
||||
[40]: https://mahotas.readthedocs.io/en/latest/wally.html
|
||||
[41]: /file/426251
|
||||
[42]: https://opensource.com/sites/default/files/uploads/9-mahotas.png (Finding Wally problem in Mahotas)
|
||||
[43]: https://itk.org/
|
||||
[44]: http://www.simpleitk.org/
|
||||
[45]: https://itk.org/ITK/resources/resources.html
|
||||
[46]: http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/
|
||||
[47]: /file/426256
|
||||
[48]: https://opensource.com/sites/default/files/uploads/10-simpleitk.gif (SimpleITK animation)
|
||||
[49]: https://github.com/InsightSoftwareConsortium/SimpleITK-Notebooks/blob/master/Utilities/intro_animation.py
|
||||
[50]: https://pypi.org/project/pgmagick/
|
||||
[51]: http://www.graphicsmagick.org/
|
||||
[52]: https://github.com/hhatto/pgmagick
|
||||
[53]: https://pgmagick.readthedocs.io/en/latest/
|
||||
[54]: /file/426261
|
||||
[55]: https://opensource.com/sites/default/files/uploads/11-pgmagick.png (Image scaling in pgmagick)
|
||||
[56]: https://pgmagick.readthedocs.io/en/latest/cookbook.html#scaling-a-jpeg-image
|
||||
[57]: /file/426266
|
||||
[58]: https://opensource.com/sites/default/files/uploads/12-pgmagick.png (Edge extraction in pgmagick)
|
||||
[59]: https://pgmagick.readthedocs.io/en/latest/cookbook.html#edge-extraction
|
||||
[60]: https://pypi.org/project/pycairo/
|
||||
[61]: https://cairographics.org/
|
||||
[62]: https://github.com/pygobject/pycairo
|
||||
[63]: https://pycairo.readthedocs.io/en/latest/tutorial.html
|
||||
[64]: /file/426271
|
||||
[65]: https://opensource.com/sites/default/files/uploads/13-pycairo.png (Pycairo)
|
||||
[66]: http://zetcode.com/gfx/pycairo/basicdrawing/
|
@ -0,0 +1,162 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (3 Ways To Check Whether A Port Is Open On The Remote Linux System?)
|
||||
[#]: via: (https://www.2daygeek.com/how-to-check-whether-a-port-is-open-on-the-remote-linux-system-server/)
|
||||
[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/)
|
||||
|
||||
3 Ways To Check Whether A Port Is Open On The Remote Linux System?
|
||||
======
|
||||
|
||||
This is an important topic, which is not only for Linux administrator and it will be very helpful for all.
|
||||
|
||||
I mean to say. It’s very useful for users who are working in IT Infra.
|
||||
|
||||
They have to check whether the port is open or not on Linux server before proceeding to next steps.
|
||||
|
||||
If it’s not open then they can directly ask the Linux admin to check on this.
|
||||
|
||||
If it’s open then we need to check with application team, etc,.
|
||||
|
||||
In this article, we will show you, how to check this using three methods.
|
||||
|
||||
It can be done using the following Linux commands.
|
||||
|
||||
* **`nc:`** Netcat is a simple Unix utility which reads and writes data across network connections, using TCP or UDP protocol.
|
||||
* **`nmap:`** Nmap (“Network Mapper”) is an open source tool for network exploration and security auditing. It was designed to rapidly scan large networks.
|
||||
* **`telnet:`** The telnet command is used for interactive communication with another host using the TELNET protocol.
|
||||
|
||||
|
||||
|
||||
### How To Check Whether A Port Is Open On The Remote Linux System Using nc (netcat) Command?
|
||||
|
||||
nc stands for netcat. Netcat is a simple Unix utility which reads and writes data across network connections, using TCP or UDP protocol.
|
||||
|
||||
It is designed to be a reliable “back-end” tool that can be used directly or easily driven by other programs and scripts.
|
||||
|
||||
At the same time, it is a feature-rich network debugging and exploration tool, since it can create almost any kind of connection you would need and has several interesting built-in capabilities.
|
||||
|
||||
Netcat has three main modes of functionality. These are the connect mode, the listen mode, and the tunnel mode.
|
||||
|
||||
**Common Syntax for nc (netcat):**
|
||||
|
||||
```
|
||||
$ nc [-options] [HostName or IP] [PortNumber]
|
||||
```
|
||||
|
||||
In this example, we are going to check whether the port 22 is open or not on the remote Linux system.
|
||||
|
||||
If it’s success then you will be getting the following output.
|
||||
|
||||
```
|
||||
# nc -zvw3 192.168.1.8 22
|
||||
Connection to 192.168.1.8 22 port [tcp/ssh] succeeded!
|
||||
```
|
||||
|
||||
**Details:**
|
||||
|
||||
* **`nc:`** It’s a command.
|
||||
* **`z:`** zero-I/O mode (used for scanning).
|
||||
* **`v:`** For verbose.
|
||||
* **`w3:`** timeout wait seconds
|
||||
* **`192.168.1.8:`** Destination system IP.
|
||||
* **`22:`** Port number needs to be verified.
|
||||
|
||||
|
||||
|
||||
If it’s fail then you will be getting the following output.
|
||||
|
||||
```
|
||||
# nc -zvw3 192.168.1.95 22
|
||||
nc: connect to 192.168.1.95 port 22 (tcp) failed: Connection refused
|
||||
```
|
||||
|
||||
### How To Check Whether A Port Is Open On The Remote Linux System Using nmap Command?
|
||||
|
||||
Nmap (“Network Mapper”) is an open source tool for network exploration and security auditing. It was designed to rapidly scan large networks, although it works fine against single hosts.
|
||||
|
||||
Nmap uses raw IP packets in novel ways to determine what hosts are available on the network, what services (application name and version) those hosts are offering, what operating systems (and OS versions) they are running, what type of packet filters/firewalls are in use, and dozens of other characteristics.
|
||||
|
||||
While Nmap is commonly used for security audits, many systems and network administrators find it useful for routine tasks such as network inventory, managing service upgrade schedules, and monitoring host or service uptime.
|
||||
|
||||
**Common Syntax for nmap:**
|
||||
|
||||
```
|
||||
$ nmap [-options] [HostName or IP] [-p] [PortNumber]
|
||||
```
|
||||
|
||||
If it’s success then you will be getting the following output.
|
||||
|
||||
```
|
||||
# nmap 192.168.1.8 -p 22
|
||||
|
||||
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-16 03:37 IST Nmap scan report for 192.168.1.8 Host is up (0.00031s latency).
|
||||
|
||||
PORT STATE SERVICE
|
||||
|
||||
22/tcp open ssh
|
||||
|
||||
Nmap done: 1 IP address (1 host up) scanned in 13.06 seconds
|
||||
```
|
||||
|
||||
If it’s fail then you will be getting the following output.
|
||||
|
||||
```
|
||||
# nmap 192.168.1.8 -p 80
|
||||
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-16 04:30 IST
|
||||
Nmap scan report for 192.168.1.8
|
||||
Host is up (0.00036s latency).
|
||||
|
||||
PORT STATE SERVICE
|
||||
80/tcp closed http
|
||||
|
||||
Nmap done: 1 IP address (1 host up) scanned in 13.07 seconds
|
||||
```
|
||||
|
||||
### How To Check Whether A Port Is Open On The Remote Linux System Using telnet Command?
|
||||
|
||||
The telnet command is used for interactive communication with another host using the TELNET protocol.
|
||||
|
||||
**Common Syntax for telnet:**
|
||||
|
||||
```
|
||||
$ telnet [HostName or IP] [PortNumber]
|
||||
```
|
||||
|
||||
If it’s success then you will be getting the following output.
|
||||
|
||||
```
|
||||
$ telnet 192.168.1.9 22
|
||||
Trying 192.168.1.9...
|
||||
Connected to 192.168.1.9.
|
||||
Escape character is '^]'.
|
||||
SSH-2.0-OpenSSH_5.3
|
||||
^]
|
||||
Connection closed by foreign host.
|
||||
```
|
||||
|
||||
If it’s fail then you will be getting the following output.
|
||||
|
||||
```
|
||||
$ telnet 192.168.1.9 80
|
||||
Trying 192.168.1.9...
|
||||
telnet: Unable to connect to remote host: Connection refused
|
||||
```
|
||||
|
||||
We had found only the above three methods. If you found any other ways, please let us know by updating your query in the comments section.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/how-to-check-whether-a-port-is-open-on-the-remote-linux-system-server/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.2daygeek.com/author/magesh/
|
||||
[b]: https://github.com/lujun9972
|
@ -0,0 +1,176 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Building and augmenting libraries by calling Rust from JavaScript)
|
||||
[#]: via: (https://opensource.com/article/19/3/calling-rust-javascript)
|
||||
[#]: author: (Ryan Levick https://opensource.com/users/ryanlevick)
|
||||
|
||||
Building and augmenting libraries by calling Rust from JavaScript
|
||||
======
|
||||
|
||||
Explore how to use WebAssembly (Wasm) to embed Rust inside JavaScript.
|
||||
|
||||
![JavaScript in Vim][1]
|
||||
|
||||
In _[Why should you use Rust in WebAssembly?][2]_ , I looked at why you might want to write WebAssembly (Wasm), and why you might choose Rust as the language to do it in. Now I'll share what that looks like by exploring ways to embed Rust inside JavaScript.
|
||||
|
||||
This is something that separates Rust from Go, C#, and other languages with large runtimes that can compile to Wasm. Rust has a minimal runtime (basically just an allocator), making it easy to use Rust from JavaScript libraries. C and C++ have similar stories, but what sets Rust apart is its tooling, which we'll take a look at now.
|
||||
|
||||
### The basics
|
||||
|
||||
If you've never used Rust before, you'll first want to get that set up. It's pretty easy. First download [**Rustup**][3], which is a way to control versions of Rust and different toolchains for cross-compilation. This will give you access to [**Cargo**][4], which is the Rust build tool and package manager.
|
||||
|
||||
Now we have a decision to make. We can easily write Rust code that runs in the browser through WebAssembly, but if we want to do anything other than make people's CPU fans spin, we'll probably at some point want to interact with the Document Object Model (DOM) or use some JavaScript API. In other words: _we need JavaScript interop_ (aka the JavaScript interoperability API).
|
||||
|
||||
### The problem and the solutions
|
||||
|
||||
WebAssembly is an extremely simple machine language. If we want to be able to communicate with JavaScript, Wasm gives us only four data types to do it with: 32- and 64-bit floats and integers. Wasm doesn't have a concept of strings, arrays, objects, or any other rich data type. Basically, we can only pass around pointers between Rust and JavaScript. Needless to say, this is less than ideal.
|
||||
|
||||
The good news is there are two libraries that facilitate communication between Rust-based Wasm and JavaScript: [**wasm-bindgen**][5] and [**stdweb**][6]. The bad news, however, is these two libraries are unfortunately incompatible with each other. **wasm-bindgen** is lower-level than **stdweb** and attempts to provide full control over how JavaScript and Rust interact. In fact, there is even talk of [rewriting **stdweb** using **wasm-bindgen**][7], which would get rid of the issue of incompatibility.
|
||||
|
||||
Because **wasm-bindgen** is the lighter-weight option (and the option officially worked on by the official [Rust WebAssembly working group][8]), we'll focus at that.
|
||||
|
||||
### wasm-bindgen and wasm-pack
|
||||
|
||||
We're going to create a function that takes a string from JavaScript, makes it uppercase and prepends "HELLO, " to it, and returns it back to JavaScript. We'll call this function **excited_greeting**!
|
||||
|
||||
First, let's create our Rust library that will house this fabulous function:
|
||||
|
||||
```
|
||||
$ cargo new my-wasm-library --lib
|
||||
$ cd my-wasm-library
|
||||
```
|
||||
|
||||
Now we'll want to replace the contents of **src/lib.rs** with our exciting logic. I think it's best to write the code out instead of copy/pasting.
|
||||
|
||||
```
|
||||
// Include the `wasm_bindgen` attribute into the current namespace.
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
// This attribute makes calling Rust from JavaScript possible.
|
||||
// It generates code that can convert the basic types wasm understands
|
||||
// (integers and floats) into more complex types like strings and
|
||||
// vice versa. If you're interested in how this works, check this out:
|
||||
// <https://blog.ryanlevick.com/posts/wasm-bindgen-interop/>
|
||||
#[wasm_bindgen]
|
||||
// This is pretty plain Rust code. If you've written Rust before this
|
||||
// should look extremely familiar. If not, why wait?! Check this out:
|
||||
// <https://doc.rust-lang.org/book/>
|
||||
pub fn excited_greeting(original: &str) -> String {
|
||||
format!("HELLO, {}", original.to_uppercase())
|
||||
}
|
||||
```
|
||||
|
||||
Second, we'll have to make two changes to our **Cargo.toml** configuration file:
|
||||
|
||||
* Add **wasm_bindgen** as a dependency.
|
||||
* Configure the type of library binary to be a **cdylib** or dynamic system library. In this case, our system is **wasm** , and setting this option is how we produce **.wasm** binary files.
|
||||
|
||||
|
||||
```
|
||||
[package]
|
||||
name = "my-wasm-library"
|
||||
version = "0.1.0"
|
||||
authors = ["$YOUR_INFO"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.33"
|
||||
```
|
||||
|
||||
Now let's build! If we just use **cargo build** , we'll get a **.wasm** binary, but in order to make it easy to call our Rust code from JavaScript, we'd like to have some JavaScript code that converts rich JavaScript types like strings and objects to pointers and passes these pointers to the Wasm module on our behalf. Doing this manually is tedious and prone to bugs.
|
||||
|
||||
Luckily, in addition to being a library, **wasm-bindgen** also has the ability to create this "glue" JavaScript for us. This means in our code we can interact with our Wasm module using normal JavaScript types, and the generated code from **wasm-bindgen** will do the dirty work of converting these rich types into the pointer types that Wasm actually understands.
|
||||
|
||||
We can use the awesome **wasm-pack** to build our Wasm binary, invoke the **wasm-bindgen** CLI tool, and package all of our JavaScript (and any optional generated TypeScript types) into one nice and neat package. Let's do that now!
|
||||
|
||||
First we'll need to install **wasm-pack** :
|
||||
|
||||
```
|
||||
$ cargo install wasm-pack
|
||||
```
|
||||
|
||||
By default, **wasm-bindgen** produces ES6 modules. We'll use our code from a simple script tag, so we just want it to produce a plain old JavaScript object that gives us access to our Wasm functions. To do this, we'll pass it the **\--target no-modules** option.
|
||||
|
||||
```
|
||||
$ wasm-pack build --target no-modules
|
||||
```
|
||||
|
||||
We now have a **pkg** directory in our project. If we look at the contents, we'll see the following:
|
||||
|
||||
* **package.json** : useful if we want to package this up as an NPM module
|
||||
* **my_wasm_library_bg.wasm** : our actual Wasm code
|
||||
* **my_wasm_library.js** : the JavaScript "glue" code
|
||||
* Some TypeScript definition files
|
||||
|
||||
|
||||
|
||||
Now we can create an **index.html** file that will make use of our JavaScript and Wasm:
|
||||
|
||||
```
|
||||
<[html][9]>
|
||||
<[head][10]>
|
||||
<[meta][11] content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
||||
</[head][10]>
|
||||
<[body][12]>
|
||||
<!-- Include our glue code -->
|
||||
<[script][13] src='./pkg/my_wasm_library.js'></[script][13]>
|
||||
<!-- Include our glue code -->
|
||||
<[script][13]>
|
||||
window.addEventListener('load', async () => {
|
||||
// Load the wasm file
|
||||
await wasm_bindgen('./pkg/my_wasm_library_bg.wasm');
|
||||
// Once it's loaded the `wasm_bindgen` object is populated
|
||||
// with the functions defined in our Rust code
|
||||
const greeting = wasm_bindgen.excited_greeting("Ryan")
|
||||
console.log(greeting)
|
||||
});
|
||||
</[script][13]>
|
||||
</[body][12]>
|
||||
</[html][9]>
|
||||
```
|
||||
|
||||
You may be tempted to open the HTML file in your browser, but unfortunately, this is not possible. For security reasons, Wasm files have to be served from the same domain as the HTML file. You'll need an HTTP server. If you have a favorite static HTTP server that can serve files from your filesystem, feel free to use that. I like to use [**basic-http-server**][14], which you can install and run like so:
|
||||
|
||||
```
|
||||
$ cargo install basic-http-server
|
||||
$ basic-http-server
|
||||
```
|
||||
|
||||
Now open the **index.html** file through the web server by going to **<http://localhost:4000/index.html>** and check your JavaScript console. You should see a very exciting greeting there!
|
||||
|
||||
If you have any questions, please [let me know][15]. Next time, we'll take a look at how we can use various browser and JavaScript APIs from within our Rust code.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/calling-rust-javascript
|
||||
|
||||
作者:[Ryan Levick][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/ryanlevick
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/javascript_vim.jpg?itok=mqkAeakO (JavaScript in Vim)
|
||||
[2]: https://opensource.com/article/19/2/why-use-rust-webassembly
|
||||
[3]: https://rustup.rs/
|
||||
[4]: https://doc.rust-lang.org/cargo/
|
||||
[5]: https://github.com/rustwasm/wasm-bindgen
|
||||
[6]: https://github.com/koute/stdweb
|
||||
[7]: https://github.com/koute/stdweb/issues/318
|
||||
[8]: https://www.rust-lang.org/governance/wgs/wasm
|
||||
[9]: http://december.com/html/4/element/html.html
|
||||
[10]: http://december.com/html/4/element/head.html
|
||||
[11]: http://december.com/html/4/element/meta.html
|
||||
[12]: http://december.com/html/4/element/body.html
|
||||
[13]: http://december.com/html/4/element/script.html
|
||||
[14]: https://github.com/brson/basic-http-server
|
||||
[15]: https://twitter.com/ryan_levick
|
107
sources/tech/20190318 How to host your own webfonts.md
Normal file
107
sources/tech/20190318 How to host your own webfonts.md
Normal file
@ -0,0 +1,107 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to host your own webfonts)
|
||||
[#]: via: (https://opensource.com/article/19/3/webfonts)
|
||||
[#]: author: (Seth Kenlon (Red Hat, Community Moderator) https://opensource.com/users/seth)
|
||||
|
||||
How to host your own webfonts
|
||||
======
|
||||
|
||||
### Customize your website by self-hosting openly licensed fonts.
|
||||
|
||||
![Open source fonts][1]
|
||||
|
||||
Fonts are often a mystery to many computer users. For example, have you designed a cool flyer and, when you take the file somewhere for printing, find all the titles rendered in Arial because the printer doesn't have the fancy font you used in your design? There are ways to prevent this, of course: you can convert words in special fonts into paths, bundle fonts into a PDF, bundle open source fonts with your design files, or—at least—list the fonts required. And yet it's still a problem because we're human and we're forgetful.
|
||||
|
||||
The web has the same sort of problem. If you have even a basic understanding of CSS, you've probably seen this kind of declaration:
|
||||
|
||||
```
|
||||
h1 { font-family: "Times New Roman", Times, serif; }
|
||||
```
|
||||
|
||||
This is a designer's attempt to define a specific font, provide a fallback if a user doesn't have Times New Roman installed, and offer yet another fallback if the user doesn't have Times either. It's better than using a graphic instead of text, but it's still an awkward, inelegant method of font non-management, However, in the early-ish days of the web, it's all we had to work with.
|
||||
|
||||
### Webfonts
|
||||
|
||||
Then webfonts happened, moving font management from the client to the server. Fonts on websites were rendered for the client by the server, rather than requiring the web browser to find a font on the user's system. Google and other providers even host openly licensed fonts, which designers can include on their sites with a simple CSS rule.
|
||||
|
||||
The problem with this free convenience, of course, is that it doesn't come without cost. It's $0 to use, but major sites like Google love to keep track of who references their data, fonts included. If you don't see a need to assist Google in building a record of everyone's activity on the web, the good news is you can host your own webfonts, and it's as simple as uploading fonts to your host and using one easy CSS rule. As a side benefit, your site may load faster, as you'll be making one fewer external call upon loading each page.
|
||||
|
||||
### Self-hosted webfonts
|
||||
|
||||
The first thing you need is an openly licensed font. This can be confusing if you're not used to thinking or caring about obscure software licenses, especially since it seems like all fonts are free. Very few of us have consciously paid for a font, and yet most people have high-priced fonts on their computers. Thanks to licensing deals, your computer may have shipped with fonts that [you aren't legally allowed to copy and redistribute][2]. Fonts like Arial, Verdana, Calibri, Georgia, Impact, Lucida and Lucida Grande, Times and Times New Roman, Trebuchet, Geneva, and many others are owned by Microsoft, Apple, and Adobe. If you purchased a computer preloaded with Windows or MacOS, you paid for the right to use the bundled fonts, but you don't own those fonts and are not permitted to upload them to a web server (unless otherwise stated).
|
||||
|
||||
Fortunately, the open source craze hit the font world long ago, and there are excellent collections of openly licensed fonts from collectives and projects like [The League of Moveable Type][3], [Font Library][4], [Omnibus Type][5], and even [Google][6] and [Adobe][7].
|
||||
|
||||
You can use most common font file formats, including TTF, OTF, WOFF, EOT, and so on. Since Sorts Mill Goudy includes a WOFF (Web Open Font Format, developed in part by Mozilla) version, I'll use it in this example. However, other formats work the same way.
|
||||
|
||||
Assuming you want to use [Sorts Mill Goudy][8] on your web page:
|
||||
|
||||
1. Upload the **GoudyStM-webfont.woff** file to your web server:
|
||||
|
||||
```
|
||||
scp GoudyStM-webfont.woff seth@example.com:~/www/fonts/
|
||||
```
|
||||
|
||||
Your host may also provide a graphical upload tool through cPanel or a similar web control panel.
|
||||
|
||||
|
||||
|
||||
2. In your site's CSS file, add an **@font-face** rule, similar to this:
|
||||
|
||||
|
||||
```
|
||||
@font-face {
|
||||
font-family: "titlefont";
|
||||
src: url("../fonts/GoudyStM-webfont.woff");
|
||||
}
|
||||
```
|
||||
|
||||
The **font-family** value is something you make up. It's a human-friendly name for whatever the font face represents. I am using "titlefont" in this example because I imagine this font will be used for the main titles on an imaginary site. You could just as easily use "officialfont" or "myfont."
|
||||
|
||||
The **src** value is the path to the font file. The path to the font must be appropriate for your server's file structure; in this example, I have the **fonts** directory alongside a **css** directory. You may not have your site structured that way, so adjust the paths as needed, remembering that a single dot means _this folder_ and two dots mean _a folder back_.
|
||||
|
||||
|
||||
|
||||
3. Now that you've defined the font face name and the location, you can call it for any given CSS class or ID you desire. For example, if you want **< h1>** to render in the Sorts Mill Goudy font, then make its CSS rule use your custom font name:
|
||||
|
||||
```
|
||||
h1 { font-family: "titlefont", serif; }
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
You're now hosting and using your own fonts.
|
||||
|
||||
|
||||
![Web fonts on a website][10]
|
||||
|
||||
_Thanks to Alexandra Kanik for teaching me about @font-face and most everything else I know about good web design._
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/19/3/webfonts
|
||||
|
||||
作者:[Seth Kenlon (Red Hat, Community Moderator)][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/life_typography_fonts.png?itok=Q1jMys5G (Open source fonts)
|
||||
[2]: https://docs.microsoft.com/en-us/typography/fonts/font-faq
|
||||
[3]: https://www.theleagueofmoveabletype.com/
|
||||
[4]: https://fontlibrary.org/
|
||||
[5]: https://www.omnibus-type.com
|
||||
[6]: https://github.com/googlefonts
|
||||
[7]: https://github.com/adobe-fonts
|
||||
[8]: https://www.theleagueofmoveabletype.com/sorts-mill-goudy
|
||||
[9]: /file/426056
|
||||
[10]: https://opensource.com/sites/default/files/uploads/webfont.jpg (Web fonts on a website)
|
@ -0,0 +1,266 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Install MEAN.JS Stack In Ubuntu 18.04 LTS)
|
||||
[#]: via: (https://www.ostechnix.com/install-mean-js-stack-ubuntu/)
|
||||
[#]: author: (sk https://www.ostechnix.com/author/sk/)
|
||||
|
||||
Install MEAN.JS Stack In Ubuntu 18.04 LTS
|
||||
======
|
||||
|
||||
![Install MEAN.JS Stack][1]
|
||||
|
||||
**MEAN.JS** is an Open-Source, full-Stack JavaScript solution for building fast, and robust web applications. **MEAN.JS** stack consists of **MongoDB** (NoSQL database), **ExpressJs** (NodeJS server-side application web framework), **AngularJS** (Client-side web application framework), and **Node.js** (JavaScript run-time, popular for being a web server platform). In this tutorial, we will be discussing how to install MEAN.JS stack in Ubuntu. This guide was tested in Ubuntu 18.04 LTS server. However, it should work on other Ubuntu versions and Ubuntu variants.
|
||||
|
||||
### Install MongoDB
|
||||
|
||||
**MongoDB** is a free, cross-platform, open source, NoSQL document-oriented database. To install MongoDB on your Ubuntu system, refer the following guide:
|
||||
|
||||
* [**Install MongoDB Community Edition In Linux**][2]
|
||||
|
||||
|
||||
|
||||
### Install Node.js
|
||||
|
||||
**NodeJS** is an open source, cross-platform, and lightweight JavaScript run-time environment that can be used to build scalable network applications.
|
||||
|
||||
To install NodeJS on your system, refer the following guide:
|
||||
|
||||
* [**How To Install NodeJS On Linux**][3]
|
||||
|
||||
|
||||
|
||||
After installing, MongoDB, and Node.js, we need to install the other required components such as **Yarn** , **Grunt** , and **Gulp** for MEAN.js stack.
|
||||
|
||||
### Install Yarn package manager
|
||||
|
||||
Yarn is a package manager used by MEAN.JS stack to manage front-end packages.
|
||||
|
||||
To install Bower, run the following command:
|
||||
|
||||
```
|
||||
$ npm install -g yarn
|
||||
```
|
||||
|
||||
### Install Grunt Task Runner
|
||||
|
||||
Grunt Task Runner is used to to automate the development process.
|
||||
|
||||
To install Grunt, run:
|
||||
|
||||
```
|
||||
$ npm install -g grunt-cli
|
||||
```
|
||||
|
||||
To verify if Yarn and Grunt have been installed, run:
|
||||
|
||||
```
|
||||
$ npm list -g --depth=0 /home/sk/.nvm/versions/node/v11.11.0/lib ├── [email protected] ├── [email protected] └── [email protected]
|
||||
```
|
||||
|
||||
### Install Gulp Task Runner (Optional)
|
||||
|
||||
This is optional. You can use Gulp instead of Grunt. To install Gulp Task Runner, run the following command:
|
||||
|
||||
```
|
||||
$ npm install -g gulp
|
||||
```
|
||||
|
||||
We have installed all required prerequisites. Now, let us deploy MEAN.JS stack.
|
||||
|
||||
### Download and Install MEAN.JS Stack
|
||||
|
||||
Install Git if it is not installed already:
|
||||
|
||||
```
|
||||
$ sudo apt-get install git
|
||||
```
|
||||
|
||||
Next, git clone the MEAN.JS repository with command:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/meanjs/mean.git meanjs
|
||||
```
|
||||
|
||||
**Sample output:**
|
||||
|
||||
```
|
||||
Cloning into 'meanjs'...
|
||||
remote: Counting objects: 8596, done.
|
||||
remote: Compressing objects: 100% (12/12), done.
|
||||
remote: Total 8596 (delta 3), reused 0 (delta 0), pack-reused 8584 Receiving objects: 100% (8596/8596), 2.62 MiB | 140.00 KiB/s, done.
|
||||
Resolving deltas: 100% (4322/4322), done.
|
||||
Checking connectivity... done.
|
||||
```
|
||||
|
||||
The above command will clone the latest version of the MEAN.JS repository to **meanjs** folder in your current working directory.
|
||||
|
||||
Go to the meanjs folder:
|
||||
|
||||
```
|
||||
$ cd meanjs/
|
||||
```
|
||||
|
||||
Run the following command to install the Node.js dependencies required for testing and running our application:
|
||||
|
||||
```
|
||||
$ npm install
|
||||
```
|
||||
|
||||
This will take some time. Please be patient.
|
||||
|
||||
* * *
|
||||
|
||||
**Troubleshooting:**
|
||||
|
||||
When I run the above command in Ubuntu 18.04 LTS, I get the following error:
|
||||
|
||||
```
|
||||
Downloading binary from https://github.com/sass/node-sass/releases/download/v4.5.3/linux-x64-67_binding.node
|
||||
Cannot download "https://github.com/sass/node-sass/releases/download/v4.5.3/linux-x64-67_binding.node":
|
||||
|
||||
HTTP error 404 Not Found
|
||||
|
||||
[....]
|
||||
```
|
||||
|
||||
If you ever get these type of common errors like “node-sass and gulp-sass”, do the following:
|
||||
|
||||
First uninstall the project and global gulp-sass modules using the following commands:
|
||||
|
||||
```
|
||||
$ npm uninstall gulp-sass
|
||||
$ npm uninstall -g gulp-sass
|
||||
```
|
||||
|
||||
Next uninstall the global node-sass module:
|
||||
|
||||
```
|
||||
$ npm uninstall -g node-sass
|
||||
```
|
||||
|
||||
Install the global node-sass first. Then install the gulp-sass module at the local project level.
|
||||
|
||||
```
|
||||
$ npm install -g node-sass
|
||||
$ npm install gulp-sass
|
||||
```
|
||||
|
||||
Now try the npm install again from the project folder using command:
|
||||
|
||||
```
|
||||
$ npm install
|
||||
```
|
||||
|
||||
Now all dependencies will start to install without any issues.
|
||||
|
||||
* * *
|
||||
|
||||
Once all dependencies are installed, run the following command to install all the front-end modules needed for the application:
|
||||
|
||||
```
|
||||
$ yarn --allow-root --config.interactive=false install
|
||||
```
|
||||
|
||||
Or,
|
||||
|
||||
```
|
||||
$ yarn --allow-root install
|
||||
```
|
||||
|
||||
You will see the following message at the end if the installation is successful.
|
||||
|
||||
```
|
||||
[...]
|
||||
> meanjs@0.6.0 snyk-protect /home/sk/meanjs
|
||||
> snyk protect
|
||||
|
||||
Successfully applied Snyk patches
|
||||
|
||||
Done in 99.47s.
|
||||
```
|
||||
|
||||
### Test MEAN.JS
|
||||
|
||||
MEAN.JS stack has been installed. We can now able to start a sample application using command:
|
||||
|
||||
```
|
||||
$ npm start
|
||||
```
|
||||
|
||||
After a few seconds, you will see a message like below. This means MEAN.JS stack is working!
|
||||
|
||||
```
|
||||
[...]
|
||||
MEAN.JS - Development Environment
|
||||
|
||||
Environment: development
|
||||
Server: http://0.0.0.0:3000
|
||||
Database: mongodb://localhost/mean-dev
|
||||
App version: 0.6.0
|
||||
MEAN.JS version: 0.6.0
|
||||
```
|
||||
|
||||
![][4]
|
||||
|
||||
To verify, open up the browser and navigate to **<http://localhost:3000>** or **<http://IP-Address:3000/>**. You should see a screen something like below.
|
||||
|
||||
![][5]
|
||||
|
||||
Mean stack test page
|
||||
|
||||
Congratulations! MEAN.JS stack is ready to start building web applications.
|
||||
|
||||
For further details, I recommend you to refer **[MEAN.JS stack official documentation][6]**.
|
||||
|
||||
* * *
|
||||
|
||||
Want to setup MEAN.JS stack in CentOS, RHEL, Scientific Linux? Check the following link for more details.
|
||||
|
||||
* **[Install MEAN.JS Stack in CentOS 7][7]**
|
||||
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
And, that’s all for now, folks. Hope this tutorial will help you to setup MEAN.JS stack.
|
||||
|
||||
If you find this tutorial useful, please share it on your social, professional networks and support OSTechNix.
|
||||
|
||||
More good stuffs to come. Stay tuned!
|
||||
|
||||
Cheers!
|
||||
|
||||
**Resources:**
|
||||
|
||||
* **[MEAN.JS website][8]**
|
||||
* [**MEAN.JS GitHub Repository**][9]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/install-mean-js-stack-ubuntu/
|
||||
|
||||
作者:[sk][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/sk/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[2]: https://www.ostechnix.com/install-mongodb-linux/
|
||||
[3]: https://www.ostechnix.com/install-node-js-linux/
|
||||
[4]: http://www.ostechnix.com/wp-content/uploads/2016/03/meanjs.png
|
||||
[5]: http://www.ostechnix.com/wp-content/uploads/2016/03/mean-stack-test-page.png
|
||||
[6]: http://meanjs.org/docs.html
|
||||
[7]: http://www.ostechnix.com/install-mean-js-stack-centos-7/
|
||||
[8]: http://meanjs.org/
|
||||
[9]: https://github.com/meanjs/mean
|
@ -0,0 +1,108 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Solus 4 ‘Fortitude’ Released with Significant Improvements)
|
||||
[#]: via: (https://itsfoss.com/solus-4-release)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
Solus 4 ‘Fortitude’ Released with Significant Improvements
|
||||
======
|
||||
|
||||
Finally, after a year of work, the much anticipated Solus 4 is here. It’s a significant release not just because this is a major upgrade, but also because this is the first major release after [Ikey Doherty (the founder of Solus) left the project][1] a few months ago.
|
||||
|
||||
Now that everything’s under control with the new _management_ , **Solus 4 Fortitude** with updated Budgie desktop and other significant improvements has officially released.
|
||||
|
||||
### What’s New in Solus 4
|
||||
|
||||
![Solus 4 Fortitude][2]
|
||||
|
||||
#### Core Improvements
|
||||
|
||||
Solus 4 comes loaded with **[Linux Kernel 4.20.16][3]** which enables better hardware support (like Touchpad support, improved support for Intel Coffee Lake and Ice Lake CPUs, and for AMD Picasso & Raven2 APUs).
|
||||
|
||||
This release also ships with the latest [FFmpeg 4.1.1][4]. Also, they have enabled the support for [dav1d][5] in [VLC][6] – which is an open source AV1 decoder. So, you can consider these upgrades to significantly improve the Multimedia experience.
|
||||
|
||||
It also includes some minor fixes to the Software Center – if you were encountering any issues while finding an application or viewing the description.
|
||||
|
||||
In addition, WPS Office has been removed from the listing.
|
||||
|
||||
#### UI Improvements
|
||||
|
||||
![Budgie 10.5][7]
|
||||
|
||||
The Budgie desktop update includes some minor changes and also comes baked in with the [Plata (Noir) GTK Theme.][8]
|
||||
|
||||
You will no longer observe same applications multiple times in the menu, they’ve fixed this. They have also introduced a “ **Caffeine** ” mode as applet which prevents the system from suspending, locking the screen or changing the brightness while you are working. You can schedule the time accordingly.
|
||||
|
||||
![Caffeine Mode][9]
|
||||
|
||||
The new Budgie desktop experience also adds quick actions to the app icons on the task bar, dubbed as “ **Icon Tasklist** “. It makes it easy to manage the active tabs on a browser or the actions to minimize and move it to a new workplace (as shown in the image below).
|
||||
|
||||
![Icon Tasklist][10]
|
||||
|
||||
As the [change log][11] mentions, the above pop over design lets you do more:
|
||||
|
||||
* _Close all instances of the selected application_
|
||||
* _Easily access per-window controls for marking it always on top, maximizing / unmaximizing, minimizing, and moving it to various workspaces._
|
||||
* _Quickly favorite / unfavorite apps_
|
||||
* _Quickly launch a new instance of the selected application_
|
||||
* _Scroll up or down on an IconTasklist button when a single window is open to activate and bring it into focus, or minimize it, based on the scroll direction._
|
||||
* _Toggle to minimize and unminimize various application windows_
|
||||
|
||||
|
||||
|
||||
The notification area now groups the notifications from specific applications instead of piling it all up. So, that’s a good improvement.
|
||||
|
||||
In addition to these, the sound widget got some cool improvements while letting you personalize the look and feel of your desktop in an efficient manner.
|
||||
|
||||
To know about all the nitty-gritty details, do refer the official [release note][11]s.
|
||||
|
||||
### Download Solus 4
|
||||
|
||||
You can get the latest version of Solus from its download page below. It is available in the default Budgie, GNOME and MATE desktop flavors.
|
||||
|
||||
[Get Solus 4][12]
|
||||
|
||||
### Wrapping Up**
|
||||
|
||||
Solus 4 is definitely an impressive upgrade – without introducing any unnecessary fancy features but by adding only the useful ones, subtle changes.
|
||||
|
||||
What do you think about the latest Solus 4 Fortitude? Have you tried it yet?
|
||||
|
||||
Let us know your thoughts in the comments below.
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/solus-4-release
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://itsfoss.com/ikey-leaves-solus/
|
||||
[2]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/solus-4-featured.jpg?fit=800%2C450&ssl=1
|
||||
[3]: https://itsfoss.com/kernel-4-20-release/
|
||||
[4]: https://www.ffmpeg.org/
|
||||
[5]: https://code.videolan.org/videolan/dav1d
|
||||
[6]: https://www.videolan.org/index.html
|
||||
[7]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/Budgie-desktop.jpg?resize=800%2C450&ssl=1
|
||||
[8]: https://gitlab.com/tista500/plata-theme
|
||||
[9]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/03/caffeine-mode.jpg?ssl=1
|
||||
[10]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/IconTasklistPopover.jpg?ssl=1
|
||||
[11]: https://getsol.us/2019/03/17/solus-4-released/
|
||||
[12]: https://getsol.us/download/
|
||||
[13]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/03/Budgie-desktop.jpg?fit=800%2C450&ssl=1
|
||||
[14]: https://www.facebook.com/sharer.php?t=Solus%204%20%E2%80%98Fortitude%E2%80%99%20Released%20with%20Significant%20Improvements&u=https%3A%2F%2Fitsfoss.com%2Fsolus-4-release%2F
|
||||
[15]: https://twitter.com/intent/tweet?text=Solus+4+%E2%80%98Fortitude%E2%80%99+Released+with+Significant+Improvements&url=https%3A%2F%2Fitsfoss.com%2Fsolus-4-release%2F&via=itsfoss2
|
||||
[16]: https://www.linkedin.com/shareArticle?title=Solus%204%20%E2%80%98Fortitude%E2%80%99%20Released%20with%20Significant%20Improvements&url=https%3A%2F%2Fitsfoss.com%2Fsolus-4-release%2F&mini=true
|
||||
[17]: https://www.reddit.com/submit?title=Solus%204%20%E2%80%98Fortitude%E2%80%99%20Released%20with%20Significant%20Improvements&url=https%3A%2F%2Fitsfoss.com%2Fsolus-4-release%2F
|
@ -0,0 +1,50 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Blockchain 2.0: Blockchain In Real Estate [Part 4])
|
||||
[#]: via: (https://www.ostechnix.com/blockchain-2-0-blockchain-in-real-estate/)
|
||||
[#]: author: (EDITOR https://www.ostechnix.com/author/editor/)
|
||||
|
||||
Blockchain 2.0: Blockchain In Real Estate [Part 4]
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2019/03/Blockchain-In-Real-Estate-720x340.png)
|
||||
|
||||
### Blockchain 2.0: Smart‘er’ Real Estate
|
||||
|
||||
The [**previous article**][1] of this series explored the features of blockchain which will enable institutions to transform and interlace **traditional banking** and **financing systems** with it. This part will explore – **Blockchain in real estate**. The real estate industry is ripe for a revolution. It’s among the most actively traded most significant asset classes known to man. However, filled with regulatory hurdles and numerous possibilities of fraud and deceit, it’s also one of the toughest to participate in. The distributed ledger capabilities of the blockchain utilizing an appropriate consensus algorithm are touted as the way forward for the industry which is traditionally regarded as conservative in its attitude to change.
|
||||
|
||||
Real estate has always been a very conservative industry in terms of its myriad operations. Somewhat rightfully so as well. A major economic crisis such as the 2008 financial crisis or the great depression from the early half of the 20th century managed to destroy the industry and its participants. However, like most products of economic value, the real estate industry is resilient and this resilience is rooted in its conservative nature.
|
||||
|
||||
The global real estate market comprises an asset class worth **$228 trillion dollars** [1]. Give or take. Other investment assets such as stocks, bonds, and shares combined are only worth **$170 trillion**. Obviously, any and all transactions implemented in such an industry is naturally carefully planned and meticulously executed, for the most part. For the most part, because real estate is also notorious for numerous instances of fraud and devastating loses which ensue them. The industry because of the very conservative nature of its operations is also tough to navigate. It’s heavily regulated with complex laws creating an intertwined web of nuances that are just too difficult for an average person to understand fully. This makes entry and participation near impossible for most people. If you’ve ever been involved in one such deal, you’ll know how heavy and long the paper trail was.
|
||||
|
||||
This hard reality is now set to change, albeit a slow and gradual transformation. The very reasons the industry has stuck to its hardy tested roots all this while can finally give way to its modern-day counterpart. The backbone of the real estate industry has always been its paper records. Land deeds, titles, agreements, rental insurance, proofs, and declarations etc., are just the tip of the iceberg here. If you’ve noticed the pattern here, this should be obvious, the distributed ledger technology that is blockchain, fits in perfectly with the needs here. Forget paper records, conventional database systems are also points of major failure. They can be modified by multiple participants, is not tamper proof or un-hackable, has a complicated set of ever-changing regulatory parameters making auditing and verifying data a nightmare. The blockchain perfectly solves all of these issues and more.
|
||||
|
||||
Starting with a trivial albeit an important example to show just how bad the current record management practices are in the real estate sector, consider the **Title Insurance business** [2], [3]. Title Insurance is used to hedge against the possibility of the land’s titles and ownership records being inadmissible and hence unenforceable. An insurance product such as this is also referred to as an indemnity cover. It is by law required in many cases that properties have title insurance, especially when dealing with property that has changed hands multiple times over the years. Mortgage firms might insist on the same as well when they back real estate deals. The fact that a product of this kind has existed since the 1850s and that it does business worth at least **$1.5 trillion a year in the US alone** is a testament to the statement at the start. A revolution in terms of how these records are maintained is imperative to have in this situation and the blockchain provides a sustainable solution. Title fraud averages around $100k per case on average as per the **American Land Title Association** and 25% of all titles involved in transactions have an issue regarding their documents[4]. The blockchain allows for setting up an immutable permanent database that will track the property itself, recording each and every transaction or investment that has gone into it. Such a ledger system will make life easier for everyone involved in the real estate industry including one-time home buyers and make financial products such as Title Insurance basically irrelevant. Converting a physical asset such as real estate to a digital asset like this is unconventional and is extant only in theory at the moment. However, such a change is imminent sooner rather than later[5].
|
||||
|
||||
Among the areas in which blockchain will have the most impact within real estate is as highlighted above in maintaining a transparent and secure title management system for properties. A blockchain based record of the property can contain information about the property, its location, history of ownership, and any related public record of the same[6]. This will permit closing real estate deals fast and obliviates the need for 3rd party monitoring and oversight. Tasks such as real estate appraisal and tax calculations become matters of tangible objective parameters rather than subjective measures and guesses because of reliable historical data which is publicly verifiable. **UBITQUITY** is one such platform that offers customized blockchain-based solutions to enterprise customers. The platform allows customers to keep track of all property details, payment records, mortgage records and even allows running smart contracts that’ll take care of taxation and leasing automatically[7].
|
||||
|
||||
This brings us to the second biggest opportunity and use case of blockchains in real estate. Since the sector is highly regulated by numerous 3rd parties apart from the counterparties involved in the trade, due-diligence and financial evaluations can be significantly time-consuming. These processes are predominantly carried out using offline channels and paperwork needs to travel for days before a final evaluation report comes out. This is especially true for corporate real estate deals and forms a bulk of the total billable hours charged by consultants. In case the transaction is backed by a mortgage, duplication of these processes is unavoidable. Once combined with digital identities for the people and institutions involved along with the property, the current inefficiencies can be avoided altogether and transactions can take place in a matter of seconds. The tenants, investors, institutions involved, consultants etc., could individually validate the data and arrive at a critical consensus thereby validating the property records for perpetuity[8]. This increases the accuracy of verification manifold. Real estate giant **RE/MAX** has recently announced a partnership with service provider **XYO Network Partners** for building a national database of real estate listings in Mexico. They hope to one day create one of the largest (as of yet) decentralized real estate title registry in the world[9].
|
||||
|
||||
However, another significant and arguably a very democratic change that the blockchain can bring about is with respect to investing in real estate. Unlike other investment asset classes where even small household investors can potentially participate, real estate often requires large hands-down payments to participate. Companies such as **ATLANT** and **BitOfProperty** tokenize the book value of a property and convert them into equivalents of a cryptocurrency. These tokens are then put for sale on their exchanges similar to how stocks and shares are traded. Any cash flow that the real estate property generates afterward is credited or debited to the token owners depending on their “share” in the property[4].
|
||||
|
||||
However, even with all of that said, Blockchain technology is still in very early stages of adoption in the real estate sector and current regulations are not exactly defined for it to be either[8]. Concepts such as distributed applications, distributed anonymous organizations, smart contracts etc., are unheard of in the legal domain in many countries. A complete overhaul of existing regulations and guidelines once all the stakeholders are well educated on the intricacies of the blockchain is the most pragmatic way forward. Again, it’ll be a slow and gradual change to go through, however a much-needed one nonetheless. The next article of the series will look at how **“Smart Contracts”** , such as those implemented by companies such as UBITQUITY and XYO are created and executed in the blockchain.
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/blockchain-2-0-blockchain-in-real-estate/
|
||||
|
||||
作者:[EDITOR][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.ostechnix.com/author/editor/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.ostechnix.com/blockchain-2-0-redefining-financial-services/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user