diff --git a/.gitignore b/.gitignore index 7b56441580..b5bb51a97a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ members.md *.html *.bak .DS_Store +sources/*/.* +translated/*/.* \ No newline at end of file diff --git a/published/20141127 Keeping (financial) score with Ledger .md b/published/20141127 Keeping (financial) score with Ledger .md new file mode 100644 index 0000000000..2bcecd2174 --- /dev/null +++ b/published/20141127 Keeping (financial) score with Ledger .md @@ -0,0 +1,75 @@ +使用 Ledger 记录(财务)情况 +====== + +自 2005 年搬到加拿大以来,我使用 [Ledger CLI][1] 来跟踪我的财务状况。我喜欢纯文本的方式,它支持虚拟信封意味着我可以同时将我的银行帐户余额和我的虚拟分配到不同的目录下。以下是我们如何使用这些虚拟信封分别管理我们的财务状况。 + +每个月,我都有一个条目将我生活开支分配到不同的目录中,包括家庭开支的分配。W- 不要求太多, 所以我要谨慎地处理这两者之间的差别和我自己的生活费用。我们处理它的方式是我支付固定金额,这是贷记我支付的杂货。由于我们的杂货总额通常低于我预算的家庭开支,因此任何差异都会留在标签上。我过去常常给他写支票,但最近我只是支付偶尔额外的大笔费用。 + +这是个示例信封分配: + +``` +2014.10.01 * Budget + [Envelopes:Living] + [Envelopes:Household] $500 + ;; More lines go here +``` + +这是设置的信封规则之一。它鼓励我正确地分类支出。所有支出都从我的 “Play” 信封中取出。 + +``` += /^Expenses/ + (Envelopes:Play) -1.0 +``` + +这个为家庭支出报销 “Play” 信封,将金额从 “Household” 信封转移到 “Play” 信封。 + +``` += /^Expenses:House$/ + (Envelopes:Play) 1.0 + (Envelopes:Household) -1.0 +``` + +我有一套定期的支出来模拟我的预算中的家庭开支。例如,这是 10 月份的。 + +``` +2014.10.1 * House + Expenses:House + Assets:Household $-500 +``` + +这是杂货交易的形式: + +``` +2014.09.28 * No Frills + Assets:Household:Groceries $70.45 + Liabilities:MBNA:September $-70.45 + +``` + +接着 `ledger bal Assets:Household` 就会告诉我是否欠他钱(负余额)。如果我支付大笔费用(例如:机票、通管道),那么正常家庭开支预算会逐渐减少余额。 + +我从 W- 那找到了一个为我的信用卡交易添加一个月标签的技巧,他还使用 Ledger 跟踪他的交易。它允许我再次检查条目的余额,看看前一个条目是否已被正确清除。 + +这个资产分类使用有点奇怪,但它在精神上对我有用。 + +使用 Ledger 以这种方式跟踪它可以让我跟踪我们的杂货费用以及我实际支付费用和我预算费用之间的差额。如果我最终支出超出预期,我可以从更多可自由支配的信封中移动虚拟货币,因此我的预算始终保持平衡。 + +Ledger 是一个强大的工具。相当极客,但也许更多的工作流描述可能会帮助那些正在搞清楚它的人! + +-------------------------------------------------------------------------------- + +via: http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/ + +作者:[Sacha Chua][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://sachachua.com +[1]:http://www.ledger-cli.org/ +[2]:http://sachachua.com/blog/category/finance/ +[3]:http://sachachua.com/blog/tag/ledger/ +[4]:http://pages.sachachua.com/sharing/blog.html?url=http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/ +[5]:http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/#comments diff --git a/published/201703/20170223 How to install Arch Linux on VirtualBox.md b/published/201703/20170223 How to install Arch Linux on VirtualBox.md index 58a094b048..cdd68a0642 100644 --- a/published/201703/20170223 How to install Arch Linux on VirtualBox.md +++ b/published/201703/20170223 How to install Arch Linux on VirtualBox.md @@ -104,10 +104,10 @@ Arch Linux 也因其丰富的 Wiki 帮助文档而大受推崇。该系统基于 ][23] 输入下面的命令来检查网络连接。 - + ``` ping google.com -``` +``` 这个单词 ping 表示网路封包搜寻。你将会看到下面的返回信息,表明 Arch Linux 已经连接到外网了。这是执行安装过程中的很关键的一点。(LCTT 译注:或许你 ping 不到那个不存在的网站,你选个存在的吧。) @@ -117,8 +117,8 @@ ping google.com 输入如下命令清屏: -``` -clear +``` +clear ``` 在开始安装之前,你得先为硬盘分区。输入 `fdisk -l` ,你将会看到当前系统的磁盘分区情况。注意一开始你给 Arch Linux 系统分配的 20 GB 存储空间。 @@ -137,8 +137,8 @@ clear 输入下面的命令: -``` -cfdisk +``` +cfdisk ``` 你将看到 `gpt`、`dos`、`sgi` 和 `sun` 类型,选择 `dos` 选项,然后按回车。 @@ -185,8 +185,8 @@ cfdisk 以同样的方式创建逻辑分区。在“退出(quit)”选项按回车键,然后输入下面的命令来清屏: -``` -clear +``` +clear ``` [ @@ -195,21 +195,21 @@ clear 输入下面的命令来格式化新建的分区: -``` +``` mkfs.ext4 /dev/sda1 -``` +``` 这里的 `sda1` 是分区名。使用同样的命令来格式化第二个分区 `sda3` : -``` +``` mkfs.ext4 /dev/sda3 -``` +``` 格式化 swap 分区: -``` +``` mkswap /dev/sda2 -``` +``` [ ![Format the swap partition with mkswap](https://www.howtoforge.com/images/install_arch_linux_on_virtual_box/121224.png) @@ -217,14 +217,14 @@ mkswap /dev/sda2 使用下面的命令来激活 swap 分区: -``` -swapon /dev/sda2 +``` +swapon /dev/sda2 ``` 输入 clear 命令清屏: -``` -clear +``` +clear ``` [ @@ -233,9 +233,9 @@ clear 输入下面的命令来挂载主分区以开始系统安装: -``` -mount /dev/sda1 / mnt -``` +``` +mount /dev/sda1 /mnt +``` [ ![Mount the partitions](https://www.howtoforge.com/images/install_arch_linux_on_virtual_box/121226.png) @@ -245,9 +245,9 @@ mount /dev/sda1 / mnt 输入下面的命令来引导系统启动: -``` +``` pacstrap /mnt base base-devel -``` +``` 可以看到系统正在同步数据包。 @@ -263,9 +263,9 @@ pacstrap /mnt base base-devel 系统基本软件安装完成后,输入下面的命令来创建 fstab 文件: -``` +``` genfstab /mnt>> /mnt/etc/fstab -``` +``` [ ![Generating /etc/fstab](https://www.howtoforge.com/images/install_arch_linux_on_virtual_box/121229.png) @@ -275,14 +275,14 @@ genfstab /mnt>> /mnt/etc/fstab 输入下面的命令来更改系统的根目录为 Arch Linux 的安装目录: -``` +``` arch-chroot /mnt /bin/bash -``` +```  现在来更改语言配置: -``` -nano /etc/local.gen +``` +nano /etc/locale.gen ``` [ @@ -297,9 +297,9 @@ nano /etc/local.gen 输入下面的命令来激活它: -``` +``` locale-gen -``` +``` 按回车。 @@ -309,8 +309,8 @@ locale-gen 使用下面的命令来创建 `/etc/locale.conf` 配置文件: -``` -nano /etc/locale.conf +``` +nano /etc/locale.conf ``` 然后按回车。现在你就可以在配置文件中输入下面一行内容来为系统添加语言: @@ -326,9 +326,9 @@ LANG=en_US.UTF-8 ][44] 输入下面的命令来同步时区: - + ``` -ls user/share/zoneinfo +ls /usr/share/zoneinfo ``` 下面你将看到整个世界的时区列表。 @@ -339,9 +339,9 @@ ls user/share/zoneinfo 输入下面的命令来选择你所在的时区: -``` +``` ln –s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime -``` +``` 或者你可以从下面的列表中选择其它名称。 @@ -351,8 +351,8 @@ ln –s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 使用下面的命令来设置标准时间: -``` -hwclock --systohc –utc +``` +hwclock --systohc --utc ``` 硬件时钟已同步。 @@ -363,8 +363,8 @@ hwclock --systohc –utc 设置 root 帐号密码: -``` -passwd +``` +passwd ``` 按回车。 然而输入你想设置的密码,按回车确认。 @@ -377,9 +377,9 @@ passwd 使用下面的命令来设置主机名: -``` +``` nano /etc/hostname -``` +``` 然后按回车。输入你想设置的主机名称,按 `control + x` ,按 `y` ,再按回车 。 @@ -389,9 +389,9 @@ nano /etc/hostname 启用 dhcpcd : -``` +``` systemctl enable dhcpcd -``` +``` 这样在下一次系统启动时, dhcpcd 将会自动启动,并自动获取一个 IP 地址: @@ -403,9 +403,9 @@ systemctl enable dhcpcd 最后一步,输入以下命令来初始化 grub 安装。输入以下命令: -``` +``` pacman –S grub os-rober -``` +``` 然后按 `y` ,将会下载相关程序。 @@ -415,14 +415,14 @@ pacman –S grub os-rober 使用下面的命令来将启动加载程序安装到硬盘上: -``` +``` grub-install /dev/sda -``` +``` 然后进行配置: -``` -grub-mkconfig -o /boot/grub/grub.cfg +``` +grub-mkconfig -o /boot/grub/grub.cfg ``` [ @@ -431,9 +431,9 @@ grub-mkconfig -o /boot/grub/grub.cfg 最后重启系统: -``` +``` reboot -``` +``` 然后按回车 。 @@ -459,7 +459,7 @@ reboot via: https://www.howtoforge.com/tutorial/install-arch-linux-on-virtualbox/ -译者简介: +译者简介: rusking:春城初春/春水初生/春林初盛/春風十裏不如妳 diff --git a/translated/tech/20170404 Kernel Tracing with Ftrace.md b/published/20170404 Kernel Tracing with Ftrace.md similarity index 75% rename from translated/tech/20170404 Kernel Tracing with Ftrace.md rename to published/20170404 Kernel Tracing with Ftrace.md index 6ed3a87bf9..6c209d4e0d 100644 --- a/translated/tech/20170404 Kernel Tracing with Ftrace.md +++ b/published/20170404 Kernel Tracing with Ftrace.md @@ -1,49 +1,45 @@ -使用 Ftrace 跟踪内核 +使用 ftrace 跟踪内核 ============================================================ -标签: [ftrace][8],[kernel][9],[kernel profiling][10],[kernel tracing][11],[linux][12],[tracepoints][13] - ![](https://blog.selectel.com/wp-content/uploads/2017/04/PR-1801-2-2.png) -在内核级别上分析事件有很多的工具:[SystemTap][14],[ktap][15],[Sysdig][16],[LTTNG][17]等等,并且你也可以在网络上找到关于这些工具的大量介绍文章和资料。 +在内核层面上分析事件有很多的工具:[SystemTap][14]、[ktap][15]、[Sysdig][16]、[LTTNG][17] 等等,你也可以在网络上找到关于这些工具的大量介绍文章和资料。 而对于使用 Linux 原生机制去跟踪系统事件以及检索/分析故障信息的方面的资料却很少找的到。这就是 [ftrace][18],它是添加到内核中的第一款跟踪工具,今天我们来看一下它都能做什么,让我们从它的一些重要术语开始吧。 ### 内核跟踪和分析 -内核分析可以发现性能“瓶颈”。分析能够帮我们发现在一个程序中性能损失的准确位置。特定的程序生成一个概述 — 一个事件的总结 — 它能够用于帮我们找出哪个函数占用了大量的运行时间。尽管这些程序并不能识别出为什么会损失性能。 +内核分析Kernel profiling可以发现性能“瓶颈”。分析能够帮我们发现在一个程序中性能损失的准确位置。特定的程序生成一个概述profile — 这是一个事件总结 — 它能够用于帮我们找出哪个函数占用了大量的运行时间。尽管这些程序并不能识别出为什么会损失性能。 -瓶颈经常发生在无法通过分析来识别的情况下。去推断出为什么会发生事件,去保存发生事件时的相关上下文,这就需要去跟踪。 +瓶颈经常发生在无法通过分析来识别的情况下。要推断出为什么会发生事件,就必须保存发生事件时的相关上下文,这就需要去跟踪tracing。 -跟踪可以理解为在一个正常工作的系统上活动的信息收集进程。它使用特定的工具来完成这项工作,就像录音机来记录声音一样,用它来记录各种注册的系统事件。 +跟踪可以理解为在一个正常工作的系统上活动的信息收集过程。它使用特定的工具来完成这项工作,就像录音机来记录声音一样,用它来记录各种系统事件。 跟踪程序能够同时跟踪应用级和操作系统级的事件。它们收集的信息能够用于诊断多种系统问题。 有时候会将跟踪与日志比较。它们两者确时很相似,但是也有不同的地方。 -对于跟踪,记录的信息都是些低级别事件。它们的数量是成百上千的,甚至是成千上万的。对于日志,记录的信息都是些高级别事件,数量上通常少多了。这些包含用户登陆系统、应用程序错误、数据库事务等等。 +对于跟踪,记录的信息都是些低级别事件。它们的数量是成百上千的,甚至是成千上万的。对于日志,记录的信息都是些高级别事件,数量上通常少多了。这些包含用户登录系统、应用程序错误、数据库事务等等。 就像日志一样,跟踪数据可以被原样读取,但是用特定的应用程序提取的信息更有用。所有的跟踪程序都能这样做。 在内核跟踪和分析方面,Linux 内核有三个主要的机制: -* 跟踪点 —— 一种基于静态测试代码的工作机制 - -* 探针 —— 一种动态跟踪机制,用于在任意时刻中断内核代码的运行,调用它自己的处理程序,在完成需要的操作之后再返回。 - -* perf_events —— 一个访问 PMU(性能监视单元)的接口 +* 跟踪点tracepoint:一种基于静态测试代码的工作机制 +* 探针kprobe:一种动态跟踪机制,用于在任意时刻中断内核代码的运行,调用它自己的处理程序,在完成需要的操作之后再返回 +* perf_events —— 一个访问 PMU(性能监视单元Performance Monitoring Unit)的接口 我并不想在这里写关于这些机制方面的内容,任何对它们感兴趣的人可以去访问 [Brendan Gregg 的博客][19]。 使用 ftrace,我们可以与这些机制进行交互,并可以从用户空间直接得到调试信息。下面我们将讨论这方面的详细内容。示例中的所有命令行都是在内核版本为 3.13.0-24 的 Ubuntu 14.04 中运行的。 -### Ftrace:常用信息 +### ftrace:常用信息 -Ftrace 是函数 Trace 的简写,但它能做的远不止这些:它可以跟踪上下文切换、测量进程阻塞时间、计算高优先级任务的活动时间等等。 +ftrace 是 Function Trace 的简写,但它能做的远不止这些:它可以跟踪上下文切换、测量进程阻塞时间、计算高优先级任务的活动时间等等。 -Ftrace 是由 Steven Rostedt 开发的,从 2008 年发布的内核 2.6.27 中开始就内置了。这是为记录数据提供的一个调试 `Ring` 缓冲区的框架。这些数据由集成到内核中的跟踪程序来采集。 +ftrace 是由 Steven Rostedt 开发的,从 2008 年发布的内核 2.6.27 中开始就内置了。这是为记录数据提供的一个调试 Ring 缓冲区的框架。这些数据由集成到内核中的跟踪程序来采集。 -Ftrace 工作在 debugfs 文件系统上,这是在大多数现代 Linux 分发版中默认挂载的文件系统。为开始使用 ftrace,你将进入到 `sys/kernel/debug/tracing` 目录(仅对 root 用户可用): +ftrace 工作在 debugfs 文件系统上,在大多数现代 Linux 发行版中都默认挂载了。要开始使用 ftrace,你将进入到 `sys/kernel/debug/tracing` 目录(仅对 root 用户可用): ``` # cd /sys/kernel/debug/tracing @@ -70,16 +66,13 @@ kprobe_profile stack_max_size uprobe_profile 我不想去描述这些文件和子目录;它们的描述在 [官方文档][20] 中已经写的很详细了。我只想去详细介绍与我们这篇文章相关的这几个文件: * available_tracers —— 可用的跟踪程序 - * current_tracer —— 正在运行的跟踪程序 - -* tracing_on —— 负责启用或禁用数据写入到 `Ring` 缓冲区的系统文件(如果启用它,在文件中添加数字 1,禁用它,添加数字 0) - +* tracing_on —— 负责启用或禁用数据写入到 Ring 缓冲区的系统文件(如果启用它,数字 1 被添加到文件中,禁用它,数字 0 被添加) * trace —— 以人类友好格式保存跟踪数据的文件 ### 可用的跟踪程序 -我们可以使用如下的命令去查看可用的跟踪程序的一个列表 +我们可以使用如下的命令去查看可用的跟踪程序的一个列表: ``` root@andrei:/sys/kernel/debug/tracing#: cat available_tracers @@ -89,18 +82,14 @@ blk mmiotrace function_graph wakeup_rt wakeup function nop 我们来快速浏览一下每个跟踪程序的特性: * function —— 一个无需参数的函数调用跟踪程序 - * function_graph —— 一个使用子调用的函数调用跟踪程序 - -* blk —— 一个与块 I/O 跟踪相关的调用和事件跟踪程序(它是 blktrace 的用途) - +* blk —— 一个与块 I/O 跟踪相关的调用和事件跟踪程序(它是 blktrace 使用的) * mmiotrace —— 一个内存映射 I/O 操作跟踪程序 - -* nop —— 简化的跟踪程序,就像它的名字所暗示的那样,它不做任何事情(尽管在某些情况下可能会派上用场,我们将在后文中详细解释) +* nop —— 最简单的跟踪程序,就像它的名字所暗示的那样,它不做任何事情(尽管在某些情况下可能会派上用场,我们将在后文中详细解释) ### 函数跟踪程序 -在开始介绍函数跟踪程序 ftrace 之前,我们先看一下测试脚本: +在开始介绍函数跟踪程序 ftrace 之前,我们先看一个测试脚本: ``` #!/bin/sh @@ -117,7 +106,7 @@ less ${dir}/trace 这个脚本是非常简单的,但是还有几个需要注意的地方。命令 `sysctl ftrace.enabled=1` 启用了函数跟踪程序。然后我们通过写它的名字到 `current_tracer` 文件来启用 `current tracer`。 -接下来,我们写入一个 `1` 到 `tracing_on`,它启用了 `Ring` 缓冲区。这些语法都要求在 `1` 和 `>` 符号前后有一个空格;写成像 `echo1> tracing_on` 这样将不能工作。一行之后我们禁用它(如果 `0` 写入到 `tracing_on`, 缓冲区不会被清除并且 ftrace 并不会被禁用)。 +接下来,我们写入一个 `1` 到 `tracing_on`,它启用了 Ring 缓冲区。这些语法都要求在 `1` 和 `>` 符号前后有一个空格;写成像 `echo 1> tracing_on` 这样将不能工作。一行之后我们禁用它(如果 `0` 写入到 `tracing_on`, 缓冲区不会被清除并且 ftrace 并不会被禁用)。 我们为什么这样做呢?在两个 `echo` 命令之间,我们看到了命令 `sleep 1`。我们启用了缓冲区,运行了这个命令,然后禁用它。这将使跟踪程序采集了这个命令运行期间发生的所有系统调用的信息。 @@ -156,21 +145,18 @@ less ${dir}/trace trace.sh-1295 [000] d... 90.502879: __acct_update_integrals <-acct_account_cputime ``` -这个输出以缓冲区中的信息条目数量和写入的条目数量开始。这两者的数据差异是缓冲区中事件的丢失数量(在我们的示例中没有发生丢失)。 +这个输出以“缓冲区中的信息条目数量”和“写入的全部条目数量”开始。这两者的数据差异是缓冲区中事件的丢失数量(在我们的示例中没有发生丢失)。 在这里有一个包含下列信息的函数列表: * 进程标识符(PID) - * 运行这个进程的 CPU(CPU#) - * 进程开始时间(TIMESTAMP) - * 被跟踪函数的名字以及调用它的父级函数;例如,在我们输出的第一行,`rb_simple_write` 调用了 `mutex-unlock` 函数。 -### Function_graph 跟踪程序 +### function_graph 跟踪程序 -`function_graph` 跟踪程序的工作和函数一样,但是它更详细:它显示了每个函数的进入和退出点。使用这个跟踪程序,我们可以跟踪函数的子调用并且测量每个函数的运行时间。 +function_graph 跟踪程序的工作和函数跟踪程序一样,但是它更详细:它显示了每个函数的进入和退出点。使用这个跟踪程序,我们可以跟踪函数的子调用并且测量每个函数的运行时间。 我们来编辑一下最后一个示例的脚本: @@ -215,11 +201,11 @@ less ${dir}/trace 0) ! 208.154 us | } /* ip_local_deliver_finish */ ``` -在这个图中,`DURATION` 展示了花费在每个运行的函数上的时间。注意使用 `+` 和 `!` 符号标记的地方。加号(+)意思是这个函数花费的时间超过 10 毫秒;而感叹号(!)意思是这个函数花费的时间超过了 100 毫秒。 +在这个图中,`DURATION` 展示了花费在每个运行的函数上的时间。注意使用 `+` 和 `!` 符号标记的地方。加号(`+`)意思是这个函数花费的时间超过 10 毫秒;而感叹号(`!`)意思是这个函数花费的时间超过了 100 毫秒。 在 `FUNCTION_CALLS` 下面,我们可以看到每个函数调用的信息。 -和 C 语言一样使用了花括号({)标记每个函数的边界,它展示了每个函数的开始和结束,一个用于开始,一个用于结束;不能调用其它任何函数的叶子函数用一个分号(;)标记。 +和 C 语言一样使用了花括号(`{`)标记每个函数的边界,它展示了每个函数的开始和结束,一个用于开始,一个用于结束;不能调用其它任何函数的叶子函数用一个分号(`;`)标记。 ### 函数过滤器 @@ -249,13 +235,13 @@ ftrace 还有很多过滤选项。对于它们更详细的介绍,你可以去 ### 跟踪事件 -我们在上面提到到跟踪点机制。跟踪点是插入的由系统事件触发的特定代码。跟踪点可以是动态的(意味着可能会在它们上面附加几个检查),也可以是静态的(意味着不会附加任何检查)。 +我们在上面提到到跟踪点机制。跟踪点是插入的触发系统事件的特定代码。跟踪点可以是动态的(意味着可能会在它们上面附加几个检查),也可以是静态的(意味着不会附加任何检查)。 -静态跟踪点不会对系统有任何影响;它们只是增加几个字节用于调用测试函数以及在一个独立的节上增加一个数据结构。 +静态跟踪点不会对系统有任何影响;它们只是在测试的函数末尾增加几个字节的函数调用以及在一个独立的节上增加一个数据结构。 -当相关代码片断运行时,动态跟踪点调用一个跟踪函数。跟踪数据是写入到 `Ring` 缓冲区。 +当相关代码片断运行时,动态跟踪点调用一个跟踪函数。跟踪数据是写入到 Ring 缓冲区。 -跟踪点可以设置在代码的任何位置;事实上,它们确实可以在许多的内核函数中找到。我们来看一下 `kmem_cache_alloc` 函数(它在 [这里][22]): +跟踪点可以设置在代码的任何位置;事实上,它们确实可以在许多的内核函数中找到。我们来看一下 `kmem_cache_alloc` 函数(取自 [这里][22]): ``` { @@ -294,7 +280,7 @@ fs kvm power scsi vfs ftrace kvmmmu printk signal vmscan ``` -所有可能的事件都按子系统分组到子目录中。在我们开始跟踪事件之前,我们要先确保启用了 `Ring` 缓冲区写入: +所有可能的事件都按子系统分组到子目录中。在我们开始跟踪事件之前,我们要先确保启用了 Ring 缓冲区写入: ``` root@andrei:/sys/kernel/debug/tracing# cat tracing_on @@ -306,25 +292,25 @@ root@andrei:/sys/kernel/debug/tracing# cat tracing_on root@andrei:/sys/kernel/debug/tracing# echo 1 > tracing_on ``` -在我们上一篇的文章中,我们写了关于 `chroot()` 系统调用的内容;我们来跟踪访问一下这个系统调用。为了跟踪,我们使用 `nop` 因为函数跟踪程序和 `function_graph` 跟踪程序记录的信息太多,它包含了我们不感兴趣的事件信息。 +在我们上一篇的文章中,我们写了关于 `chroot()` 系统调用的内容;我们来跟踪访问一下这个系统调用。对于我们的跟踪程序,我们使用 `nop` 因为函数跟踪程序和 `function_graph` 跟踪程序记录的信息太多,它包含了我们不感兴趣的事件信息。 ``` root@andrei:/sys/kernel/debug/tracing# echo nop > current_tracer ``` -所有事件相关的系统调用都保存在系统调用目录下。在这里我们将找到一个进入和退出多个系统调用的目录。我们需要在相关的文件中通过写入数字 `1` 来激活跟踪点: +所有事件相关的系统调用都保存在系统调用目录下。在这里我们将找到一个进入和退出各种系统调用的目录。我们需要在相关的文件中通过写入数字 `1` 来激活跟踪点: ``` root@andrei:/sys/kernel/debug/tracing# echo 1 > events/syscalls/sys_enter_chroot/enable ``` -然后我们使用 `chroot` 来创建一个独立的文件系统(更多内容,请查看 [这篇文章][23])。在我们执行完我们需要的命令之后,我们将禁用跟踪程序,以便于不需要的信息或者过量信息出现在输出中: +然后我们使用 `chroot` 来创建一个独立的文件系统(更多内容,请查看 [之前这篇文章][23])。在我们执行完我们需要的命令之后,我们将禁用跟踪程序,以便于不需要的信息或者过量信息不会出现在输出中: ``` root@andrei:/sys/kernel/debug/tracing# echo 0 > tracing_on ``` -然后,我们去查看 `Ring` 缓冲区的内容。在输出的结束部分,我们找到了有关的系统调用信息(这里只是一个节选)。 +然后,我们去查看 Ring 缓冲区的内容。在输出的结束部分,我们找到了有关的系统调用信息(这里只是一个节选)。 ``` root@andrei:/sys/kernel/debug/tracing# сat trace @@ -343,15 +329,10 @@ root@andrei:/sys/kernel/debug/tracing# сat trace 在这篇文篇中,我们做了一个 ftrace 的功能概述。我们非常感谢你的任何意见或者补充。如果你想深入研究这个主题,我们为你推荐下列的资源: * [https://www.kernel.org/doc/Documentation/trace/tracepoints.txt][1] — 一个跟踪点机制的详细描述 - * [https://www.kernel.org/doc/Documentation/trace/events.txt][2] — 在 Linux 中跟踪系统事件的指南 - * [https://www.kernel.org/doc/Documentation/trace/ftrace.txt][3] — ftrace 的官方文档 - * [https://lttng.org/files/thesis/desnoyers-dissertation-2009-12-v27.pdf][4] — Mathieu Desnoyers(作者是跟踪点和 LTTNG 的创建者)的关于内核跟踪和分析的学术论文。 - * [https://lwn.net/Articles/370423/][5] — Steven Rostedt 的关于 ftrace 功能的文章 - * [http://alex.dzyoba.com/linux/profiling-ftrace.html][6] — 用 ftrace 分析实际案例的一个概述 -------------------------------------------------------------------------------- @@ -360,7 +341,7 @@ via:https://blog.selectel.com/kernel-tracing-ftrace/ 作者:[Andrej Yemelianov][a] 译者:[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/) 荣誉推出 diff --git a/published/20170829 An Advanced System Configuration Utility For Ubuntu Power Users.md b/published/20170829 An Advanced System Configuration Utility For Ubuntu Power Users.md new file mode 100644 index 0000000000..07b851caf2 --- /dev/null +++ b/published/20170829 An Advanced System Configuration Utility For Ubuntu Power Users.md @@ -0,0 +1,129 @@ +Ubunsys:面向 Ubuntu 资深用户的一个高级系统配置工具 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-4-1-720x340.png) + + +**Ubunsys** 是一个面向 Ubuntu 及其衍生版的基于 Qt 的高级系统工具。高级用户可以使用命令行轻松完成大多数配置。不过为了以防万一某天,你突然不想用命令行了,就可以用 Ubnusys 这个程序来配置你的系统或其衍生系统,如 Linux Mint、Elementary OS 等。Ubunsys 可用来修改系统配置,安装、删除、更新包和旧内核,启用或禁用 `sudo` 权限,安装主线内核,更新软件安装源,清理垃圾文件,将你的 Ubuntu 系统升级到最新版本等等。以上提到的所有功能都可以通过鼠标点击完成。你不需要再依赖于命令行模式,下面是你能用 Ubunsys 做到的事: + + * 安装、删除、更新包 + * 更新和升级软件源 + * 安装主线内核 + * 删除旧的和不再使用的内核 + * 系统整体更新 + * 将系统升级到下一个可用的版本 + * 将系统升级到最新的开发版本 + * 清理系统垃圾文件 + * 在不输入密码的情况下启用或者禁用 `sudo` 权限 + * 当你在终端输入密码时使 `sudo` 密码可见 + * 启用或禁用系统休眠 + * 启用或禁用防火墙 + * 打开、备份和导入 `sources.list.d` 和 `sudoers` 文件 + * 显示或者隐藏启动项 + * 启用或禁用登录音效 + * 配置双启动 + * 启用或禁用锁屏 + * 智能系统更新 + * 使用脚本管理器更新/一次性执行脚本 + * 从 `git` 执行常规用户安装脚本 + * 检查系统完整性和缺失的 GPG 密钥 + * 修复网络 + * 修复已破损的包 + * 还有更多功能在开发中 + +**重要提示:** Ubunsys 不适用于 Ubuntu 新手。它很危险并且仍然不是稳定版。它可能会使你的系统崩溃。如果你刚接触 Ubuntu 不久,不要使用。但如果你真的很好奇这个应用能做什么,仔细浏览每一个选项,并确定自己能承担风险。在使用这一应用之前记着备份你自己的重要数据。 + +### 安装 Ubunsys + +Ubunsys 开发者制作了一个 PPA 来简化安装过程,Ubunsys 现在可以在 Ubuntu 16.04 LTS、 Ubuntu 17.04 64 位版本上使用。 + +逐条执行下面的命令,将 Ubunsys 的 PPA 添加进去,并安装它。 + +``` +sudo add-apt-repository ppa:adgellida/ubunsys +sudo apt-get update +sudo apt-get install ubunsys +``` + +如果 PPA 无法使用,你可以在[发布页面][1]根据你自己当前系统,选择正确的安装包,直接下载并安装 Ubunsys。 + +### 用途 + +一旦安装完成,从菜单栏启动 Ubunsys。下图是 Ubunsys 主界面。 + +![][3] + +你可以看到,Ubunsys 有四个主要部分,分别是 Packages、Tweaks、System 和 Repair。在每一个标签项下面都有一个或多个子标签项以对应不同的操作。 + +**Packages** + +这一部分允许你安装、删除和更新包。 + +![][4] + +**Tweaks** + +在这一部分,我们可以对系统进行多种调整,例如: + + * 打开、备份和导入 `sources.list.d` 和 `sudoers` 文件; + * 配置双启动; + * 启用或禁用登录音效、防火墙、锁屏、系统休眠、`sudo` 权限(在不需要密码的情况下)同时你还可以针对某一用户启用或禁用 `sudo` 权限(在不需要密码的情况下); + * 在终端中输入密码时可见(禁用星号)。 + +![][5] + +**System** + +这一部分被进一步分成 3 个部分,每个都是针对某一特定用户类型。 + +**Normal user** 这一标签下的选项可以: + + * 更新、升级包和软件源 + * 清理系统 + * 执行常规用户安装脚本 + +**Advanced user** 这一标签下的选项可以: + +* 清理旧的/无用的内核 +* 安装主线内核 +* 智能包更新 +* 升级系统 + +**Developer** 这一部分可以将系统升级到最新的开发版本。 + +![][6] + +**Repair** + +这是 Ubunsys 的第四个也是最后一个部分。正如名字所示,这一部分能让我们修复我们的系统、网络、缺失的 GPG 密钥,和已经缺失的包。 + +![][7] + +正如你所见,Ubunsys 可以在几次点击下就能完成诸如系统配置、系统维护和软件维护之类的任务。你不需要一直依赖于终端。Ubunsys 能帮你完成任何高级任务。再次声明,我警告你,这个应用不适合新手,而且它并不稳定。所以当你使用的时候,能会出现 bug 或者系统崩溃。在仔细研究过每一个选项的影响之后再使用它。 + +谢谢阅读! + +### 参考资源 + +- [Ubunsys GitHub Repository][8] + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/ubunsys-advanced-system-configuration-utility-ubuntu-power-users/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[wenwensnow](https://github.com/wenwensnow) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:https://github.com/adgellida/ubunsys/releases +[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[3]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-1.png +[4]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-2.png +[5]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-5.png +[6]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-9.png +[7]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-11.png +[8]:https://github.com/adgellida/ubunsys \ No newline at end of file diff --git a/published/20171003 Streams a new general purpose data structure in Redis.md b/published/20171003 Streams a new general purpose data structure in Redis.md new file mode 100644 index 0000000000..92933058bb --- /dev/null +++ b/published/20171003 Streams a new general purpose data structure in Redis.md @@ -0,0 +1,183 @@ +Streams:一个新的 Redis 通用数据结构 +====== + +直到几个月以前,对于我来说,在消息传递的环境中,streams只是一个有趣且相对简单的概念。这个概念在 Kafka 流行之后,我主要研究它们在 Disque 案例中的应用,Disque 是一个消息队列,它将在 Redis 4.2 中被转换为 Redis 的一个模块。后来我决定让 Disque 都用 AP 消息(LCTT 译注:参见 [CAP 定理][1]) ,也就是说,它将在不需要客户端过多参与的情况下实现容错和可用性,这样一来,我更加确定地认为流的概念在那种情况下并不适用。 + +然而在那时 Redis 有个问题,那就是缺省情况下导出数据结构并不轻松。它在 Redis 列表list有序集sorted list发布/订阅Pub/Sub功能之间有某些缺陷。你可以权衡使用这些工具对一系列消息或事件建模。 + +有序集是内存消耗大户,那自然就不能对投递的相同消息进行一次又一次的建模,客户端不能阻塞新消息。因为有序集并不是一个序列化的数据结构,它是一个元素可以根据它们量的变化而移动的集合:所以它不像时序性的数据那样。 + +列表有另外的问题,它在某些特定的用例中会产生类似的适用性问题:你无法浏览列表中间的内容,因为在那种情况下,访问时间是线性的。此外,没有任何指定输出的功能,列表上的阻塞操作仅为单个客户端提供单个元素。列表中没有固定的元素标识,也就是说,不能指定从哪个元素开始给我提供内容。 + +对于一对多的工作任务,有发布/订阅机制,它在大多数情况下是非常好的,但是,对于某些不想“即发即弃”fire-and-forget的东西:保留一个历史是很重要的,不只是因为是断开之后会重新获得消息,也因为某些如时序性的消息列表,用范围查询浏览是非常重要的:比如在这 10 秒范围内温度读数是多少? + +我试图解决上述问题,我想规划一个通用的有序集合,并列入一个独特的、更灵活的数据结构,然而,我的设计尝试最终以生成一个比当前的数据结构更加矫揉造作的结果而告终。Redis 有个好处,它的数据结构导出更像自然的计算机科学的数据结构,而不是 “Salvatore 发明的 API”。因此,我最终停止了我的尝试,并且说,“ok,这是我们目前能提供的”,或许我会为发布/订阅增加一些历史信息,或者为列表访问增加一些更灵活的方式。然而,每次在会议上有用户对我说 “你如何在 Redis 中模拟时间系列” 或者类似的问题时,我的脸就绿了。 + +### 起源 + +在 Redis 4.0 中引入模块之后,用户开始考虑他们自己怎么去修复这些问题。其中一个用户 Timothy Downs 通过 IRC 和我说道: + + \ 我计划给这个模块增加一个事务日志式的数据类型 —— 这意味着大量的订阅者可以在不导致 redis 内存激增的情况下做一些像发布/订阅那样的事情 + \ 订阅者持有他们在消息队列中的位置,而不是让 Redis 必须维护每个消费者的位置和为每个订阅者复制消息 + +他的思路启发了我。我想了几天,并且意识到这可能是我们马上同时解决上面所有问题的契机。我需要去重新构思 “日志” 的概念是什么。日志是个基本的编程元素,每个人都使用过它,因为它只是简单地以追加模式打开一个文件,并以一定的格式写入数据。然而 Redis 数据结构必须是抽象的。它们在内存中,并且我们使用内存并不是因为我们懒,而是因为使用一些指针,我们可以概念化数据结构并把它们抽象,以使它们摆脱明确的限制。例如,一般来说日志有几个问题:偏移不是逻辑化的,而是真实的字节偏移,如果你想要与条目插入的时间相关的逻辑偏移应该怎么办?我们有范围查询可用。同样,日志通常很难进行垃圾回收:在一个只能进行追加操作的数据结构中怎么去删除旧的元素?好吧,在我们理想的日志中,我们只需要说,我想要数字最大的那个条目,而旧的元素一个也不要,等等。 + +当我从 Timothy 的想法中受到启发,去尝试着写一个规范的时候,我使用了 Redis 集群中的 radix 树去实现,优化了它内部的某些部分。这为实现一个有效利用空间的日志提供了基础,而且仍然有可能在对数时间logarithmic time内访问范围。同时,我开始去读关于 Kafka 的流相关的内容以获得另外的灵感,它也非常适合我的设计,最后借鉴了 Kafka 消费组consumer groups的概念,并且再次针对 Redis 进行优化,以适用于 Redis 在内存中使用的情况。然而,该规范仅停留在纸面上,在一段时间后我几乎把它从头到尾重写了一遍,以便将我与别人讨论的所得到的许多建议一起增加到 Redis 升级中。我希望 Redis 流能成为对于时间序列有用的特性,而不仅是一个常见的事件和消息类的应用程序。 + +### 让我们写一些代码吧 + +从 Redis 大会回来后,整个夏天我都在实现一个叫 listpack 的库。这个库是 `ziplist.c` 的继任者,那是一个表示在单个分配中的字符串元素列表的数据结构。它是一个非常特殊的序列化格式,其特点在于也能够以逆序(从右到左)解析:以便在各种用例中替代 ziplists。 + +结合 radix 树和 listpacks 的特性,它可以很容易地去构建一个空间高效的日志,并且还是可索引的,这意味着允许通过 ID 和时间进行随机访问。自从这些就绪后,我开始去写一些代码以实现流数据结构。我还在完成这个实现,不管怎样,现在在 Github 上的 Redis 的 streams 分支里它已经可以跑起来了。我并没有声称那个 API 是 100% 的最终版本,但是,这有两个有意思的事实:一,在那时只有消费群组是缺失的,加上一些不太重要的操作流的命令,但是,所有的大的方面都已经实现了。二,一旦各个方面比较稳定了之后,我决定大概用两个月的时间将所有的流的特性向后移植backport到 4.0 分支。这意味着 Redis 用户想要使用流,不用等待 Redis 4.2 发布,它们在生产环境马上就可用了。这是可能的,因为作为一个新的数据结构,几乎所有的代码改变都出现在新的代码里面。除了阻塞列表操作之外:该代码被重构了,我们对于流和列表阻塞操作共享了相同的代码,而极大地简化了 Redis 内部实现。 + +### 教程:欢迎使用 Redis 的 streams + +在某些方面,你可以认为流是 Redis 列表的一个增强版本。流元素不再是一个单一的字符串,而是一个字段fieldvalue组成的对象。范围查询更适用而且更快。在流中,每个条目都有一个 ID,它是一个逻辑偏移量。不同的客户端可以阻塞等待blocking-wait比指定的 ID 更大的元素。Redis 流的一个基本的命令是 `XADD`。是的,所有的 Redis 流命令都是以一个 `X` 为前缀的。 + +``` +> XADD mystream * sensor-id 1234 temperature 10.5 +1506871964177.0 +``` + +这个 `XADD` 命令将追加指定的条目作为一个指定的流 —— “mystream” 的新元素。上面示例中的这个条目有两个字段:`sensor-id` 和 `temperature`,每个条目在同一个流中可以有不同的字段。使用相同的字段名可以更好地利用内存。有意思的是,字段的排序是可以保证顺序的。`XADD` 仅返回插入的条目的 ID,因为在第三个参数中是星号(`*`),表示由命令自动生成 ID。通常这样做就够了,但是也可以去强制指定一个 ID,这种情况用于复制这个命令到从服务器slave serverAOFappend-only file 文件。 + +这个 ID 是由两部分组成的:一个毫秒时间和一个序列号。`1506871964177` 是毫秒时间,它只是一个毫秒级的 UNIX 时间戳。圆点(`.`)后面的数字 `0` 是一个序号,它是为了区分相同毫秒数的条目增加上去的。这两个数字都是 64 位的无符号整数。这意味着,我们可以在流中增加所有想要的条目,即使是在同一毫秒中。ID 的毫秒部分使用 Redis 服务器的当前本地时间生成的 ID 和流中的最后一个条目 ID 两者间的最大的一个。因此,举例来说,即使是计算机时间回跳,这个 ID 仍然是增加的。在某些情况下,你可以认为流条目的 ID 是完整的 128 位数字。然而,事实上它们与被添加到的实例的本地时间有关,这意味着我们可以在毫秒级的精度的范围随意查询。 + +正如你想的那样,快速添加两个条目后,结果是仅一个序号递增了。我们可以用一个 `MULTI`/`EXEC` 块来简单模拟“快速插入”: + +``` +> MULTI +OK +> XADD mystream * foo 10 +QUEUED +> XADD mystream * bar 20 +QUEUED +> EXEC +1) 1506872463535.0 +2) 1506872463535.1 +``` + +在上面的示例中,也展示了无需指定任何初始模式schema的情况下,对不同的条目使用不同的字段。会发生什么呢?就像前面提到的一样,只有每个块(它通常包含 50-150 个消息内容)的第一个消息被使用。并且,相同字段的连续条目都使用了一个标志进行了压缩,这个标志表示与“它们与这个块中的第一个条目的字段相同”。因此,使用相同字段的连续消息可以节省许多内存,即使是字段集随着时间发生缓慢变化的情况下也很节省内存。 + +为了从流中检索数据,这里有两种方法:范围查询,它是通过 `XRANGE` 命令实现的;流播streaming,它是通过 `XREAD` 命令实现的。`XRANGE` 命令仅取得包括从开始到停止范围内的全部条目。因此,举例来说,如果我知道它的 ID,我可以使用如下的命名取得单个条目: + +``` +> XRANGE mystream 1506871964177.0 1506871964177.0 +1) 1) 1506871964177.0 + 2) 1) "sensor-id" + 2) "1234" + 3) "temperature" + 4) "10.5" +``` + +不管怎样,你都可以使用指定的开始符号 `-` 和停止符号 `+` 表示最小和最大的 ID。为了限制返回条目的数量,也可以使用 `COUNT` 选项。下面是一个更复杂的 `XRANGE` 示例: + +``` +> XRANGE mystream - + COUNT 2 +1) 1) 1506871964177.0 + 2) 1) "sensor-id" + 2) "1234" + 3) "temperature" + 4) "10.5" +2) 1) 1506872463535.0 + 2) 1) "foo" + 2) "10" +``` + +这里我们讲的是 ID 的范围,然后,为了取得在一个给定时间范围内的特定范围的元素,你可以使用 `XRANGE`,因为 ID 的“序号” 部分可以省略。因此,你可以只指定“毫秒”时间即可,下面的命令的意思是:“从 UNIX 时间 1506872463 开始给我 10 个条目”: + +``` +127.0.0.1:6379> XRANGE mystream 1506872463000 + COUNT 10 +1) 1) 1506872463535.0 + 2) 1) "foo" + 2) "10" +2) 1) 1506872463535.1 + 2) 1) "bar" + 2) "20" +``` + +关于 `XRANGE` 需要注意的最重要的事情是,假设我们在回复中收到 ID,随后连续的 ID 只是增加了序号部分,所以可以使用 `XRANGE` 遍历整个流,接收每个调用的指定个数的元素。Redis 中的`*SCAN` 系列命令允许迭代 Redis 数据结构,尽管事实上它们不是为迭代设计的,但这样可以避免再犯相同的错误。 + +### 使用 XREAD 处理流播:阻塞新的数据 + +当我们想通过 ID 或时间去访问流中的一个范围或者是通过 ID 去获取单个元素时,使用 `XRANGE` 是非常完美的。然而,在使用流的案例中,当数据到达时,它必须由不同的客户端来消费时,这就不是一个很好的解决方案,这需要某种形式的汇聚池pooling。(对于 *某些* 应用程序来说,这可能是个好主意,因为它们仅是偶尔连接查询的) + +`XREAD` 命令是为读取设计的,在同一个时间,从多个流中仅指定我们从该流中得到的最后条目的 ID。此外,如果没有数据可用,我们可以要求阻塞,当数据到达时,就解除阻塞。类似于阻塞列表操作产生的效果,但是这里并没有消费从流中得到的数据,并且多个客户端可以同时访问同一份数据。 + +这里有一个典型的 `XREAD` 调用示例: + +``` +> XREAD BLOCK 5000 STREAMS mystream otherstream $ $ +``` + +它的意思是:从 `mystream` 和 `otherstream` 取得数据。如果没有数据可用,阻塞客户端 5000 毫秒。在 `STREAMS` 选项之后指定我们想要监听的关键字,最后的是指定想要监听的 ID,指定的 ID 为 `$` 的意思是:假设我现在需要流中的所有元素,因此,只需要从下一个到达的元素开始给我。 + +如果我从另一个客户端发送这样的命令: + +``` +> XADD otherstream * message “Hi There” +``` + +在 `XREAD` 侧会出现什么情况呢? + +``` +1) 1) "otherstream" + 2) 1) 1) 1506935385635.0 + 2) 1) "message" + 2) "Hi There" +``` + +与收到的数据一起,我们也得到了数据的关键字。在下次调用中,我们将使用接收到的最新消息的 ID: + +``` +> XREAD BLOCK 5000 STREAMS mystream otherstream $ 1506935385635.0 +``` + +依次类推。然而需要注意的是使用方式,客户端有可能在一个非常大的延迟之后再次连接(因为它处理消息需要时间,或者其它什么原因)。在这种情况下,期间会有很多消息堆积,为了确保客户端不被消息淹没,以及服务器不会因为给单个客户端提供大量消息而浪费太多的时间,使用 `XREAD` 的 `COUNT` 选项是非常明智的。 + +### 流封顶 + +目前看起来还不错……然而,有些时候,流需要删除一些旧的消息。幸运的是,这可以使用 `XADD` 命令的 `MAXLEN` 选项去做: + +``` +> XADD mystream MAXLEN 1000000 * field1 value1 field2 value2 +``` + +它是基本意思是,如果在流中添加新元素后发现消息数量超过了 `1000000` 个,那么就删除旧的消息,以便于元素总量重新回到 `1000000` 以内。它很像是在列表中使用的 `RPUSH` + `LTRIM`,但是,这次我们是使用了一个内置机制去完成的。然而,需要注意的是,上面的意思是每次我们增加一个新的消息时,我们还需要另外的工作去从流中删除旧的消息。这将消耗一些 CPU 资源,所以在计算 `MAXLEN` 之前,尽可能使用 `~` 符号,以表明我们不要求非常 *精确* 的 1000000 个消息,就是稍微多一些也不是大问题: + +``` +> XADD mystream MAXLEN ~ 1000000 * foo bar +``` + +这种方式的 XADD 仅当它可以删除整个节点的时候才会删除消息。相比普通的 `XADD`,这种方式几乎可以自由地对流进行封顶。 + +### 消费组(开发中) + +这是第一个 Redis 中尚未实现而在开发中的特性。灵感也是来自 Kafka,尽管在这里是以不同的方式实现的。重点是使用了 `XREAD`,客户端也可以增加一个 `GROUP ` 选项。相同组的所有客户端将自动得到 *不同的* 消息。当然,同一个流可以被多个组读取。在这种情况下,所有的组将收到流中到达的消息的相同副本。但是,在每个组内,消息是不会重复的。 + +当指定组时,能够指定一个 `RETRY ` 选项去扩展组:在这种情况下,如果消息没有通过 `XACK` 进行确认,它将在指定的毫秒数后进行再次投递。这将为消息投递提供更佳的可靠性,这种情况下,客户端没有私有的方法将消息标记为已处理。这一部分也正在开发中。 + +### 内存使用和节省加载时间 + +因为用来建模 Redis 流的设计,内存使用率是非常低的。这取决于它们的字段、值的数量和长度,对于简单的消息,每使用 100MB 内存可以有几百万条消息。此外,该格式设想为需要极少的序列化:listpack 块以 radix 树节点方式存储,在磁盘上和内存中都以相同方式表示的,因此它们可以很轻松地存储和读取。例如,Redis 可以在 0.3 秒内从 RDB 文件中读取 500 万个条目。这使流的复制和持久存储非常高效。 + +我还计划允许从条目中间进行部分删除。现在仅实现了一部分,策略是在条目在标记中标识条目为已删除,并且,当已删除条目占全部条目的比例达到指定值时,这个块将被回收重写,如果需要,它将被连到相邻的另一个块上,以避免碎片化。 + +### 关于最终发布时间的结论 + +Redis 的流特性将包含在年底前(LCTT 译注:本文原文发布于 2017 年 10 月)推出的 Redis 4.0 系列的稳定版中。我认为这个通用的数据结构将为 Redis 提供一个巨大的补丁,以用于解决很多现在很难以解决的情况:那意味着你(之前)需要创造性地“滥用”当前提供的数据结构去解决那些问题。一个非常重要的使用场景是时间序列,但是,我觉得对于其它场景来说,通过 `TREAD` 来流播消息将是非常有趣的,因为对于那些需要更高可靠性的应用程序,可以使用发布/订阅模式来替换“即用即弃”,还有其它全新的使用场景。现在,如果你想在有问题环境中评估这个新数据结构,可以更新 GitHub 上的 streams 分支开始试用。欢迎向我们报告所有的 bug。:-) + +如果你喜欢观看视频的方式,这里有一个现场演示:https://www.youtube.com/watch?v=ELDzy9lCFHQ + +--- + +via: http://antirez.com/news/114 + +作者:[antirez][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy), [pityonline](https://github.com/pityonline) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: http://antirez.com/ +[1]: https://zh.wikipedia.org/wiki/CAP%E5%AE%9A%E7%90%86 diff --git a/translated/tech/20171024 Learn Blockchains by Building One.md b/published/20171024 Learn Blockchains by Building One.md similarity index 70% rename from translated/tech/20171024 Learn Blockchains by Building One.md rename to published/20171024 Learn Blockchains by Building One.md index 23135eeec9..acbcaed1de 100644 --- a/translated/tech/20171024 Learn Blockchains by Building One.md +++ b/published/20171024 Learn Blockchains by Building One.md @@ -1,40 +1,41 @@ -通过构建一个区块链来学习区块链技术 +想学习区块链?那就用 Python 构建一个 ====== +> 了解区块链是如何工作的最快的方法是构建一个。 + ![](https://cdn-images-1.medium.com/max/2000/1*zutLn_-fZZhy7Ari-x-JWQ.jpeg) -你看到这篇文章是因为和我一样,对加密货币的大热而感到兴奋。并且想知道区块链是如何工作的 —— 它们背后的技术是什么。 + +你看到这篇文章是因为和我一样,对加密货币的大热而感到兴奋。并且想知道区块链是如何工作的 —— 它们背后的技术基础是什么。 但是理解区块链并不容易 —— 至少对我来说是这样。我徜徉在各种难懂的视频中,并且因为示例太少而陷入深深的挫败感中。 -我喜欢在实践中学习。这迫使我去处理被卡在代码级别上的难题。如果你也是这么做的,在本指南结束的时候,你将拥有一个功能正常的区块链,并且实实在在地理解了它的工作原理。 +我喜欢在实践中学习。这会使得我在代码层面上处理主要问题,从而可以让我坚持到底。如果你也是这么做的,在本指南结束的时候,你将拥有一个功能正常的区块链,并且实实在在地理解了它的工作原理。 ### 开始之前 … -记住,区块链是一个 _不可更改的、有序的_ 被称为区块的记录链。它们可以包括事务~~(交易???校对确认一下,下同)~~、文件或者任何你希望的真实数据。最重要的是它们是通过使用_哈希_链接到一起的。 +记住,区块链是一个 _不可更改的、有序的_ 记录(被称为区块)的链。它们可以包括交易transaction、文件或者任何你希望的真实数据。最重要的是它们是通过使用_哈希_链接到一起的。 如果你不知道哈希是什么,[这里有解释][1]。 - **_本指南的目标读者是谁?_** 你应该能很容易地读和写一些基本的 Python 代码,并能够理解 HTTP 请求是如何工作的,因为我们讨论的区块链将基于 HTTP。 + **_本指南的目标读者是谁?_** 你应该能轻松地读、写一些基本的 Python 代码,并能够理解 HTTP 请求是如何工作的,因为我们讨论的区块链将基于 HTTP。 **_我需要做什么?_** 确保安装了 [Python 3.6][2]+(以及 `pip`),还需要去安装 Flask 和非常好用的 Requests 库: ``` - pip install Flask==0.12.2 requests==2.18.4 +pip install Flask==0.12.2 requests==2.18.4 ``` 当然,你也需要一个 HTTP 客户端,像 [Postman][3] 或者 cURL。哪个都行。 **_最终的代码在哪里可以找到?_** 源代码在 [这里][4]。 -* * * - ### 第 1 步:构建一个区块链 -打开你喜欢的文本编辑器或者 IDE,我个人 ❤️ [PyCharm][5]。创建一个名为 `blockchain.py` 的新文件。我将使用一个单个的文件,如果你看晕了,可以去参考 [源代码][6]。 +打开你喜欢的文本编辑器或者 IDE,我个人喜欢 [PyCharm][5]。创建一个名为 `blockchain.py` 的新文件。我将仅使用一个文件,如果你看晕了,可以去参考 [源代码][6]。 #### 描述一个区块链 -我们将创建一个 `Blockchain` 类,它的构造函数将去初始化一个空列表(去存储我们的区块链),以及另一个列表去保存事务。下面是我们的类规划: +我们将创建一个 `Blockchain` 类,它的构造函数将去初始化一个空列表(去存储我们的区块链),以及另一个列表去保存交易。下面是我们的类规划: ``` class Blockchain(object): @@ -58,15 +59,16 @@ class Blockchain(object): @property def last_block(self): # Returns the last Block in the chain -pass + pass ``` +*我们的 Blockchain 类的原型* -我们的区块链类负责管理链。它将存储事务并且有一些为链中增加新区块的助理性质的方法。现在我们开始去充实一些类的方法。 +我们的 `Blockchain` 类负责管理链。它将存储交易并且有一些为链中增加新区块的辅助性质的方法。现在我们开始去充实一些类的方法。 -#### 一个区块是什么样子的? +#### 区块是什么样子的? -每个区块有一个索引、一个时间戳(Unix 时间)、一个事务的列表、一个证明(后面会详细解释)、以及前一个区块的哈希。 +每个区块有一个索引、一个时间戳(Unix 时间)、一个交易的列表、一个证明(后面会详细解释)、以及前一个区块的哈希。 单个区块的示例应该是下面的样子: @@ -86,13 +88,15 @@ block = { } ``` -此刻,链的概念应该非常明显 —— 每个新区块包含它自身的信息和前一个区域的哈希。这一点非常重要,因为这就是区块链不可更改的原因:如果攻击者修改了一个早期的区块,那么所有的后续区块将包含错误的哈希。 +*我们的区块链中的块示例* -这样做有意义吗?如果没有,就让时间来埋葬它吧 —— 这就是区块链背后的核心思想。 +此刻,链的概念应该非常明显 —— 每个新区块包含它自身的信息和前一个区域的哈希。**这一点非常重要,因为这就是区块链不可更改的原因**:如果攻击者修改了一个早期的区块,那么**所有**的后续区块将包含错误的哈希。 -#### 添加事务到一个区块 +*这样做有意义吗?如果没有,就让时间来埋葬它吧 —— 这就是区块链背后的核心思想。* -我们将需要一种区块中添加事务的方式。我们的 `new_transaction()` 就是做这个的,它非常简单明了: +#### 添加交易到一个区块 + +我们将需要一种区块中添加交易的方式。我们的 `new_transaction()` 就是做这个的,它非常简单明了: ``` class Blockchain(object): @@ -113,14 +117,14 @@ class Blockchain(object): 'amount': amount, }) -return self.last_block['index'] + 1 + return self.last_block['index'] + 1 ``` -在 `new_transaction()` 运行后将在列表中添加一个事务,它返回添加事务后的那个区块的索引 —— 那个区块接下来将被挖矿。提交事务的用户后面会用到这些。 +在 `new_transaction()` 运行后将在列表中添加一个交易,它返回添加交易后的那个区块的索引 —— 那个区块接下来将被挖矿。提交交易的用户后面会用到这些。 #### 创建新区块 -当我们的区块链被实例化后,我们需要一个创世区块(一个没有祖先的区块)来播种它。我们也需要去添加一些 “证明” 到创世区块,它是挖矿(工作量证明 PoW)的成果。我们在后面将讨论更多挖矿的内容。 +当我们的 `Blockchain` 被实例化后,我们需要一个创世区块(一个没有祖先的区块)来播种它。我们也需要去添加一些 “证明” 到创世区块,它是挖矿(工作量证明 PoW)的成果。我们在后面将讨论更多挖矿的内容。 除了在我们的构造函数中创建创世区块之外,我们还需要写一些方法,如 `new_block()`、`new_transaction()` 以及 `hash()`: @@ -190,18 +194,18 @@ class Blockchain(object): # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes block_string = json.dumps(block, sort_keys=True).encode() -return hashlib.sha256(block_string).hexdigest() + return hashlib.sha256(block_string).hexdigest() ``` 上面的内容简单明了 —— 我添加了一些注释和文档字符串,以使代码清晰可读。到此为止,表示我们的区块链基本上要完成了。但是,你肯定想知道新区块是如何被创建、打造或者挖矿的。 #### 理解工作量证明 -一个工作量证明(PoW)算法是在区块链上创建或者挖出新区块的方法。PoW 的目标是去撞出一个能够解决问题的数字。这个数字必须满足“找到它很困难但是验证它很容易”的条件 —— 网络上的任何人都可以计算它。这就是 PoW 背后的核心思想。 +工作量证明Proof of Work(PoW)算法是在区块链上创建或者挖出新区块的方法。PoW 的目标是去撞出一个能够解决问题的数字。这个数字必须满足“找到它很困难但是验证它很容易”的条件 —— 网络上的任何人都可以计算它。这就是 PoW 背后的核心思想。 我们来看一个非常简单的示例来帮助你了解它。 -我们来解决一个问题,一些整数 x 乘以另外一个整数 y 的结果的哈希值必须以 0 结束。因此,hash(x * y) = ac23dc…0。为简单起见,我们先把 x = 5 固定下来。在 Python 中的实现如下: +我们来解决一个问题,一些整数 `x` 乘以另外一个整数 `y` 的结果的哈希值必须以 `0` 结束。因此,`hash(x * y) = ac23dc…0`。为简单起见,我们先把 `x = 5` 固定下来。在 Python 中的实现如下: ``` from hashlib import sha256 @@ -215,19 +219,21 @@ while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0": print(f'The solution is y = {y}') ``` -在这里的答案是 y = 21。因为它产生的哈希值是以 0 结尾的: +在这里的答案是 `y = 21`。因为它产生的哈希值是以 0 结尾的: ``` hash(5 * 21) = 1253e9373e...5e3600155e860 ``` +在比特币中,工作量证明算法被称之为 [Hashcash][10]。与我们上面的例子没有太大的差别。这就是矿工们进行竞赛以决定谁来创建新块的算法。一般来说,其难度取决于在一个字符串中所查找的字符数量。然后矿工会因其做出的求解而得到奖励的币——在一个交易当中。 + 网络上的任何人都可以很容易地去核验它的答案。 #### 实现基本的 PoW 为我们的区块链来实现一个简单的算法。我们的规则与上面的示例类似: -> 找出一个数字 p,它与前一个区块的答案进行哈希运算得到一个哈希值,这个哈希值的前四位必须是由 0 组成。 +> 找出一个数字 `p`,它与前一个区块的答案进行哈希运算得到一个哈希值,这个哈希值的前四位必须是由 `0` 组成。 ``` import hashlib @@ -266,25 +272,21 @@ class Blockchain(object): guess = f'{last_proof}{proof}'.encode() guess_hash = hashlib.sha256(guess).hexdigest() -return guess_hash[:4] == "0000" + return guess_hash[:4] == "0000" ``` 为了调整算法的难度,我们可以修改前导 0 的数量。但是 4 个零已经足够难了。你会发现,将前导 0 的数量每增加一,那么找到正确答案所需要的时间难度将大幅增加。 我们的类基本完成了,现在我们开始去使用 HTTP 请求与它交互。 -* * * - ### 第 2 步:以 API 方式去访问我们的区块链 -我们将去使用 Python Flask 框架。它是个微框架,使用它去做端点到 Python 函数的映射很容易。这样我们可以使用 HTTP 请求基于 web 来与我们的区块链对话。 +我们将使用 Python Flask 框架。它是个微框架,使用它去做端点到 Python 函数的映射很容易。这样我们可以使用 HTTP 请求基于 web 来与我们的区块链对话。 我们将创建三个方法: -* `/transactions/new` 在一个区块上创建一个新事务 - +* `/transactions/new` 在一个区块上创建一个新交易 * `/mine` 告诉我们的服务器去挖矿一个新区块 - * `/chain` 返回完整的区块链 #### 配置 Flask @@ -332,33 +334,33 @@ def full_chain(): return jsonify(response), 200 if __name__ == '__main__': -app.run(host='0.0.0.0', port=5000) + app.run(host='0.0.0.0', port=5000) ``` 对上面的代码,我们做添加一些详细的解释: * Line 15:实例化我们的节点。更多关于 Flask 的知识读 [这里][7]。 - * Line 18:为我们的节点创建一个随机的名字。 - * Line 21:实例化我们的区块链类。 - -* Line 24–26:创建 /mine 端点,这是一个 GET 请求。 - -* Line 28–30:创建 /transactions/new 端点,这是一个 POST 请求,因为我们要发送数据给它。 - -* Line 32–38:创建 /chain 端点,它返回全部区块链。 - +* Line 24–26:创建 `/mine` 端点,这是一个 GET 请求。 +* Line 28–30:创建 `/transactions/new` 端点,这是一个 POST 请求,因为我们要发送数据给它。 +* Line 32–38:创建 `/chain` 端点,它返回全部区块链。 * Line 40–41:在 5000 端口上运行服务器。 -#### 事务端点 +#### 交易端点 -这就是对一个事务的请求,它是用户发送给服务器的: +这就是对一个交易的请求,它是用户发送给服务器的: ``` -{ "sender": "my address", "recipient": "someone else's address", "amount": 5} +{ + "sender": "my address", + "recipient": "someone else's address", + "amount": 5 +} ``` +因为我们已经有了添加交易到块中的类方法,剩下的就很容易了。让我们写个函数来添加交易: + ``` import hashlib import json @@ -383,18 +385,17 @@ def new_transaction(): index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount']) response = {'message': f'Transaction will be added to Block {index}'} -return jsonify(response), 201 + return jsonify(response), 201 ``` -创建事务的方法 + +*创建交易的方法* #### 挖矿端点 我们的挖矿端点是见证奇迹的地方,它实现起来很容易。它要做三件事情: 1. 计算工作量证明 - -2. 因为矿工(我们)添加一个事务而获得报酬,奖励矿工(我们) 1 个硬币 - +2. 因为矿工(我们)添加一个交易而获得报酬,奖励矿工(我们) 1 个币 3. 通过将它添加到链上而打造一个新区块 ``` @@ -434,10 +435,10 @@ def mine(): 'proof': block['proof'], 'previous_hash': block['previous_hash'], } -return jsonify(response), 200 + return jsonify(response), 200 ``` -注意,挖掘出的区块的接收方是我们的节点地址。现在,我们所做的大部分工作都只是与我们的区块链类的方法进行交互的。到目前为止,我们已经做到了,现在开始与我们的区块链去交互。 +注意,挖掘出的区块的接收方是我们的节点地址。现在,我们所做的大部分工作都只是与我们的 `Blockchain` 类的方法进行交互的。到目前为止,我们已经做完了,现在开始与我们的区块链去交互。 ### 第 3 步:与我们的区块链去交互 @@ -447,24 +448,33 @@ return jsonify(response), 200 ``` $ python blockchain.py +* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) ``` -我们通过生成一个 GET 请求到 http://localhost:5000/mine 去尝试挖一个区块: +我们通过生成一个 `GET` 请求到 `http://localhost:5000/mine` 去尝试挖一个区块: ![](https://cdn-images-1.medium.com/max/1600/1*ufYwRmWgQeA-Jxg0zgYLOA.png) -使用 Postman 去生成一个 GET 请求 -我们通过生成一个 POST 请求到 http://localhost:5000/transactions/new 去创建一个区块,它带有一个包含我们的事务结构的 `Body`: +*使用 Postman 去生成一个 GET 请求* + +我们通过生成一个 `POST` 请求到 `http://localhost:5000/transactions/new` 去创建一个区块,请求数据包含我们的交易结构: ![](https://cdn-images-1.medium.com/max/1600/1*O89KNbEWj1vigMZ6VelHAg.png) -使用 Postman 去生成一个 POST 请求 + +*使用 Postman 去生成一个 POST 请求* 如果你不使用 Postman,也可以使用 cURL 去生成一个等价的请求: ``` -$ curl -X POST -H "Content-Type: application/json" -d '{ "sender": "d4ee26eee15148ee92c6cd394edd974e", "recipient": "someone-other-address", "amount": 5}' "http://localhost:5000/transactions/new" +$ curl -X POST -H "Content-Type: application/json" -d '{ + "sender": "d4ee26eee15148ee92c6cd394edd974e", + "recipient": "someone-other-address", + "amount": 5 +}' "http://localhost:5000/transactions/new" ``` -我重启动我的服务器,然后我挖到了两个区块,这样总共有了3 个区块。我们通过请求 http://localhost:5000/chain 来检查整个区块链: + +我重启动我的服务器,然后我挖到了两个区块,这样总共有了 3 个区块。我们通过请求 `http://localhost:5000/chain` 来检查整个区块链: + ``` { "chain": [ @@ -503,18 +513,18 @@ $ curl -X POST -H "Content-Type: application/json" -d '{ "sender": "d4ee26eee151 } ], "length": 3 +} ``` ### 第 4 步:共识 -这是很酷的一个地方。我们已经有了一个基本的区块链,它可以接收事务并允许我们去挖掘出新区块。但是区块链的整个重点在于它是去中心化的。而如果它们是去中心化的,那我们如何才能确保它们表示在同一个区块链上?这就是共识问题,如果我们希望在我们的网络上有多于一个的节点运行,那么我们将必须去实现一个共识算法。 +这是很酷的一个地方。我们已经有了一个基本的区块链,它可以接收交易并允许我们去挖掘出新区块。但是区块链的整个重点在于它是去中心化的decentralized。而如果它们是去中心化的,那我们如何才能确保它们表示在同一个区块链上?这就是共识Consensus问题,如果我们希望在我们的网络上有多于一个的节点运行,那么我们将必须去实现一个共识算法。 #### 注册新节点 在我们能实现一个共识算法之前,我们需要一个办法去让一个节点知道网络上的邻居节点。我们网络上的每个节点都保留有一个该网络上其它节点的注册信息。因此,我们需要更多的端点: -1. /nodes/register 以 URLs 的形式去接受一个新节点列表 - -2. /nodes/resolve 去实现我们的共识算法,由它来解决任何的冲突 —— 确保节点有一个正确的链。 +1. `/nodes/register` 以 URL 的形式去接受一个新节点列表 +2. `/nodes/resolve` 去实现我们的共识算法,由它来解决任何的冲突 —— 确保节点有一个正确的链。 我们需要去修改我们的区块链的构造函数,来提供一个注册节点的方法: @@ -538,11 +548,12 @@ class Blockchain(object): """ parsed_url = urlparse(address) -self.nodes.add(parsed_url.netloc) + self.nodes.add(parsed_url.netloc) ``` -一个添加邻居节点到我们的网络的方法 -注意,我们将使用一个 `set()` 去保存节点列表。这是一个非常合算的方式,它将确保添加的内容是幂等的 —— 这意味着不论你将特定的节点添加多少次,它都是精确地只出现一次。 +*一个添加邻居节点到我们的网络的方法* + +注意,我们将使用一个 `set()` 去保存节点列表。这是一个非常合算的方式,它将确保添加的节点是幂等idempotent的 —— 这意味着不论你将特定的节点添加多少次,它都是精确地只出现一次。 #### 实现共识算法 @@ -615,12 +626,12 @@ class Blockchain(object) self.chain = new_chain return True -return False + return False ``` 第一个方法 `valid_chain()` 是负责来检查链是否有效,它通过遍历区块链上的每个区块并验证它们的哈希和工作量证明来检查这个区块链是否有效。 -`resolve_conflicts()` 方法用于遍历所有的邻居节点,下载它们的链并使用上面的方法去验证它们是否有效。如果找到有效的链,确定谁是最长的链,然后我们就用最长的链来替换我们的当前的链。 +`resolve_conflicts()` 方法用于遍历所有的邻居节点,下载它们的链并使用上面的方法去验证它们是否有效。**如果找到有效的链,确定谁是最长的链,然后我们就用最长的链来替换我们的当前的链。** 在我们的 API 上来注册两个端点,一个用于添加邻居节点,另一个用于解决冲突: @@ -658,18 +669,20 @@ def consensus(): 'chain': blockchain.chain } -return jsonify(response), 200 + return jsonify(response), 200 ``` -这种情况下,如果你愿意可以使用不同的机器来做,然后在你的网络上启动不同的节点。或者是在同一台机器上使用不同的端口启动另一个进程。我是在我的机器上使用了不同的端口启动了另一个节点,并将它注册到了当前的节点上。因此,我现在有了两个节点:[http://localhost:5000][9] 和 http://localhost:5001。 +这种情况下,如果你愿意,可以使用不同的机器来做,然后在你的网络上启动不同的节点。或者是在同一台机器上使用不同的端口启动另一个进程。我是在我的机器上使用了不同的端口启动了另一个节点,并将它注册到了当前的节点上。因此,我现在有了两个节点:`http://localhost:5000` 和 `http://localhost:5001`。 ![](https://cdn-images-1.medium.com/max/1600/1*Dd78u-gmtwhQWHhPG3qMTQ.png) -注册一个新节点 + +*注册一个新节点* 我接着在节点 2 上挖出一些新区块,以确保这个链是最长的。之后我在节点 1 上以 `GET` 方式调用了 `/nodes/resolve`,这时,节点 1 上的链被共识算法替换成节点 2 上的链了: ![](https://cdn-images-1.medium.com/max/1600/1*SGO5MWVf7GguIxfz6S8NVw.png) -工作中的共识算法 + +*工作中的共识算法* 然后将它们封装起来 … 找一些朋友来帮你一起测试你的区块链。 @@ -677,7 +690,7 @@ return jsonify(response), 200 我希望以上内容能够鼓舞你去创建一些新的东西。我是加密货币的狂热拥护者,因此我相信区块链将迅速改变我们对经济、政府和记录保存的看法。 -**更新:** 我正计划继续它的第二部分,其中我将扩展我们的区块链,使它具备事务验证机制,同时讨论一些你可以在其上产生你自己的区块链的方式。 +**更新:** 我正计划继续它的第二部分,其中我将扩展我们的区块链,使它具备交易验证机制,同时讨论一些你可以在其上产生你自己的区块链的方式。(LCTT 译注:第二篇并没有~!) -------------------------------------------------------------------------------- @@ -685,7 +698,7 @@ via: https://hackernoon.com/learn-blockchains-by-building-one-117428612f46 作者:[Daniel van Flymen][a] 译者:[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/) 荣誉推出 @@ -699,3 +712,4 @@ via: https://hackernoon.com/learn-blockchains-by-building-one-117428612f46 [7]:http://flask.pocoo.org/docs/0.12/quickstart/#a-minimal-application [8]:http://localhost:5000/transactions/new [9]:http://localhost:5000 +[10]:https://en.wikipedia.org/wiki/Hashcash \ No newline at end of file diff --git a/translated/tech/20171116 How to improve ROI on automation- 4 tips.md b/published/20171116 How to improve ROI on automation- 4 tips.md similarity index 87% rename from translated/tech/20171116 How to improve ROI on automation- 4 tips.md rename to published/20171116 How to improve ROI on automation- 4 tips.md index edce4dcdb2..2139c43c64 100644 --- a/translated/tech/20171116 How to improve ROI on automation- 4 tips.md +++ b/published/20171116 How to improve ROI on automation- 4 tips.md @@ -1,12 +1,15 @@ 如何提升自动化的 ROI:4 个小提示 ====== +> 想要在你的自动化项目上达成强 RIO?采取如下步骤来规避失败。 + ![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/cio_it_investments_2.png?itok=Ut1XIIBN) -在过去的几年间,有关自动化技术的讨论已经很多了。COO 们和运营团队(事实上还有其它的业务部门)对成本随着工作量的增加而增加的这一事实可以重新定义而感到震惊。 -机器人流程自动化(RPA)似乎预示着运营的圣杯(Holy Grail):“我们提供了开箱即用的功能来满足你的日常操作所需 —— 检查电子邮件、保存附件、取数据、更新表格、生成报告、文件以及目录操作。构建一个机器人就像配置这些功能一样简单,然后用机器人将这些操作链接到一起,而不用去请求 IT 部门来构建它们。”这是一个多么诱人的话题。 +在过去的几年间,有关自动化技术的讨论已经很多了。COO 们和运营团队(事实上还有其它的业务部门)对于可以重新定义成本随着工作量的增加而增加的这一事实而感到震惊。 -低成本、几乎不出错、非常遵守流程 —— 对 COO 们和运营领导来说,这些好处即实用可行度又高。RPA 工具承诺,它从运营中节省下来的费用就足够支付它的成本(有一个短的回报期),这一事实使得业务的观点更具有吸引力。 +机器人流程自动化Robotic Process Automation(RPA)似乎预示着运营的圣杯Holy Grail:“我们提供了开箱即用的功能来满足你的日常操作所需 —— 检查电子邮件、保存附件、取数据、更新表格、生成报告、文件以及目录操作。构建一个机器人就像配置这些功能一样简单,然后用机器人将这些操作链接到一起,而不用去请求 IT 部门来构建它们。”这是一个多么诱人的话题。 + +低成本、几乎不出错、非常遵守流程 —— 对 COO 们和运营领导来说,这些好处真实可及。RPA 工具承诺,它从运营中节省下来的费用就足够支付它的成本(有一个短的回报期),这一事实使得业务的观点更具有吸引力。 自动化的谈论都趋向于类似的话题:COO 们和他们的团队想知道,自动化操作能够给他们带来什么好处。他们想知道 RPA 平台特性和功能,以及自动化在现实中的真实案例。从这一点到概念验证的实现过程通常很短暂。 @@ -14,7 +17,7 @@ 但是自动化带来的现实好处有时候可能比你所预期的时间要晚。采用 RPA 的公司在其实施后可能会对它们自身的 ROI 提出一些质疑。一些人没有看到预期之中的成本节省,并对其中的原因感到疑惑。 -## 你是不是自动化了错误的东西? +### 你是不是自动化了错误的东西? 在这些情况下,自动化的愿景和现实之间的差距是什么呢?我们来分析一下它,在决定去继续进行一个自动化验证项目(甚至是一个成熟的实践)之后,我们来看一下通常会发生什么。 @@ -26,7 +29,7 @@ 那么,对于领导们来说,怎么才能确保实施自动化能够带来他们想要的 ROI 呢?实现这个目标有四步: -## 1. 教育团队 +### 1. 教育团队 在你的团队中,从 COO 职位以下的人中,很有可能都听说过 RPA 和运营自动化。同样很有可能他们都有许多的问题和担心。在你开始启动实施之前解决这些问题和担心是非常重要的。 @@ -36,23 +39,23 @@ “实施自动化的第一步是更好地理解你的流程。” -## 2. 审查内部流程 +### 2. 审查内部流程 实施自动化的第一步是更好地理解你的流程。每个 RPA 实施之前都应该进行流程清单、动作分析、以及成本/价值的绘制练习。 -这些练习对于理解流程中何处价值产生(或成本,如果没有价值的情况下)是至关重要的。并且这些练习需要在每个流程或者每个任务这样的粒度级别上来做。 +这些练习对于理解流程中何处产生价值(或成本,如果没有价值的情况下)是至关重要的。并且这些练习需要在每个流程或者每个任务这样的粒度级别上来做。 这将有助你去识别和优先考虑最合适的自动化候选者。由于能够或者可能需要自动化的任务数量较多,流程一般需要分段实施自动化,因此优先级很重要。 **建议**:设置一个小的工作团队,每个运营团队都参与其中。从每个运营团队中提名一个协调人 —— 一般是运营团队的领导或者团队管理者。在团队级别上组织一次研讨会,去构建流程清单、识别候选流程、以及推动购买。你的自动化合作伙伴很可能有“加速器” —— 调查问卷、计分卡等等 —— 这些将帮助你加速完成这项活动。 -## 3. 为优先业务提供强有力的指导 +### 3. 为优先业务提供强有力的指导 实施自动化经常会涉及到在运营团队之间,基于业务价值对流程选择和自动化优先级上要达成共识(有时候是打破平衡)虽然团队的参与仍然是分析和实施的关键部分,但是领导仍然应该是最终的决策者。 **建议**:安排定期会议从工作团队中获取最新信息。除了像推动达成共识和购买之外,工作团队还应该在团队层面上去查看领导们关于 ROI、平台选择、以及自动化优先级上的指导性决定。 -## 4. 应该推动 CIO 和 COO 的紧密合作 +### 4. 应该推动 CIO 和 COO 的紧密合作 当运营团队和技术团队紧密合作时,自动化的实施将异常顺利。COO 需要去帮助推动与 CIO 团队的合作。 @@ -68,7 +71,7 @@ via: https://enterprisersproject.com/article/2017/11/how-improve-roi-automation- 作者:[Rajesh Kamath][a] 译者:[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/) 荣誉推出 diff --git a/sources/tech/20180103 How To Find The Installed Proprietary Packages In Arch Linux.md b/published/20180103 How To Find The Installed Proprietary Packages In Arch Linux.md similarity index 63% rename from sources/tech/20180103 How To Find The Installed Proprietary Packages In Arch Linux.md rename to published/20180103 How To Find The Installed Proprietary Packages In Arch Linux.md index 69b523426c..29c05462ac 100644 --- a/sources/tech/20180103 How To Find The Installed Proprietary Packages In Arch Linux.md +++ b/published/20180103 How To Find The Installed Proprietary Packages In Arch Linux.md @@ -1,34 +1,40 @@ -How To Find The Installed Proprietary Packages In Arch Linux +如何在 Arch Linux 中查找已安装的专有软件包? ====== + ![](https://www.ostechnix.com/wp-content/uploads/2018/01/Absolutely-Proprietary-720x340.jpg) -Are you an avid free software supporter and currently using any Arch based distribution? I've got a small tip for you! Now, you can easily find the installed proprietary packages in Arch Linux and its variants such as Antergos, Manjaro Linux etc. You don't need to refer the license details of the installed package in its website or use any external tool to find out whether the package is free or proprietary. -### Find The Installed Proprietary Packages In Arch Linux +你是狂热的自由软件支持者吗?你目前在使用任何基于 Arch 的 Linux 发行版吗?我有一个小小的提示送给你!现在,你可以轻松地在 Arch Linux 及其变体(如 Antergos、Manjaro Linux 等)中找到已安装的专有软件包。你无需在已安装软件包的网站中参考其许可细节,也无需使用任何其它外部工具来查明软件包是自由的还是专有的。(LCTT 译注:其实下面还是借助了一个外部程序) -A fellow developer has developed an utility named **" Absolutely Proprietary"**, a proprietary package detector for arch-based distributions. It compares all installed packages in your Arch based system against Parabola's package [blacklist][1] and [aur-blacklist][2] and then prints your **Stallman Freedom Index** (free/total). Additionally, you can save the list to a file and share or compare it with other systems/users. +### 在 Arch Linux 中查找已安装的专有软件包 -Before installing it, Make sure you have installed **python** and **git**. +一位开发人员开发了一个名为 “[Absolutely Proprietary][5]” 的实用程序,它是一种用于基于 Arch 发行版的专有软件包检测器。它将基于 Arch 系统中的所有安装包与 Parabola 的软件包 [blacklist][1]和 [aur-blacklist][2] 进行比较,然后显示出你的斯托曼自由指数Stallman Freedom Index(“自由/总计”比分)。此外,你可以将该列表保存到文件中,并与其他系统/用户共享或比较。 + +在安装之前,确保你安装了 Python 和 Git。 + +然后,`git clone` 仓库: -Then, git clone the repository: ``` git clone https://github.com/vmavromatis/absolutely-proprietary.git ``` -This command will download all contents in a directory called 'absolutely-proprietary' in your current working directory. +这条命令将会下载所有内容到你当前工作目录中的 `absolutely-proprietary` 目录。 + +进入此目录: -Change to that directory: ``` cd absolutely-proprietary ``` -And, find the installed proprietary packages using command: +接着,使用以下命令查找已安装的专有软件: + ``` python main.py ``` -This command will download the blacklist.txt, aur-blacklist.txt and compare the locally installed packages with the remote packages and displays the +这条命令将会下载 `blacklist.txt`、`aur-blacklist.txt`,并将本地已安装的软件包与远程软件包进行比较并显示其指数。 + +以下是在我的 Arch Linux 桌面的示例输出: -Here is the sample output from my Arch Linux desktop: ``` Retrieving local packages (including AUR)... Downloading https://git.parabola.nu/blacklist.git/plain/blacklist.txt @@ -73,9 +79,10 @@ Your Stallman Freedom Index is 96.57 Save list to file? (Y/n) ``` -[![][3]][4] +![][4] + +如你所见,我的系统中有 47 个专有软件包。就像我说的那样,我们可以将它保存到文件中稍后查看。为此,当提示你将列表保存在文件时,请按 `y`。然后按 `y` 接受默认值,或按 `n` 以你喜欢的格式和位置来保存它。 -As you can see, I have 47 proprietary packages in my system. Like I said already, we can save it to a file and review them later. To do so, jut press 'y' when you are prompted to save the list in a file. Then press 'y' to accept the defaults or hit 'n' to save it in your preferred format and location. ``` Save list to file? (Y/n) y Save as markdown table? (Y/n) y @@ -87,29 +94,29 @@ using the "less -S /home/sk/absolutely-proprietary/y.md" or, if installed, the "most /home/sk/absolutely-proprietary/y.md" commands ``` -As you may noticed, I have only the **nonfree** packages. It will display two more type of packages such as semifree, uses-nonfree. +你可能已经注意到,我只有 **nonfree** 包。它还会显示另外两种类型的软件包,例如 semifree、 uses-nonfree。 - * **nonfree** : This package is blatantly nonfree software. - * **semifree** : This package is mostly free, but contains some nonfree software. - * **uses-nonfree** : This package depends on, recommends, or otherwise inappropriately integrates with other nonfree software or services. + * **nonfree**:这个软件包是公然的非自由软件。 + * **semifree**:这个软件包大部分是自由的,但包含一些非自由软件。 + * **uses-nonfree**:这个软件包依赖、推荐或不恰当地与其他自由软件或服务集成。 +该使用程序的另一个显著特点是它不仅显示了专有软件包,而且还显示这些包的替代品。 +希望这有些帮助。我很快就会在这里提供另一份有用的指南。敬请关注! -Another notable feature of this utility is it's not just displays the propriety packages, but also alternatives to such packages. - -Hope this helps. I will be soon here with another useful guide soon. Stay tuned! - -Cheers! +干杯! +资源: +- [Absolutely Proprietary][5] -------------------------------------------------------------------------------- via: https://www.ostechnix.com/find-installed-proprietary-packages-arch-linux/ 作者:[SK][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 @@ -117,4 +124,5 @@ via: https://www.ostechnix.com/find-installed-proprietary-packages-arch-linux/ [1]:https://git.parabola.nu/blacklist.git/plain/blacklist.txt [2]:https://git.parabola.nu/blacklist.git/plain/aur-blacklist.txt [3]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 -[4]:http://www.ostechnix.com/wp-content/uploads/2018/01/Proprietary-Packages-1-1.png () +[4]:http://www.ostechnix.com/wp-content/uploads/2018/01/Proprietary-Packages-1-1.png +[5]:https://github.com/vmavromatis/absolutely-proprietary \ No newline at end of file diff --git a/translated/tech/20180115 How debuggers really work.md b/published/20180115 How debuggers really work.md similarity index 85% rename from translated/tech/20180115 How debuggers really work.md rename to published/20180115 How debuggers really work.md index b4b5740fe1..e7f2772948 100644 --- a/translated/tech/20180115 How debuggers really work.md +++ b/published/20180115 How debuggers really work.md @@ -1,13 +1,15 @@ 调试器到底怎样工作 ====== +> 你也许用过调速器检查过你的代码,但你知道它们是如何做到的吗? + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/annoyingbugs.png?itok=ywFZ99Gs) 供图:opensource.com -调试器是那些大多数(即使不是每个)开发人员在软件工程职业生涯中至少使用过一次的软件之一,但是你们中有多少人知道它们到底是如何工作的?我在悉尼 [linux.conf.au 2018][1] 的演讲中,将讨论从头开始编写调试器...使用 [Rust][2]! +调试器是大多数(即使不是每个)开发人员在软件工程职业生涯中至少使用过一次的那些软件之一,但是你们中有多少人知道它们到底是如何工作的?我在悉尼 [linux.conf.au 2018][1] 的演讲中,将讨论从头开始编写调试器……使用 [Rust][2]! -在本文中,术语调试器/跟踪器可以互换。 “被跟踪者”是指正在被跟踪者跟踪的进程。 +在本文中,术语调试器debugger跟踪器tracer可以互换。 “被跟踪者Tracee”是指正在被跟踪器跟踪的进程。 ### ptrace 系统调用 @@ -17,59 +19,46 @@ long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data); ``` -这是一个可以操纵进程几乎所有方面的系统调用;但是,在调试器可以连接到一个进程之前,“被跟踪者”必须以请求 `PTRACE_TRACEME` 调用 `ptrace`。这告诉 Linux,父进程通过 `ptrace` 连接到这个进程是合法的。但是......我们如何强制一个进程调用 `ptrace`?很简单!`fork/execve` 提供了在 `fork` 之后但在被跟踪者真正开始使用 `execve` 之前调用 `ptrace` 的简单方法。很方便地,`fork` 还会返回被跟踪者的 `pid`,这是后面使用 `ptrace` 所必需的。 +这是一个可以操纵进程几乎所有方面的系统调用;但是,在调试器可以连接到一个进程之前,“被跟踪者”必须以请求 `PTRACE_TRACEME` 调用 `ptrace`。这告诉 Linux,父进程通过 `ptrace` 连接到这个进程是合法的。但是……我们如何强制一个进程调用 `ptrace`?很简单!`fork/execve` 提供了在 `fork` 之后但在被跟踪者真正开始使用 `execve` 之前调用 `ptrace` 的简单方法。很方便地,`fork` 还会返回被跟踪者的 `pid`,这是后面使用 `ptrace` 所必需的。 现在被跟踪者可以被调试器追踪,重要的变化发生了: - * 每当一个信号被传送到被调试者时,它就会停止,并且一个可以被 `wait` 系列系统调用捕获的等待事件被传送给跟踪器。 + * 每当一个信号被传送到被跟踪者时,它就会停止,并且一个可以被 `wait` 系列的系统调用捕获的等待事件被传送给跟踪器。 * 每个 `execve` 系统调用都会导致 `SIGTRAP` 被传递给被跟踪者。(与之前的项目相结合,这意味着被跟踪者在一个 `execve` 完全发生之前停止。) 这意味着,一旦我们发出 `PTRACE_TRACEME` 请求并调用 `execve` 系统调用来实际在被跟踪者(进程上下文)中启动程序时,被跟踪者将立即停止,因为 `execve` 会传递一个 `SIGTRAP`,并且会被跟踪器中的等待事件捕获。我们如何继续?正如人们所期望的那样,`ptrace` 有大量的请求可以用来告诉被跟踪者可以继续: - * `PTRACE_CONT`:这是最简单的。 被跟踪者运行,直到它接收到一个信号,此时等待事件被传递给跟踪器。这是最常见的实现真实世界调试器的“继续直至断点”和“永远继续”选项的方式。断点将在下面介绍。 * `PTRACE_SYSCALL`:与 `PTRACE_CONT` 非常相似,但在进入系统调用之前以及在系统调用返回到用户空间之前停止。它可以与其他请求(我们将在本文后面介绍)结合使用来监视和修改系统调用的参数或返回值。系统调用追踪程序 `strace` 很大程度上使用这个请求来获知进程发起了哪些系统调用。 * `PTRACE_SINGLESTEP`:这个很好理解。如果您之前使用过调试器(你会知道),此请求会执行下一条指令,然后立即停止。 - - 我们可以通过各种各样的请求停止进程,但我们如何获得被调试者的状态?进程的状态大多是通过其寄存器捕获的,所以当然 `ptrace` 有一个请求来获得(或修改)寄存器: * `PTRACE_GETREGS`:这个请求将给出被跟踪者刚刚被停止时的寄存器的状态。 - * `PTRACE_SETREGS`:如果跟踪器之前通过调用 `PTRACE_GETREGS` 得到了寄存器的值,它可以在参数结构中修改相应寄存器的值并使用 `PTRACE_SETREGS` 将寄存器设为新值。 + * `PTRACE_SETREGS`:如果跟踪器之前通过调用 `PTRACE_GETREGS` 得到了寄存器的值,它可以在参数结构中修改相应寄存器的值,并使用 `PTRACE_SETREGS` 将寄存器设为新值。 * `PTRACE_PEEKUSER` 和 `PTRACE_POKEUSER`:这些允许从被跟踪者的 `USER` 区读取信息,这里保存了寄存器和其他有用的信息。 这可以用来修改单一寄存器,而避免使用更重的 `PTRACE_{GET,SET}REGS` 请求。 - - 在调试器仅仅修改寄存器是不够的。调试器有时需要读取一部分内存,甚至对其进行修改。GDB 可以使用 `print` 得到一个内存位置或变量的值。`ptrace` 通过下面的方法实现这个功能: * `PTRACE_PEEKTEXT` 和 `PTRACE_POKETEXT`:这些允许读取和写入被跟踪者地址空间中的一个字。当然,使用这个功能时被跟踪者要被暂停。 - - -真实世界的调试器也有类似断点和观察点的功能。 在接下来的部分中,我将深入体系结构对调试器支持的细节。为了清晰和简洁,本文将只考虑x86。 +真实世界的调试器也有类似断点和观察点的功能。 在接下来的部分中,我将深入体系结构对调试器支持的细节。为了清晰和简洁,本文将只考虑 x86。 ### 体系结构的支持 `ptrace` 很酷,但它是如何工作? 在前面的部分中,我们已经看到 `ptrace` 跟信号有很大关系:`SIGTRAP` 可以在单步跟踪、`execve` 之前以及系统调用前后被传送。信号可以通过一些方式产生,但我们将研究两个具体的例子,以展示信号可以被调试器用来在给定的位置停止程序(有效地创建一个断点!): - * **未定义的指令**:当一个进程尝试执行一个未定义的指令,CPU 将产生一个异常。此异常通过 CPU 中断处理,内核中相应的中断处理程序被调用。这将导致一个 `SIGILL` 信号被发送给进程。 这依次导致进程被停止,跟踪器通过一个等待事件被通知,然后它可以决定后面做什么。在 x86 上,指令 `ud2` 被确保始终是未定义的。 - * **调试中断**:前面的方法的问题是,`ud2` 指令需要占用两个字节的机器码。存在一条特殊的单字节指令能够触发一个中断,它是 `int $3`,机器码是 `0xCC`。 当该中断发出时,内核向进程发送一个 `SIGTRAP`,如前所述,跟踪器被通知。 - - -这很好,但如何做我们胁迫的被跟踪者执行这些指令? 这很简单:利用 `ptrace` 的 `PTRACE_POKETEXT` 请求,它可以覆盖内存中的一个字。 调试器将使用 `PTRACE_PEEKTEXT` 读取该位置原来的值并替换为 `0xCC` ,然后在其内部状态中记录该处原来的值,以及它是一个断点的事实。 下次被跟踪者执行到该位置时,它将被通过 `SIGTRAP` 信号自动停止。 然后调试器的最终用户可以决定如何继续(例如,检查寄存器)。 +这很好,但如何我们才能胁迫被跟踪者执行这些指令? 这很简单:利用 `ptrace` 的 `PTRACE_POKETEXT` 请求,它可以覆盖内存中的一个字。 调试器将使用 `PTRACE_PEEKTEXT` 读取该位置原来的值并替换为 `0xCC` ,然后在其内部状态中记录该处原来的值,以及它是一个断点的事实。 下次被跟踪者执行到该位置时,它将被通过 `SIGTRAP` 信号自动停止。 然后调试器的最终用户可以决定如何继续(例如,检查寄存器)。 好吧,我们已经讲过了断点,那观察点呢? 当一个特定的内存位置被读或写,调试器如何停止程序? 当然你不可能为了能够读或写内存而去把每一个指令都覆盖为 `int $3`。有一组调试寄存器为了更有效的满足这个目的而被设计出来: - * `DR0` 到 `DR3`:这些寄存器中的每个都包含一个地址(内存位置),调试器因为某种原因希望被跟踪者在那些地址那里停止。 其原因以掩码方式被设定在 `DR7` 寄存器中。 - * `DR4` 和 `DR5`:这些分别是 `DR6` 和 `DR7`过时的别名。 + * `DR4` 和 `DR5`:这些分别是 `DR6` 和 `DR7` 过时的别名。 * `DR6`:调试状态。包含有关 `DR0` 到 `DR3` 中的哪个寄存器导致调试异常被引发的信息。这被 Linux 用来计算与 `SIGTRAP` 信号一起传递给被跟踪者的信息。 - * `DR7`:调试控制。通过使用这些寄存器中的位,调试器可以控制如何解释DR0至DR3中指定的地址。位掩码控制监视点的尺寸(监视1,2,4或8个字节)以及是否在执行、读取、写入时引发异常,或在读取或写入时引发异常。 - + * `DR7`:调试控制。通过使用这些寄存器中的位,调试器可以控制如何解释 `DR0` 至 `DR3` 中指定的地址。位掩码控制监视点的尺寸(监视1、2、4 或 8 个字节)以及是否在执行、读取、写入时引发异常,或在读取或写入时引发异常。 由于调试寄存器是进程的 `USER` 区域的一部分,调试器可以使用 `PTRACE_POKEUSER` 将值写入调试寄存器。调试寄存器只与特定进程相关,因此在进程抢占并重新获得 CPU 控制权之前,调试寄存器会被恢复。 @@ -88,7 +77,7 @@ via: https://opensource.com/article/18/1/how-debuggers-really-work 作者:[Levente Kurusa][a] 译者:[stephenxs](https://github.com/stephenxs) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180115 Why DevSecOps matters to IT leaders.md b/published/20180115 Why DevSecOps matters to IT leaders.md new file mode 100644 index 0000000000..3ca2d5d3ea --- /dev/null +++ b/published/20180115 Why DevSecOps matters to IT leaders.md @@ -0,0 +1,87 @@ +为什么 DevSecOps 对 IT 领导来说如此重要 +====== + +> DevSecOps 也许不是一个优雅的词汇,但是其结果很吸引人:更强的安全、提前出现在开发周期中。来看看一个 IT 领导与 Meltdown 的拼搏。 + +![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/TEP_SecurityTraining1_620x414_1014.png?itok=zqxqJGDG) + +如果 [DevOps][1] 最终是关于创造更好的软件,那也就意味着是更安全的软件。 + +而到了术语 “DevSecOps”,就像任何其他 IT 术语一样,DevSecOps —— 一个更成熟的 DevOps 的后代 ——可能容易受到炒作和盗用。但这个术语对那些拥抱了 DevOps 文化的领导者们来说具有重要的意义,并且其实践和工具可以帮助他们实现其承诺。 + +说道这里:“DevSecOps”是什么意思? + +“DevSecOps 是开发、安全、运营的混合,”来自 [Datical][2] 的首席技术官和联合创始人 Robert 说。“这提醒我们,对我们的应用程序来说安全和创建并部署应用到生产中一样重要。” + +**[想阅读其他首席技术官的 DevOps 文章吗?查阅我们丰富的资源,[DevOps:IT 领导者指南][3]]** + +向非技术人员解释 DevSecOps 的一个简单的方法是:它是指将安全有意并提前加入到开发过程中。 + +“安全团队从历史上一直都被孤立于开发团队——每个团队在 IT 的不同领域都发展了很强的专业能力”,来自红帽安全策的专家 Kirsten 最近告诉我们。“不需要这样,非常关注安全也关注他们通过软件来兑现商业价值的能力的企业正在寻找能够在应用开发生命周期中加入安全的方法。他们通过在整个 CI/CD 管道中集成安全实践、工具和自动化来采用 DevSecOps。” + +“为了能够做的更好,他们正在整合他们的团队——专业的安全人员从开始设计到部署到生产中都融入到了开发团队中了,”她说,“双方都收获了价值——每个团队都拓展了他们的技能和基础知识,使他们自己都成更有价值的技术人员。 DevOps 做的很正确——或者说 DevSecOps——提高了 IT 的安全性。” + +IT 团队比任何以往都要求要快速频繁的交付服务。DevOps 在某种程度上可以成为一个很棒的推动者,因为它能够消除开发和运营之间通常遇到的一些摩擦,运营一直被排挤在整个过程之外直到要部署的时候,开发者把代码随便一放之后就不再去管理,他们承担更少的基础架构的责任。那种孤立的方法引起了很多问题,委婉的说,在数字时代,如果将安全孤立起来同样的情况也会发生。 + +“我们已经采用了 DevOps,因为它已经被证明通过移除开发和运营之间的阻碍来提高 IT 的绩效,”Reevess 说,“就像我们不应该在开发周期要结束时才加入运营,我们不应该在快要结束时才加入安全。” + +### 为什么 DevSecOps 必然出现 + +或许会把 DevSecOps 看作是另一个时髦词,但对于安全意识很强的IT领导者来说,它是一个实质性的术语:在软件开发管道中安全必须是第一层面的要素,而不是部署前的最后一步的螺栓,或者更糟的是,作为一个团队只有当一个实际的事故发生的时候安全人员才会被重用争抢。 + +“DevSecOps 不只是一个时髦的术语——因为多种原因它是现在和未来 IT 将呈现的状态”,来自 [Sumo Logic] 的安全和合规副总裁 George 说道,“最重要的好处是将安全融入到开发和运营当中开提供保护的能力” + +此外,DevSecOps 的出现可能是 DevOps 自身逐渐成熟并扎根于 IT 之中的一个征兆。 + +“企业中的 DevOps 文化已成定局,而且那意味着开发者们正以不断增长的速度交付功能和更新,特别是自我管理的组织会对合作和衡量的结果更加满意”,来自 [CYBRIC] 的首席技术官和联合创始人 Mike 说道。 + +在实施 DevOps 的同时继续保留原有安全措施的团队和公司,随着他们继续部署的更快更频繁可能正在经历越来越多的安全管理风险上的痛苦。 + +“现在的手工的安全测试方法会继续远远被甩在后面。” + +“如今,手动的安全测试方法正被甩得越来越远,利用自动化和协作将安全测试转移到软件开发生命周期中,因此推动 DevSecOps 的文化是 IT 领导者们为增加整体的灵活性提供安全保证的唯一途径”,Kail 说。 + +转移安全测试也使开发者受益:他们能够在开放的较早的阶段验证并解决潜在的问题——这样很少需要或者甚至不需要安全人员的介入,而不是在一个新的服务或者更新部署之前在他们的代码中发现一个明显的漏洞。 + +“做的正确,DevSecOps 能够将安全融入到开发生命周期中,允许开发者们在没有安全中断的情况下更加快速容易的保证他们应用的安全”,来自 [SAS][8] 的首席信息安全员 Wilson 说道。 + +Wilson 指出静态(SAST)和源组合分析(SCA)工具,集成到团队的持续交付管道中,作为有用的技术通过给予开发者关于他们的代码中的潜在问题和第三方依赖中的漏洞的反馈来使之逐渐成为可能。 + +“因此,开发者们能够主动和迭代的缓解应用安全的问题,然后在不需要安全人员介入的情况下重新进行安全扫描。” Wilson 说。他同时指出 DevSecOps 能够帮助开发者简化更新和打补丁。 + +DevSecOps 并不意味着你不再需要安全组的意见了,就如同 DevOps 并不意味着你不再需要基础架构专家;它只是帮助你减少在生产中发现缺陷的可能性,或者减少导致降低部署速度的阻碍,因为缺陷已经在开发周期中被发现解决了。 + +“如果他们有问题或者需要帮助,我们就在这儿,但是因为已经给了开发者他们需要的保护他们应用安全的工具,我们很少在一个深入的测试中发现一个导致中断的问题,”Wilson 说道。 + +### DevSecOps 遇到 Meltdown + +Sumo Locic 的 Gerchow 向我们分享了一个在运转中的 DevSecOps 文化的一个及时案例:当最近 [Meltdown 和 Spectre] 的消息传来的时候,团队的 DevSecOps 方法使得有了一个快速的响应来减轻风险,没有任何的通知去打扰内部或者外部的顾客,Gerchow 所说的这点对原生云、高监管的公司来说特别的重要。 + +第一步:Gerchow 的小型安全团队都具有一定的开发能力,能够通过 Slack 和它的主要云供应商协同工作来确保它的基础架构能够在 24 小时之内完成修复。 + +“接着我的团队立即开始进行系统级的修复,实现终端客户的零停机时间,不需要去开工单给工程师,如果那样那意味着你需要等待很长的变更过程。所有的变更都是通过 Slack 的自动 jira 票据进行,通过我们的日志监控和分析解决方案”,Gerchow 解释道。 + +在本质上,它听起来非常像 DevOps 文化,匹配正确的人员、过程和工具,但它明确的将安全作为文化中的一部分进行了混合。 + +“在传统的环境中,这将花费数周或数月的停机时间来处理,因为开发、运维和安全三者是相互独立的”,Gerchow 说道,“通过一个 DevSecOps 的过程和习惯,终端用户可以通过简单的沟通和当日修复获得无缝的体验。” + +-------------------------------------------------------------------------------- + +via: https://enterprisersproject.com/article/2018/1/why-devsecops-matters-it-leaders + +作者:[Kevin Casey][a] +译者:[FelixYFZ](https://github.com/FelixYFZ) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://enterprisersproject.com/user/kevin-casey +[1]:https://enterprisersproject.com/tags/devops +[2]:https://www.datical.com/ +[3]:https://enterprisersproject.com/devops?sc_cid=70160000000h0aXAAQ +[4]:https://www.redhat.com/en?intcmp=701f2000000tjyaAAA +[5]:https://enterprisersproject.com/article/2017/10/what-s-next-devops-5-trends-watch +[6]:https://www.sumologic.com/ +[7]:https://www.cybric.io/ +[8]:https://www.sas.com/en_us/home.html +[9]:https://www.redhat.com/en/blog/what-are-meltdown-and-spectre-heres-what-you-need-know?intcmp=701f2000000tjyaAAA diff --git a/published/20180126 Running a Python application on Kubernetes.md b/published/20180126 Running a Python application on Kubernetes.md new file mode 100644 index 0000000000..a6b709a22c --- /dev/null +++ b/published/20180126 Running a Python application on Kubernetes.md @@ -0,0 +1,276 @@ +在 Kubernetes 上运行一个 Python 应用程序 +============================================================ + +> 这个分步指导教程教你通过在 Kubernetes 上部署一个简单的 Python 应用程序来学习部署的流程。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/build_structure_tech_program_code_construction.png?itok=nVsiLuag) + +Kubernetes 是一个具备部署、维护和可伸缩特性的开源平台。它在提供可移植性、可扩展性以及自我修复能力的同时,简化了容器化 Python 应用程序的管理。 + +不论你的 Python 应用程序是简单还是复杂,Kubernetes 都可以帮你高效地部署和伸缩它们,在有限的资源范围内滚动升级新特性。 + +在本文中,我将描述在 Kubernetes 上部署一个简单的 Python 应用程序的过程,它包括: + +* 创建 Python 容器镜像 +* 发布容器镜像到镜像注册中心 +* 使用持久卷 +* 在 Kubernetes 上部署 Python 应用程序 + +### 必需条件 + +你需要 Docker、`kubectl` 以及这个 [源代码][10]。 + +Docker 是一个构建和承载已发布的应用程序的开源平台。可以参照 [官方文档][11] 去安装 Docker。运行如下的命令去验证你的系统上运行的 Docker: + +``` +$ docker info +Containers: 0 +Images: 289 +Storage Driver: aufs + Root Dir: /var/lib/docker/aufs + Dirs: 289 +Execution Driver: native-0.2 +Kernel Version: 3.16.0-4-amd64 +Operating System: Debian GNU/Linux 8 (jessie) +WARNING: No memory limit support +WARNING: No swap limit support +``` + +`kubectl` 是在 Kubernetes 集群上运行命令的一个命令行界面。运行下面的 shell 脚本去安装 `kubectl`: + +``` +curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl +``` + +部署到 Kubernetes 的应用要求必须是一个容器化的应用程序。我们来回顾一下 Python 应用程序的容器化过程。 + +### 一句话了解容器化 + +容器化是指将一个应用程序所需要的东西打包进一个自带操作系统的容器中。这种完整机器虚拟化的好处是,一个应用程序能够在任何机器上运行而无需考虑它的依赖项。 + +我们以 Roman Gaponov 的 [文章][12] 为参考,来为我们的 Python 代码创建一个容器。 + +### 创建一个 Python 容器镜像 + +为创建这些镜像,我们将使用 Docker,它可以让我们在一个隔离的 Linux 软件容器中部署应用程序。Docker 可以使用来自一个 Dockerfile 中的指令来自动化构建镜像。 + +这是我们的 Python 应用程序的 Dockerfile: + +``` +FROM python:3.6 +MAINTAINER XenonStack + +# Creating Application Source Code Directory +RUN mkdir -p /k8s_python_sample_code/src + +# Setting Home Directory for containers +WORKDIR /k8s_python_sample_code/src + +# Installing python dependencies +COPY requirements.txt /k8s_python_sample_code/src +RUN pip install --no-cache-dir -r requirements.txt + +# Copying src code to Container +COPY . /k8s_python_sample_code/src/app + +# Application Environment variables +ENV APP_ENV development + +# Exposing Ports +EXPOSE 5035 + +# Setting Persistent data +VOLUME ["/app-data"] + +# Running Python Application +CMD ["python", "app.py"] +``` + +这个 Dockerfile 包含运行我们的示例 Python 代码的指令。它使用的开发环境是 Python 3.5。 + +### 构建一个 Python Docker 镜像 + +现在,我们可以使用下面的这个命令按照那些指令来构建 Docker 镜像: + +``` +docker build -t k8s_python_sample_code . +``` + +这个命令为我们的 Python 应用程序创建了一个 Docker 镜像。 + +### 发布容器镜像 + +我们可以将我们的 Python 容器镜像发布到不同的私有/公共云仓库中,像 Docker Hub、AWS ECR、Google Container Registry 等等。本教程中我们将发布到 Docker Hub。 + +在发布镜像之前,我们需要给它标记一个版本号: + +``` +docker tag k8s_python_sample_code:latest k8s_python_sample_code:0.1 +``` + +### 推送镜像到一个云仓库 + +如果使用一个 Docker 注册中心而不是 Docker Hub 去保存镜像,那么你需要在你本地的 Docker 守护程序和 Kubernetes Docker 守护程序上添加一个容器注册中心。对于不同的云注册中心,你可以在它上面找到相关信息。我们在示例中使用的是 Docker Hub。 + +运行下面的 Docker 命令去推送镜像: + +``` +docker push k8s_python_sample_code +``` + +### 使用 CephFS 持久卷 + +Kubernetes 支持许多的持久存储提供商,包括 AWS EBS、CephFS、GlusterFS、Azure Disk、NFS 等等。我在示例中使用 CephFS 做为 Kubernetes 的持久卷。 + +为使用 CephFS 存储 Kubernetes 的容器数据,我们将创建两个文件: + +`persistent-volume.yml` : + +``` +apiVersion: v1 +kind: PersistentVolume +metadata: + name: app-disk1 + namespace: k8s_python_sample_code +spec: + capacity: + storage: 50Gi + accessModes: + - ReadWriteMany + cephfs: + monitors: + - "172.17.0.1:6789" + user: admin + secretRef: + name: ceph-secret + readOnly: false +``` + +`persistent_volume_claim.yaml`: + +``` +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: appclaim1 + namespace: k8s_python_sample_code +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 10Gi +``` + +现在,我们将使用 `kubectl` 去添加持久卷并声明到 Kubernetes 集群中: + +``` +$ kubectl create -f persistent-volume.yml +$ kubectl create -f persistent-volume-claim.yml +``` + +现在,我们准备去部署 Kubernetes。 + +### 在 Kubernetes 上部署应用程序 + +为管理部署应用程序到 Kubernetes 上的最后一步,我们将创建两个重要文件:一个服务文件和一个部署文件。 + +使用下列的内容创建服务文件,并将它命名为 `k8s_python_sample_code.service.yml`: + +``` +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: k8s_python_sample_code + name: k8s_python_sample_code + namespace: k8s_python_sample_code +spec: + type: NodePort + ports: + - port: 5035 + selector: + k8s-app: k8s_python_sample_code +``` + +使用下列的内容创建部署文件并将它命名为 `k8s_python_sample_code.deployment.yml`: + +``` +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: +  name: k8s_python_sample_code +  namespace: k8s_python_sample_code +spec: +  replicas: 1 +  template: +  metadata: +    labels: +    k8s-app: k8s_python_sample_code +  spec: +    containers: +    - name: k8s_python_sample_code +      image: k8s_python_sample_code:0.1 +      imagePullPolicy: "IfNotPresent" +      ports: +      - containerPort: 5035 +      volumeMounts: +        - mountPath: /app-data +          name: k8s_python_sample_code +     volumes:  +         - name: +           persistentVolumeClaim: +             claimName: appclaim1 +``` + +最后,我们使用 `kubectl` 将应用程序部署到 Kubernetes: + +``` +$ kubectl create -f k8s_python_sample_code.deployment.yml $ kubectl create -f k8s_python_sample_code.service.yml +``` + +现在,你的应用程序已经成功部署到 Kubernetes。 + +你可以通过检查运行的服务来验证你的应用程序是否在运行: + +``` +kubectl get services +``` + +或许 Kubernetes 可以解决未来你部署应用程序的各种麻烦! + + _想学习更多关于 Python 的知识?Nanjekye 的书,[和平共处的 Python 2 和 3][7] 提供了完整的方法,让你写的代码在 Python 2 和 3 上完美运行,包括如何转换已有的 Python 2 代码为能够可靠运行在 Python 2 和 3 上的代码的详细示例。_ + + +### 关于作者 + + [![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/joannah-nanjekye.jpg?itok=F4RqEjoA)][13] Joannah Nanjekye - Straight Outta 256,只要结果不问原因,充满激情的飞行员,喜欢用代码说话。[关于我的更多信息][8] + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/running-python-application-kubernetes + +作者:[Joannah Nanjekye][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/nanjekyejoannah +[1]:https://opensource.com/resources/python?intcmp=7016000000127cYAAQ +[2]:https://opensource.com/resources/python/ides?intcmp=7016000000127cYAAQ +[3]:https://opensource.com/resources/python/gui-frameworks?intcmp=7016000000127cYAAQ +[4]:https://opensource.com/tags/python?intcmp=7016000000127cYAAQ +[5]:https://developers.redhat.com/?intcmp=7016000000127cYAAQ +[6]:https://opensource.com/article/18/1/running-python-application-kubernetes?rate=D9iKksKbd9q9vOVb92Mg-v0Iyqn0QVO5fbIERTbSHz4 +[7]:https://www.apress.com/gp/book/9781484229545 +[8]:https://opensource.com/users/nanjekyejoannah +[9]:https://opensource.com/user/196386/feed +[10]:https://github.com/jnanjekye/k8s_python_sample_code/tree/master +[11]:https://docs.docker.com/engine/installation/ +[12]:https://hackernoon.com/docker-tutorial-getting-started-with-python-redis-and-nginx-81a9d740d091 +[13]:https://opensource.com/users/nanjekyejoannah +[14]:https://opensource.com/users/nanjekyejoannah +[15]:https://opensource.com/users/nanjekyejoannah +[16]:https://opensource.com/tags/python +[17]:https://opensource.com/tags/kubernetes diff --git a/published/20180128 Being open about data privacy.md b/published/20180128 Being open about data privacy.md new file mode 100644 index 0000000000..d927af148d --- /dev/null +++ b/published/20180128 Being open about data privacy.md @@ -0,0 +1,95 @@ +对数据隐私持开放的态度 +====== + +> 尽管有包括 GDPR 在内的法规,数据隐私对于几乎所有的人来说都是很重要的事情。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/GOV_opendata.png?itok=M8L2HGVx) + +今天(LCTT 译注:本文发表于 2018/1/28)是[数据隐私日][1]Data Privacy Day,(在欧洲叫“数据保护日Data Protection Day”),你可能会认为现在我们处于一个开源的世界中,所有的数据都应该是自由的,[就像人们想的那样][2],但是现实并没那么简单。主要有两个原因: + +1. 我们中的大多数(不仅仅是在开源中)认为至少有些关于我们自己的数据是不愿意分享出去的(我在之前发表的一篇文章中列举了一些例子[3]) +2. 我们很多人虽然在开源中工作,但事实上是为了一些商业公司或者其他一些组织工作,也是在合法的要求范围内分享数据。 + +所以实际上,数据隐私对于每个人来说是很重要的。 + +事实证明,在美国和欧洲之间,人们和政府认为让组织使用哪些数据的出发点是有些不同的。前者通常为商业实体(特别是愤世嫉俗的人们会指出是大型的商业实体)利用他们所收集到的关于我们的数据提供了更多的自由度。在欧洲,完全是另一观念,一直以来持有的多是有更多约束限制的观念,而且在 5 月 25 日,欧洲的观点可以说取得了胜利。 + +### 通用数据保护条例(GDPR)的影响 + +那是一个相当全面的声明,其实事实上这是 2016 年欧盟通过的一项称之为通用数据保护条例General Data Protection Regulation(GDPR)的立法的日期。数据通用保护条例在私人数据怎样才能被保存,如何才能被使用,谁能使用,能被持有多长时间这些方面设置了严格的规则。它描述了什么数据属于私人数据——而且涉及的条目范围非常广泛,从你的姓名、家庭住址到你的医疗记录以及接通你电脑的 IP 地址。 + +通用数据保护条例的重要之处是它并不仅仅适用于欧洲的公司,如果你是阿根廷人、日本人、美国人或者是俄罗斯的公司而且你正在收集涉及到欧盟居民的数据,你就要受到这个条例的约束管辖。 + +“哼!” 你可能会这样说^注1 ,“我的业务不在欧洲:他们能对我有啥约束?” 答案很简单:如果你想继续在欧盟做任何生意,你最好遵守,因为一旦你违反了通用数据保护条例的规则,你将会受到你的全球总收入百分之四的惩罚。是的,你没听错,是全球总收入,而不是仅仅在欧盟某一国家的的收入,也不只是净利润,而是全球总收入。这将会让你去叮嘱告知你的法律团队,他们就会知会你的整个团队,同时也会立即去指引你的 IT 团队,确保你的行为在相当短的时间内合规。 + +看上去这和非欧盟公民没有什么相关性,但其实不然,对大多数公司来说,对所有的他们的顾客、合作伙伴以及员工实行同样的数据保护措施是件既简单又有效的事情,而不是仅针对欧盟公民实施,这将会是一件很有利的事情。^注2 + +然而,数据通用保护条例不久将在全球实施并不意味着一切都会变的很美好^注3 :事实并非如此,我们一直在丢弃关于我们自己的信息——而且允许公司去使用它。 + +有一句话是这么说的(尽管很争议):“如果你没有在付费,那么你就是产品。”这句话的意思就是如果你没有为某一项服务付费,那么其他的人就在付费使用你的数据。你有付费使用 Facebook、推特、谷歌邮箱?你觉得他们是如何赚钱的?大部分是通过广告,一些人会争论那是他们向你提供的一项服务而已,但事实上是他们在利用你的数据从广告商里获取收益。你不是一个真正的广告的顾客——只有当你从看了广告后买了他们的商品之后你才变成了他们的顾客,但直到这个发生之前,都是广告平台和广告商的关系。 + +有些服务是允许你通过付费来消除广告的(流媒体音乐平台声破天就是这样的),但从另一方面来讲,即使你认为付费的服务也可以启用广告(例如,亚马逊正在努力让 Alexa 发广告),除非我们想要开始为这些所有的免费服务付费,我们需要清楚我们所放弃的,而且在我们暴露的和不想暴露的之间做一些选择。 + +### 谁是顾客? + +关于数据的另一个问题一直在困扰着我们,它是产生的数据量的直接结果。有许多组织一直在产生巨量的数据,包括公共的组织比如大学、医院或者是政府部门^注4 ——而且他们没有能力去储存这些数据。如果这些数据没有长久的价值也就没什么要紧的,但事实正好相反,随着处理大数据的工具正在开发中,而且这些组织也认识到他们现在以及在不久的将来将能够去挖掘这些数据。 + +然而他们面临的是,随着数据的增长和存储量无法跟上该怎么办。幸运的是——而且我是带有讽刺意味的使用了这个词^注5 ,大公司正在介入去帮助他们。“把你们的数据给我们,”他们说,“我们将免费保存。我们甚至让你随时能够使用你所收集到的数据!”这听起来很棒,是吗?这是大公司^注6 的一个极具代表性的例子,站在慈善的立场上帮助公共组织管理他们收集到的关于我们的数据。 + +不幸的是,慈善不是唯一的理由。他们是附有条件的:作为同意保存数据的交换条件,这些公司得到了将数据访问权限出售给第三方的权利。你认为公共组织,或者是被收集数据的人在数据被出售使用权使给第三方,以及在他们如何使用上能有发言权吗?我将把这个问题当做一个练习留给读者去思考。^注7 + +### 开放和积极 + +然而并不只有坏消息。政府中有一项在逐渐发展起来的“开放数据”运动鼓励各个部门免费开放大量他们的数据给公众或者其他组织。在某些情况下,这是专门立法的。许多志愿组织——尤其是那些接受公共资金的——正在开始这样做。甚至商业组织也有感兴趣的苗头。而且,有一些技术已经可行了,例如围绕不同的隐私和多方计算上,正在允许跨越多个数据集挖掘数据,而不用太多披露个人的信息——这个计算问题从未如现在比你想象的更容易。 + +这些对我们来说意味着什么呢?我之前在网站 Opensource.com 上写过关于[开源的共享福利][4],而且我越来越相信我们需要把我们的视野从软件拓展到其他区域:硬件、组织,和这次讨论有关的,数据。让我们假设一下你是 A 公司要提向另一家公司客户 B^注8 提供一项服务 。在此有四种不同类型的数据: + + 1. 数据完全开放:对 A 和 B 都是可得到的,世界上任何人都可以得到 + 2. 数据是已知的、共享的,和机密的:A 和 B 可得到,但其他人不能得到 + 3. 数据是公司级别上保密的:A 公司可以得到,但 B 顾客不能 + 4. 数据是顾客级别保密的:B 顾客可以得到,但 A 公司不能 + +首先,也许我们对数据应该更开放些,将数据默认放到选项 1 中。如果那些数据对所有人开放——在无人驾驶、语音识别,矿藏以及人口数据统计会有相当大的作用的。^注9 如果我们能够找到方法将数据放到选项 2、3 和 4 中,不是很好吗?——或者至少它们中的一些——在选项 1 中是可以实现的,同时仍将细节保密?这就是研究这些新技术的希望。 +然而有很长的路要走,所以不要太兴奋,同时,开始考虑将你的的一些数据默认开放。 + +### 一些具体的措施 + +我们如何处理数据的隐私和开放?下面是我想到的一些具体的措施:欢迎大家评论做出更多的贡献。 + + * 检查你的组织是否正在认真严格的执行通用数据保护条例。如果没有,去推动实施它。 + * 要默认加密敏感数据(或者适当的时候用散列算法),当不再需要的时候及时删掉——除非数据正在被处理使用,否则没有任何借口让数据清晰可见。 + * 当你注册了一个服务的时候考虑一下你公开了什么信息,特别是社交媒体类的。 + * 和你的非技术朋友讨论这个话题。 + * 教育你的孩子、你朋友的孩子以及他们的朋友。然而最好是去他们的学校和他们的老师谈谈在他们的学校中展示。 + * 鼓励你所服务和志愿贡献的组织,或者和他们沟通一些推动数据的默认开放。不是去思考为什么我要使数据开放,而是从我为什么不让数据开放开始。 + * 尝试去访问一些开源数据。挖掘使用它、开发应用来使用它,进行数据分析,画漂亮的图,^注10 制作有趣的音乐,考虑使用它来做些事。告诉组织去使用它们,感谢它们,而且鼓励他们去做更多。 + +**注:** + +1. 我承认你可能尽管不会。 +2. 假设你坚信你的个人数据应该被保护。 +3. 如果你在思考“极好的”的寓意,在这点上你并不孤独。 +4. 事实上这些机构能够有多开放取决于你所居住的地方。 +5. 假设我是英国人,那是非常非常大的剂量。 +6. 他们可能是巨大的公司:没有其他人能够负担得起这么大的存储和基础架构来使数据保持可用。 +7. 不,答案是“不”。 +8. 尽管这个例子也同样适用于个人。看看:A 可能是 Alice,B 可能是 BOb…… +9. 并不是说我们应该暴露个人的数据或者是这样的数据应该被保密,当然——不是那类的数据。 +10. 我的一个朋友当她接孩子放学的时候总是下雨,所以为了避免确认失误,她在整个学年都访问天气信息并制作了图表分享到社交媒体上。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/being-open-about-data-privacy + +作者:[Mike Bursell][a] +译者:[FelixYFZ](https://github.com/FelixYFZ) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/mikecamel +[1]:https://en.wikipedia.org/wiki/Data_Privacy_Day +[2]:https://en.wikipedia.org/wiki/Information_wants_to_be_free +[3]:https://aliceevebob.wordpress.com/2017/06/06/helping-our-governments-differently/ +[4]:https://opensource.com/article/17/11/commonwealth-open-source +[5]:http://www.outpost9.com/reference/jargon/jargon_40.html#TAG2036 diff --git a/translated/tech/20180228 Why Python devs should use Pipenv.md b/published/20180228 Why Python devs should use Pipenv.md similarity index 54% rename from translated/tech/20180228 Why Python devs should use Pipenv.md rename to published/20180228 Why Python devs should use Pipenv.md index 1e5d3dcd79..57a305f4b4 100644 --- a/translated/tech/20180228 Why Python devs should use Pipenv.md +++ b/published/20180228 Why Python devs should use Pipenv.md @@ -1,101 +1,101 @@ 为什么 Python 开发人员应该使用 Pipenv ===== +> 只用了一年, Pipenv 就变成了管理软件包依赖关系的 Python 官方推荐资源。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/python-programming-code-keyboard.png?itok=fxiSpmnd) -这篇文章是与 [Jeff Triplett][1] 共同撰写的。 - -Pipenv 是由 Kenneth Reitz 在一年多前创建的“面向人类(to校正者:这里为人类感觉翻译为为开发者更好一点)而生的 Python 开发工作流”,它已经成为管理软件包依赖关系的[ Python 官方推荐资源][2]。但是对于它解决了什么问题,以及它如何比使用 `pip` 和 `requirements.txt` 文件的标准工作流更有用处,这两点仍然存在困惑。在本月的 Python 专栏中,我们将填补这些空白。 +Pipenv 是由 Kenneth Reitz 在一年多前创建的“面向开发者而生的 Python 开发工作流”,它已经成为管理软件包依赖关系的[ Python 官方推荐资源][2]。但是对于它解决了什么问题,以及它如何比使用 `pip` 和 `requirements.txt` 文件的标准工作流更有用处,这两点仍然存在困惑。在本月的 Python 专栏中,我们将填补这些空白。 ### Python 包安装简史 为了理解 Pipenv 所解决的问题,看一看 Python 包管理如何发展十分有用的。 -让我们回到第一个 Python 版本,我们有 Python,但是没有干净的方法来安装软件包。 +让我们回到第一个 Python 版本,这时我们有了 Python,但是没有干净的方法来安装软件包。 然后有了 [Easy Install][3],这是一个可以相对容易地安装其他 Python 包的软件包,但它也带来了一个问题:卸载不需要的包并不容易。 [pip][4] 登场,绝大多数 Python 用户都熟悉它。`pip` 可以让我们安装和卸载包。我们可以指定版本,运行 `pip freeze > requirements.txt` 来输出一个已安装包列表到一个文本文件,还可以用相同的文本文件配合 `pip install -r requirements.txt` 来安装一个应用程序需要的所有包。 -但是 `pip` 并没有包含将包彼此隔离的方法。我们可能会开发使用相同库的不同版本的应用程序,因此我们需要一种方法来实现这一点。随之而来的是[虚拟环境][5],它使我们能够为我们开发的每个应用程序创建一个小型的,隔离的环境。我们已经看到了许多管理虚拟环境的工具:[virtualenv][6], [venv][7], [virtualenvwrapper][8], [pyenv][9], [pyenv-virtualenv][10], [pyenv-virtualenvwrapper][11] 等等。它们都可以很好地使用 `pip` 和 `requirements.txt` 文件。 +但是 `pip` 并没有包含将软件包彼此隔离的方法。我们可能会开发使用相同库的不同版本的应用程序,因此我们需要一种方法来实现这一点。随之而来的是[虚拟环境][5],它使我们能够为我们开发的每个应用程序创建一个小型的、隔离的环境。我们已经看到了许多管理虚拟环境的工具:[virtualenv][6]、 [venv][7]、 [virtualenvwrapper][8]、 [pyenv][9]、 [pyenv-virtualenv][10]、 [pyenv-virtualenvwrapper][11] 等等。它们都可以很好地使用 `pip` 和 `requirements.txt` 文件。 ### 新方法:Pipenv Pipenv 旨在解决几个问题: -首先,问题是需要 `pip` 库来安装包,外加一个用于创建虚拟环境的库,以及用于管理虚拟环境的库,以及与这些库相关的所有命令。这些都需要管理。Pipenv 附带包管理和虚拟环境支持,因此你可以使用一个工具来安装、卸载、跟踪和记录依赖性,并创建、使用和组织你的虚拟环境。当你使用它启动一个项目时,如果你还没有使用它的话,Pipenv 将自动为该项目创建一个虚拟环境。 +首先,需要 `pip` 库来安装包,外加一个用于创建虚拟环境的库,以及用于管理虚拟环境的库,再有与这些库相关的所有命令。这些都需要管理。Pipenv 附带包管理和虚拟环境支持,因此你可以使用一个工具来安装、卸载、跟踪和记录依赖性,并创建、使用和组织你的虚拟环境。当你使用它启动一个项目时,如果你还没有使用虚拟环境的话,Pipenv 将自动为该项目创建一个虚拟环境。 -Pipenv 通过放弃 `requirements.txt` 规范转而将其移动到一个名为 [Pipfile][12] 的新文档中来完成这种依赖管理。当你使用 Pipenv 安装一个库时,项目的 `Pipfile` 会自动更新安装细节,包括版本信息,还有可能的 Git 仓库位置,文件路径和其他信息。 +Pipenv 通过放弃 `requirements.txt` 规范转而将其移动到一个名为 [Pipfile][12] 的新文档中来完成这种依赖管理。当你使用 Pipenv 安装一个库时,项目的 `Pipfile` 会自动更新安装细节,包括版本信息,还有可能的 Git 仓库位置、文件路径和其他信息。 -其次,Pipenv 希望能更容易地管理复杂的相互依赖关系。你的应用程序可能依赖于某个特定版本的库,而那个库可能依赖于另一个特定版本的库,而它只是依赖关系(to 校正者:这句话不太理解)。当你的应用程序使用的两个库有冲突的依赖关系时,你的情况会变得很艰难。Pipenv 希望通过在一个名为 `Pipfile.lock` 的文件中跟踪应用程序相互依赖关系树来减轻这种痛苦。`Pipfile.lock` 还会验证生产中是否使用了正确版本的依赖关系。 +其次,Pipenv 希望能更容易地管理复杂的相互依赖关系。你的应用程序可能依赖于某个特定版本的库,而那个库可能依赖于另一个特定版本的库,这些依赖关系如海龟般堆叠起来。当你的应用程序使用的两个库有冲突的依赖关系时,你的情况会变得很艰难。Pipenv 希望通过在一个名为 `Pipfile.lock` 的文件中跟踪应用程序相互依赖关系树来减轻这种痛苦。`Pipfile.lock` 还会验证生产中是否使用了正确版本的依赖关系。 -另外,当多个开发人员在开发一个项目时,Pipenv 很方便。通过 `pip` 工作流,Casey 可能会安装一个库,并花两天时间使用该库实现一个新功能。当 Casey 提交更改时,他可能会忘记运行 `pip freeze` 来更新 requirements 文件。第二天,Jamie 拉取 Casey 的变化,突然测试失败。这样会花费好一会儿才能意识到问题是在 requirements 文件中缺少相关库,而 Jamie 尚未在虚拟环境中安装这些文件。 +另外,当多个开发人员在开发一个项目时,Pipenv 很方便。通过 `pip` 工作流,凯西可能会安装一个库,并花两天时间使用该库实现一个新功能。当凯西提交更改时,他可能会忘记运行 `pip freeze` 来更新 `requirements.txt` 文件。第二天,杰米拉取凯西的改变,测试就突然失败了。这样会花费好一会儿才能意识到问题是在 `requirements.txt` 文件中缺少相关库,而杰米尚未在虚拟环境中安装这些文件。 -因为 Pipenv 会在安装时自动记录依赖性,如果 Jamie 和 Casey 使用了 Pipenv,`Pipfile` 会自动更新并包含在 Casey 的提交中。这样 Jamie 和 Casey 就可以节省时间并更快地运送他们的产品。 +因为 Pipenv 会在安装时自动记录依赖性,如果杰米和凯西使用了 Pipenv,`Pipfile` 会自动更新并包含在凯西的提交中。这样杰米和凯西就可以节省时间并更快地运送他们的产品。 -最后,将 Pipenv 推荐给在你项目上工作的其他人,因为它使用标准化的方式来安装项目依赖项,开发和测试需求。使用 `pip` 工作流和 requirements 文件意味着你可能只有一个 `requirements.txt` 文件,或针对不同环境的多个 requirements 文件。例如,你的同事可能不清楚他们是否应该在他们的笔记本电脑上运行项目时运行 `dev.txt` 还是 `local.txt`。当两个相似的 requirements 文件彼此不同步时它也会造成混淆:`local.txt` 是否过时了,还是真的应该与 `dev.txt` 不同?多个 requirements 文件需要更多的上下文和文档,以使其他人能够按照预期正确安装依赖关系。这个工作流程有可能会混淆同时并增加你的维护负担。 +最后,将 Pipenv 推荐给在你项目上工作的其他人,因为它使用标准化的方式来安装项目依赖项和开发和测试的需求。使用 `pip` 工作流和 `requirements.txt` 文件意味着你可能只有一个 `requirements.txt` 文件,或针对不同环境的多个 `requirements.txt` 文件。例如,你的同事可能不清楚他们是否应该在他们的笔记本电脑上运行项目时是运行 `dev.txt` 还是 `local.txt`。当两个相似的 `requirements.txt` 文件彼此不同步时它也会造成混淆:`local.txt` 是否过时了,还是真的应该与 `dev.txt` 不同?多个 `requirements.txt` 文件需要更多的上下文和文档,以使其他人能够按照预期正确安装依赖关系。这个工作流程有可能会混淆同时并增加你的维护负担。 使用 Pipenv,它会生成 `Pipfile`,通过为你管理对不同环境的依赖关系,可以避免这些问题。该命令将安装主项目依赖项: + ``` pipenv install - ``` -添加 `--dev` 标志将安装 dev/testing requirements: +添加 `--dev` 标志将安装开发/测试的 `requirements.txt`: + ``` pipenv install --dev - ``` 使用 Pipenv 还有其他好处:它具有更好的安全特性,以易于理解的格式绘制你的依赖关系,无缝处理 `.env` 文件,并且可以在一个文件中自动处理开发与生产环境的不同依赖关系。你可以在[文档][13]中阅读更多内容。 -### Pipenv 行动 +### 使用 Pipenv 使用 Pipenv 的基础知识在官方 Python 包管理教程[管理应用程序依赖关系][14]部分中详细介绍。要安装 Pipenv,使用 `pip`: + ``` pip install pipenv - ``` 要安装在项目中使用的包,请更改为项目的目录。然后安装一个包(我们将使用 Django 作为例子),运行: + ``` pipenv install django - ``` 你会看到一些输出,表明 Pipenv 正在为你的项目创建一个 `Pipfile`。 如果你还没有使用虚拟环境,你还会看到 Pipenv 的一些输出,说明它正在为你创建一个虚拟环境。 -然后,你将看到你在安装包时习惯看到的输出。 +然后,你将看到你在安装包时常看到的输出。 为了生成 `Pipfile.lock` 文件,运行: + ``` pipenv lock - ``` -你也可以使用 Pipenv 运行 Python 脚本。运行名为 `hello.py` 的(to 校正者:这里 top-level该怎么翻译)Python 脚本: +你也可以使用 Pipenv 运行 Python 脚本。运行名为 `hello.py` 的上层 Python 脚本: + ``` pipenv run python hello.py - ``` 你将在控制台中看到预期结果。 启动一个 shell,运行: + ``` pipenv shell - ``` 如果你想将当前使用 `requirements.txt` 文件的项目转换为使用 Pipenv,请安装 Pipenv 并运行: + ``` pipenv install requirements.txt - ``` -这将创建一个 Pipfile 并安装指定的 requirements。考虑一下升级你的项目! +这将创建一个 Pipfile 并安装指定的 `requirements.txt`。考虑一下升级你的项目! ### 了解更多 @@ -106,9 +106,9 @@ pipenv install requirements.txt via: https://opensource.com/article/18/2/why-python-devs-should-use-pipenv -作者:[Lacey Williams Henschel][a] +作者:[Lacey Williams Henschel][a], [Jeff Triplett][1] 译者:[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/) 荣誉推出 diff --git a/translated/tech/20180302 5 open source software tools for supply chain management.md b/published/20180302 5 open source software tools for supply chain management.md similarity index 56% rename from translated/tech/20180302 5 open source software tools for supply chain management.md rename to published/20180302 5 open source software tools for supply chain management.md index 8ead3394de..3c000a2717 100644 --- a/translated/tech/20180302 5 open source software tools for supply chain management.md +++ b/published/20180302 5 open source software tools for supply chain management.md @@ -1,23 +1,25 @@ 供应链管理方面的 5 个开源软件工具 ====== +> 跟踪您的库存和您需要的材料,用这些供应链管理工具制造产品。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BIZ_Maze2.png?itok=EH_L-J6Q) 本文最初发表于 2016 年 1 月 14 日,最后的更新日期为 2018 年 3 月 2 日。 -如果你正在管理着处理实体货物的业务,[供应链管理][1] 是你的业务流程中非常重要的一部分。不论你是经营着一个只有几个客户的小商店,还是在世界各地拥有数百万计客户和成千上万产品的世界财富 500 强的制造商或零售商,很清楚地知道你的库存和制造产品所需要的零部件,对你来说都是非常重要的事情。 +如果你正在管理着处理实体货物的业务,[供应链管理][1] 是你的业务流程中非常重要的一部分。不论你是经营着一个只有几个客户的小商店,还是在世界各地拥有数以百万计客户和成千上万产品的世界财富 500 强的制造商或零售商,很清楚地知道你的库存和制造产品所需要的零部件,对你来说都是非常重要的事情。 -保持对货品、供应商、客户的持续跟踪,并且所有与它们相关的变动部分都会从中受益,并且,在某些情况下完全依赖专门的软件来帮助管理这些工作流。在本文中,我们将去了解一些免费的和开源的供应链管理方面的软件,以及它们的其中一些功能。 +保持对货品、供应商、客户的持续跟踪,而且所有与它们相关的变动部分都会受益于这些用来帮助管理工作流的专门软件,而在某些情况下需要完全依赖这些软件。在本文中,我们将去了解一些自由及开源的供应链管理方面的软件,以及它们的其中一些功能。 -供应链管理比单纯的库存管理更为强大。它能帮你去跟踪货物流以降低成本,以及为可能发生的各种糟糕的变化来制定应对计划。它能够帮你对出口合规性进行跟踪,不论是合法性、最低品质要求、还是社会和环境的合规性。它能够帮你计划最低供应量,让你能够在订单数量和交付时间之间做出明智的决策。 +供应链管理比单纯的库存管理更为强大。它能帮你去跟踪货物流以降低成本,以及为可能发生的各种糟糕的变化来制定应对计划。它能够帮你对出口合规性进行跟踪,不论是否是出于法律要求、最低品质要求、还是社会和环境责任。它能够帮你计划最低供应量,让你能够在订单数量和交付时间之间做出明智的决策。 -由于它的本质决定了许多供应链管理软件是与类似的软件捆绑在一起的,比如,[客户关系管理][2](CRM)和 [企业资源计划管理][3] (ERP)。因此,当你选择哪个工具更适合你的组织时,你可能会考虑与其它工具集成作为你的决策依据之一。 +由于其本质决定了许多供应链管理软件是与类似的软件捆绑在一起的,比如,[客户关系管理][2](CRM)和 [企业资源计划管理][3] (ERP)。因此,当你选择哪个工具更适合你的组织时,你可能会考虑与其它工具集成作为你的决策依据之一。 ### Apache OFBiz -[Apache OFBiz][4] 是一套帮你管理多种业务流程的相关工具。虽然它能管理多种相关问题,比如,目录、电子商务网站、帐户、和销售点,它在供应链管理方面的主要功能关注于仓库管理、履行、订单、和生产管理。它的可定制性很强,但是,它需要大量的规划去设置和集成到你现有的流程中。这就是它适用于中大型业务的原因之一。项目的功能构建于三个层面:展示层、业务层、和数据层,它是一个弹性很好的解决方案,但是,再强调一遍,它也很复杂。 +[Apache OFBiz][4] 是一套帮你管理多种业务流程的相关工具。虽然它能管理多种相关问题,比如,分类、电子商务网站、会计和 POS,它在供应链管理方面的主要功能关注于仓库管理、履行、订单和生产管理。它的可定制性很强,但是,对应的它需要大量的规划去设置和集成到你现有的流程中。这就是它适用于中大型业务的原因之一。项目的功能构建于三个层面:展示层、业务层和数据层,它是一个弹性很好的解决方案,但是,再强调一遍,它也很复杂。 -Apache OFBiz 的源代码在 [项目仓库][5] 中可以找到。Apache OFBiz 是用 Java 写的,并且它是按 [Apache 2.0 license][6] 授权的。 +Apache OFBiz 的源代码在其 [项目仓库][5] 中可以找到。Apache OFBiz 是用 Java 写的,并且它是按 [Apache 2.0 许可证][6] 授权的。 如果你对它感兴趣,你也可以去查看 [opentaps][7],它是在 OFBiz 之上构建的。Opentaps 强化了 OFBiz 的用户界面,并且添加了 ERP 和 CRM 的核心功能,包括仓库管理、采购和计划。它是按 [AGPL 3.0][8] 授权使用的,对于不接受开源授权的组织,它也提供了商业授权。 @@ -25,25 +27,25 @@ Apache OFBiz 的源代码在 [项目仓库][5] 中可以找到。Apache OFBiz [OpenBoxes][9] 是一个供应链管理和存货管理项目,最初的主要设计目标是为了医疗行业中的药品跟踪管理,但是,它可以通过修改去跟踪任何类型的货品和相关的业务流。它有一个需求预测工具,可以基于历史订单数量、存储跟踪、支持多种场所、过期日期跟踪、销售点支持等进行预测,并且它还有许多其它功能,这使它成为医疗行业的理想选择,但是,它也可以用于其它行业。 -它在 [Eclipse Public License][10] 下可用,OpenBoxes 主要是由 Groovy 写的,它的源代码可以在 [GitHub][11] 上看到。 +它在 [Eclipse 公开许可证][10] 下可用,OpenBoxes 主要是由 Groovy 写的,它的源代码可以在 [GitHub][11] 上看到。 ### OpenLMIS -与 OpenBoxes 类似,[OpenLMIS][12] 也是一个医疗行业的供应链管理工具,但是,它专用设计用于在非洲的资源缺乏地区使用,以确保有限的药物和医疗用品能够用到需要的病人上。它是 API 驱动的,这样用户可以去定制和扩展 OpenLMIS,同时还能维护一个与通用基准代码的连接。它是由络克菲勒基金会开发的,其它的贡献者包括联合国、美国国际开发署、和比尔 & 梅林达 盖茨基金会。 +与 OpenBoxes 类似,[OpenLMIS][12] 也是一个医疗行业的供应链管理工具,但是,它专用设计用于在非洲的资源缺乏地区使用,以确保有限的药物和医疗用品能够用到需要的病人上。它是 API 驱动的,这样用户可以去定制和扩展 OpenLMIS,同时还能维护一个与通用基准代码的连接。它是由洛克菲勒基金会开发的,其它的贡献者包括联合国、美国国际开发署、和比尔 & 梅林达·盖茨基金会。 -OpenLMIS 是用 Java 和 JavaScript 的 AngularJS 写的。它在 [AGPL 3.0 license][13] 下使用,它的源代码在 [GitHub][13] 上可以找到。 +OpenLMIS 是用 Java 和 JavaScript 的 AngularJS 写的。它在 [AGPL 3.0 许可证][13] 下使用,它的源代码在 [GitHub][13] 上可以找到。 ### Odoo -你可能在我们以前的 [ERP 项目][3] 榜的文章上见到过 [Odoo][14]。事实上,根据你的需要,一个全功能的 ERP 对你来说是最适合的。Odoo 的供应链管理工具主要围绕存货和采购管理,同时还与电子商务网站和销售点连接,但是,它也可以与其它的工具连接,比如,与 [frePPLe][15] 连接,它是一个开源的生产计划工具。 +你可能在我们以前的 [ERP 项目][3] 榜的文章上见到过 [Odoo][14]。事实上,根据你的需要,一个全功能的 ERP 对你来说是最适合的。Odoo 的供应链管理工具主要围绕存货和采购管理,同时还与电子商务网站和 POS 连接,但是,它也可以与其它的工具连接,比如,与 [frePPLe][15] 连接,它是一个开源的生产计划工具。 -Odoo 既有软件即服务的解决方案,也有开源的社区版本。开源的版本是以 [LGPL][16] 版本 3 下发行的,源代码在 [GitHub][17] 上可以找到。Odoo 主要是用 Python 来写的。 +Odoo 既有软件即服务(SaaS)的解决方案,也有开源的社区版本。开源的版本是以 [LGPL][16] 版本 3 下发行的,源代码在 [GitHub][17] 上可以找到。Odoo 主要是用 Python 来写的。 ### xTuple -[xTuple][18] 标称自己是“为成长中的企业提供供应链管理软件”,它专注于已经超越了传统的小型企业 ERP 和 CRM 解决方案的企业。它的开源版本称为 Postbooks,添加了一些存货、分销、采购、以及供应商报告的功能,它提供的核心功能是帐务、CRM、以及 ERP 功能,而它的商业版本扩展了制造和分销的 [功能][19]。 +[xTuple][18] 标称自己是“为成长中的企业提供供应链管理软件”,它专注于已经超越了其传统的小型企业 ERP 和 CRM 解决方案的企业。它的开源版本称为 Postbooks,添加了一些存货、分销、采购、以及供应商报告的功能,它提供的核心功能是会计、CRM、以及 ERP 功能,而它的商业版本扩展了制造和分销的 [功能][19]。 -xTuple 在 [CPAL][20] 下使用,这个项目欢迎开发者去 fork 它,为基于存货的制造商去创建其它的业务软件。它的 Web 应用核心是用 JavaScript 写的,它的源代码在 [GitHub][21] 上可以找到。 +xTuple 在 [CPAL][20] 下使用,这个项目欢迎开发者去复刻它,为基于存货的制造商去创建其它的业务软件。它的 Web 应用核心是用 JavaScript 写的,它的源代码在 [GitHub][21] 上可以找到。 就这些,当然了,还有其它的可以帮你处理供应链管理的开源软件。如果你知道还有更好的软件,请在下面的评论区告诉我们。 @@ -53,14 +55,14 @@ via: https://opensource.com/tools/supply-chain-management 作者:[Jason Baker][a] 译者:[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/jason-baker [1]:https://en.wikipedia.org/wiki/Supply_chain_management [2]:https://opensource.com/business/14/7/top-5-open-source-crm-tools -[3]:https://opensource.com/resources/top-4-open-source-erp-systems +[3]:https://linux.cn/article-9785-1.html [4]:http://ofbiz.apache.org/ [5]:http://ofbiz.apache.org/source-repositories.html [6]:http://www.apache.org/licenses/LICENSE-2.0 diff --git a/published/20180305 What-s next in IT automation- 6 trends to watch.md b/published/20180305 What-s next in IT automation- 6 trends to watch.md new file mode 100644 index 0000000000..d907efbf41 --- /dev/null +++ b/published/20180305 What-s next in IT automation- 6 trends to watch.md @@ -0,0 +1,132 @@ +IT 自动化的下一步是什么: 6 大趋势 +====== + +> 自动化专家分享了一点对 [自动化][6]不远的将来的看法。请将这些保留在你的视线之内。 + +![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/cio_ai_artificial_intelligence.png?itok=o0csm9l2) + +我们最近讨论了 [推动 IT 自动化的因素][1],可以看到[当前趋势][2]正在增长,以及那些给刚开始使用自动化部分流程的组织的 [有用的技巧][3] 。 + +噢,我们也分享了如何在贵公司[进行自动化的案例][4]及 [长期成功的关键][5]的专家建议。 + +现在,只有一个问题:自动化的下一步是什么? 我们邀请一系列专家分享一下 [自动化][6]不远的将来的看法。 以下是他们建议 IT 领域领导需密切关注的六大趋势。 + +### 1、 机器学习的成熟 + +对于关于 [机器学习][7](与“自我学习系统”相似的定义)的讨论,对于绝大多数组织的项目来说,实际执行起来它仍然为时过早。但预计这将发生变化,机器学习将在下一次 IT 自动化浪潮中将扮演着至关重要的角色。 + +[Advanced Systems Concepts, Inc.][8] 公司的工程总监 Mehul Amin 指出机器学习是 IT 自动化下一个关键增长领域之一。 + +“随着数据化的发展,自动化软件理应可以自我决策,否则这就是开发人员的责任了”,Amin 说。 “例如,开发者构建了需要执行的内容,但通过使用来自系统内部分析的软件,可以确定执行该流程的最佳系统。” + +假设将这个系统延伸到其他地方中。Amin 指出,机器学习可以使自动化系统在必要的时候提供额外的资源,以需要满足时间线或 SLA,同样在不需要资源以及其他的可能性的时候退出。 + +显然不只有 Amin 一个人这样认为。 + +“IT 自动化正在走向自我学习的方向” ,[Sungard Availability Services][9] 公司首席架构师 Kiran Chitturi 表示,“系统将会能测试和监控自己,加强业务流程和软件交付能力。” + +Chitturi 指出自动化测试就是个例子。脚本测试已经被广泛采用,但很快这些自动化测试流程将会更容易学习,更快发展,例如开发出新的代码或将更为广泛地影响生产环境。 + +### 2、 人工智能催生的自动化 + +上述原则同样适合与相关的(但是独立的) [人工智能][10]的领域。根据对人工智能的定义,机器学习在短时间内可能会对 IT 领域产生巨大的影响(并且我们可能会看到这两个领域的许多重叠的定义和理解)。假定新兴的人工智能技术将也会产生新的自动化机会。 + +[SolarWinds][11] 公司技术负责人 Patrick Hubbard 说,“人工智能和机器学习的整合普遍被认为对未来几年的商业成功起至关重要的作用。” + +### 3、 这并不意味着不再需要人力 + +让我们试着安慰一下那些不知所措的人:前两种趋势并不一定意味着我们将失去工作。 + +这很可能意味着各种角色的改变,以及[全新角色][12]的创造。 + +但是在可预见的将来,至少,你不必需要对机器人鞠躬。 + +“一台机器只能运行在给定的环境变量中——它不能选择包含新的变量,在今天只有人类可以这样做,” Hubbard 解释说。“但是,对于 IT 专业人员来说,这将需要培养 AI 和自动化技能,如对程序设计、编程、管理人工智能和机器学习功能算法的基本理解,以及用强大的安全状态面对更复杂的网络攻击。” + +Hubbard 分享一些新的工具或功能例子,例如支持人工智能的安全软件或机器学习的应用程序,这些应用程序可以远程发现石油管道中的维护需求。两者都可以提高效益和效果,自然不会代替需要信息安全或管道维护的人员。 + +“许多新功能仍需要人工监控,”Hubbard 说。“例如,为了让机器确定一些‘预测’是否可能成为‘规律’,人为的管理是必要的。” + +即使你把机器学习和 AI 先放在一边,看待一般的 IT 自动化,同样原理也是成立的,尤其是在软件开发生命周期中。 + +[Juniper Networks][13] 公司自动化首席架构师 Matthew Oswalt ,指出 IT 自动化增长的根本原因是它通过减少操作基础设施所需的人工工作量来创造直接价值。 + +> 在代码上,操作工程师可以使用事件驱动的自动化提前定义他们的工作流程,而不是在凌晨 3 点来应对基础设施的问题。 + +“它也将操作工作流程作为代码而不再是容易过时的文档或系统知识阶段,”Oswalt 解释说。“操作人员仍然需要在[自动化]工具响应事件方面后发挥积极作用。采用自动化的下一个阶段是建立一个能够跨 IT 频谱识别发生的有趣事件的系统,并以自主方式进行响应。在代码上,操作工程师可以使用事件驱动的自动化提前定义他们的工作流程,而不是在凌晨 3 点来应对基础设施的问题。他们可以依靠这个系统在任何时候以同样的方式作出回应。” + +### 4、 对自动化的焦虑将会减少 + +SolarWinds 公司的 Hubbard 指出,“自动化”一词本身就产生大量的不确定性和担忧,不仅仅是在 IT 领域,而且是跨专业领域,他说这种担忧是合理的。但一些随之而来的担忧可能被夸大了,甚至与科技产业本身共存。现实可能实际上是这方面的镇静力:当自动化的实际实施和实践帮助人们认识到这个列表中的第 3 项时,我们将看到第 4 项的出现。 + +“今年我们可能会看到对自动化焦虑的减少,更多的组织开始接受人工智能和机器学习作为增加现有人力资源的一种方式,”Hubbard 说。“自动化历史上为更多的工作创造了空间,通过降低成本和时间来完成较小任务,并将劳动力重新集中到无法自动化并需要人力的事情上。人工智能和机器学习也是如此。” + +自动化还将减少令 IT 领导者神经紧张的一些焦虑:安全。正如[红帽][14]公司首席架构师 Matt Smith 最近[指出][15]的那样,自动化将越来越多地帮助 IT 部门降低与维护任务相关的安全风险。 + +他的建议是:“首先在维护活动期间记录和自动化 IT 资产之间的交互。通过依靠自动化,您不仅可以消除之前需要大量手动操作和手术技巧的任务,还可以降低人为错误的风险,并展示当您的 IT 组织采纳变更和新工作方法时可能发生的情况。最终,这将迅速减少对应用安全补丁的抵制。而且它还可以帮助您的企业在下一次重大安全事件中摆脱头条新闻。” + +**[ 阅读全文: [12个企业安全坏习惯要打破。][16] ] ** + +### 5、 脚本和自动化工具将持续发展 + +许多组织看到了增加自动化的第一步,通常以脚本或自动化工具(有时称为配置管理工具)的形式作为“早期”工作。 + +但是随着各种自动化技术的使用,对这些工具的观点也在不断发展。 + +[DataVision][18] 首席运营官 Mark Abolafia 表示:“数据中心环境中存在很多重复性过程,容易出现人为错误,[Ansible][17] 等技术有助于缓解这些问题。“通过 Ansible ,人们可以为一组操作编写特定的步骤,并输入不同的变量,例如地址等,使过去长时间的过程链实现自动化,而这些过程以前都需要人为触摸和更长的交付时间。” + +**[想了解更多关于 Ansible 这个方面的知识吗?阅读相关文章:[使用 Ansible 时的成功秘诀][19]。 ]** + +另一个因素是:工具本身将继续变得更先进。 + +“使用先进的 IT 自动化工具,开发人员将能够在更短的时间内构建和自动化工作流程,减少易出错的编码,” ASCI 公司的 Amin 说。“这些工具包括预先构建的、预先测试过的拖放式集成,API 作业,丰富的变量使用,参考功能和对象修订历史记录。” + +### 6、 自动化开创了新的指标机会 + +正如我们在此前所说的那样,IT 自动化不是万能的。它不会修复被破坏的流程,或者以其他方式为您的组织提供全面的灵丹妙药。这也是持续不断的:自动化并不排除衡量性能的必要性。 + +**[ 参见我们的相关文章 [DevOps 指标:你在衡量什么重要吗?][20] ]** + +实际上,自动化应该打开了新的机会。 + +[Janeiro Digital][21] 公司架构师总裁 Josh Collins 说,“随着越来越多的开发活动 —— 源代码管理、DevOps 管道、工作项目跟踪等转向 API 驱动的平台,将这些原始数据拼接在一起以描绘组织效率提升的机会和图景”。 + +Collins 认为这是一种可能的新型“开发组织度量指标”。但不要误认为这意味着机器和算法可以突然预测 IT 所做的一切。 + +“无论是衡量个人资源还是整体团队,这些指标都可以很强大 —— 但应该用大量的背景来衡量。”Collins 说,“将这些数据用于高层次趋势并确认定性观察 —— 而不是临床评级你的团队。” + +**想要更多这样知识, IT 领导者?[注册我们的每周电子邮件通讯][22]。** + +-------------------------------------------------------------------------------- + +via: https://enterprisersproject.com/article/2018/3/what-s-next-it-automation-6-trends-watch + +作者:[Kevin Casey][a] +译者:[MZqk](https://github.com/MZqk) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://enterprisersproject.com/user/kevin-casey +[1]:https://enterprisersproject.com/article/2017/12/5-factors-fueling-automation-it-now +[2]:https://enterprisersproject.com/article/2017/12/4-trends-watch-it-automation-expands +[3]:https://enterprisersproject.com/article/2018/1/getting-started-automation-6-tips +[4]:https://enterprisersproject.com/article/2018/1/how-make-case-it-automation +[5]:https://enterprisersproject.com/article/2018/1/it-automation-best-practices-7-keys-long-term-success +[6]:https://enterprisersproject.com/tags/automation +[7]:https://enterprisersproject.com/article/2018/2/how-spot-machine-learning-opportunity +[8]:https://www.advsyscon.com/en-us/ +[9]:https://www.sungardas.com/en/ +[10]:https://enterprisersproject.com/tags/artificial-intelligence +[11]:https://www.solarwinds.com/ +[12]:https://enterprisersproject.com/article/2017/12/8-emerging-ai-jobs-it-pros +[13]:https://www.juniper.net/ +[14]:https://www.redhat.com/en?intcmp=701f2000000tjyaAAA +[15]:https://enterprisersproject.com/article/2018/2/12-bad-enterprise-security-habits-break +[16]:https://enterprisersproject.com/article/2018/2/12-bad-enterprise-security-habits-break?sc_cid=70160000000h0aXAAQ +[17]:https://opensource.com/tags/ansible +[18]:https://datavision.com/ +[19]:https://opensource.com/article/18/2/tips-success-when-getting-started-ansible?intcmp=701f2000000tjyaAAA +[20]:https://enterprisersproject.com/article/2017/7/devops-metrics-are-you-measuring-what-matters?sc_cid=70160000000h0aXAAQ +[21]:https://www.janeirodigital.com/ +[22]:https://enterprisersproject.com/email-newsletter?intcmp=701f2000000tsjPAAQ diff --git a/published/20180313 Migrating to Linux- Using Sudo.md b/published/20180313 Migrating to Linux- Using Sudo.md new file mode 100644 index 0000000000..2eb4b7d47e --- /dev/null +++ b/published/20180313 Migrating to Linux- Using Sudo.md @@ -0,0 +1,81 @@ +迁移到 Linux:使用 sudo +====== + +> sudo 机制可以让你轻松以普通用户偶尔执行管理任务。让我们来学习一下。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ray-hennessy-233438-unsplash.jpg?itok=d4l7QUtF) + +本文是我们关于迁移到 Linux 的系列文章的第五篇。如果你错过了之前的那些,你可以在这里赶上: + +[第1部分 - 入门介绍][1] +[第2部分 - 磁盘、文件和文件系统][2] +[第3部分 - 图形操作环境][3] +[第4部分 - 命令行][4] + +你可能一直想了解 Linux。也许它在你的工作场所使用,如果你每天使用它,你的工作效率会更高。或者,也许你想在家里的某些计算机上安装 Linux。无论是什么原因,这一系列文章都是为了让过渡更容易。 + +与许多其他操作系统一样,Linux 支持多用户。它甚至支持多个用户同时登录。 + +用户帐户通常会被分配一个可以存储文件的家目录。通常这个家目​​录位于: + +``` +/home/ +``` + +这样,每个用户都有存储自己的文档和其他文件的独立位置。 + +### 管理任务 + +在传统的 Linux 安装中,常规用户帐户无权在系统上执行管理任务。典型的安装 Linux 的系统会要求用户以管理员身份登录以执行某些任务,而不是为每个用户分配权限以执行各种任务。 + +Linux 上的管理员帐户称为 root。 + +### Sudo 解释 + +从历史上看,要执行管理任务,必须以 root 身份登录,执行任务,然后登出。这个过程有点乏味,所以很多人以 root 登录并且整天都以管理员身份工作。这种做法可能会导致灾难性的后果,例如,意外删除系统中的所有文件。当然,root 用户可以做任何事情,因此没有任何保护措施可以防止有人意外地执行影响很大的操作。 + +创建 `sudo` 工具是为了使你更容易以常规用户帐户登录,偶尔以 root 身份执行管理任务,而无需登录、执行任务然后登出。具体来说,`sudo` 允许你以不同的用户身份运行命令。如果你未指定特定用户,则假定你指的是 root 用户。 + +`sudo` 可以有复杂的设置,允许用户有权限使用 `sudo` 运行某些命令,而其他的不行。通常,安装的桌面系统会使创建的第一个帐户在 `sudo` 中有完全的权限,因此你作为主要用户可以完全管理 Linux 安装。 + +### 使用 Sudo + +某些安装 Linux 的系统设置了 `sudo`,因此你仍需要知道 root 帐户的密码才能执行管理任务。其他人,设置 `sudo` 输入自己的密码。这里有不同的哲学。 + +当你尝试在图形环境中执行管理任务时,通常会打开一个要求输入密码的对话框。输入你自己的密码(例如,在 Ubuntu 上)或 root 帐户的密码(例如,Red Hat)。 + +当你尝试在命令行中执行管理任务时,它通常只会给你一个 “permission denied” 错误。然后你在前面用 `sudo` 重新运行命令。例如: + +``` +systemctl start vsftpd +Failed to start vsftpd.service: Access denied + +sudo systemctl start vsftpd +[sudo] password for user1: +``` + +### 何时使用 Sudo + +以 root 身份运行命令(在 `sudo` 或其他情况下)并不总是解决权限错误的最佳解决方案。虽然将以 root 身份运行会消除 “permission denied” 错误,但有时最好寻找根本原因而不是仅仅解决症状。有时文件拥有错误的所有者和权限。 + +当你在尝试一个需要 root 权限来执行操作的任务或者程序时使用 `sudo`。如果文件恰好由另一个用户(包括 root 用户)拥有,请不要使用 `sudo`。在第二种情况下,最好正确设置文件的权限。 + +通过 Linux 基金会和 edX 的免费[“Linux 介绍”][5]课程了解有关 Linux 的更多信息。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/3/migrating-linux-using-sudo + +作者:[John Bonesio][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/johnbonesio +[1]:https://linux.cn/article-9212-1.html +[2]:https://linux.cn/article-9213-1.html +[3]:https://linux.cn/article-9293-1.html +[4]:https://linux.cn/article-9565-1.html +[5]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/translated/tech/20180315 Kubernetes distributed application deployment with sample Face Recognition App.md b/published/20180315 Kubernetes distributed application deployment with sample Face Recognition App.md similarity index 81% rename from translated/tech/20180315 Kubernetes distributed application deployment with sample Face Recognition App.md rename to published/20180315 Kubernetes distributed application deployment with sample Face Recognition App.md index a05307301a..612b84c53d 100644 --- a/translated/tech/20180315 Kubernetes distributed application deployment with sample Face Recognition App.md +++ b/published/20180315 Kubernetes distributed application deployment with sample Face Recognition App.md @@ -1,9 +1,11 @@ -Kubernetes 分布式应用部署实战 -- 以人脸识别应用为例 +Kubernetes 分布式应用部署实战:以人脸识别应用为例 ============================================================ -# 简介 +![](https://skarlso.github.io/img/2018/03/kube_overview.png) -伙计们,请做好准备,下面将是一段漫长的旅程,期望你能够乐在其中。 +## 简介 + +伙计们,请搬好小板凳坐好,下面将是一段漫长的旅程,期望你能够乐在其中。 我将基于 [Kubernetes][5] 部署一个分布式应用。我曾试图编写一个尽可能真实的应用,但由于时间和精力有限,最终砍掉了很多细节。 @@ -11,17 +13,17 @@ Kubernetes 分布式应用部署实战 -- 以人脸识别应用为例 让我们开始吧。 -# 应用 +## 应用 ### TL;DR ![kube overview](https://skarlso.github.io/img/kube_overview.png) -应用本身由 6 个组件构成。代码可以从如下链接中找到:[Kubenetes 集群示例][6]。 +该应用本身由 6 个组件构成。代码可以从如下链接中找到:[Kubenetes 集群示例][6]。 这是一个人脸识别服务,通过比较已知个人的图片,识别给定图片对应的个人。前端页面用表格形式简要的展示图片及对应的个人。具体而言,向 [接收器][6] 发送请求,请求包含指向一个图片的链接。图片可以位于任何位置。接受器将图片地址存储到数据库 (MySQL) 中,然后向队列发送处理请求,请求中包含已保存图片的 ID。这里我们使用 [NSQ][8] 建立队列。 -[图片处理][9]服务一直监听处理请求队列,从中获取任务。处理过程包括如下几步:获取图片 ID,读取图片,通过 [gRPC][11] 将图片路径发送至 Python 编写的[人脸识别][10]后端。如果识别成功,后端给出图片对应个人的名字。图片处理器进而根据个人 ID 更新图片记录,将其标记为处理成功。如果识别不成功,图片被标记为待解决。如果图片识别过程中出现错误,图片被标记为失败。 +[图片处理][9] 服务一直监听处理请求队列,从中获取任务。处理过程包括如下几步:获取图片 ID,读取图片,通过 [gRPC][11] 将图片路径发送至 Python 编写的 [人脸识别][10] 后端。如果识别成功,后端给出图片对应个人的名字。图片处理器进而根据个人 ID 更新图片记录,将其标记为处理成功。如果识别不成功,图片被标记为待解决。如果图片识别过程中出现错误,图片被标记为失败。 标记为失败的图片可以通过计划任务等方式进行重试。 @@ -33,39 +35,31 @@ Kubernetes 分布式应用部署实战 -- 以人脸识别应用为例 ``` curl -d '{"path":"/unknown_images/unknown0001.jpg"}' http://127.0.0.1:8000/image/post - ``` -此时,接收器将路径path存储到共享数据库集群中,对应的条目包括数据库服务提供的 ID。本应用采用”持久层提供条目对象唯一标识“的模型。获得条目 ID 后,接收器向 NSQ 发送消息,至此接收器的工作完成。 +此时,接收器将路径path存储到共享数据库集群中,该实体存储后将从数据库服务收到对应的 ID。本应用采用“实体对象Entity Object的唯一标识由持久层提供”的模型。获得实体 ID 后,接收器向 NSQ 发送消息,至此接收器的工作完成。 ### 图片处理器 -从这里开始变得有趣起来。图片处理器首次运行时会创建两个 Go routines,具体为: +从这里开始变得有趣起来。图片处理器首次运行时会创建两个 Go 协程routine,具体为: ### Consume -这是一个 NSQ 消费者,需要完成三项任务。首先,监听队列中的消息。其次,当有新消息到达时,将对应的 ID 追加到一个线程安全的 ID 片段中,以供第二个 routine 处理。最后,告知第二个 routine 处理新任务,方法为 [sync.Condition][12]。 +这是一个 NSQ 消费者,需要完成三项必需的任务。首先,监听队列中的消息。其次,当有新消息到达时,将对应的 ID 追加到一个线程安全的 ID 片段中,以供第二个协程处理。最后,告知第二个协程处理新任务,方法为 [sync.Condition][12]。 ### ProcessImages -该 routine 会处理指定 ID 片段,直到对应片段全部处理完成。当处理完一个片段后,该 routine 并不是在一个通道上睡眠等待,而是进入悬挂状态。对每个 ID,按如下步骤顺序处理: +该协程会处理指定 ID 片段,直到对应片段全部处理完成。当处理完一个片段后,该协程并不是在一个通道上睡眠等待,而是进入悬挂状态。对每个 ID,按如下步骤顺序处理: * 与人脸识别服务建立 gRPC 连接,其中人脸识别服务会在人脸识别部分进行介绍 - -* 从数据库获取图片对应的条目 - +* 从数据库获取图片对应的实体 * 为 [断路器][1] 准备两个函数 * 函数 1: 用于 RPC 方法调用的主函数 - * 函数 2: 基于 ping 的断路器健康检查 - * 调用函数 1 将图片路径发送至人脸识别服务,其中路径应该是人脸识别服务可以访问的,最好是共享的,例如 NFS - -* 如果调用失败,将图片条目状态更新为 FAILEDPROCESSING - +* 如果调用失败,将图片实体状态更新为 FAILEDPROCESSING * 如果调用成功,返回值是一个图片的名字,对应数据库中的一个个人。通过联合 SQL 查询,获取对应个人的 ID - -* 将数据库中的图片条目状态更新为 PROCESSED,更新图片被识别成的个人的 ID +* 将数据库中的图片实体状态更新为 PROCESSED,更新图片被识别成的个人的 ID 这个服务可以复制多份同时运行。 @@ -89,7 +83,7 @@ curl -d '{"path":"/unknown_images/unknown0001.jpg"}' http://127.0.0.1:8000/image 注意:我曾经试图使用 [GoCV][14],这是一个极好的 Go 库,但欠缺所需的 C 绑定。推荐马上了解一下这个库,它会让你大吃一惊,例如编写若干行代码即可实现实时摄像处理。 -这个 Python 库的工作方式本质上很简单。准备一些你认识的人的图片,把信息记录下来。对于我而言,我有一个图片文件夹,包含若干图片,名称分别为 `hannibal_1.jpg, hannibal_2.jpg, gergely_1.jpg, john_doe.jpg`。在数据库中,我使用两个表记录信息,分别为 `person, person_images`,具体如下: +这个 Python 库的工作方式本质上很简单。准备一些你认识的人的图片,把信息记录下来。对于我而言,我有一个图片文件夹,包含若干图片,名称分别为 `hannibal_1.jpg`、 `hannibal_2.jpg`、 `gergely_1.jpg`、 `john_doe.jpg`。在数据库中,我使用两个表记录信息,分别为 `person`、 `person_images`,具体如下: ``` +----+----------+ @@ -126,13 +120,13 @@ NSQ 是 Go 编写的小规模队列,可扩展且占用系统内存较少。NSQ ### 配置 -为了尽可能增加灵活性以及使用 Kubernetes 的 ConfigSet 特性,我在开发过程中使用 .env 文件记录配置信息,例如数据库服务的地址以及 NSQ 的查询地址。在生产环境或 Kubernetes 环境中,我将使用环境变量属性配置。 +为了尽可能增加灵活性以及使用 Kubernetes 的 ConfigSet 特性,我在开发过程中使用 `.env` 文件记录配置信息,例如数据库服务的地址以及 NSQ 的查询地址。在生产环境或 Kubernetes 环境中,我将使用环境变量属性配置。 ### 应用小结 这就是待部署应用的全部架构信息。应用的各个组件都是可变更的,他们之间仅通过数据库、消息队列和 gRPC 进行耦合。考虑到更新机制的原理,这是部署分布式应用所必须的;在部署部分我会继续分析。 -# 使用 Kubernetes 部署应用 +## 使用 Kubernetes 部署应用 ### 基础知识 @@ -144,55 +138,51 @@ Kubernetes 是容器化服务及应用的管理器。它易于扩展,可以管 在 Kubernetes 中,你给出期望的应用状态,Kubernetes 会尽其所能达到对应的状态。状态可以是已部署、已暂停,有 2 个副本等,以此类推。 -Kubernetes 使用标签和注释标记组件,包括服务,部署,副本组,守护进程组等在内的全部组件都被标记。考虑如下场景,为了识别 pod 与 应用的对应关系,使用 `app: myapp` 标签。假设应用已部署 2 个容器,如果你移除其中一个容器的 `app` 标签,Kubernetes 只能识别到一个容器(隶属于应用),进而启动一个新的具有 `myapp` 标签的实例。 +Kubernetes 使用标签和注释标记组件,包括服务、部署、副本组、守护进程组等在内的全部组件都被标记。考虑如下场景,为了识别 pod 与应用的对应关系,使用 `app: myapp` 标签。假设应用已部署 2 个容器,如果你移除其中一个容器的 `app` 标签,Kubernetes 只能识别到一个容器(隶属于应用),进而启动一个新的具有 `myapp` 标签的实例。 ### Kubernetes 集群 -要使用 Kubernetes,需要先搭建一个 Kubernetes 集群。搭建 Kubernetes 集群可能是一个痛苦的经历,但所幸有工具可以帮助我们。Minikube 为我们在本地搭建一个单节点集群。AWS 的一个 beta 服务工作方式类似于 Kubernetes 集群,你只需请求 Nodes 并定义你的部署即可。Kubernetes 集群组件的文档如下:[Kubernetes 集群组件][17]。 +要使用 Kubernetes,需要先搭建一个 Kubernetes 集群。搭建 Kubernetes 集群可能是一个痛苦的经历,但所幸有工具可以帮助我们。Minikube 为我们在本地搭建一个单节点集群。AWS 的一个 beta 服务工作方式类似于 Kubernetes 集群,你只需请求节点并定义你的部署即可。Kubernetes 集群组件的文档如下:[Kubernetes 集群组件][17]。 -### 节点 (Nodes) +### 节点 -节点是工作单位,形式可以是虚拟机、物理机,也可以是各种类型的云主机。 +节点node是工作单位,形式可以是虚拟机、物理机,也可以是各种类型的云主机。 -### Pods +### Pod -Pods 是本地容器组成的集合,即一个 Pod 中可能包含若干个容器。Pod 创建后具有自己的 DNS 和 虚拟 IP,这样 Kubernetes 可以对到达流量进行负载均衡。你几乎不需要直接和容器打交道;即使是调试的时候,例如查看日志,你通常调用 `kubectl logs deployment/your-app -f` 查看部署日志,而不是使用 `-c container_name` 查看具体某个容器的日志。`-f` 参数表示从日志尾部进行流式输出。 +Pod 是本地容器逻辑上组成的集合,即一个 Pod 中可能包含若干个容器。Pod 创建后具有自己的 DNS 和虚拟 IP,这样 Kubernetes 可以对到达流量进行负载均衡。你几乎不需要直接和容器打交道;即使是调试的时候,例如查看日志,你通常调用 `kubectl logs deployment/your-app -f` 查看部署日志,而不是使用 `-c container_name` 查看具体某个容器的日志。`-f` 参数表示从日志尾部进行流式输出。 -### 部署 (Deployments) +### 部署 -在 Kubernetes 中创建任何类型的资源时,后台使用一个部署,它指定了资源的期望状态。使用部署对象,你可以将 Pod 或服务变更为另外的状态,也可以更新应用或上线新版本应用。你一般不会直接操作副本组 (后续会描述),而是通过部署对象创建并管理。 +在 Kubernetes 中创建任何类型的资源时,后台使用一个部署deployment组件,它指定了资源的期望状态。使用部署对象,你可以将 Pod 或服务变更为另外的状态,也可以更新应用或上线新版本应用。你一般不会直接操作副本组 (后续会描述),而是通过部署对象创建并管理。 -### 服务 (Services) +### 服务 -默认情况下,Pod 会获取一个 IP 地址。但考虑到 Pod 是 Kubernetes 中的易失性组件,我们需要更加持久的组件。不论是队列,mysql,内部 API 或前端,都需要长期运行并使用保持不变的 IP 或 更佳的 DNS 记录。 +默认情况下,Pod 会获取一个 IP 地址。但考虑到 Pod 是 Kubernetes 中的易失性组件,我们需要更加持久的组件。不论是队列,MySQL、内部 API 或前端,都需要长期运行并使用保持不变的 IP 或更好的 DNS 记录。 -为解决这个问题,Kubernetes 提供了服务组件,可以定义访问模式,支持的模式包括负载均衡,简单 IP 或 内部 DNS。 +为解决这个问题,Kubernetes 提供了服务service组件,可以定义访问模式,支持的模式包括负载均衡、简单 IP 或内部 DNS。 Kubernetes 如何获知服务运行正常呢?你可以配置健康性检查和可用性检查。健康性检查是指检查容器是否处于运行状态,但容器处于运行状态并不意味着服务运行正常。对此,你应该使用可用性检查,即请求应用的一个特别接口endpoint。 -由于服务非常重要,推荐你找时间阅读以下文档:[服务][18]。严肃的说,需要阅读的东西很多,有 24 页 A4 纸的篇幅,涉及网络,服务及自动发现。这也有助于你决定是否真的打算在生产环境中使用 Kubernetes。 +由于服务非常重要,推荐你找时间阅读以下文档:[服务][18]。严肃的说,需要阅读的东西很多,有 24 页 A4 纸的篇幅,涉及网络、服务及自动发现。这也有助于你决定是否真的打算在生产环境中使用 Kubernetes。 ### DNS / 服务发现 -在 Kubernetes 集群中创建服务后,该服务会从名为 kube-proxy 和 kube-dns 的特殊 Kubernetes 部署中获取一个 DNS 记录。他们两个用于提供集群内的服务发现。如果你有一个正在运行的 mysql 服务并配置 `clusterIP: no`,那么集群内部任何人都可以通过 `mysql.default.svc.cluster.local` 访问该服务,其中: +在 Kubernetes 集群中创建服务后,该服务会从名为 `kube-proxy` 和 `kube-dns` 的特殊 Kubernetes 部署中获取一个 DNS 记录。它们两个用于提供集群内的服务发现。如果你有一个正在运行的 MySQL 服务并配置 `clusterIP: no`,那么集群内部任何人都可以通过 `mysql.default.svc.cluster.local` 访问该服务,其中: * `mysql` – 服务的名称 - * `default` – 命名空间的名称 - * `svc` – 对应服务分类 - * `cluster.local` – 本地集群的域名 -可以使用自定义设置更改本地集群的域名。如果想让服务可以从集群外访问,需要使用 DNS 提供程序并使用例如 Nginx 将 IP 地址绑定至记录。服务对应的对外 IP 地址可以使用如下命令查询: +可以使用自定义设置更改本地集群的域名。如果想让服务可以从集群外访问,需要使用 DNS 服务,并使用例如 Nginx 将 IP 地址绑定至记录。服务对应的对外 IP 地址可以使用如下命令查询: * 节点端口方式 – `kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services mysql` - * 负载均衡方式 – `kubectl get -o jsonpath="{.spec.ports[0].LoadBalancer}" services mysql` ### 模板文件 -类似 Docker Compose, TerraForm 或其它的服务管理工具,Kubernetes 也提供了基础设施描述模板。这意味着,你几乎不用手动操作。 +类似 Docker Compose、TerraForm 或其它的服务管理工具,Kubernetes 也提供了基础设施描述模板。这意味着,你几乎不用手动操作。 以 Nginx 部署为例,查看下面的 yaml 模板: @@ -218,26 +208,26 @@ spec: #(4) image: nginx:1.7.9 ports: - containerPort: 80 - ``` 在这个示例部署中,我们做了如下操作: -* (1) 使用 kind 关键字定义模板类型 -* (2) 使用 metadata 关键字,增加该部署的识别信息,使用 labels 标记每个需要创建的资源 (3) -* (4) 然后使用 spec 关键字描述所需的状态 - * (5) nginx 应用需要 3 个副本 - * (6) Pod 中容器的模板定义部分 - * 容器名称为 nginx - * 容器模板为 nginx:1.7.9 (本例使用 Docker 镜像) +* (1) 使用 `kind` 关键字定义模板类型 +* (2) 使用 `metadata` 关键字,增加该部署的识别信息 +* (3) 使用 `labels` 标记每个需要创建的资源 +* (4) 然后使用 `spec` 关键字描述所需的状态 +* (5) nginx 应用需要 3 个副本 +* (6) Pod 中容器的模板定义部分 +* 容器名称为 nginx +* 容器模板为 nginx:1.7.9 (本例使用 Docker 镜像) -### 副本组 (ReplicaSet) +### 副本组 -副本组是一个底层的副本管理器,用于保证运行正确数目的应用副本。相比而言,部署是更高层级的操作,应该用于管理副本组。除非你遇到特殊的情况,需要控制副本的特性,否则你几乎不需要直接操作副本组。 +副本组ReplicaSet是一个底层的副本管理器,用于保证运行正确数目的应用副本。相比而言,部署是更高层级的操作,应该用于管理副本组。除非你遇到特殊的情况,需要控制副本的特性,否则你几乎不需要直接操作副本组。 -### 守护进程组 (DaemonSet) +### 守护进程组 -上面提到 Kubernetes 始终使用标签,还有印象吗?守护进程组是一个控制器,用于确保守护进程化的应用一直运行在具有特定标签的节点中。 +上面提到 Kubernetes 始终使用标签,还有印象吗?守护进程组DaemonSet是一个控制器,用于确保守护进程化的应用一直运行在具有特定标签的节点中。 例如,你将所有节点增加 `logger` 或 `mission_critical` 的标签,以便运行日志 / 审计服务的守护进程。接着,你创建一个守护进程组并使用 `logger` 或 `mission_critical` 节点选择器。Kubernetes 会查找具有该标签的节点,确保守护进程的实例一直运行在这些节点中。因而,节点中运行的所有进程都可以在节点内访问对应的守护进程。 @@ -253,7 +243,7 @@ spec: #(4) ### Kubernetes 部分小结 -Kubernetes 是容器编排的便捷工具,工作单元为 Pods,具有分层架构。最顶层是部署,用于操作其它资源,具有高度可配置性。对于你的每个命令调用,Kubernetes 提供了对应的 API,故理论上你可以编写自己的代码,向 Kubernetes API 发送数据,得到与 `kubectl` 命令同样的效果。 +Kubernetes 是容器编排的便捷工具,工作单元为 Pod,具有分层架构。最顶层是部署,用于操作其它资源,具有高度可配置性。对于你的每个命令调用,Kubernetes 提供了对应的 API,故理论上你可以编写自己的代码,向 Kubernetes API 发送数据,得到与 `kubectl` 命令同样的效果。 截至目前,Kubernetes 原生支持所有主流云服务供应商,而且完全开源。如果你愿意,可以贡献代码;如果你希望对工作原理有深入了解,可以查阅代码:[GitHub 上的 Kubernetes 项目][22]。 @@ -272,7 +262,7 @@ kubectl get nodes -o yaml ### 构建容器 -Kubernetes 支持大多数现有的容器技术。我这里使用 Docker。每一个构建的服务容器,对应代码库中的一个 Dockerfile 文件。我推荐你仔细阅读它们,其中大多数都比较简单。对于 Go 服务,我采用了最近引入的多步构建的方式。Go 服务基于 Alpine Linux 镜像创建。人脸识别程序使用 Python,NSQ 和 MySQL 使用对应的容器。 +Kubernetes 支持大多数现有的容器技术。我这里使用 Docker。每一个构建的服务容器,对应代码库中的一个 Dockerfile 文件。我推荐你仔细阅读它们,其中大多数都比较简单。对于 Go 服务,我采用了最近引入的多步构建的方式。Go 服务基于 Alpine Linux 镜像创建。人脸识别程序使用 Python、NSQ 和 MySQL 使用对应的容器。 ### 上下文 @@ -293,9 +283,9 @@ Switched to context "kube-face-cluster". ``` 此后,所有 `kubectl` 命令都会使用 `face` 命名空间。 -(译注:作者后续并没有使用 face 命名空间,模板文件中的命名空间仍为 default,可能 face 命名空间用于开发环境。如果希望使用 face 命令空间,需要将内部 DNS 地址中的 default 改成 face;如果只是测试,可以不执行这两条命令。) +(LCTT 译注:作者后续并没有使用 face 命名空间,模板文件中的命名空间仍为 default,可能 face 命名空间用于开发环境。如果希望使用 face 命令空间,需要将内部 DNS 地址中的 default 改成 face;如果只是测试,可以不执行这两条命令。) -### 应用部署 +## 应用部署 Pods 和 服务概览: @@ -318,7 +308,6 @@ type: Opaque data: mysql_password: base64codehere mysql_userpassword: base64codehere - ``` 其中 base64 编码通过如下命令生成: @@ -326,10 +315,9 @@ data: ``` echo -n "ubersecurepassword" | base64 echo -n "root:ubersecurepassword" | base64 - ``` -(LCTT 译注:secret yaml 文件中的 data 应该有两条,一条对应 mysql_password, 仅包含密码;另一条对应 mysql_userpassword,包含用户和密码。后文会用到 mysql_userpassword,但没有提及相应的生成) +(LCTT 译注:secret yaml 文件中的 data 应该有两条,一条对应 `mysql_password`,仅包含密码;另一条对应 `mysql_userpassword`,包含用户和密码。后文会用到 `mysql_userpassword`,但没有提及相应的生成) 我的部署 yaml 对应部分如下: @@ -362,13 +350,12 @@ echo -n "root:ubersecurepassword" | base64 其中 `presistentVolumeClain` 是关键,告知 Kubernetes 当前资源需要持久化存储。持久化存储的提供方式对用户透明。类似 Pods,如果想了解更多细节,参考文档:[Kubernetes 持久化存储][27]。 -(LCTT 译注:使用 presistentVolumeClain 之前需要创建 presistentVolume,对于单节点可以使用本地存储,对于多节点需要使用共享存储,因为 Pod 可以能调度到任何一个节点) +(LCTT 译注:使用 `presistentVolumeClain` 之前需要创建 `presistentVolume`,对于单节点可以使用本地存储,对于多节点需要使用共享存储,因为 Pod 可以能调度到任何一个节点) 使用如下命令部署 MySQL 服务: ``` kubectl apply -f mysql.yaml - ``` 这里比较一下 `create` 和 `apply`。`apply` 是一种宣告式declarative的对象配置命令,而 `create` 是命令式imperative的命令。当下我们需要知道的是,`create` 通常对应一项任务,例如运行某个组件或创建一个部署;相比而言,当我们使用 `apply` 的时候,用户并没有指定具体操作,Kubernetes 会根据集群目前的状态定义需要执行的操作。故如果不存在名为 `mysql` 的服务,当我执行 `apply -f mysql.yaml` 时,Kubernetes 会创建该服务。如果再次执行这个命令,Kubernetes 会忽略该命令。但如果我再次运行 `create`,Kubernetes 会报错,告知服务已经创建。 @@ -460,7 +447,7 @@ volumes: ``` -(LCTT 译注:数据库初始化脚本需要改成对应的路径,如果是多节点,需要是共享存储中的路径。另外,作者给的 sql 文件似乎有误,person_images 表中的 person_id 列数字都小 1,作者默认 id 从 0 开始,但应该是从 1 开始) +(LCTT 译注:数据库初始化脚本需要改成对应的路径,如果是多节点,需要是共享存储中的路径。另外,作者给的 sql 文件似乎有误,`person_images` 表中的 `person_id` 列数字都小 1,作者默认 `id` 从 0 开始,但应该是从 1 开始) 运行如下命令查看引导脚本是否正确执行: @@ -489,7 +476,6 @@ mysql> ``` kubectl logs deployment/mysql -f - ``` ### NSQ 查询 @@ -505,7 +491,7 @@ NSQ 查询将以内部服务的形式运行。由于不需要外部访问,这 ``` -那么,内部 DNS 对应的条目类似于:`nsqlookup.default.svc.cluster.local`。 +那么,内部 DNS 对应的实体类似于:`nsqlookup.default.svc.cluster.local`。 无头服务的更多细节,可以参考:[无头服务][32]。 @@ -517,7 +503,7 @@ args: ["--broadcast-address=nsqlookup.default.svc.cluster.local"] ``` -你可能会疑惑,`--broadcast-address` 参数是做什么用的?默认情况下,nsqlookup 使用 `hostname` (LCTT 译注:这里是指容器的主机名,而不是 hostname 字符串本身)作为广播地址;这意味着,当用户运行回调时,回调试图访问的地址类似于 `http://nsqlookup-234kf-asdf:4161/lookup?topics=image`,但这显然不是我们期望的。将广播地址设置为内部 DNS 后,回调地址将是 `http://nsqlookup.default.svc.cluster.local:4161/lookup?topic=images`,这正是我们期望的。 +你可能会疑惑,`--broadcast-address` 参数是做什么用的?默认情况下,`nsqlookup` 使用容器的主机名作为广播地址;这意味着,当用户运行回调时,回调试图访问的地址类似于 `http://nsqlookup-234kf-asdf:4161/lookup?topics=image`,但这显然不是我们期望的。将广播地址设置为内部 DNS 后,回调地址将是 `http://nsqlookup.default.svc.cluster.local:4161/lookup?topic=images`,这正是我们期望的。 NSQ 查询还需要转发两个端口,一个用于广播,另一个用于 nsqd 守护进程的回调。在 Dockerfile 中暴露相应端口,在 Kubernetes 模板中使用它们,类似如下: @@ -533,6 +519,7 @@ NSQ 查询还需要转发两个端口,一个用于广播,另一个用于 nsq ``` 服务模板: + ``` spec: ports: @@ -592,13 +579,13 @@ NSQ 守护进程也需要一些调整的参数配置: ``` -其中我们配置了 lookup-tcp-address 和 broadcast-address 参数。前者是 nslookup 服务的 DNS 地址,后者用于回调,就像 nsqlookupd 配置中那样。 +其中我们配置了 `lookup-tcp-address` 和 `broadcast-address` 参数。前者是 nslookup 服务的 DNS 地址,后者用于回调,就像 nsqlookupd 配置中那样。 #### 对外公开 下面即将创建第一个对外公开的服务。有两种方式可供选择。考虑到该 API 负载较高,可以使用负载均衡的方式。另外,如果希望将其部署到生产环境中的任选节点,也应该使用负载均衡方式。 -但由于我使用的本地集群只有一个节点,那么使用 `节点端口` 的方式就足够了。`节点端口` 方式将服务暴露在对应节点的固定端口上。如果未指定端口,将从 30000-32767 数字范围内随机选其一个。也可以指定端口,可以在模板文件中使用 `nodePort` 设置即可。可以通过 `:` 访问该服务。如果使用多个节点,负载均衡可以将多个 IP 合并为一个 IP。 +但由于我使用的本地集群只有一个节点,那么使用 `NodePort` 的方式就足够了。`NodePort` 方式将服务暴露在对应节点的固定端口上。如果未指定端口,将从 30000-32767 数字范围内随机选其一个。也可以指定端口,可以在模板文件中使用 `nodePort` 设置即可。可以通过 `:` 访问该服务。如果使用多个节点,负载均衡可以将多个 IP 合并为一个 IP。 更多信息,请参考文档:[服务发布][33]。 @@ -643,7 +630,7 @@ spec: ### 图片处理器 -图片处理器用于将图片传送至识别组件。它需要访问 nslookupd, mysql 以及后续部署的人脸识别服务的 gRPC 接口。事实上,这是一个无聊的服务,甚至其实并不是服务(LCTT 译注:第一个服务是指在整个架构中,图片处理器作为一个服务;第二个服务是指 Kubernetes 服务)。它并需要对外暴露端口,这是第一个只包含部署的组件。长话短说,下面是完整的模板: +图片处理器用于将图片传送至识别组件。它需要访问 nslookupd、 mysql 以及后续部署的人脸识别服务的 gRPC 接口。事实上,这是一个无聊的服务,甚至其实并不是服务(LCTT 译注:第一个服务是指在整个架构中,图片处理器作为一个服务;第二个服务是指 Kubernetes 服务)。它并需要对外暴露端口,这是第一个只包含部署的组件。长话短说,下面是完整的模板: ``` --- @@ -781,7 +768,7 @@ curl -d '{"path":"/unknown_people/unknown220.jpg"}' http://192.168.99.100:30251/ ``` -图像处理器会在 `/unknown_people` 目录搜索名为 unknown220.jpg 的图片,接着在 known_foler 文件中找到 unknown220.jpg 对应个人的图片,最后返回匹配图片的名称。 +图像处理器会在 `/unknown_people` 目录搜索名为 unknown220.jpg 的图片,接着在 `known_folder` 文件中找到 `unknown220.jpg` 对应个人的图片,最后返回匹配图片的名称。 查看日志,大致信息如下: @@ -861,9 +848,9 @@ receiver-deployment-5cb4797598-sf5ds 1/1 Running 0 26s ``` -### 滚动更新 (Rolling Update) +## 滚动更新 -滚动更新过程中会发生什么呢? +滚动更新Rolling Update过程中会发生什么呢? ![kube rotate](https://skarlso.github.io/img/kube_rotate.png) @@ -871,7 +858,7 @@ receiver-deployment-5cb4797598-sf5ds 1/1 Running 0 26s 目前的 API 一次只能处理一个图片,不能批量处理,对此我并不满意。 -#### 代码 +### 代码 目前,我们使用下面的代码段处理单个图片的情形: @@ -900,7 +887,7 @@ func main() { 这里,你可能会说你并不需要保留旧代码;某些情况下,确实如此。因此,我们打算直接修改旧代码,让其通过少量参数调用新代码。这样操作操作相当于移除了旧代码。当所有客户端迁移完毕后,这部分代码也可以安全地删除。 -#### 新的 Endpoint +### 新的接口 让我们添加新的路由方法: @@ -941,7 +928,7 @@ func PostImage(w http.ResponseWriter, r *http.Request) { ``` -当然,方法名可能容易混淆,但你应该能够理解我想表达的意思。我将请求中的单个路径封装成新方法所需格式,然后将其作为请求发送给新接口处理。仅此而已。在 [滚动更新批量图片 PR][34] 中可以找到更多的修改方式。 +当然,方法名可能容易混淆,但你应该能够理解我想表达的意思。我将请求中的单个路径封装成新方法所需格式,然后将其作为请求发送给新接口处理。仅此而已。在 [滚动更新批量图片的 PR][34] 中可以找到更多的修改方式。 至此,我们使用两种方法调用接收器: @@ -958,7 +945,7 @@ curl -d '{"paths":[{"path":"unknown4456.jpg"}]}' http://127.0.0.1:8000/images/po 为了简洁,我不打算为 NSQ 和其它组件增加批量图片处理的能力。这些组件仍然是一次处理一个图片。这部分修改将留给你作为扩展内容。 :) -#### 新镜像 +### 新镜像 为实现滚动更新,我首先需要为接收器服务创建一个新的镜像。新镜像使用新标签,告诉大家版本号为 v1.1。 @@ -969,11 +956,11 @@ docker build -t skarlso/kube-receiver-alpine:v1.1 . 新镜像创建后,我们可以开始滚动更新了。 -#### 滚动更新 +### 滚动更新 在 Kubernetes 中,可以使用多种方式完成滚动更新。 -##### 手动更新 +#### 手动更新 不妨假设在我配置文件中使用的容器版本为 `v1.0`,那么实现滚动更新只需运行如下命令: @@ -991,7 +978,7 @@ kubectl rolling-update receiver --rollback 容器将回滚到使用上一个版本镜像,操作简捷无烦恼。 -##### 应用新的配置文件 +#### 应用新的配置文件 手动更新的不足在于无法版本管理。 @@ -1051,7 +1038,7 @@ kubectl delete services -all ``` -# 写在最后的话 +## 写在最后的话 各位看官,本文就写到这里了。我们在 Kubernetes 上编写、部署、更新和扩展(老实说,并没有实现)了一个分布式应用。 @@ -1065,9 +1052,9 @@ Gergely 感谢你阅读本文。 via: https://skarlso.github.io/2018/03/15/kubernetes-distributed-application/ -作者:[hannibal ][a] +作者:[hannibal][a] 译者:[pinewall](https://github.com/pinewall) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/talk/20180320 Can we build a social network that serves users rather than advertisers.md b/published/20180320 Can we build a social network that serves users rather than advertisers.md similarity index 56% rename from translated/talk/20180320 Can we build a social network that serves users rather than advertisers.md rename to published/20180320 Can we build a social network that serves users rather than advertisers.md index bd279216ca..f7d378580b 100644 --- a/translated/talk/20180320 Can we build a social network that serves users rather than advertisers.md +++ b/published/20180320 Can we build a social network that serves users rather than advertisers.md @@ -1,13 +1,15 @@ 我们能否建立一个服务于用户而非广告商的社交网络? ===== +> 找出 Human Connection 是如何将透明度和社区放在首位的。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/people_team_community_group.png?itok=Nc_lTsUK) -如今,开源软件具有深远的意义,在推动数字经济创新方面发挥着关键作用。世界正在快速彻底地改变。世界各地的人们需要一个专门的,中立的,透明的在线平台来迎接我们这个时代的挑战。 +如今,开源软件具有深远的意义,在推动数字经济创新方面发挥着关键作用。世界正在快速彻底地改变。世界各地的人们需要一个专门的、中立的、透明的在线平台来迎接我们这个时代的挑战。 -开放的原则可能会成为让我们到达那里的方法(to 校正者:这句上下文没有理解)。如果我们用开放的思维方式将数字创新与社会创新结合在一起,会发生什么? +开放的原则也许是让我们达成这一目标的方法。如果我们用开放的思维方式将数字创新与社会创新结合在一起,会发生什么? -这个问题是我们在 [Human Connection][1] 工作的核心,这是一个具有前瞻性的,以德国为基础的知识和行动网络,其使命是创建一个服务于全球的真正的社交网络。我们受到这样一种观念为指引,即人类天生慷慨而富有同情心,并且他们在慈善行为上茁壮成长。但我们还没有看到一个完全支持我们自然倾向,于乐于助人和合作以促进共同利益的社交网络。Human Connection 渴望成为让每个人都成为积极变革者的平台。 +这个问题是我们在 [Human Connection][1] 工作的核心,这是一个具有前瞻性的,以德国为基础的知识和行动网络,其使命是创建一个服务于全球的真正的社交网络。我们受到这样一种观念为指引,即人类天生慷慨而富有同情心,并且他们在慈善行为上茁壮成长。但我们还没有看到一个完全支持我们的自然趋势,与乐于助人和合作以促进共同利益的社交网络。Human Connection 渴望成为让每个人都成为积极变革者的平台。 为了实现一个以解决方案为导向的平台的梦想,让人们通过与慈善机构、社区团体和社会变革活动人士的接触,围绕社会公益事业采取行动,Human Connection 将开放的价值观作为社会创新的载体。 @@ -15,31 +17,28 @@ ### 首先是透明 -透明是 Human Connection 的指导原则之一。Human Connection 邀请世界各地的程序员通过[在 Github 上提交他们的源代码][2]共同开发平台的源代码(JavaScript, Vue, nuxt),并通过贡献代码或编程附加功能来支持真正的社交网络。 +透明是 Human Connection 的指导原则之一。Human Connection 邀请世界各地的程序员通过[在 Github 上提交他们的源代码][2]共同开发平台的源代码(JavaScript、Vue、nuxt),并通过贡献代码或编程附加功能来支持真正的社交网络。 -但我们对透明的承诺超出了我们的发展实践。事实上,当涉及到建立一种新的社交网络,促进那些对让世界变得更好的人之间的真正联系和互动,分享源代码只是迈向透明的一步。 +但我们对透明的承诺超出了我们的发展实践。事实上,当涉及到建立一种新的社交网络,促进那些让世界变得更好的人之间的真正联系和互动,分享源代码只是迈向透明的一步。 -为促进公开对话,Human Connection 团队举行[定期在线公开会议][3]。我们在这里回答问题,鼓励建议并对潜在的问题作出回应。我们的 Meet The Team (to 校正者:这里如果可以,请翻译得稍微优雅,我想不出来一个词)活动也会记录下来,并在事后向公众开放。通过对我们的流程,源代码和财务状况完全透明,我们可以保护自己免受批评或其他潜在的不利影响。 +为促进公开对话,Human Connection 团队举行[定期在线公开会议][3]。我们在这里回答问题,鼓励建议并对潜在的问题作出回应。我们的 Meet The Team 活动也会记录下来,并在事后向公众开放。通过对我们的流程,源代码和财务状况完全透明,我们可以保护自己免受批评或其他潜在的不利影响。 对透明的承诺意味着,所有在 Human Connection 上公开分享的用户贡献者将在 Creative Commons 许可下发布,最终作为数据包下载。通过让大众知识变得可用,特别是以一种分散的方式,我们创造了一个多元化社会的机会。 -一个问题指导我们所有的组织决策:“它是否服务于人民和更大的利益?”我们用[联合国宪章(UN Charter)][4]和“世界人权宣言(Universal Declaration of Human Rights)”作为我们价值体系的基础。随着我们的规模越来越大,尤其是即将推出的公测版,我们必须对此任务负责。我甚至愿意邀请 Chaos Computer Club (译者注:这是欧洲最大的黑客联盟)或其他黑客俱乐部通过随机检查我们的平台来验证我们的代码和行为的完整性。 +有一个问题指导我们所有的组织决策:“它是否服务于人民和更大的利益?”我们用[联合国宪章][4]UN Charter和“世界人权宣言Universal Declaration of Human Rights”作为我们价值体系的基础。随着我们的规模越来越大,尤其是即将推出的公测版,我们必须对此任务负责。我甚至愿意邀请 Chaos Computer Club (LCTT 译注:这是欧洲最大的黑客联盟)或其他黑客俱乐部通过随机检查我们的平台来验证我们的代码和行为的完整性。 ### 一个合作的社会 以一种[以社区为中心的协作方法][5]来编写 Human Connection 平台是超越社交网络实际应用理念的基础。我们的团队是通过找到问题的答案来驱动:“是什么让一个社交网络真正地社会化?” -一个抛弃了以利润为导向的算法,为广告商而不是最终用户服务的网络,只能通过转向对等生产和协作的过程而繁荣起来。例如,像 [Code Alliance][6] 和 [Code for America][7] 这样的组织已经证明了如何在一个开源环境中创造技术,造福人类并破坏(to 校正:这里译为改变较好)现状。社区驱动的项目,如基于地图的报告平台 [FixMyStreet][8],或者为 Humanitarian OpenStreetMap 而建立的 [Tasking Manager][9],已经将众包作为推动其使用的一种方式。 +一个抛弃了以利润为导向的算法、为最终用户而不是广告商服务的网络,只能通过转向对等生产和协作的过程而繁荣起来。例如,像 [Code Alliance][6] 和 [Code for America][7] 这样的组织已经证明了如何在一个开源环境中创造技术,造福人类并变革现状。社区驱动的项目,如基于地图的报告平台 [FixMyStreet][8],或者为 Humanitarian OpenStreetMap 而建立的 [Tasking Manager][9],已经将众包作为推动其使用的一种方式。 -我们建立 Human Connection 的方法从一开始就是合作。为了收集关于必要功能和真正社交网络的目的的初步数据,我们与巴黎索邦大学(University Sorbonne)的国家东方语言与文明研究所(National Institute for Oriental Languages and Civilizations (INALCO) )和德国斯图加特媒体大学(Stuttgart Media University )合作。这两个项目的研究结果都被纳入了 Human Connection 的早期开发。多亏了这项研究,[用户将拥有一套全新的功能][10],让他们可以控制自己看到的内容以及他们如何与他人的互动。由于早期的支持者[被邀请到网络的 alpha 版本][10],他们可以体验到第一个可用的值得注意的功能。这里有一些: - - * 将信息与行动联系起来是我们研究会议的一个重要主题。当前的社交网络让用户处于信息阶段。这两所大学的学生团体都认为,需要一个以行动为导向的组件,以满足人类共同解决问题的本能。所以我们在平台上构建了一个[“Can Do”功能][11]。这是一个人在阅读了某个话题后可以采取行动的一种方式。“Can Do” 是用户建议的活动,在“采取行动(Take Action)”领域,每个人都可以实现。 - - * “Versus” 功能是另一个定义结果的方式(to 校正者:这句话稍微注意一下)。在传统社交网络仅限于评论功能的地方,我们的学生团体认为需要采用更加结构化且有用的方式进行讨论和争论。“Versus” 是对公共帖子的反驳,它是单独显示的,并提供了一个机会来突出围绕某个问题的不同意见。 +我们建立 Human Connection 的方法从一开始就是合作。为了收集关于必要功能和真正社交网络的目的的初步数据,我们与巴黎索邦大学University Sorbonne国家东方语言与文明研究所National Institute for Oriental Languages and Civilizations(INALCO)和德国斯图加特媒体大学Stuttgart Media University合作。这两个项目的研究结果都被纳入了 Human Connection 的早期开发。多亏了这项研究,[用户将拥有一套全新的功能][10],让他们可以控制自己看到的内容以及他们如何与他人的互动。由于早期的支持者[被邀请到网络的 alpha 版本][10],他们可以体验到第一个可用的值得注意的功能。这里有一些: + * 将信息与行动联系起来是我们研究会议的一个重要主题。当前的社交网络让用户处于信息阶段。这两所大学的学生团体都认为,需要一个以行动为导向的组件,以满足人类共同解决问题的本能。所以我们在平台上构建了一个[“Can Do”功能][11]。这是一个人在阅读了某个话题后可以采取行动的一种方式。“Can Do” 是用户建议的活动,在“采取行动Take Action”领域,每个人都可以实现。 + * “Versus” 功能是另一个成果。在传统社交网络仅限于评论功能的地方,我们的学生团体认为需要采用更加结构化且有用的方式进行讨论和争论。“Versus” 是对公共帖子的反驳,它是单独显示的,并提供了一个机会来突出围绕某个问题的不同意见。 * 今天的社交网络并没有提供很多过滤内容的选项。研究表明,情绪过滤选项可以帮助我们根据日常情绪驾驭社交空间,并可能通过在我们希望仅看到令人振奋的内容的那一天时,不显示悲伤或难过的帖子来潜在地保护我们的情绪健康。 - Human Connection 邀请改革者合作开发一个网络,有可能动员世界各地的个人和团体将负面新闻变成 “Can Do”,并与慈善机构和非营利组织一起参与社会创新项目。 [订阅我们的每周时事通讯][12]以了解有关开放组织的更多信息。 @@ -51,7 +50,7 @@ via: https://opensource.com/open-organization/18/3/open-social-human-connection 作者:[Dennis Hack][a] 译者:[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/) 荣誉推出 diff --git a/published/20180320 Migrating to Linux- Installing Software.md b/published/20180320 Migrating to Linux- Installing Software.md new file mode 100644 index 0000000000..5975f7edfc --- /dev/null +++ b/published/20180320 Migrating to Linux- Installing Software.md @@ -0,0 +1,88 @@ +迁移到 Linux:安装软件 +====== + +> 所有的 Linux 打包系统和工具都会让人迷惑,但是这篇面向初学者的教程可以帮助你搞明白。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/birds-1835510_1920.jpg?itok=8i6mBStG) + +如你所见,众所瞩目的 Linux 已经用在互联网,以及 Arduino、Beagle 和树莓派主板等设备上,或许你正在考虑是时候尝试一下 Linux 了。本系列将帮助你成功过渡到 Linux。如果你错过了本系列的早期文章,可以在这里找到它们: + +- [第1部分 - 入门介绍][1] +- [第2部分 - 磁盘、文件和文件系统][2] +- [第3部分 - 图形操作环境][3] +- [第4部分 - 命令行][4] +- [第5部分 - 使用 sudo][5] + +### 安装软件 + +要在你的计算机上获得新软件,通常的方法是从供应商处获得软件产品,然后运行一个安装程序。过去,软件产品会出现在像 CD-ROM 或 DVD 一样的物理媒介上,而现在我们经常从互联网上下载软件产品。 + +使用 Linux,安装软件就像在你的智能手机上安装一样。如同你的手机应用商店一样,在 Linux 上有个提供开源软件工具和程序的中央仓库central repository,几乎任何你想要的程序都会出现在可用软件包列表中以供你安装。 + +每个程序并不需要运行单独的安装程序,而是你可以使用 Linux 发行版附带的软件包管理工具。(这里说的 Linux 发行版就是你安装的 Linux,例如 Ubuntu、Fedora、Debian 等)每个发行版在互联网上都有它自己的集中存储库(称为仓库),它们存储了数千个预先构建好的应用程序。 + +你可能会注意到,在 Linux 上安装软件有几种例外情况。有时候,你仍然需要去供应商那里获取他们的软件,因为该程序不存在于你的发行版的中央仓库中。当软件不是开源和/或自由软件的时候,通常就是这种情况。 + +另外请记住,如果你想要安装一个不在发行版仓库中的程序时,事情就不是那么简单了,即使你正在安装自由及开源程序。这篇文章没有涉及到这些更复杂的情况,请遵循在线的指引。 + +有了所有的 Linux 包管理系统和工具,接下来干什么可能仍然令人困惑。本文应该有助于澄清一些事情。 + +### 包管理 + +目前在 Linux 发行版中有几个相互竞争的用于管理、安装和删除软件的包管理系统。每个发行版都选择使用了一个包管理工具package management tools。Red Hat、Fedora、CentOS、Scientific Linux、SUSE 等使用 Red Hat 包管理(RPM)。Debian、Ubuntu、Linux Mint 等等都使用 Debian 包管理系统,简称 DPKG。还有一些其它包管理系统,但 RPM 和 DPKG 是最常见的。 + +![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/package-installer.png?itok=V9OU1Q0u) + +*图 1: Package installers* + +无论你使用的软件包管理是什么,它们通常都是一组构建于另外一种工具之上的工具(图 1)。最底层是一个命令行工具,它可以让你做任何与安装软件相关的一切工作。你可以列出已安装的程序、删除程序、安装软件包文件等等。 + +这个底层工具并不总是最方便使用的,所以通常会有一个命令行工具,它可以使用单个命令在发行版的中央仓库中找到软件包,并下载和安装它以及任何依赖项。最后,通常会有一个图形应用程序graphical application,可以让你使用鼠标选择任何想要的内容,然后单击 “install” 按钮即可。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/package-kit.png?itok=YimOq2Je) + +*图 2: PackageKit* + +对于基于 Red Hat 的发行版,包括 Fedora、CentOS、Scientific Linux 等,它们的底层工具是 rpm,高级工具叫做 dnf(在旧系统上是 yum)。图形安装程序称为 PackageKit(图 2),它可能在系统管理菜单下显示名字为 “Add/Remove Software(添加/删除软件)”。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu-software.png?itok=5QSctLEW) + +*图 3: Ubuntu Software* + +对于基于 Debian 的发行版,包括 Debian、Ubuntu、Linux Mint、Elementary OS 等,它们的底层命令行工具是 dpkg,高级工具称为 apt。在 Ubuntu 上管理已安装软件的图形工具是 Ubuntu Software(图 3)。对于 Debian 和 Linux Mint,图形工具称为新立得Synaptic,它也可以安装在 Ubuntu 上。 + +你也可以在 Debian 相关发行版上安装一个基于文本的图形化工具 aptitude。它比新立得更强大,并且即使你只能访问命令行也能工作。如果你想通过各种选项进行各种操作,你可以试试这个,但它使用起来比新立得更复杂。其它发行版也可能有自己独特的工具。 + +### 命令行工具 + +在 Linux 上安装软件的在线说明通常描述了在命令行中键入的命令。这些说明通常更容易理解,并且将命令复制粘贴到命令行窗口中,可以在不出错的情况下一步步进行。这与下面的说明相反:“打开这个菜单,选择这个程序,输入这个搜索模式,点击这个标签,选择这个程序,然后点击这个按钮”,这经常让你在各种操作中迷失。 + +有时你正在使用的 Linux 没有图形环境,因此熟悉从命令行安装软件包是件好事。表 1 和表 2 列出了基于 RPM 和 DPKG 系统的一下常见操作及其相关命令。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table_1_0.png?itok=hQ_o5Oh2) + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table_2.png?itok=yl3UPQDw) + +请注意 SUSE,它像 RedHat 和 Fedora 一样使用 RPM,却没有 dnf 或 yum。相反,它使用一个名为 zypper 的程序作为高级命令行工具。其他发行版也可能有不同的工具,例如 Arch Linux 上的 pacman 或 Gentoo 上的 emerge。有很多包管理工具,所以你可能需要查找哪个适用于你的发行版。 + +这些技巧应该能让你更好地了解如何在新的 Linux 中安装程序,以及更好地了解 Linux 中各种软件包管理方式如何相互关联。 + +通过 Linux 基金会和 edX 的免费 [“Linux 入门”][6]课程了解有关 Linux 的更多信息。 + +--- + +via: https://www.linux.com/blog/learn/2018/3/migrating-linux-installing-software + +作者:[JOHN BONESIO][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[pityonline](https://github.com/pityonline), [wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/johnbonesio +[1]:https://linux.cn/article-9212-1.html +[2]:https://linux.cn/article-9213-1.html +[3]:https://linux.cn/article-9293-1.html +[4]:https://linux.cn/article-9565-1.html +[5]:https://linux.cn/article-9819-1.html +[6]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/translated/tech/20180423 An introduction to Python bytecode.md b/published/20180423 An introduction to Python bytecode.md similarity index 50% rename from translated/tech/20180423 An introduction to Python bytecode.md rename to published/20180423 An introduction to Python bytecode.md index c27346bc91..832f6a4c1c 100644 --- a/translated/tech/20180423 An introduction to Python bytecode.md +++ b/published/20180423 An introduction to Python bytecode.md @@ -1,7 +1,11 @@ Python 字节码介绍 ====== + +> 了解 Python 字节码是什么,Python 如何使用它来执行你的代码,以及知道它是如何帮到你的。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82) -如果你从没有写过 Python,或者甚至只是使用过 Python,你或许已经习惯于看 Python 源代码文件;它们的名字以 `.py` 结尾。你可能还看到过其它类型的文件,比如使用 `.pyc` 结尾的文件,或许你可能听说过,它们就是 Python 的 "字节码" 文件。(在 Python 3 上这些可能不容易看到 — 因为它们与你的 `.py` 文件不在同一个目录下,它们在一个叫 `__pycache__` 的子目录中)或者你也听说过,这是节省时间的一种方法,它可以避免每次运行 Python 时去重新解析源代码。 + +如果你曾经编写过 Python,或者只是使用过 Python,你或许经常会看到 Python 源代码文件——它们的名字以 `.py` 结尾。你可能还看到过其它类型的文件,比如以 `.pyc` 结尾的文件,或许你可能听说过它们就是 Python 的 “字节码bytecode” 文件。(在 Python 3 上这些可能不容易看到 —— 因为它们与你的 `.py` 文件不在同一个目录下,它们在一个叫 `__pycache__` 的子目录中)或者你也听说过,这是节省时间的一种方法,它可以避免每次运行 Python 时去重新解析源代码。 但是,除了 “噢,原来这就是 Python 字节码” 之外,你还知道这些文件能做什么吗?以及 Python 是如何使用它们的? @@ -9,29 +13,26 @@ Python 字节码介绍 ### Python 如何工作 -Python 经常被介绍为它是一个解释型语言 — 其中一个原因是程序运行时,你的源代码被转换成 CPU 的原生指令 — 但这样认为只是部分正确。Python 与大多数解释型语言一样,确实是将源代码编译为一组虚拟机指令,并且 Python 解释器是针对相应的虚拟机实现的。这种中间格式被称为 “字节码”。 +Python 经常被介绍为它是一个解释型语言 —— 其中一个原因是在程序运行时,你的源代码被转换成 CPU 的原生指令 —— 但这样的看法只是部分正确。Python 与大多数解释型语言一样,确实是将源代码编译为一组虚拟机指令,并且 Python 解释器是针对相应的虚拟机实现的。这种中间格式被称为 “字节码”。 因此,这些 `.pyc` 文件是 Python 悄悄留下的,是为了让它们运行的 “更快”,或者是针对你的源代码的 “优化” 版本;它们是你的程序在 Python 虚拟机上运行的字节码指令。 -我们来看一个示例。这里是用 Python 写的经典程序 "Hello, World!": +我们来看一个示例。这里是用 Python 写的经典程序 “Hello, World!”: + ``` def hello() -     print("Hello, World!") - ``` 下面是转换后的字节码(转换为人类可读的格式): -``` -2           0 LOAD_GLOBAL              0 (print) - -            2 LOAD_CONST               1 ('Hello, World!') - -            4 CALL_FUNCTION            1 ``` +2 0 LOAD_GLOBAL 0 (print) + 2 LOAD_CONST 1 ('Hello, World!') + 4 CALL_FUNCTION 1 +``` -如果你输入那个 `hello()` 函数,然后使用 [CPython][1] 解释器去运行它,上面的 Python 程序将会运行。它看起来可能有点奇怪,因此,我们来深入了解一下它都做了些什么。 +如果你输入那个 `hello()` 函数,然后使用 [CPython][1] 解释器去运行它,那么上述列出的内容就是 Python 所运行的。它看起来可能有点奇怪,因此,我们来深入了解一下它都做了些什么。 ### Python 虚拟机内幕 @@ -39,84 +40,68 @@ CPython 使用一个基于栈的虚拟机。也就是说,它完全面向栈数 CPython 使用三种类型的栈: - 1. **调用栈**。这是运行 Python 程序的主要结构。它为每个当前活动的函数调用使用了一个东西 — "帧“,栈底是程序的入口点。每个函数调用推送一个新帧到调用栈,每当函数调用返回后,这个帧被销毁。 - 2. 在每个帧中,有一个 **计算栈** (也称为 **数据栈**)。这个栈就是 Python 函数运行的地方,运行的 Python 代码大多数是由推入到这个栈中的东西组成的,操作它们,然后在返回后销毁它们。 - 3. 在每个帧中,还有一个 **块栈**。它被 Python 用于去跟踪某些类型的控制结构:loops、`try`/`except` 块、以及 `with` 块,全部推入到块栈中,当你退出这些控制结构时,块栈被销毁。这将帮助 Python 了解任意给定时刻哪个块是活动的,比如,一个 `continue` 或者 `break` 语句可能影响正确的块。 - - +1. 调用栈call stack。这是运行 Python 程序的主要结构。它为每个当前活动的函数调用使用了一个东西 —— “frame”,栈底是程序的入口点。每个函数调用推送一个新的帧到调用栈,每当函数调用返回后,这个帧被销毁。 +2. 在每个帧中,有一个计算栈evaluation stack (也称为数据栈data stack)。这个栈就是 Python 函数运行的地方,运行的 Python 代码大多数是由推入到这个栈中的东西组成的,操作它们,然后在返回后销毁它们。 +3. 在每个帧中,还有一个块栈block stack。它被 Python 用于去跟踪某些类型的控制结构:循环、`try` / `except` 块、以及 `with` 块,全部推入到块栈中,当你退出这些控制结构时,块栈被销毁。这将帮助 Python 了解任意给定时刻哪个块是活动的,比如,一个 `continue` 或者 `break` 语句可能影响正确的块。 大多数 Python 字节码指令操作的是当前调用栈帧的计算栈,虽然,还有一些指令可以做其它的事情(比如跳转到指定指令,或者操作块栈)。 为了更好地理解,假设我们有一些调用函数的代码,比如这个:`my_function(my_variable, 2)`。Python 将转换为一系列字节码指令: - 1. 一个 `LOAD_NAME` 指令去查找函数对象 `my_function`,然后将它推入到计算栈的顶部 - 2. 另一个 `LOAD_NAME` 指令去查找变量 `my_variable`,然后将它推入到计算栈的顶部 - 3. 一个 `LOAD_CONST` 指令去推入一个实整数值 `2` 到计算栈的顶部 - 4. 一个 `CALL_FUNCTION` 指令 +1. 一个 `LOAD_NAME` 指令去查找函数对象 `my_function`,然后将它推入到计算栈的顶部 +2. 另一个 `LOAD_NAME` 指令去查找变量 `my_variable`,然后将它推入到计算栈的顶部 +3. 一个 `LOAD_CONST` 指令去推入一个实整数值 `2` 到计算栈的顶部 +4. 一个 `CALL_FUNCTION` 指令 - - -这个 `CALL_FUNCTION` 指令将有 2 个参数,它表示那个 Python 需要从栈顶弹出两个位置参数;然后函数将在它上面进行调用,并且它也同时被弹出(对于函数涉及的关键字参数,它使用另一个不同的指令 — `CALL_FUNCTION_KW`,但使用的操作原则类似,以及第三个指令 — `CALL_FUNCTION_EX`,它适用于函数调用涉及到使用 `*` 或 `**` 操作符的情况)。一旦 Python 拥有了这些之后,它将在调用栈上分配一个新帧,填充到函数调用的本地变量上,然后,运行那个帧内的 `my_function` 字节码。运行完成后,这个帧将被调用栈销毁,最初的帧内返回的 `my_function` 将被推入到计算栈的顶部。 +这个 `CALL_FUNCTION` 指令将有 2 个参数,它表示那个 Python 需要从栈顶弹出两个位置参数;然后函数将在它上面进行调用,并且它也同时被弹出(对于函数涉及的关键字参数,它使用另一个不同的指令 —— `CALL_FUNCTION_KW`,但使用的操作原则类似,以及第三个指令 —— `CALL_FUNCTION_EX`,它适用于函数调用涉及到参数使用 `*` 或 `**` 操作符的情况)。一旦 Python 拥有了这些之后,它将在调用栈上分配一个新帧,填充到函数调用的本地变量上,然后,运行那个帧内的 `my_function` 字节码。运行完成后,这个帧将被调用栈销毁,而在最初的帧内,`my_function` 的返回值将被推入到计算栈的顶部。 ### 访问和理解 Python 字节码 -如果你想玩转字节码,那么,Python 标准库中的 `dis` 模块将对你有非常大的帮助;`dis` 模块为 Python 字节码提供了一个 "反汇编",它可以让你更容易地得到一个人类可读的版本,以及查找各种字节码指令。[`dis` 模块的文档][2] 可以让你遍历它的内容,并且提供一个字节码指令能够做什么和有什么样的参数的完整清单。 +如果你想玩转字节码,那么,Python 标准库中的 `dis` 模块将对你有非常大的帮助;`dis` 模块为 Python 字节码提供了一个 “反汇编”,它可以让你更容易地得到一个人类可读的版本,以及查找各种字节码指令。[`dis` 模块的文档][2] 可以让你遍历它的内容,并且提供一个字节码指令能够做什么和有什么样的参数的完整清单。 例如,获取上面的 `hello()` 函数的列表,可以在一个 Python 解析器中输入如下内容,然后运行它: + ``` import dis - dis.dis(hello) - ``` -函数 `dis.dis()` 将反汇编一个函数、方法、类、模块、编译过的 Python 代码对象、或者字符串包含的源代码,以及显示出一个人类可读的版本。`dis` 模块中另一个方便的功能是 `distb()`。你可以给它传递一个 Python 追溯对象,或者发生预期外情况时调用它,然后它将反汇编发生预期外情况时在调用栈上最顶端的函数,并显示它的字节码,以及插入一个指向到引发意外情况的指令的指针。 +函数 `dis.dis()` 将反汇编一个函数、方法、类、模块、编译过的 Python 代码对象、或者字符串包含的源代码,以及显示出一个人类可读的版本。`dis` 模块中另一个方便的功能是 `distb()`。你可以给它传递一个 Python 追溯对象,或者在发生预期外情况时调用它,然后它将在发生预期外情况时反汇编调用栈上最顶端的函数,并显示它的字节码,以及插入一个指向到引发意外情况的指令的指针。 它也可以用于查看 Python 为每个函数构建的编译后的代码对象,因为运行一个函数将会用到这些代码对象的属性。这里有一个查看 `hello()` 函数的示例: + ``` >>> hello.__code__ - ", line 1> - >>> hello.__code__.co_consts - (None, 'Hello, World!') - >>> hello.__code__.co_varnames - () - >>> hello.__code__.co_names - ('print',) - ``` -代码对象在函数中可以作为属性 `__code__` 来访问,并且携带了一些重要的属性: +代码对象在函数中可以以属性 `__code__` 来访问,并且携带了一些重要的属性: * `co_consts` 是存在于函数体内的任意实数的元组 * `co_varnames` 是函数体内使用的包含任意本地变量名字的元组 * `co_names` 是在函数体内引用的任意非本地名字的元组 - - -许多字节码指令 — 尤其是那些推入到栈中的加载值,或者在变量和属性中的存储值 — 在这些用作它们参数的元组中使用索引。 +许多字节码指令 —— 尤其是那些推入到栈中的加载值,或者在变量和属性中的存储值 —— 在这些元组中的索引作为它们参数。 因此,现在我们能够理解 `hello()` 函数中所列出的字节码: - 1. `LOAD_GLOBAL 0`:告诉 Python 通过 `co_names` (它是 `print` 函数)的索引 0 上的名字去查找它指向的全局对象,然后将它推入到计算栈 - 2. `LOAD_CONST 1`:带入 `co_consts` 在索引 1 上的实数值,并将它推入(索引 0 上的实数值是 `None`,它表示在 `co_consts` 中,因为 Python 函数调用有一个隐式的返回值 `None`,如果没有显式的返回表达式,就返回这个隐式的值 )。 - 3. `CALL_FUNCTION 1`:告诉 Python 去调用一个函数;它需要从栈中弹出一个位置参数,然后,新的栈顶将被函数调用。 +1. `LOAD_GLOBAL 0`:告诉 Python 通过 `co_names` (它是 `print` 函数)的索引 0 上的名字去查找它指向的全局对象,然后将它推入到计算栈 +2. `LOAD_CONST 1`:带入 `co_consts` 在索引 1 上的字面值,并将它推入(索引 0 上的字面值是 `None`,它表示在 `co_consts` 中,因为 Python 函数调用有一个隐式的返回值 `None`,如果没有显式的返回表达式,就返回这个隐式的值 )。 +3. `CALL_FUNCTION 1`:告诉 Python 去调用一个函数;它需要从栈中弹出一个位置参数,然后,新的栈顶将被函数调用。 - - -"原始的" 字节码 — 是非人类可读格式的字节 — 也可以在代码对象上作为 `co_code` 属性可用。如果你有兴趣尝试手工反汇编一个函数时,你可以从它们的十进制字节值中,使用列出 `dis.opname` 的方式去查看字节码指令的名字。 +“原始的” 字节码 —— 是非人类可读格式的字节 —— 也可以在代码对象上作为 `co_code` 属性可用。如果你有兴趣尝试手工反汇编一个函数时,你可以从它们的十进制字节值中,使用列出 `dis.opname` 的方式去查看字节码指令的名字。 ### 字节码的用处 -现在,你已经了解的足够多了,你可能会想 ” OK,我认为它很酷,但是知道这些有什么实际价值呢?“由于对它很好奇,我们去了解它,但是除了好奇之外,Python 字节码在几个方面还是非常有用的。 +现在,你已经了解的足够多了,你可能会想 “OK,我认为它很酷,但是知道这些有什么实际价值呢?”由于对它很好奇,我们去了解它,但是除了好奇之外,Python 字节码在几个方面还是非常有用的。 -首先,理解 Python 的运行模型可以帮你更好地理解你的代码。人们都开玩笑说,C 将成为一个 ”便携式汇编器“,在那里你可以很好地猜测出一段 C 代码转换成什么样的机器指令。理解 Python 字节码之后,你在使用 Python 时也具备同样的能力 — 如果你能预料到你的 Python 源代码将被转换成什么样的字节码,那么你可以知道如何更好地写和优化 Python 源代码。 +首先,理解 Python 的运行模型可以帮你更好地理解你的代码。人们都开玩笑说,C 是一种 “可移植汇编器”,你可以很好地猜测出一段 C 代码转换成什么样的机器指令。理解 Python 字节码之后,你在使用 Python 时也具备同样的能力 —— 如果你能预料到你的 Python 源代码将被转换成什么样的字节码,那么你可以知道如何更好地写和优化 Python 源代码。 第二,理解字节码可以帮你更好地回答有关 Python 的问题。比如,我经常看到一些 Python 新手困惑为什么某些结构比其它结构运行的更快(比如,为什么 `{}` 比 `dict()` 快)。知道如何去访问和阅读 Python 字节码将让你很容易回答这样的问题(尝试对比一下: `dis.dis("{}")` 与 `dis.dis("dict()")` 就会明白)。 @@ -131,7 +116,6 @@ dis.dis(hello) * 最后,CPython 解析器是一个开源软件,你可以在 [GitHub][1] 上阅读它。它在文件 `Python/ceval.c` 中实现了字节码解析器。[这是 Python 3.6.4 发行版中那个文件的链接][5];字节码指令是由第 1266 行开始的 `switch` 语句来处理的。 - 学习更多内容,参与到 James Bennett 的演讲,[有关字节的知识:理解 Python 字节码][6],将在 [PyCon Cleveland 2018][7] 召开。 -------------------------------------------------------------------------------- @@ -141,7 +125,7 @@ via: https://opensource.com/article/18/4/introduction-python-bytecode 作者:[James Bennett][a] 选题:[lujun9972](https://github.com/lujun9972) 译者:[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/) 荣誉推出 diff --git a/sources/tech/20180425 JavaScript Router.md b/published/20180425 JavaScript Router.md similarity index 51% rename from sources/tech/20180425 JavaScript Router.md rename to published/20180425 JavaScript Router.md index feb543fba8..34bf9cff3d 100644 --- a/sources/tech/20180425 JavaScript Router.md +++ b/published/20180425 JavaScript Router.md @@ -1,7 +1,8 @@ -Translating by qhwdw -JavaScript Router +JavaScript 路由器 ====== -There are a lot of frameworks/libraries to build single page applications, but I wanted something more minimal. I’ve come with a solution and I just wanted to share it 🙂 + +构建单页面应用(SPA)有许多的框架/库,但是我希望它们能少一些。我有一个解决方案,我想共享给大家。 + ``` class Router { constructor() { @@ -49,16 +50,16 @@ function notFoundPage() { console.log(router.exec('/')) // home page console.log(router.exec('/users/john')) // john's page console.log(router.exec('/foo')) // not found page - ``` -To use it you add handlers for a URL pattern. This pattern can be a simple string or a regular expression. Using a string will match exactly that, but a regular expression allows you to do fancy things like capture parts from the URL as seen with the user page or match any URL as seen with the not found page. +使用它你可以为一个 URL 模式添加处理程序。这个模式可能是一个简单的字符串或一个正则表达式。使用一个字符串将精确匹配它,但是如果使用一个正则表达式将允许你做一些更复杂的事情,比如,从用户页面上看到的 URL 中获取其中的一部分,或者匹配任何没有找到页面的 URL。 -I’ll explain what does that `exec` method… As I said, the URL pattern can be a string or a regular expression, so it first checks for a string. In case the pattern is equal to the given pathname, it returns the execution of the handler. If it is a regular expression, we do a match with the given pathname. In case it matches, it returns the execution of the handler passing to it the captured parameters. +我将详细解释这个 `exec` 方法 … 正如我前面说的,URL 模式既有可能是一个字符串,也有可能是一个正则表达式,因此,我首先来检查它是否是一个字符串。如果模式与给定的路径名相同,它返回运行处理程序。如果是一个正则表达式,我们与给定的路径名进行匹配。如果匹配成功,它将获取的参数传递给处理程序,并返回运行这个处理程序。 -### Working Example +### 工作示例 + +那个例子正好记录到了控制台。我们尝试将它整合到一个页面,看看它是什么样的。 -That example just logs to the console. Let’s try to integrate it to a page and see something. ``` @@ -77,40 +78,41 @@ That example just logs to the console. Let’s try to integrate it to a page and
- ``` -This is the `index.html`. For single page applications, you must do special work on the server side because all unknown paths should return this `index.html`. For development, I’m using an npm tool called [serve][1]. This tool is to serve static content. With the flag `-s`/`--single` you can serve single page applications. +这是 `index.html`。对于单页面应用程序来说,你必须在服务器侧做一个特别的工作,因为所有未知的路径都将返回这个 `index.html`。在开发时,我们使用了一个 npm 工具调用了 [serve][1]。这个工具去提供静态内容。使用标志 `-s`/`--single`,你可以提供单页面应用程序。 + +使用 [Node.js][2] 和安装的 npm(它与 Node 一起安装),运行: -With [Node.js][2] and npm (comes with Node) installed, run: ``` npm i -g serve serve -s - ``` -That HTML file loads the script `main.js` as a module. It has a simple `
` and a `
` element in which we’ll render the corresponding page. +那个 HTML 文件将脚本 `main.js` 加载为一个模块。在我们渲染的相关页面中,它有一个简单的 `
` 和一个 `
` 元素。 + +在 `main.js` 文件中: -Inside the `main.js` file: ``` const main = document.querySelector('main') const result = router.exec(location.pathname) main.innerHTML = result - ``` -We call `router.exec()` passing the current pathname and setting the result as HTML in the main element. +我们调用传递了当前路径名为参数的 `router.exec()`,然后将 `result` 设置为 `main` 元素的 HTML。 -If you go to localhost and play with it you’ll see that it works, but not as you expect from a SPA. Single page applications shouldn’t refresh when you click on links. +如果你访问 `localhost` 并运行它,你将看到它能够正常工作,但不是预期中的来自一个单页面应用程序。当你点击链接时,单页面应用程序将不会被刷新。 -We’ll have to attach event listeners to each anchor link click, prevent the default behavior and do the correct rendering. Because a single page application is something dynamic, you expect creating anchor links on the fly so to add the event listeners I’ll use a technique called [event delegation][3]. +我们将在每个点击的链接的锚点上附加事件监听器,防止出现缺省行为,并做出正确的渲染。因为一个单页面应用程序是一个动态的东西,你预期要创建的锚点链接是动态的,因此要添加事件监听器,我使用的是一个叫 [事件委托][3] 的方法。 -I’ll attach a click event listener to the whole document and check if that click was on an anchor link (or inside one). +我给整个文档附加一个点击事件监听器,然后去检查在锚点上(或内部)是否有点击事件。 -In the `Router` class I’ll have a method that will register a callback that will run for every time we click on a link or a “popstate” event occurs. The popstate event is dispatched every time you use the browser back or forward buttons. +在 `Router` 类中,我有一个注册回调的方法,在我们每次点击一个链接或者一个 `popstate` 事件发生时,这个方法将被运行。每次你使用浏览器的返回或者前进按钮时,`popstate` 事件将被发送。 -To the callback we’ll pass that same `router.exec(location.pathname)` for convenience. -```class Router { +为了方便其见,我们给回调传递与 `router.exec(location.pathname)` 相同的参数。 + +``` +class Router { // ... install(callback) { const execCallback = () => { @@ -149,19 +151,20 @@ To the callback we’ll pass that same `router.exec(location.pathname)` for conv } ``` -For link clicks, besides calling the callback, we update the URL with `history.pushState()`. +对于链接的点击事件,除调用了回调之外,我们还使用 `history.pushState()` 去更新 URL。 + +我们将前面的 `main` 元素中的渲染移动到 `install` 回调中。 -We’ll move that previous render we did in the main element into the install callback. ``` router.install(result => { main.innerHTML = result }) - ``` #### DOM -Those handlers you pass to the router doesn’t need to return a `string`. If you need more power you can return actual DOM. Ex: +你传递给路由器的这些处理程序并不需要返回一个字符串。如果你需要更多的东西,你可以返回实际的 DOM。如: + ``` const homeTmpl = document.createElement('template') homeTmpl.innerHTML = ` @@ -178,7 +181,7 @@ function homePage() { ``` -And now in the install callback you can check if the result is a `string` or a `Node`. +现在,在 `install` 回调中,你可以去检查 `result` 是一个 `string` 还是一个 `Node`。 ``` router.install(result => { if (typeof result === 'string') { @@ -190,9 +193,9 @@ router.install(result => { }) ``` -That will cover the basic features. I wanted to share this because I’ll use this router in next blog posts. +这些就是基本的功能。我希望将它共享出来,因为我将在下篇文章中使用到这个路由器。 -I’ve published it as an [npm package][4]. +我已经以一个 [npm 包][4] 的形式将它发布了。 -------------------------------------------------------------------------------- @@ -200,8 +203,8 @@ via: https://nicolasparada.netlify.com/posts/js-router/ 作者:[Nicolás Parada][a] 选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180428 How to get a core dump for a segfault on Linux.md b/published/20180428 How to get a core dump for a segfault on Linux.md new file mode 100644 index 0000000000..0b45ebea9f --- /dev/null +++ b/published/20180428 How to get a core dump for a segfault on Linux.md @@ -0,0 +1,178 @@ +在 Linux 上如何得到一个段错误的核心转储 +============================================================ + +本周工作中,我花了整整一周的时间来尝试调试一个段错误。我以前从来没有这样做过,我花了很长时间才弄清楚其中涉及的一些基本事情(获得核心转储、找到导致段错误的行号)。于是便有了这篇博客来解释如何做那些事情! + +在看完这篇博客后,你应该知道如何从“哦,我的程序出现段错误,但我不知道正在发生什么”到“我知道它出现段错误时的堆栈、行号了! “。 + +### 什么是段错误? + +“段错误segmentation fault”是指你的程序尝试访问不允许访问的内存地址的情况。这可能是由于: + +* 试图解引用空指针(你不被允许访问内存地址 `0`); +* 试图解引用其他一些不在你内存(LCTT 译注:指不在合法的内存地址区间内)中的指针; +* 一个已被破坏并且指向错误的地方的 C++ 虚表指针C++ vtable pointer,这导致程序尝试执行没有执行权限的内存中的指令; +* 其他一些我不明白的事情,比如我认为访问未对齐的内存地址也可能会导致段错误(LCTT 译注:在要求自然边界对齐的体系结构,如 MIPS、ARM 中更容易因非对齐访问产生段错误)。 + +这个“C++ 虚表指针”是我的程序发生段错误的情况。我可能会在未来的博客中解释这个,因为我最初并不知道任何关于 C++ 的知识,并且这种虚表查找导致程序段错误的情况也是我所不了解的。 + +但是!这篇博客后不是关于 C++ 问题的。让我们谈论的基本的东西,比如,我们如何得到一个核心转储? + +### 步骤1:运行 valgrind + +我发现找出为什么我的程序出现段错误的最简单的方式是使用 `valgrind`:我运行 + +``` +valgrind -v your-program +``` + +这给了我一个故障时的堆栈调用序列。 简洁! + +但我想也希望做一个更深入调查,并找出些 `valgrind` 没告诉我的信息! 所以我想获得一个核心转储并探索它。 + +### 如何获得一个核心转储 + +核心转储core dump是您的程序内存的一个副本,并且当您试图调试您的有问题的程序哪里出错的时候它非常有用。 + +当您的程序出现段错误,Linux 的内核有时会把一个核心转储写到磁盘。 当我最初试图获得一个核心转储时,我很长一段时间非常沮丧,因为 - Linux 没有生成核心转储!我的核心转储在哪里? + +这就是我最终做的事情: + +1. 在启动我的程序之前运行 `ulimit -c unlimited` +2. 运行 `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` + +### ulimit:设置核心转储的最大尺寸 + +`ulimit -c` 设置核心转储的最大尺寸。 它往往设置为 0,这意味着内核根本不会写核心转储。 它以千字节为单位。 `ulimit` 是按每个进程分别设置的 —— 你可以通过运行 `cat /proc/PID/limit` 看到一个进程的各种资源限制。 + +例如这些是我的系统上一个随便一个 Firefox 进程的资源限制: + +``` +$ cat /proc/6309/limits +Limit Soft Limit Hard Limit Units +Max cpu time unlimited unlimited seconds +Max file size unlimited unlimited bytes +Max data size unlimited unlimited bytes +Max stack size 8388608 unlimited bytes +Max core file size 0 unlimited bytes +Max resident set unlimited unlimited bytes +Max processes 30571 30571 processes +Max open files 1024 1048576 files +Max locked memory 65536 65536 bytes +Max address space unlimited unlimited bytes +Max file locks unlimited unlimited locks +Max pending signals 30571 30571 signals +Max msgqueue size 819200 819200 bytes +Max nice priority 0 0 +Max realtime priority 0 0 +Max realtime timeout unlimited unlimited us +``` + +内核在决定写入多大的核心转储文件时使用软限制soft limit(在这种情况下,`max core file size = 0`)。 您可以使用 shell 内置命令 `ulimit`(`ulimit -c unlimited`) 将软限制增加到硬限制hard limit。 + +### kernel.core_pattern:核心转储保存在哪里 + +`kernel.core_pattern` 是一个内核参数,或者叫 “sysctl 设置”,它控制 Linux 内核将核心转储文件写到磁盘的哪里。 + +内核参数是一种设定您的系统全局设置的方法。您可以通过运行 `sysctl -a` 得到一个包含每个内核参数的列表,或使用 `sysctl kernel.core_pattern` 来专门查看 `kernel.core_pattern` 设置。 + +所以 `sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` 将核心转储保存到目录 `/tmp` 下,并以 `core` 加上一系列能够标识(出故障的)进程的参数构成的后缀为文件名。 + +如果你想知道这些形如 `%e`、`%p` 的参数都表示什么,请参考 [man core][1]。 + +有一点很重要,`kernel.core_pattern` 是一个全局设置 —— 修改它的时候最好小心一点,因为有可能其它系统功能依赖于把它被设置为一个特定的方式(才能正常工作)。 + +### kernel.core_pattern 和 Ubuntu + +默认情况下在 ubuntu 系统中,`kernel.core_pattern` 被设置为下面的值: + +``` +$ sysctl kernel.core_pattern +kernel.core_pattern = |/usr/share/apport/apport %p %s %c %d %P +``` + +这引起了我的迷惑(这 apport 是干什么的,它对我的核心转储做了什么?)。以下关于这个我了解到的: + +* Ubuntu 使用一种叫做 apport 的系统来报告 apt 包有关的崩溃信息。 +* 设定 `kernel.core_pattern=|/usr/share/apport/apport %p %s %c %d %P` 意味着核心转储将被通过管道送给 `apport` 程序。 +* apport 的日志保存在文件 `/var/log/apport.log` 中。 +* apport 默认会忽略来自不属于 Ubuntu 软件包一部分的二进制文件的崩溃信息 + +我最终只是跳过了 apport,并把 `kernel.core_pattern` 重新设置为 `sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t`,因为我在一台开发机上,我不在乎 apport 是否工作,我也不想尝试让 apport 把我的核心转储留在磁盘上。 + +### 现在你有了核心转储,接下来干什么? + +好的,现在我们了解了 `ulimit` 和 `kernel.core_pattern` ,并且实际上在磁盘的 `/tmp` 目录中有了一个核心转储文件。太好了!接下来干什么?我们仍然不知道该程序为什么会出现段错误! + +下一步将使用 `gdb` 打开核心转储文件并获取堆栈调用序列。 + +### 从 gdb 中得到堆栈调用序列 + +你可以像这样用 `gdb` 打开一个核心转储文件: + +``` +$ gdb -c my_core_file +``` + +接下来,我们想知道程序崩溃时的堆栈是什么样的。在 `gdb` 提示符下运行 `bt` 会给你一个调用序列backtrace。在我的例子里,`gdb` 没有为二进制文件加载符号信息,所以这些函数名就像 “??????”。幸运的是,(我们通过)加载符号修复了它。 + +下面是如何加载调试符号。 + +``` +symbol-file /path/to/my/binary +sharedlibrary +``` + +这从二进制文件及其引用的任何共享库中加载符号。一旦我这样做了,当我执行 `bt` 时,gdb 给了我一个带有行号的漂亮的堆栈跟踪! + +如果你想它能工作,二进制文件应该以带有调试符号信息的方式被编译。在试图找出程序崩溃的原因时,堆栈跟踪中的行号非常有帮助。:) + +### 查看每个线程的堆栈 + +通过以下方式在 `gdb` 中获取每个线程的调用栈! + +``` +thread apply all bt full +``` + +### gdb + 核心转储 = 惊喜 + + +如果你有一个带调试符号的核心转储以及 `gdb`,那太棒了!您可以上下查看调用堆栈(LCTT 译注:指跳进调用序列不同的函数中以便于查看局部变量),打印变量,并查看内存来得知发生了什么。这是最好的。 + +如果您仍然正在基于 gdb 向导来工作上,只打印出栈跟踪与bt也可以。 :) + +### ASAN + +另一种搞清楚您的段错误的方法是使用 AddressSanitizer 选项编译程序(“ASAN”,即 `$CC -fsanitize=address`)然后运行它。 本文中我不准备讨论那个,因为本文已经相当长了,并且在我的例子中打开 ASAN 后段错误消失了,可能是因为 ASAN 使用了一个不同的内存分配器(系统内存分配器,而不是 tcmalloc)。 + +在未来如果我能让 ASAN 工作,我可能会多写点有关它的东西。(LCTT 译注:这里指使用 ASAN 也能复现段错误) + +### 从一个核心转储得到一个堆栈跟踪真的很亲切! + +这个博客听起来很多,当我做这些的时候很困惑,但说真的,从一个段错误的程序中获得一个堆栈调用序列不需要那么多步骤: + +1. 试试用 `valgrind` + +如果那没用,或者你想要拿到一个核心转储来调查: + +1. 确保二进制文件编译时带有调试符号信息; +2. 正确的设置 `ulimit` 和 `kernel.core_pattern`; +3. 运行程序; +4. 一旦你用 `gdb` 调试核心转储了,加载符号并运行 `bt`; +5. 尝试找出发生了什么! + +我可以使用 `gdb` 弄清楚有个 C++ 的虚表条目指向一些被破坏的内存,这有点帮助,并且使我感觉好像更懂了 C++ 一点。也许有一天我们会更多地讨论如何使用 `gdb` 来查找问题! + +-------------------------------------------------------------------------------- + +via: https://jvns.ca/blog/2018/04/28/debugging-a-segfault-on-linux/ + +作者:[Julia Evans][a] +译者:[stephenxs](https://github.com/stephenxs) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://jvns.ca/about/ +[1]:http://man7.org/linux/man-pages/man5/core.5.html diff --git a/published/20180429 Passwordless Auth- Client.md b/published/20180429 Passwordless Auth- Client.md new file mode 100644 index 0000000000..0a14e7a871 --- /dev/null +++ b/published/20180429 Passwordless Auth- Client.md @@ -0,0 +1,359 @@ +无密码验证:客户端 +====== + +我们继续 [无密码验证][1] 的文章。上一篇文章中,我们用 Go 写了一个 HTTP 服务,用这个服务来做无密码验证 API。今天,我们为它再写一个 JavaScript 客户端。 + +我们将使用 [这里的][2] 这个单页面应用程序(SPA)来展示使用的技术。如果你还没有读过它,请先读它。 + +记住流程: + +- 用户输入其 email。 +- 用户收到一个带有魔法链接的邮件。 +- 用户点击该链接、 +- 用户验证成功。 + +对于根 URL(`/`),我们将根据验证的状态分别使用两个不同的页面:一个是带有访问表单的页面,或者是已验证通过的用户的欢迎页面。另一个页面是验证回调的重定向页面。 + +### 伺服 + +我们将使用相同的 Go 服务器来为客户端提供服务,因此,在我们前面的 `main.go` 中添加一些路由: + +``` +router.Handle("GET", "/...", http.FileServer(SPAFileSystem{http.Dir("static")})) +``` + +``` +type SPAFileSystem struct { + fs http.FileSystem +} + +func (spa SPAFileSystem) Open(name string) (http.File, error) { + f, err := spa.fs.Open(name) + if err != nil { + return spa.fs.Open("index.html") + } + return f, nil +} +``` + +这个伺服文件放在 `static` 下,配合 `static/index.html` 作为回调。 + +你可以使用你自己的服务器,但是你得在服务器上启用 [CORS][3]。 + +### HTML + +我们来看一下那个 `static/index.html` 文件。 + +``` + + + + + + Passwordless Demo + + + + + +``` + +单页面应用程序的所有渲染由 JavaScript 来完成,因此,我们使用了一个空的 body 部分和一个 `main.js` 文件。 + +我们将使用 [上篇文章][2] 中的 Router。 + +### 渲染 + +现在,我们使用下面的内容来创建一个 `static/js/main.js` 文件: + +``` +import Router from 'https://unpkg.com/@nicolasparada/router' +import { isAuthenticated } from './auth.js' + +const router = new Router() + +router.handle('/', guard(view('home'))) +router.handle('/callback', view('callback')) +router.handle(/^\//, view('not-found')) + +router.install(async resultPromise => { + document.body.innerHTML = '' + document.body.appendChild(await resultPromise) +}) + +function view(name) { + return (...args) => import(`/js/pages/${name}-page.js`) + .then(m => m.default(...args)) +} + +function guard(fn1, fn2 = view('welcome')) { + return (...args) => isAuthenticated() + ? fn1(...args) + : fn2(...args) +} +``` + +与上篇文章不同的是,我们实现了一个 `isAuthenticated()` 函数和一个 `guard()` 函数,使用它去渲染两种验证状态的页面。因此,当用户访问 `/` 时,它将根据用户是否通过了验证来展示主页或者是欢迎页面。 + +### 验证 + +现在,我们来编写 `isAuthenticated()` 函数。使用下面的内容来创建一个 `static/js/auth.js` 文件: + +``` +export function getAuthUser() { + const authUserItem = localStorage.getItem('auth_user') + const expiresAtItem = localStorage.getItem('expires_at') + + if (authUserItem !== null && expiresAtItem !== null) { + const expiresAt = new Date(expiresAtItem) + + if (!isNaN(expiresAt.valueOf()) && expiresAt > new Date()) { + try { + return JSON.parse(authUserItem) + } catch (_) { } + } + } + + return null +} + +export function isAuthenticated() { + return localStorage.getItem('jwt') !== null && getAuthUser() !== null +} +``` + +当有人登入时,我们将保存 JSON 格式的 web 令牌、它的过期日期,以及在 `localStorage` 上的当前已验证用户。这个模块就是这个用处。 + + * `getAuthUser()` 用于从 `localStorage` 获取已认证的用户,以确认 JSON 格式的 Web 令牌没有过期。 + * `isAuthenticated()` 在前面的函数中用于去检查它是否没有返回 `null`。 + +### 获取 + +在继续这个页面之前,我将写一些与服务器 API 一起使用的 HTTP 工具。 + +我们使用以下的内容去创建一个 `static/js/http.js` 文件: + +``` +import { isAuthenticated } from './auth.js' + +function get(url, headers) { + return fetch(url, { + headers: Object.assign(getAuthHeader(), headers), + }).then(handleResponse) +} + +function post(url, body, headers) { + return fetch(url, { + method: 'POST', + headers: Object.assign(getAuthHeader(), { 'content-type': 'application/json' }, headers), + body: JSON.stringify(body), + }).then(handleResponse) +} + +function getAuthHeader() { + return isAuthenticated() + ? { authorization: `Bearer ${localStorage.getItem('jwt')}` } + : {} +} + +export async function handleResponse(res) { + const body = await res.clone().json().catch(() => res.text()) + const response = { + statusCode: res.status, + statusText: res.statusText, + headers: res.headers, + body, + } + if (!res.ok) { + const message = typeof body === 'object' && body !== null && 'message' in body + ? body.message + : typeof body === 'string' && body !== '' + ? body + : res.statusText + const err = new Error(message) + throw Object.assign(err, response) + } + return response +} + +export default { + get, + post, +} +``` + +这个模块导出了 `get()` 和 `post()` 函数。它们是 `fetch` API 的封装。当用户是已验证的,这二个函数注入一个 `Authorization: Bearer ` 头到请求中;这样服务器就能对我们进行身份验证。 + +### 欢迎页 + +我们现在来到欢迎页面。用如下的内容创建一个 `static/js/pages/welcome-page.js` 文件: + +``` +const template = document.createElement('template') +template.innerHTML = ` +

Passwordless Demo

+

Access

+
+ + +
+` + +export default function welcomePage() { + const page = template.content.cloneNode(true) + + page.getElementById('access-form') + .addEventListener('submit', onAccessFormSubmit) + + return page +} +``` + +这个页面使用一个 `HTMLTemplateElement` 作为视图。这只是一个输入用户 email 的简单表单。 + +为了避免干扰,我将跳过错误处理部分,只是将它们输出到控制台上。 + +现在,我们来写 `onAccessFormSubmit()` 函数。 + +``` +import http from '../http.js' + +function onAccessFormSubmit(ev) { + ev.preventDefault() + + const form = ev.currentTarget + const input = form.querySelector('input') + const email = input.value + + sendMagicLink(email).catch(err => { + console.error(err) + if (err.statusCode === 404 && wantToCreateAccount()) { + runCreateUserProgram(email) + } + }) +} + +function sendMagicLink(email) { + return http.post('/api/passwordless/start', { + email, + redirectUri: location.origin + '/callback', + }).then(() => { + alert('Magic link sent. Go check your email inbox.') + }) +} + +function wantToCreateAccount() { + return prompt('No user found. Do you want to create an account?') +} +``` + +它对 `/api/passwordless/start` 发起了 POST 请求,请求体中包含 `email` 和 `redirectUri`。在本例中它返回 `404 Not Found` 状态码时,我们将创建一个用户。 + +``` +function runCreateUserProgram(email) { + const username = prompt("Enter username") + if (username === null) return + + http.post('/api/users', { email, username }) + .then(res => res.body) + .then(user => sendMagicLink(user.email)) + .catch(console.error) +} +``` + +这个用户创建程序,首先询问用户名,然后使用 email 和用户名做一个 `POST` 请求到 `/api/users`。成功之后,给创建的用户发送一个魔法链接。 + +### 回调页 + +这是访问表单的全部功能,现在我们来做回调页面。使用如下的内容来创建一个 `static/js/pages/callback-page.js` 文件: + +``` +import http from '../http.js' + +const template = document.createElement('template') +template.innerHTML = ` +

Authenticating you

+` + +export default function callbackPage() { + const page = template.content.cloneNode(true) + + const hash = location.hash.substr(1) + const fragment = new URLSearchParams(hash) + for (const [k, v] of fragment.entries()) { + fragment.set(decodeURIComponent(k), decodeURIComponent(v)) + } + const jwt = fragment.get('jwt') + const expiresAt = fragment.get('expires_at') + + http.get('/api/auth_user', { authorization: `Bearer ${jwt}` }) + .then(res => res.body) + .then(authUser => { + localStorage.setItem('jwt', jwt) + localStorage.setItem('auth_user', JSON.stringify(authUser)) + localStorage.setItem('expires_at', expiresAt) + + location.replace('/') + }) + .catch(console.error) + + return page +} +``` + +请记住……当点击魔法链接时,我们会来到 `/api/passwordless/verify_redirect`,它将把我们重定向到重定向 URI,我们将放在哈希中的 JWT 和过期日期传递给 `/callback`。 + +回调页面解码 URL 中的哈希,提取这些参数去做一个 `GET` 请求到 `/api/auth_user`,用 JWT 保存所有数据到 `localStorage` 中。最后,重定向到主页面。 + +### 主页 + +创建如下内容的 `static/pages/home-page.js` 文件: + +``` +import { getAuthUser } from '../auth.js' + +export default function homePage() { + const authUser = getAuthUser() + + const template = document.createElement('template') + template.innerHTML = ` +

Passwordless Demo

+

Welcome back, ${authUser.username} 👋

+ + ` + + const page = template.content + + page.getElementById('logout-button') + .addEventListener('click', logout) + + return page +} + +function logout() { + localStorage.clear() + location.reload() +} +``` + +这个页面用于欢迎已验证用户,同时也有一个登出按钮。`logout()` 函数的功能只是清理掉 `localStorage` 并重载这个页面。 + +这就是全部内容了。我猜你在此之前已经看过这个 [demo][4] 了。当然,这些源代码也在同一个 [仓库][5] 中。 + +-------------------------------------------------------------------------------- + +via: https://nicolasparada.netlify.com/posts/passwordless-auth-client/ + +作者:[Nicolás Parada][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://nicolasparada.netlify.com/ +[1]:https://linux.cn/article-9748-1.html +[2]:https://linux.cn/article-9815-1.html +[3]:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS +[4]:https://go-passwordless-demo.herokuapp.com/ +[5]:https://github.com/nicolasparada/go-passwordless-demo diff --git a/published/20180430 3 practical Python tools- magic methods, iterators and generators, and method magic.md b/published/20180430 3 practical Python tools- magic methods, iterators and generators, and method magic.md new file mode 100644 index 0000000000..7ddd3f33cc --- /dev/null +++ b/published/20180430 3 practical Python tools- magic methods, iterators and generators, and method magic.md @@ -0,0 +1,406 @@ +日常 Python 编程优雅之道 +====== + +> 3 个可以使你的 Python 代码更优雅、可读、直观和易于维护的工具。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/serving-bowl-forks-dinner.png?itok=a3YqPwr5) + +Python 提供了一组独特的工具和语言特性来使你的代码更加优雅、可读和直观。为正确的问题选择合适的工具,你的代码将更易于维护。在本文中,我们将研究其中的三个工具:魔术方法、迭代器和生成器,以及方法魔术。 + +### 魔术方法 + +魔术方法可以看作是 Python 的管道。它们被称为“底层”方法,用于某些内置的方法、符号和操作。你可能熟悉的常见魔术方法是 `__init__()`,当我们想要初始化一个类的新实例时,它会被调用。 + +你可能已经看过其他常见的魔术方法,如 `__str__` 和 `__repr__`。Python 中有一整套魔术方法,通过实现其中的一些方法,我们可以修改一个对象的行为,甚至使其行为类似于内置数据类型,例如数字、列表或字典。 + +让我们创建一个 `Money` 类来示例: + +``` +class Money: + + currency_rates = { + '$': 1, + '€': 0.88, + } + + def __init__(self, symbol, amount): + self.symbol = symbol + self.amount = amount + + def __repr__(self): + return '%s%.2f' % (self.symbol, self.amount) + + def convert(self, other): + """ Convert other amount to our currency """ + new_amount = ( + other.amount / self.currency_rates[other.symbol] + * self.currency_rates[self.symbol]) + + return Money(self.symbol, new_amount) +``` + +该类定义为给定的货币符号和汇率定义了一个货币汇率,指定了一个初始化器(也称为构造函数),并实现 `__repr__`,因此当我们打印这个类时,我们会看到一个友好的表示,例如 `$2.00` ,这是一个带有货币符号和金额的 `Money('$', 2.00)` 实例。最重要的是,它定义了一种方法,允许你使用不同的汇率在不同的货币之间进行转换。 + +打开 Python shell,假设我们已经定义了使用两种不同货币的食品的成本,如下所示: + +``` +>>> soda_cost = Money('$', 5.25) +>>> soda_cost + $5.25 + +>>> pizza_cost = Money('€', 7.99) +>>> pizza_cost + €7.99 +``` + +我们可以使用魔术方法使得这个类的实例之间可以相互交互。假设我们希望能够将这个类的两个实例一起加在一起,即使它们是不同的货币。为了实现这一点,我们可以在 `Money` 类上实现 `__add__` 这个魔术方法: + +``` +class Money: + + # ... previously defined methods ... + + def __add__(self, other): + """ Add 2 Money instances using '+' """ + new_amount = self.amount + self.convert(other).amount + return Money(self.symbol, new_amount) +``` + +现在我们可以以非常直观的方式使用这个类: + +``` +>>> soda_cost = Money('$', 5.25) +>>> pizza_cost = Money('€', 7.99) +>>> soda_cost + pizza_cost + $14.33 +>>> pizza_cost + soda_cost + €12.61 +``` + +当我们将两个实例加在一起时,我们得到以第一个定义的货币符号所表示的结果。所有的转换都是在底层无缝完成的。如果我们想的话,我们也可以为减法实现 `__sub__`,为乘法实现 `__mul__` 等等。阅读[模拟数字类型][1]或[魔术方法指南][2]来获得更多信息。 + +我们学习到 `__add__` 映射到内置运算符 `+`。其他魔术方法可以映射到像 `[]` 这样的符号。例如,在字典中通过索引或键来获得一项,其实是使用了 `__getitem__` 方法: + +``` +>>> d = {'one': 1, 'two': 2} +>>> d['two'] +2 +>>> d.__getitem__('two') +2 +``` + +一些魔术方法甚至映射到内置函数,例如 `__len__()` 映射到 `len()`。 + +``` +class Alphabet: + letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + def __len__(self): + return len(self.letters) + +>>> my_alphabet = Alphabet() +>>> len(my_alphabet) + 26 +``` + +### 自定义迭代器 + +对于新的和经验丰富的 Python 开发者来说,自定义迭代器是一个非常强大的但令人迷惑的主题。 + +许多内置类型,例如列表、集合和字典,已经实现了允许它们在底层迭代的协议。这使我们可以轻松地遍历它们。 + +``` +>>> for food in ['Pizza', 'Fries']: + +         print(food + '. Yum!') + +Pizza. Yum! +Fries. Yum! +``` + +我们如何迭代我们自己的自定义类?首先,让我们来澄清一些术语。 + + * 要成为一个可迭代对象,一个类需要实现 `__iter__()` + * `__iter__()` 方法需要返回一个迭代器 + * 要成为一个迭代器,一个类需要实现 `__next__()`(或[在 Python 2][3]中是 `next()`),当没有更多的项要迭代时,必须抛出一个 `StopIteration` 异常。 + +呼!这听起来很复杂,但是一旦你记住了这些基本概念,你就可以在任何时候进行迭代。 + +我们什么时候想使用自定义迭代器?让我们想象一个场景,我们有一个 `Server` 实例在不同的端口上运行不同的服务,如 `http` 和 `ssh`。其中一些服务处于 `active` 状态,而其他服务则处于 `inactive` 状态。 + +``` +class Server: + + services = [ + {'active': False, 'protocol': 'ftp', 'port': 21}, + {'active': True, 'protocol': 'ssh', 'port': 22}, + {'active': True, 'protocol': 'http', 'port': 80}, + ] +``` + +当我们遍历 `Server` 实例时,我们只想遍历那些处于 `active` 的服务。让我们创建一个 `IterableServer` 类: + +``` +class IterableServer: +    def __init__(self): +        self.current_pos = 0 +    def __next__(self): +        pass  # TODO: 实现并记得抛出 StopIteration +``` + +首先,我们将当前位置初始化为 `0`。然后,我们定义一个 `__next__()` 方法来返回下一项。我们还将确保在没有更多项返回时抛出 `StopIteration`。到目前为止都很好!现在,让我们实现这个 `__next__()` 方法。 + +``` +class IterableServer: +    def __init__(self): +        self.current_pos = 0.  # 我们初始化当前位置为 0 +    def __iter__(self):  # 我们可以在这里返回 self,因为实现了 __next__ +        return self +    def __next__(self): +        while self.current_pos < len(self.services): +            service = self.services[self.current_pos] +            self.current_pos += 1 +            if service['active']: +                return service['protocol'], service['port'] +        raise StopIteration +    next = __next__  # 可选的 Python2 兼容性 +``` + +我们对列表中的服务进行遍历,而当前的位置小于服务的个数,但只有在服务处于活动状态时才返回。一旦我们遍历完服务,就会抛出一个 `StopIteration` 异常。 + + +因为我们实现了 `__next__()` 方法,当它耗尽时,它会抛出 `StopIteration`。我们可以从 `__iter__()` 返回 `self`,因为 `IterableServer` 类遵循 `iterable` 协议。 + +现在我们可以遍历一个 `IterableServer` 实例,这将允许我们查看每个处于活动的服务,如下所示: + +``` +>>> for protocol, port in IterableServer(): + +        print('service %s is running on port %d' % (protocol, port)) + +service ssh is running on port 22 + +service http is running on port 21 + +``` + +太棒了,但我们可以做得更好!在这样类似的实例中,我们的迭代器不需要维护大量的状态,我们可以简化代码并使用 [generator(生成器)][4] 来代替。 + +``` +class Server: +    services = [ +        {'active': False, 'protocol': 'ftp', 'port': 21}, +        {'active': True, 'protocol': 'ssh', 'port': 22}, +        {'active': True, 'protocol': 'http', 'port': 21}, +    ] +    def __iter__(self): +        for service in self.services: +            if service['active']: +                yield service['protocol'], service['port'] +``` + +`yield` 关键字到底是什么?在定义生成器函数时使用 yield。这有点像 `return`,虽然 `return` 在返回值后退出函数,但 `yield` 会暂停执行直到下次调用它。这允许你的生成器的功能在它恢复之前保持状态。查看 [yield 的文档][5]以了解更多信息。使用生成器,我们不必通过记住我们的位置来手动维护状态。生成器只知道两件事:它现在需要做什么以及计算下一个项目需要做什么。一旦我们到达执行点,即 `yield` 不再被调用,我们就知道停止迭代。 + +这是因为一些内置的 Python 魔法。在 [Python 关于 `__iter__()` 的文档][6]中我们可以看到,如果 `__iter__()` 是作为一个生成器实现的,它将自动返回一个迭代器对象,该对象提供 `__iter__()` 和 `__next__()` 方法。阅读这篇很棒的文章,深入了解[迭代器,可迭代对象和生成器][7]。 + +### 方法魔法 + +由于其独特的方面,Python 提供了一些有趣的方法魔法作为语言的一部分。 + +其中一个例子是别名功能。因为函数只是对象,所以我们可以将它们赋值给多个变量。例如: + +``` +>>> def foo(): +       return 'foo' +>>> foo() +'foo' +>>> bar = foo +>>> bar() +'foo' +``` + +我们稍后会看到它的作用。 + +Python 提供了一个方便的内置函数[称为 `getattr()`][8],它接受 `object, name, default` 参数并在 `object` 上返回属性 `name`。这种编程方式允许我们访问实例变量和方法。例如: + +``` +>>> class Dog: + sound = 'Bark' + def speak(self): + print(self.sound + '!', self.sound + '!') + +>>> fido = Dog() + +>>> fido.sound +'Bark' +>>> getattr(fido, 'sound') +'Bark' + +>>> fido.speak +> +>>> getattr(fido, 'speak') +> + + +>>> fido.speak() +Bark! Bark! +>>> speak_method = getattr(fido, 'speak') +>>> speak_method() +Bark! Bark! +``` + +这是一个很酷的技巧,但是我们如何在实际中使用 `getattr` 呢?让我们看一个例子,我们编写一个小型命令行工具来动态处理命令。 + +``` +class Operations: +    def say_hi(self, name): +        print('Hello,', name) +    def say_bye(self, name): +        print ('Goodbye,', name) +    def default(self, arg): +        print ('This operation is not supported.') + +if __name__ == '__main__': +    operations = Operations() +    # 假设我们做了错误处理 +    command, argument = input('> ').split() +    func_to_call = getattr(operations, command, operations.default) +    func_to_call(argument) +``` + +脚本的输出是: + +``` +$ python getattr.py +> say_hi Nina +Hello, Nina +> blah blah +This operation is not supported. +``` + +接下来,我们来看看 `partial`。例如,`functool.partial(func, *args, **kwargs)` 允许你返回一个新的 [partial 对象][9],它的行为类似 `func`,参数是 `args` 和 `kwargs`。如果传入更多的 `args`,它们会被附加到 `args`。如果传入更多的 `kwargs`,它们会扩展并覆盖 `kwargs`。让我们通过一个简短的例子来看看: + +``` +>>> from functools import partial +>>> basetwo = partial(int, base=2) +>>> basetwo + +>>> basetwo('10010') +18 + +# 这等同于 +>>> int('10010', base=2) +``` + +让我们看看在我喜欢的一个[名为 `agithub`][10] 的库中的一些示例代码中,这个方法魔术是如何结合在一起的,这是一个(名字起得很 low 的) REST API 客户端,它具有透明的语法,允许你以最小的配置快速构建任何 REST API 原型(不仅仅是 GitHub)。我发现这个项目很有趣,因为它非常强大,但只有大约 400 行 Python 代码。你可以在大约 30 行配置代码中添加对任何 REST API 的支持。`agithub` 知道协议所需的一切(`REST`、`HTTP`、`TCP`),但它不考虑上游 API。让我们深入到它的实现中。 + +以下是我们如何为 GitHub API 和任何其他相关连接属性定义端点 URL 的简化版本。在这里查看[完整代码][11]。 + +``` +class GitHub(API): +    def __init__(self, token=None, *args, **kwargs): +        props = ConnectionProperties(api_url = kwargs.pop('api_url', 'api.github.com')) +        self.setClient(Client(*args, **kwargs)) +        self.setConnectionProperties(props) +``` + +然后,一旦配置了[访问令牌][12],就可以开始使用 [GitHub API][13]。 + +``` +>>> gh = GitHub('token') +>>> status, data = gh.user.repos.get(visibility='public', sort='created') +>>> # ^ 映射到 GET /user/repos +>>> data +... ['tweeter', 'snipey', '...'] +``` + +请注意,你要确保 URL 拼写正确,因为我们没有验证 URL。如果 URL 不存在或出现了其他任何错误,将返回 API 抛出的错误。那么,这一切是如何运作的呢?让我们找出答案。首先,我们将查看一个 [`API` 类][14]的简化示例: + +``` +class API: +    # ... other methods ... +    def __getattr__(self, key): +        return IncompleteRequest(self.client).__getattr__(key) +    __getitem__ = __getattr__ +``` + +在 `API` 类上的每次调用都会调用 [`IncompleteRequest` 类][15]作为指定的 `key`。 + +``` +class IncompleteRequest: +    # ... other methods ... +    def __getattr__(self, key): +        if key in self.client.http_methods: +            htmlMethod = getattr(self.client, key) +            return partial(htmlMethod, url=self.url) +        else: +            self.url += '/' + str(key) +            return self +    __getitem__ = __getattr__ + +class Client: +    http_methods = ('get')  # 还有 post, put, patch 等等。 +    def get(self, url, headers={}, **params): +        return self.request('GET', url, None, headers) +``` + +如果最后一次调用不是 HTTP 方法(如 `get`、`post` 等),则返回带有附加路径的 `IncompleteRequest`。否则,它从[`Client` 类][16]获取 HTTP 方法对应的正确函数,并返回 `partial`。 + +如果我们给出一个不存在的路径会发生什么? + +``` +>>> status, data = this.path.doesnt.exist.get() +>>> status +... 404 +``` + +因为 `__getattr__` 别名为 `__getitem__`: + +``` +>>> owner, repo = 'nnja', 'tweeter' +>>> status, data = gh.repos[owner][repo].pulls.get() +>>> # ^ Maps to GET /repos/nnja/tweeter/pulls +>>> data +.... # {....} +``` + +这真心是一些方法魔术! + +### 了解更多 + +Python 提供了大量工具,使你的代码更优雅,更易于阅读和理解。挑战在于找到合适的工具来完成工作,但我希望本文为你的工具箱添加了一些新工具。而且,如果你想更进一步,你可以在我的博客 [nnja.io][17] 上阅读有关装饰器、上下文管理器、上下文生成器和命名元组的内容。随着你成为一名更好的 Python 开发人员,我鼓励你到那里阅读一些设计良好的项目的源代码。[Requests][18] 和 [Flask][19] 是两个很好的起步的代码库。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/4/elegant-solutions-everyday-python-problems + +作者:[Nina Zakharenko][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/nnja +[1]:https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types +[2]:https://rszalski.github.io/magicmethods/ +[3]:https://docs.python.org/2/library/stdtypes.html#iterator.next +[4]:https://docs.python.org/3/library/stdtypes.html#generator-types +[5]:https://docs.python.org/3/reference/expressions.html#yieldexpr +[6]:https://docs.python.org/3/reference/datamodel.html#object.__iter__ +[7]:http://nvie.com/posts/iterators-vs-generators/ +[8]:https://docs.python.org/3/library/functions.html#getattr +[9]:https://docs.python.org/3/library/functools.html#functools.partial +[10]:https://github.com/mozilla/agithub +[11]:https://github.com/mozilla/agithub/blob/master/agithub/GitHub.py +[12]:https://github.com/settings/tokens +[13]:https://developer.github.com/v3/repos/#list-your-repositories +[14]:https://github.com/mozilla/agithub/blob/dbf7014e2504333c58a39153aa11bbbdd080f6ac/agithub/base.py#L30-L58 +[15]:https://github.com/mozilla/agithub/blob/dbf7014e2504333c58a39153aa11bbbdd080f6ac/agithub/base.py#L60-L100 +[16]:https://github.com/mozilla/agithub/blob/dbf7014e2504333c58a39153aa11bbbdd080f6ac/agithub/base.py#L102-L231 +[17]:http://nnja.io +[18]:https://github.com/requests/requests +[19]:https://github.com/pallets/flask +[20]:https://us.pycon.org/2018/schedule/presentation/164/ +[21]:https://us.pycon.org/2018/ diff --git a/published/20180502 Customizing your text colors on the Linux command line.md b/published/20180502 Customizing your text colors on the Linux command line.md new file mode 100644 index 0000000000..393e857ed2 --- /dev/null +++ b/published/20180502 Customizing your text colors on the Linux command line.md @@ -0,0 +1,165 @@ +在 Linux 命令行中自定义文本颜色 +====== + +> 在 Linux 命令行当中使用不同颜色以期提供一种根据文件类型来识别文件的简单方式。你可以修改这些颜色,但是在做之前应该对你做的事情有充分的理由。 + +![](https://images.idgesg.net/images/article/2018/05/numbers-100756457-large.jpg) + +如果你在 Linux 命令行上花费了大量的时间(如果没有,那么你可能不会读这篇文章),你无疑注意到了 `ls` 以多种不同的颜色显示文件。你可能也注意到了一些区别 —— 目录是一种颜色,可执行文件是另一种颜色等等。 + +这一切是如何发生的呢?以及,你可以选择哪些选项来改变颜色分配可能就不是很多人都知道的。 + +一种方法是运行 `dircolors` 命令得到一大堆展示了如何指定这些颜色的数据。它会显示以下这些东西: + +``` +$ dircolors +LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do +=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg +=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01 +;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01 +;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=0 +1;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31 +:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*. +xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.t +bz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.j +ar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.a +lz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.r +z=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*. +mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35: +*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35: +*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;3 +5:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01; +35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01 +;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01 +;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01 +;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;3 +5:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;3 +5:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;3 +6:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00; +36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00; +36:*.spx=00;36:*.xspf=00;36:'; +export LS_COLORS +``` + +如果你擅长解析文件,那么你可能会注意到这个列表有一种模式patten。用冒号分隔开,你会看到这样的东西: + +``` +$ dircolors | tr ":" "\n" | head -10 +LS_COLORS='rs=0 +di=01;34 +ln=01;36 +mh=00 +pi=40;33 +so=01;35 +do=01;35 +bd=40;33;01 +cd=40;33;01 +or=40;31;01 +``` + +OK,这里有一个模式 —— 一系列定义,有一到三个数字组件。我们来看看其中的一个定义。 + +``` +pi=40;33 +``` + +有些人可能会问的第一个问题是“pi 是什么?”在这里,我们研究的是颜色和文件类型,所以这显然不是以 3.14 开头的那个有趣的数字。当然不是,这个 “pi” 代表 “pipe(管道)” —— Linux 系统上的一种特殊类型的文件,它可以将数据从一个程序传递给另一个程序。所以,让我们建立一个管道。 + +``` +$ mknod /tmp/mypipe p +$ ls -l /tmp/mypipe +prw-rw-r-- 1 shs shs 0 May 1 14:00 /tmp/mypipe +``` + +当我们在终端窗口中查看我们的管道和其他几个文件时,颜色差异非常明显。 + +![font colors][1] + +在 `pi` 的定义中(如上所示),“40” 使文件在终端(或 PuTTY)窗口中使用黑色背景显示,31 使字体颜色变红。管道是特殊的文件,这种特殊的处理使它们在目录列表中突出显示。 + +`bd` 和 `cd` 定义是相同的 —— `40;33;01`,它有一个额外的设置。这个设置会导致 块设备block device(bd)和 字符设备character device(cd)以黑色背景,橙色字体和另一种效果显示 —— 字符将以粗体显示。 + +以下列表显示由文件类型file type所指定的颜色和字体分配: + +``` +setting file type +======= ========= +rs=0 reset to no color +di=01;34 directory +ln=01;36 link +mh=00 multi-hard link +pi=40;33 pipe +so=01;35 socket +do=01;35 door +bd=40;33;01 block device +cd=40;33;01 character device +or=40;31;01 orphan +mi=00 missing? +su=37;41 setuid +sg=30;43 setgid +ca=30;41 file with capability +tw=30;42 directory with sticky bit and world writable +ow=34;42 directory that is world writable +st=37;44 directory with sticky bit +ex=01;93 executable +``` + +你可能已经注意到,在 `dircolors` 命令输出中,我们的大多数定义都以星号开头(例如,`*.wav=00;36`)。这些按文件扩展名file extension而不是文件类型定义显示属性。这有一个示例: + +``` +$ dircolors | tr ":" "\n" | tail -10 +*.mpc=00;36 +*.ogg=00;36 +*.ra=00;36 +*.wav=00;36 +*.oga=00;36 +*.opus=00;36 +*.spx=00;36 +*.xspf=00;36 +'; +export LS_COLORS +``` + +这些设置(上面列表中所有的 `00;36`)将使这些文件名以青色显示。可用的颜色如下所示。 + +![all colors][2] + +### 如何改变设置 + +你要使用 `ls` 的别名来打开颜色显示功能。这通常是 Linux 系统上的默认设置,看起来是这样的: + +``` +alias ls='ls --color=auto' +``` + +如果要关闭字体颜色,可以运行 `unalias ls` 命令,然后文件列表将仅以默认字体颜色显示。 + +你可以通过修改 `$LS_COLORS` 设置和导出修改后的设置来更改文本颜色。 + +``` +$ export LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;... +``` + +注意:上面的命令由于太长被截断了。 + +如果希望文本颜色的修改是永久性的,则需要将修改后的 `$LS_COLORS` 定义添加到一个启动文件中,例如 `.bashrc`。 + +### 更多关于命令行文本 + +你可以在 NetworkWorld 的 [2016 年 11 月][3]的帖子中找到有关文本颜色的其他信息。 + +--- + +via: https://www.networkworld.com/article/3269587/linux/customizing-your-text-colors-on-the-linux-command-line.html + +作者:[Sandra Henry-Stocker][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[pityonline](https://github.com/pityonline) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[1]: https://images.idgesg.net/images/article/2018/05/font-colors-100756483-large.jpg +[2]: https://images.techhive.com/images/article/2016/11/all-colors-100691990-large.jpg +[3]: https://www.networkworld.com/article/3138909/linux/coloring-your-world-with-ls-colors.html diff --git a/published/20180508 How To Check Ubuntu Version and Other System Information Easily.md b/published/20180508 How To Check Ubuntu Version and Other System Information Easily.md new file mode 100644 index 0000000000..48c5f617ed --- /dev/null +++ b/published/20180508 How To Check Ubuntu Version and Other System Information Easily.md @@ -0,0 +1,134 @@ +如何轻松地检查 Ubuntu 版本以及其它系统信息 +====== + +> 摘要:想知道你正在使用的 Ubuntu 具体是什么版本吗?这篇文档将告诉你如何检查你的 Ubuntu 版本、桌面环境以及其他相关的系统信息。 + +通常,你能非常容易的通过命令行或者图形界面获取你正在使用的 Ubuntu 的版本。当你正在尝试学习一篇互联网上的入门教材或者正在从各种各样的论坛里获取帮助的时候,知道当前正在使用的 Ubuntu 确切的版本号、桌面环境以及其他的系统信息将是尤为重要的。 + +在这篇简短的文章中,作者将展示各种检查 [Ubuntu][1] 版本以及其他常用的系统信息的方法。 + +### 如何在命令行检查 Ubuntu 版本 + +这个是获得 Ubuntu 版本的最好的办法。我本想先展示如何用图形界面做到这一点,但是我决定还是先从命令行方法说起,因为这种方法不依赖于你使用的任何[桌面环境][2]。 你可以在 Ubuntu 的任何变种系统上使用这种方法。 + +打开你的命令行终端 (`Ctrl+Alt+T`), 键入下面的命令: + +``` +lsb_release -a +``` + +上面命令的输出应该如下: + +``` +No LSB modules are available. +Distributor ID: Ubuntu +Description: Ubuntu 16.04.4 LTS +Release: 16.04 +Codename: xenial +``` + +![How to check Ubuntu version in command line][3] + +正像你所看到的,当前我的系统安装的 Ubuntu 版本是 Ubuntu 16.04, 版本代号: Xenial。 + +且慢!为什么版本描述中显示的是 Ubuntu 16.04.4 而发行版本是 16.04?到底哪个才是正确的版本?16.04 还是 16.04.4? 这两者之间有什么区别? + +如果言简意赅的回答这个问题的话,那么答案应该是你正在使用 Ubuntu 16.04。这个是基准版本,而 16.04.4 进一步指明这是 16.04 的第四个补丁版本。你可以将补丁版本理解为 Windows 世界里的服务包。在这里,16.04 和 16.04.4 都是正确的版本号。 + +那么输出的 Xenial 又是什么?那正是 Ubuntu 16.04 的版本代号。你可以阅读下面这篇文章获取更多信息:[了解 Ubuntu 的命名惯例][4]。 + +#### 其他一些获取 Ubuntu 版本的方法 + +你也可以使用下面任意的命令得到 Ubuntu 的版本: + +``` +cat /etc/lsb-release +``` + +输出如下信息: + +``` +DISTRIB_ID=Ubuntu +DISTRIB_RELEASE=16.04 +DISTRIB_CODENAME=xenial +DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS" +``` + +![How to check Ubuntu version in command line][5] + + +你还可以使用下面的命令来获得 Ubuntu 版本: + +``` +cat /etc/issue +``` + + +命令行的输出将会如下: + +``` +Ubuntu 16.04.4 LTS \n \l +``` + +不要介意输出末尾的\n \l. 这里 Ubuntu 版本就是 16.04.4,或者更加简单:16.04。 + + +### 如何在图形界面下得到 Ubuntu 版本 + +在图形界面下获取 Ubuntu 版本更是小事一桩。这里我使用了 Ubuntu 18.04 的图形界面系统 GNOME 的屏幕截图来展示如何做到这一点。如果你在使用 Unity 或者别的桌面环境的话,显示可能会有所不同。这也是为什么我推荐使用命令行方式来获得版本的原因:你不用依赖形形色色的图形界面。 + +下面我来展示如何在桌面环境获取 Ubuntu 版本。 + +进入‘系统设置’并点击下面的‘详细信息’栏。 + +![Finding Ubuntu version graphically][6] + +你将会看到系统的 Ubuntu 版本和其他和桌面系统有关的系统信息 这里的截图来自 [GNOME][7] 。 + +![Finding Ubuntu version graphically][8] + +### 如何知道桌面环境以及其他的系统信息 + +你刚才学习的是如何得到 Ubuntu 的版本信息,那么如何知道桌面环境呢? 更进一步, 如果你还想知道当前使用的 Linux 内核版本呢? + +有各种各样的命令你可以用来得到这些信息,不过今天我想推荐一个命令行工具, 叫做 [Neofetch][9]。 这个工具能在命令行完美展示系统信息,包括 Ubuntu 或者其他 Linux 发行版的系统图标。 + +用下面的命令安装 Neofetch: + +``` +sudo apt install neofetch +``` + +安装成功后,运行 `neofetch` 将会优雅的展示系统的信息如下。 + +![System information in Linux terminal][10] + +如你所见,`neofetch` 完全展示了 Linux 内核版本、Ubuntu 的版本、桌面系统版本以及环境、主题和图标等等信息。 + + +希望我如上展示方法能帮到你更快的找到你正在使用的 Ubuntu 版本和其他系统信息。如果你对这篇文章有其他的建议,欢迎在评论栏里留言。 + +再见。:) + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/how-to-know-ubuntu-unity-version/ + +作者:[Abhishek Prakash][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[DavidChenLiang](https://github.com/davidchenliang) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/abhishek/ +[1]:https://www.ubuntu.com/ +[2]:https://en.wikipedia.org/wiki/Desktop_environment +[3]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/check-ubuntu-version-command-line-1-800x216.jpeg +[4]:https://itsfoss.com/linux-code-names/ +[5]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/check-ubuntu-version-command-line-2-800x185.jpeg +[6]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/ubuntu-version-system-settings.jpeg +[7]:https://www.gnome.org/ +[8]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/checking-ubuntu-version-gui.jpeg +[9]:https://itsfoss.com/display-linux-logo-in-ascii/ +[10]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/ubuntu-system-information-terminal-800x400.jpeg diff --git a/translated/talk/20180514 A year as Android Engineer.md b/published/20180514 A year as Android Engineer.md similarity index 79% rename from translated/talk/20180514 A year as Android Engineer.md rename to published/20180514 A year as Android Engineer.md index 940d479d98..573b0ef825 100644 --- a/translated/talk/20180514 A year as Android Engineer.md +++ b/published/20180514 A year as Android Engineer.md @@ -2,7 +2,8 @@ Android 工程师的一年 ============================================================ ![](https://cdn-images-1.medium.com/max/2000/1*tqshw1o4JZZlA1HW3Cki1Q.png) ->妙绝的绘画来自 [Miquel Beltran][0] + +> 这幅妙绝的绘画来自 [Miquel Beltran][0] 我的技术生涯,从两年前算起。开始是 QA 测试员,一年后就转入开发人员角色。没怎么努力,也没有投入过多的个人时间。 @@ -12,7 +13,7 @@ Android 工程师的一年 我的第一个职位角色, Android 开发者,开始于一年前。我工作的这家公司,可以花一半的时间去尝试其它角色的工作,这给我从 QA 职位转到 Android 开发者职位创造了机会。 -这一转变归功于我在晚上和周末投入学习 Android 的时间。我通过了[ Android 基础纳米学位][3]、[Andriod 工程师纳米学位][4]课程,也获得了[ Google 开发者认证][5]。这部分的详细故事在[这儿][6]。 +这一转变归功于我在晚上和周末投入学习 Android 的时间。我通过了 [Android 基础纳米学位][3]、[Andriod 工程师纳米学位][4]课程,也获得了 [Google 开发者认证][5]。这部分的详细故事在[这儿][6]。 两个月后,公司雇佣了另一位 QA,我转向全职工作。挑战从此开始! @@ -46,29 +47,27 @@ Android 工程师的一年 一个例子就是拉取代码进行公开展示和代码审查。有是我会请同事私下检查我的代码,并不想被公开拉取,向任何人展示。 -其他时候,当我做代码审查时,会花好几分钟盯着"批准"按纽犹豫不决,在担心审查通过的会被其他同事找出毛病。 +其他时候,当我做代码审查时,会花好几分钟盯着“批准”按纽犹豫不决,在担心审查通过的代码会被其他同事找出毛病。 当我在一些事上持反对意见时,由于缺乏相关知识,担心被坐冷板凳,从来没有大声说出来过。 > 某些时间我会请同事私下[...]检查我的代码,以避免被公开展示。 -* * * - ### 新的公司,新的挑战 -后来,我手边有了个新的机会。感谢曾经和我共事的朋友,我被[ Babbel ][7]邀请去参加初级 Android 工程师职位的招聘流程。 +后来,我手边有了个新的机会。感谢曾经和我共事的朋友,我被 [Babbel][7] 邀请去参加初级 Android 工程师职位的招聘流程。 我见到了他们的团队,同时自告奋勇的在他们办公室主持了一次本地会议。此事让我下定决心要申请这个职位。我喜欢公司的箴言:全民学习。其次,公司每个人都非常友善,在那儿工作看起来很愉快!但我没有马上申请,因为我认为自己不够好,所以为什么能申请呢? -还好我的朋友和搭档推动我这样做,他们给了我发送简历的力量和勇气。过后不久就进入了面试流程。这很简单:以很小的应该程序来进行编码挑战,随后是和团队一起的技术面试,之后是和招聘经理间关于团队合作的面试。 +还好我的朋友和搭档推动我这样做,他们给了我发送简历的力量和勇气。过后不久就进入了面试流程。这很简单:以很小的程序的形式来进行编码挑战,随后是和团队一起的技术面试,之后是和招聘经理间关于团队合作的面试。 #### 招聘过程 我用周未的时间来完成编码挑战的项目,并在周一就立即发送过去。不久就受邀去当场面试。 -技术面试是关于编程挑战本身,我们谈论了 Android 好的不好的、我为什么以这种方式实现这功能,以及如何改进等等。随后是招聘经理进行的一次简短的关于团队合作面试,也有涉及到编程挑战的事,我们谈到了我面临的挑战,我如何解决这些问题,等等。 +技术面试是关于编程挑战本身,我们谈论了 Android 好的不好的地方、我为什么以这种方式实现这功能,以及如何改进等等。随后是招聘经理进行的一次简短的关于团队合作面试,也有涉及到编程挑战的事,我们谈到了我面临的挑战,我如何解决这些问题,等等。 -最后,通过面试,得到 offer, 我授受了! +最后,通过面试,得到 offer,我授受了! 我的 Android 工程师生涯的第一年,有九个月在一个公司,后面三个月在当前的公司。 @@ -88,7 +87,7 @@ Android 工程师的一年 两次三次后,压力就堵到胸口。为什么我还不知道?为什么就那么难理解?这种状态让我焦虑万分。 -我意识到我需要承认我确实不懂某个特定的主题,但第一步是要知道有这么个概念!有是,仅仅需要的就是更多的时间、更多的练习,最终会"在大脑中完全演绎" :-) +我意识到我需要承认我确实不懂某个特定的主题,但第一步是要知道有这么个概念!有时,仅仅需要的就是更多的时间、更多的练习,最终会“在大脑中完全演绎” :-) 例如,我常常为 Java 的接口类和抽象类所困扰,不管看了多少的例子,还是不能完全明白他们之间的区别。但一旦我使用后,即使还不能解释其工作原理,也知道了怎么使用以及什么时候使用。 @@ -102,19 +101,13 @@ Android 工程师的一年 工程师的角色不仅仅是编码,而是广泛的技能。 我仍然处于旅程的起点,在掌握它的道路上,我想着重于以下几点: -* 交流:因为英文不是我的母语,所以有的时候我会努力传达我的想法,这在我工作中是至关重要的。我可以通过写作,阅读和交谈来解决这个问题。 - -* 提有建设性的反馈意见: 我想给同事有意义的反馈,这样我们一起共同发展。 - -* 为我的成就感到骄傲: 我需要创建一个列表来跟踪各种成就,无论大小,或整体进步,所以当我挣扎时我可以回顾并感觉良好。 - -* 不要着迷于不知道的事情: 当有很多新事物出现时很难做到都知道,所以只关注必须的,及手头项目需要的东西,这非常重要的。 - -* 多和同事分享知识。我是初级的并不意味着没有可以分享的!我需要持续分享我感兴趣的的文章及讨论话题。我知道同事们会感激我的。 - -* 耐心和持续学习: 和现在一样的保持不断学习,但对自己要有更多耐心。 - -* 自我保健: 随时注意休息,不要为难自己。 放松也富有成效。 +* 交流:因为英文不是我的母语,所以有的时候我需要努力传达我的想法,这在我工作中是至关重要的。我可以通过写作,阅读和交谈来解决这个问题。 +* 提有建设性的反馈意见:我想给同事有意义的反馈,这样我们一起共同发展。 +* 为我的成就感到骄傲:我需要创建一个列表来跟踪各种成就,无论大小,或整体进步,所以当我挣扎时我可以回顾并感觉良好。 +* 不要着迷于不知道的事情:当有很多新事物出现时很难做到都知道,所以只关注必须的,及手头项目需要的东西,这非常重要的。 +* 多和同事分享知识:我是初级的并不意味着没有可以分享的!我需要持续分享我感兴趣的的文章及讨论话题。我知道同事们会感激我的。 +* 耐心和持续学习:和现在一样的保持不断学习,但对自己要有更多耐心。 +* 自我保健:随时注意休息,不要为难自己。 放松也富有成效。 -------------------------------------------------------------------------------- @@ -122,7 +115,7 @@ via: https://proandroiddev.com/a-year-as-android-engineer-55e2a428dfc8 作者:[Lara Martín][a] 译者:[runningwater](https://github.com/runningwater) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180515 Give Your Linux Desktop a Stunning Makeover With Xenlism Themes.md b/published/20180515 Give Your Linux Desktop a Stunning Makeover With Xenlism Themes.md new file mode 100644 index 0000000000..07dc338eb2 --- /dev/null +++ b/published/20180515 Give Your Linux Desktop a Stunning Makeover With Xenlism Themes.md @@ -0,0 +1,90 @@ +使用 Xenlism 主题对你的 Linux 桌面进行令人惊叹的改造 +============================================================ + +> 简介:Xenlism 主题包提供了一个美观的 GTK 主题、彩色图标和简约的壁纸,将你的 Linux 桌面转变为引人注目的操作系统。 + +除非我找到一些非常棒的东西,否则我不会每天都把整篇文章献给一个主题。我曾经经常发布主题和图标。但最近,我更喜欢列出[最佳 GTK 主题][6]和图标主题。这对我和你来说都更方便,你可以在一个地方看到许多美丽的主题。 + +在 [Pop OS 主题][7]套件之后,Xenlism 是另一个让我对它的外观感到震惊的主题。 + +![Xenlism GTK theme for Ubuntu and Other Linux](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/xenlishm-minimalism-gtk-theme-800x450.jpeg) + +Xenlism GTK 主题基于 Arc 主题,其得益于许多主题的灵感。GTK 主题提供类似于 macOS 的 Windows 按钮,我既不特别喜欢,也没有特别不喜欢。GTK 主题采用扁平、简约的布局,我喜欢这样。 + +Xenlism 套件中有两个图标主题。Xenlism Wildfire 是以前的,已经进入我们的[最佳图标主题][8]列表。 + +![Beautiful Xenlism Wildfire theme for Ubuntu and Other Linux](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/xenlism-wildfire-theme-800x450.jpeg) + +*Xenlism Wildfire 图标* + +Xenlsim Storm 是一个相对较新的图标主题,但同样美观。 + +![Beautiful Xenlism Storm theme for Ubuntu and Other Linux](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/xenlism-storm-theme-1-800x450.jpeg) + +*Xenlism Storm 图标* + +Xenlism 主题在 GPL 许可下开源。 + +### 如何在 Ubuntu 18.04 上安装 Xenlism 主题包 + +Xenlism 开发提供了一种通过 PPA 安装主题包的更简单方法。尽管 PPA 可用于 Ubuntu 16.04,但我发现 GTK 主题不适用于 Unity。它适用于 Ubuntu 18.04 中的 GNOME 桌面。 + +打开终端(`Ctrl+Alt+T`)并逐个使用以下命令: + +``` +sudo add-apt-repository ppa:xenatt/xenlism +sudo apt update +``` + +该 PPA 提供四个包: + +* xenlism-finewalls:一组壁纸,可直接在 Ubuntu 的壁纸中使用。截图中使用了其中一个壁纸。 +* xenlism-minimalism-theme:GTK 主题 +* xenlism-storm:一个图标主题(见前面的截图) +* xenlism-wildfire-icon-theme:具有多种颜色变化的另一个图标主题(文件夹颜色在变体中更改) + +你可以自己决定要安装的主题组件。就个人而言,我认为安装所有组件没有任何损害。 + +``` +sudo apt install xenlism-minimalism-theme xenlism-storm-icon-theme xenlism-wildfire-icon-theme xenlism-finewalls +``` + +你可以使用 GNOME Tweaks 来更改主题和图标。如果你不熟悉该过程,我建议你阅读本教程以学习[如何在 Ubuntu 18.04 GNOME 中安装主题][9]。 + +### 在其他 Linux 发行版中获取 Xenlism 主题 + +你也可以在其他 Linux 发行版上安装 Xenlism 主题。各种 Linux 发行版的安装说明可在其网站上找到: + +[安装 Xenlism 主题][10] + +### 你怎么看? + +我知道不是每个人都会同意我,但我喜欢这个主题。我想你将来会在 It's FOSS 的教程中会看到 Xenlism 主题的截图。 + +你喜欢 Xenlism 主题吗?如果不喜欢,你最喜欢什么主题?在下面的评论部分分享你的意见。 + +### 关于作者 + +我是一名专业软件开发人员,也是 It's FOSS 的创始人。我是一名狂热的 Linux 爱好者和开源爱好者。我使用 Ubuntu 并相信分享知识。除了Linux,我喜欢经典侦探之谜。我是 Agatha Christie 作品的忠实粉丝。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/xenlism-theme/ + +作者:[Abhishek Prakash][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://itsfoss.com/author/abhishek/ +[1]:https://itsfoss.com/author/abhishek/ +[2]:https://itsfoss.com/xenlism-theme/#comments +[3]:https://itsfoss.com/category/desktop/ +[4]:https://itsfoss.com/tag/themes/ +[5]:https://itsfoss.com/tag/xenlism/ +[6]:https://itsfoss.com/best-gtk-themes/ +[7]:https://itsfoss.com/pop-icon-gtk-theme-ubuntu/ +[8]:https://itsfoss.com/best-icon-themes-ubuntu-16-04/ +[9]:https://itsfoss.com/install-themes-ubuntu/ +[10]:http://xenlism.github.io/minimalism/#install diff --git a/published/20180522 How to Run Your Own Git Server.md b/published/20180522 How to Run Your Own Git Server.md new file mode 100644 index 0000000000..ca438b25a4 --- /dev/null +++ b/published/20180522 How to Run Your Own Git Server.md @@ -0,0 +1,246 @@ +搭建属于你自己的 Git 服务器 +====== + +![](https://www.linux.com/images/stories/41373/GitLab-3.png) + +> 在本文中,我们的目的是让你了解如何设置属于自己的Git服务器。 + +[Git][1] 是由 [Linux Torvalds 开发][2]的一个版本控制系统,现如今正在被全世界大量开发者使用。许多公司喜欢使用基于 Git 版本控制的 GitHub 代码托管。[根据报道,GitHub 是现如今全世界最大的代码托管网站][3]。GitHub 宣称已经有 920 万用户和 2180 万个仓库。许多大型公司现如今也将代码迁移到 GitHub 上。[甚至于谷歌,一家搜索引擎公司,也正将代码迁移到 GitHub 上][4]。 + +### 运行你自己的 Git 服务器 + +GitHub 能提供极佳的服务,但却有一些限制,尤其是你是单人或是一名 coding 爱好者。GitHub 其中之一的限制就是其中免费的服务没有提供代码私有托管业务。[你不得不支付每月 7 美金购买 5 个私有仓库][5],并且想要更多的私有仓库则要交更多的钱。 + +万一你想要私有仓库或需要更多权限控制,最好的方法就是在你的服务器上运行 Git。不仅你能够省去一笔钱,你还能够在你的服务器有更多的操作。在大多数情况下,大多数高级 Linux 用户已经拥有自己的服务器,并且在这些服务器上方式 Git 就像“啤酒一样免费”(LCTT 译注:指免费软件)。 + +在这篇教程中,我们主要讲在你的服务器上,使用两种代码管理的方法。一种是运行一个纯 Git 服务器,另一个是使用名为 [GitLab][6] 的 GUI 工具。在本教程中,我在 VPS 上运行的操作系统是 Ubuntu 14.04 LTS。 + +### 在你的服务器上安装 Git + +在本篇教程中,我们考虑一个简单案例,我们有一个远程服务器和一台本地服务器,现在我们需要使用这两台机器来工作。为了简单起见,我们就分别叫它们为远程服务器和本地服务器。 + +首先,在两边的机器上安装 Git。你可以从依赖包中安装 Git,在本文中,我们将使用更简单的方法: + +``` +sudo apt-get install git-core +``` + +为 Git 创建一个用户。 + +``` +sudo useradd git +passwd git +``` + +为了容易的访问服务器,我们设置一个免密 ssh 登录。首先在你本地电脑上创建一个 ssh 密钥: + +``` +ssh-keygen -t rsa +``` + +这时会要求你输入保存密钥的路径,这时只需要点击回车保存在默认路径。第二个问题是输入访问远程服务器所需的密码。它生成两个密钥——公钥和私钥。记下您在下一步中需要使用的公钥的位置。 + +现在您必须将这些密钥复制到服务器上,以便两台机器可以相互通信。在本地机器上运行以下命令: + +``` +cat ~/.ssh/id_rsa.pub | ssh git@remote-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" +``` + +现在,用 `ssh` 登录进服务器并为 Git 创建一个项目路径。你可以为你的仓库设置一个你想要的目录。 + +现在跳转到该目录中: + +``` +cd /home/swapnil/project-1.git +``` + +现在新建一个空仓库: + +``` +git init --bare +Initialized empty Git repository in /home/swapnil/project-1.git +``` + +现在我们需要在本地机器上新建一个基于 Git 版本控制仓库: + +``` +mkdir -p /home/swapnil/git/project +``` + +进入我们创建仓库的目录: + +``` +cd /home/swapnil/git/project +``` + +现在在该目录中创建项目所需的文件。留在这个目录并启动 `git`: + +``` +git init +Initialized empty Git repository in /home/swapnil/git/project +``` + +把所有文件添加到仓库中: + +``` +git add . +``` + +现在,每次添加文件或进行更改时,都必须运行上面的 `add` 命令。 您还需要为每个文件更改都写入提交消息。提交消息基本上说明了我们所做的更改。 + +``` +git commit -m "message" -a +[master (root-commit) 57331ee] message + 2 files changed, 2 insertions(+) + create mode 100644 GoT.txt + create mode 100644 writing.txt +``` + +在这种情况下,我有一个名为 GoT(《权力的游戏》的点评)的文件,并且我做了一些更改,所以当我运行命令时,它指定对文件进行更改。 在上面的命令中 `-a` 选项意味着提交仓库中的所有文件。 如果您只更改了一个,则可以指定该文件的名称而不是使用 `-a`。 + +举一个例子: + +``` +git commit -m "message" GoT.txt +[master e517b10] message + 1 file changed, 1 insertion(+) +``` + +到现在为止,我们一直在本地服务器上工作。现在我们必须将这些更改推送到远程服务器上,以便通过互联网访问,并且可以与其他团队成员进行协作。 + +``` +git remote add origin ssh://git@remote-server/repo->path-on-server..git +``` + +现在,您可以使用 `pull` 或 `push` 选项在服务器和本地计算机之间推送或拉取: + +``` +git push origin master +``` + +如果有其他团队成员想要使用该项目,则需要将远程服务器上的仓库克隆到其本地计算机上: + +``` +git clone git@remote-server:/home/swapnil/project.git +``` + +这里 `/home/swapnil/project.git` 是远程服务器上的项目路径,在你本机上则会改变。 + +然后进入本地计算机上的目录(使用服务器上的项目名称): + +``` +cd /project +``` + +现在他们可以编辑文件,写入提交更改信息,然后将它们推送到服务器: + +``` +git commit -m 'corrections in GoT.txt story' -a +``` + +然后推送改变: + +``` +git push origin master +``` + +我认为这足以让一个新用户开始在他们自己的服务器上使用 Git。 如果您正在寻找一些 GUI 工具来管理本地计算机上的更改,则可以使用 GUI 工具,例如 QGit 或 GitK for Linux。 + +![](https://www.linux.com/images/stories/41373/QGit.jpg) + +### 使用 GitLab + +这是项目所有者和协作者的纯命令行解决方案。这当然不像使用 GitHub 那么简单。不幸的是,尽管 GitHub 是全球最大的代码托管商,但是它自己的软件别人却无法使用。因为它不是开源的,所以你不能获取源代码并编译你自己的 GitHub。这与 WordPress 或 Drupal 不同,您无法下载 GitHub 并在您自己的服务器上运行它。 + +像往常一样,在开源世界中,是没有终结的尽头。GitLab 是一个非常优秀的项目。这是一个开源项目,允许用户在自己的服务器上运行类似于 GitHub 的项目管理系统。 + +您可以使用 GitLab 为团队成员或公司运行类似于 GitHub 的服务。您可以使用 GitLab 在公开发布之前开发私有项目。 + +GitLab 采用传统的开源商业模式。他们有两种产品:免费的开源软件,用户可以在自己的服务器上安装,以及类似于 GitHub 的托管服务。 + +可下载版本有两个版本,免费的社区版和付费企业版。企业版基于社区版,但附带针对企业客户的其他功能。它或多或少与 WordPress.org 或 Wordpress.com 提供的服务类似。 + +社区版具有高度可扩展性,可以在单个服务器或群集上支持 25000 个用户。GitLab 的一些功能包括:Git 仓库管理,代码评论,问题跟踪,活动源和维基。它配备了 GitLab CI,用于持续集成和交付。 + +Digital Ocean 等许多 VPS 提供商会为用户提供 GitLab 服务。 如果你想在你自己的服务器上运行它,你可以手动安装它。GitLab 为不同的操作系统提供了软件包。 在我们安装 GitLab 之前,您可能需要配置 SMTP 电子邮件服务器,以便 GitLab 可以在需要时随时推送电子邮件。官方推荐使用 Postfix。所以,先在你的服务器上安装 Postfix: + +``` +sudo apt-get install postfix +``` + +在安装 Postfix 期间,它会问你一些问题,不要跳过它们。 如果你一不小心跳过,你可以使用这个命令来重新配置它: + +``` +sudo dpkg-reconfigure postfix +``` + +运行此命令时,请选择 “Internet Site”并为使用 Gitlab 的域名提供电子邮件 ID。 + +我是这样输入的: + +``` +xxx@x.com +``` + +用 Tab 键并为 postfix 创建一个用户名。接下来将会要求你输入一个目标邮箱。 + +在剩下的步骤中,都选择默认选项。当我们安装且配置完成后,我们继续安装 GitLab。 + +我们使用 `wget` 来下载软件包(用 [最新包][7] 替换下载链接): + +``` +wget https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.9.4-omnibus.1-1_amd64.deb +``` + +然后安装这个包: + +``` +sudo dpkg -i gitlab_7.9.4-omnibus.1-1_amd64.deb +``` + +现在是时候配置并启动 GitLab 了。 + +``` +sudo gitlab-ctl reconfigure +``` + +您现在需要在配置文件中配置域名,以便您可以访问 GitLab。打开文件。 + +``` +nano /etc/gitlab/gitlab.rb +``` + +在这个文件中编辑 `external_url` 并输入服务器域名。保存文件,然后从 Web 浏览器中打开新建的一个 GitLab 站点。 + +![](https://www.linux.com/images/stories/41373/GitLab-1.jpg) + +默认情况下,它会以系统管理员的身份创建 `root`,并使用 `5iveL!fe` 作为密码。 登录到 GitLab 站点,然后更改密码。 + +![](https://www.linux.com/images/stories/41373/GitLab-2.png) + +密码更改后,登录该网站并开始管理您的项目。 + +![](https://www.linux.com/images/stories/41373/GitLab-3.png) + +GitLab 有很多选项和功能。最后,我借用电影“黑客帝国”中的经典台词:“不幸的是,没有人知道 GitLab 可以做什么。你必须亲自尝试一下。” + + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/how-run-your-own-git-server + +作者:[Swapnil Bhartiya][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[wyxplus](https://github.com/wyxplus) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/arnieswap +[1]:https://github.com/git/git +[2]:https://www.linuxfoundation.org/blog/10-years-of-git-an-interview-with-git-creator-linus-torvalds/ +[3]:https://github.com/about/press +[4]:http://google-opensource.blogspot.com/2015/03/farewell-to-google-code.html +[5]:https://github.com/pricing +[6]:https://about.gitlab.com/ +[7]:https://about.gitlab.com/downloads/ diff --git a/translated/tech/20180529 5 trending open source machine learning JavaScript frameworks.md b/published/20180529 5 trending open source machine learning JavaScript frameworks.md similarity index 66% rename from translated/tech/20180529 5 trending open source machine learning JavaScript frameworks.md rename to published/20180529 5 trending open source machine learning JavaScript frameworks.md index 4c59c540df..da6138b5e0 100644 --- a/translated/tech/20180529 5 trending open source machine learning JavaScript frameworks.md +++ b/published/20180529 5 trending open source machine learning JavaScript frameworks.md @@ -1,49 +1,50 @@ - 五个最热门的开源机器学习 JavaScript 框架 ====== + +> 如果是你一位想要深入机器学习的 JavaScript 程序员或想成为一位使用 JavaScript 的机器学习专家,那么这些开源框架也许会吸引你。 + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/web-spider-frame-framework-2.png?itok=ng6O0fd4) -开源工具的可用性使得开发者能够更加轻松地开发应用,这一点使机器学习领域本身获得了巨大的极高。(例如,AndreyBu,他来自德国,在机器学习领域拥有五年以上的经验,他一直在使用各种各样的开源框架来创造富有魅力的机器学习项目。 +开源工具的涌现使得开发者能够更加轻松地开发应用,这一点使机器学习领域本身获得了极大增长。(例如,AndreyBu,他来自德国,在机器学习领域拥有五年以上的经验,他一直在使用各种各样的开源框架来创造富有魅力的机器学习项目。) -虽然 python 支持绝大多数的机器学习框架,但是 JavaScript 也并没有被抛弃。JavaScript 开发者可以在浏览器中使用各种框架来训练和部署机器学习模型。 +虽然 Python 是绝大多数的机器学习框架所采用的语言,但是 JavaScript 也并没有被抛下。JavaScript 开发者可以在浏览器中使用各种框架来训练和部署机器学习模型。 下面是 JavaScript 中最热门五个机器学习框架 -### 1\. TensorFlow.js +### 1、 TensorFlow.js -[TensorFlow.js][2] 是一个开源库,它使你能在浏览器中完整地运行机器学习程序,它是 Deeplearn.js 的继承者,Deeplearn.js 不再被提供更新。TensorFlow.js 在 Deeplearn.js 功能的基础上进行了改善,使你能够充分利用浏览器,得到更加深入的机器学习经验。 +[TensorFlow.js][2] 是一个开源库,它使你能在浏览器中完整地运行机器学习程序,它是 Deeplearn.js 的继承者,Deeplearn.js 不再更新了。TensorFlow.js 在 Deeplearn.js 功能的基础上进行了改善,使你能够充分利用浏览器,得到更加深入的机器学习经验。 -通过这个开源库,你可以在浏览器中使用有各种功能的、直观的 API 来定义、训练和部署模型。除此之外,它能够自动为 WebGL 和 Node.js 提供支持。 +通过这个开源库,你可以在浏览器中使用有各种功能的、直观的 API 来定义、训练和部署模型。除此之外,它自动提供 WebGL 和 Node.js 的支持。 如果您有了一个已经训练过的模型,你想要导入到浏览器中。TensorFlow.js 可以让你做到这一点,你也可以在不离开浏览器的情况下重新训练已有的模型。 -现在有很多在浏览器中提供广泛的机器学习功能的资源型开源工具,这个机器学习工具库就是这些开源工具的集合。这个工具库为好几种机器学习算法提供支持,包括非监督式学习、监督式学习、数据处理、人工神经网络(ANN)、数学和回归。 +### 2、 机器学习工具库 -如果你以前使用 python,现在想找类似于 Scikit-learn 的,能在浏览器中使用 JavaScript 进行机器学习的工具,这套工具会满足你的要求。 +现在有很多在浏览器中提供广泛的机器学习功能的资源型开源工具,这个[机器学习工具库][3]就是这些开源工具的集合。这个工具库为好几种机器学习算法提供支持,包括非监督式学习、监督式学习、数据处理、人工神经网络(ANN)、数学和回归。 -### 3\. Keras.js +如果你以前使用 Python,现在想找类似于 Scikit-learn 的,能在浏览器中使用 JavaScript 进行机器学习的工具,这套工具会满足你的要求。 + +### 3、 Keras.js [Keras.js][4] 是另外一个热门的开源框架,它使你能够在浏览器中运行机器学习模型,它使用 WebGL 来提供 GPU 模式的支持。如果你有使用 Node.js 的模型,你就只能在 GPU 模式下运行它。Keras.js 还为使用任意后端框架的模型训练提供支持,例如 Microsoft Cognitive Toolkit (CNTK) 。 一些 Keras 模型可以部署在客户端浏览器上,包括 Inception v3 (训练在 ImageNet 上),50 层冗余网络(训练在 ImageNet 上),和卷积变化自动编码器(训练在 MNIST 上)。 -### 4\. Brain.js +### 4、 Brain.js -机器学习里的概念非常重要,它可能会使刚开始进入这个领域的人们气馁,这个领域里的学术用语和专业词汇可能会使初学者感到崩溃,而解决以上问题的能力就是 Brain.js 的优势所在。它是开源的,基于 JavaScript 的框架,简化了定义、训练和运行神经网络的流程。 +机器学习里的概念非常重要,它可能会使刚开始进入这个领域的人们气馁,这个领域里的学术用语和专业词汇可能会使初学者感到崩溃,而解决以上问题的能力就是 [Brain.js][5] 的优势所在。它是开源的,基于 JavaScript 的框架,简化了定义、训练和运行神经网络的流程。 如果你是一个 JavaScript 开发者,并且在机器学习领域是完全的新手,Brain.js 能减低你学习的难度曲线。它可以和 Node.js 一起使用,或者运行在客户端浏览器里来训练机器学习模型。Brain.js 支持部分类型的神经网络,包括前馈式网络、Ellman 网络,和门循环单元网络。 -### 5\. STDLib +### 5、 STDLib [STDLib][6] 是一个基于 JavaScript 和 Node.js 应用的开源库,如果您正在寻找一种在浏览器中运行,支持科学和数字化的基于 web 的机器学习应用,STDLib 能满足你的需要。 - -这个库能提供全面而先进的数学和统计学上的功能,来帮助你构建高性能的机器学习模型。你同样也可以使用它扩展的公用程序来构建应用程序和其他的库。除此之外,如果你想要一个数据可视化和探索性数据分析的框架。 - -STDLib,你,值得拥有。 +这个库能提供全面而先进的数学和统计学上的功能,来帮助你构建高性能的机器学习模型。你同样也可以使用它丰富的功能来构建应用程序和其他的库。除此之外,如果你想要一个数据可视化和探索性数据分析的框架 —— STDLib,你,值得拥有。 -### Conclusion +### 总结 如果你是一个 JavaScript 开发者,并且打算深入研究令人兴奋的机器学习世界,或者说,你是一个机器学习方面的专家,打算开始尝试使用 JavaScript ,那么上述的开源框架会激起您的兴趣。 @@ -56,7 +57,7 @@ via: https://opensource.com/article/18/5/machine-learning-javascript-frameworks 作者:[Dr.Michael J.Garbade][a] 选题:[lujun9972](https://github.com/lujun9972) 译者:[hopefully2333](https://github.com/hopefully2333) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180531 You don-t know Bash- An introduction to Bash arrays.md b/published/20180531 You don-t know Bash- An introduction to Bash arrays.md new file mode 100644 index 0000000000..48bf345327 --- /dev/null +++ b/published/20180531 You don-t know Bash- An introduction to Bash arrays.md @@ -0,0 +1,228 @@ +你所不了解的 Bash:关于 Bash 数组的介绍 +====== + +> 进入这个古怪而神奇的 Bash 数组的世界。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming-code-keyboard-laptop.png?itok=pGfEfu2S) + +尽管软件工程师常常使用命令行来进行各种开发,但命令行中的数组似乎总是一个模糊的东西(虽然不像正则操作符 `=~` 那么复杂隐晦)。除开隐晦和有疑问的语法,[Bash][1] 数组其实是非常有用的。 + +### 稍等,这是为什么? + +写 Bash 相关的东西很难,但如果是写一篇像手册那样注重怪异语法的文章,就会非常简单。不过请放心,这篇文章的目的就是让你不用去读该死的使用手册。 + +#### 真实(通常是有用的)示例 + +为了这个目的,想象一下真实世界的场景以及 Bash 是怎么帮忙的:你正在公司里面主导一个新工作,评估并优化内部数据管线的运行时间。首先,你要做个参数扫描分析来评估管线使用线程的状况。简单起见,我们把这个管道当作一个编译好的 C++ 黑盒子,这里面我们能够调整的唯一的参数是用于处理数据的线程数量:`./pipeline --threads 4`。 + +### 基础 + +我们首先要做的事是定义一个数组,用来容纳我们想要测试的 `--threads` 参数: + +``` +allThreads=(1 2 4 8 16 32 64 128) +``` + +本例中,所有元素都是数字,但参数并不一定是数字,Bash 中的数组可以容纳数字和字符串,比如 `myArray=(1 2 "three" 4 "five")` 就是个有效的表达式。就像 Bash 中其它的变量一样,确保赋值符号两边没有空格。否则 Bash 将会把变量名当作程序来执行,把 `=` 当作程序的第一个参数。 + +现在我们初始化了数组,让我们解析它其中的一些元素。仅仅输入 `echo $allThreads` ,你能发现,它只会输出第一个元素。 + +要理解这个产生的原因,需要回到上一步,回顾我们一般是怎么在 Bash 中输出变量。考虑以下场景: + +``` +type="article" +echo "Found 42 $type" +``` + +假如我们得到的变量 `$type` 是一个单词,我们想要添加在句子结尾一个 `s`。我们无法直接把 `s` 加到 `$type` 里面,因为这会把它变成另一个变量,`$types`。尽管我们可以利用像 `echo "Found 42 "$type"s"` 这样的代码形变,但解决这个问题的最好方法是用一个花括号:`echo "Found 42 ${type}s"`,这让我们能够告诉 Bash 变量名的起止位置(有趣的是,JavaScript/ES6 在 [template literals][2] 中注入变量和表达式的语法和这里是一样的) + +事实上,尽管 Bash 变量一般不用花括号,但在数组中需要用到花括号。这反而允许我们指定要访问的索引,例如 `echo ${allThreads[1]}` 返回的是数组中的第二个元素。如果不写花括号,比如 `echo $allThreads[1]`,会导致 Bash 把 `[1]` 当作字符串然后输出。 + +是的,Bash 数组的语法很怪,但是至少他们是从 0 开始索引的,不像有些语言(说的就是你,`R` 语言)。 + +### 遍历数组 + +上面的例子中我们直接用整数作为数组的索引,我们现在考虑两种其他情况:第一,如果想要数组中的第 `$i` 个元素,这里 `$i` 是一个代表索引的变量,我们可以这样 `echo ${allThreads[$i]}` 解析这个元素。第二,要输出一个数组的所有元素,我们把数字索引换成 `@` 符号(你可以把 `@` 当作表示 `all` 的符号):`echo ${allThreads[@]}`。 + +#### 遍历数组元素 + +记住上面讲过的,我们遍历 `$allThreads` 数组,把每个值当作 `--threads` 参数启动管线: + +``` +for t in ${allThreads[@]}; do +  ./pipeline --threads $t +done +``` + +#### 遍历数组索引 + +接下来,考虑一个稍稍不同的方法。不遍历所有的数组元素,我们可以遍历所有的索引: + +``` +for i in ${!allThreads[@]}; do +  ./pipeline --threads ${allThreads[$i]} +done +``` + +一步一步看:如之前所见,`${allThreads[@]}` 表示数组中的所有元素。前面加了个感叹号,变成 `${!allThreads[@]}`,这会返回数组索引列表(这里是 0 到 7)。换句话说。`for` 循环就遍历所有的索引 `$i` 并从 `$allThreads` 中读取第 `$i` 个元素,当作 `--threads` 选项的参数。 + +这看上去很辣眼睛,你可能奇怪为什么我要一开始就讲这个。这是因为有时候在循环中需要同时获得索引和对应的值,例如,如果你想要忽视数组中的第一个元素,使用索引可以避免额外创建在循环中累加的变量。 + +### 填充数组 + +到目前为止,我们已经能够用给定的 `--threads` 选项启动管线了。现在假设按秒计时的运行时间输出到管线。我们想要捕捉每个迭代的输出,然后把它保存在另一个数组中,因此我们最终可以随心所欲的操作它。 + +#### 一些有用的语法 + +在深入代码前,我们要多介绍一些语法。首先,我们要能解析 Bash 命令的输出。用这个语法可以做到:`output=$( ./my_script.sh )`,这会把命令的输出存储到变量 `$output` 中。 + +我们需要的第二个语法是如何把我们刚刚解析的值添加到数组中。完成这个任务的语法看起来很熟悉: + +``` +myArray+=( "newElement1" "newElement2" ) +``` + +#### 参数扫描 + +万事具备,执行参数扫描的脚步如下: + +``` +allThreads=(1 2 4 8 16 32 64 128) +allRuntimes=() +for t in ${allThreads[@]}; do + runtime=$(./pipeline --threads $t) + allRuntimes+=( $runtime ) +done +``` + +就是这个了! + +### 还有什么能做的? + +这篇文章中,我们讲过使用数组进行参数扫描的场景。我敢保证有很多理由要使用 Bash 数组,这里就有两个例子: + +#### 日志警告 + +本场景中,把应用分成几个模块,每一个都有它自己的日志文件。我们可以编写一个 cron 任务脚本,当某个模块中出现问题标志时向特定的人发送邮件: + +``` +# 日志列表,发生问题时应该通知的人 +logPaths=("api.log" "auth.log" "jenkins.log" "data.log") +logEmails=("jay@email" "emma@email" "jon@email" "sophia@email") + +# 在每个日志中查找问题标志 +for i in ${!logPaths[@]}; +do +  log=${logPaths[$i]} +  stakeholder=${logEmails[$i]} +  numErrors=$( tail -n 100 "$log" | grep "ERROR" | wc -l ) + + # 如果近期发现超过 5 个错误,就警告负责人 +  if [[ "$numErrors" -gt 5 ]]; +  then +    emailRecipient="$stakeholder" +    emailSubject="WARNING: ${log} showing unusual levels of errors" +    emailBody="${numErrors} errors found in log ${log}" +    echo "$emailBody" | mailx -s "$emailSubject" "$emailRecipient" +  fi +done +``` + +#### API 查询 + +如果你想要生成一些分析数据,分析你的 Medium 帖子中用户评论最多的。由于我们无法直接访问数据库,SQL 不在我们考虑范围,但我们可以用 API! + +为了避免陷入关于 API 授权和令牌的冗长讨论,我们将会使用 [JSONPlaceholder][3],这是一个面向公众的测试服务 API。一旦我们查询每个帖子,解析出每个评论者的邮箱,我们就可以把这些邮箱添加到我们的结果数组里: + +``` +endpoint="https://jsonplaceholder.typicode.com/comments" +allEmails=() + +# 查询前 10 个帖子 +for postId in {1..10}; +do + # 执行 API 调用,获取该帖子评论者的邮箱 +  response=$(curl "${endpoint}?postId=${postId}") +  + # 使用 jq 把 JSON 响应解析成数组 +  allEmails+=( $( jq '.[].email' <<< "$response" ) ) +done +``` + +注意这里我是用 [jq 工具][4] 从命令行里解析 JSON 数据。关于 `jq` 的语法超出了本文的范围,但我强烈建议你了解它。 + +你可能已经想到,使用 Bash 数组在数不胜数的场景中很有帮助,我希望这篇文章中的示例可以给你思维的启发。如果你从自己的工作中找到其它的例子想要分享出来,请在帖子下方评论。 + +### 请等等,还有很多东西! + +由于我们在本文讲了很多数组语法,这里是关于我们讲到内容的总结,包含一些还没讲到的高级技巧: + +| 语法 | 效果 | +|:--|:--| +| `arr=()` | 创建一个空数组 | +| `arr=(1 2 3)` | 初始化数组 | +| `${arr[2]}` | 取得第三个元素 | +| `${arr[@]}` | 取得所有元素 | +| `${!arr[@]}` | 取得数组索引 | +| `${#arr[@]}` | 计算数组长度 | +| `arr[0]=3` | 覆盖第 1 个元素 | +| `arr+=(4)` | 添加值 | +| `str=$(ls)` | 把 `ls` 输出保存到字符串 | +| `arr=( $(ls) )` | 把 `ls` 输出的文件保存到数组里 | +| `${arr[@]:s:n}` | 取得从索引 `s` 开始的 `n` 个元素 | + +### 最后一点思考 + +正如我们所见,Bash 数组的语法很奇怪,但我希望这篇文章让你相信它们很有用。只要你理解了这些语法,你会发现以后会经常使用 Bash 数组。 + +#### Bash 还是 Python? + +问题来了:什么时候该用 Bash 数组而不是其他的脚本语法,比如 Python? + +对我而言,完全取决于需求——如果你可以只需要调用命令行工具就能立马解决问题,你也可以用 Bash。但有些时候,当你的脚本属于一个更大的 Python 项目时,你也可以用 Python。 + +比如,我们可以用 Python 来实现参数扫描,但我们只用编写一个 Bash 的包装: + +``` +import subprocess + +all_threads = [1, 2, 4, 8, 16, 32, 64, 128] +all_runtimes = [] + +# 用不同的线程数字启动管线 +for t in all_threads: +  cmd = './pipeline --threads {}'.format(t) + + # 使用子线程模块获得返回的输出 +  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) +  output = p.communicate()[0] +  all_runtimes.append(output) +``` + +由于本例中没法避免使用命令行,所以可以优先使用 Bash。 + +#### 羞耻的宣传时间 + +如果你喜欢这篇文章,这里还有很多类似的文章! [在此注册,加入 OSCON][5],2018 年 7 月 17 号我会在这做一个主题为 [你所不了解的 Bash][6] 的在线编码研讨会。没有幻灯片,不需要门票,只有你和我在命令行里面敲代码,探索 Bash 中的奇妙世界。 + +本文章由 [Medium] 首发,再发布时已获得授权。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays + +作者:[Robert Aboukhalil][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[BriFuture](https://github.com/BriFuture) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/robertaboukhalil +[1]:https://opensource.com/article/17/7/bash-prompt-tips-and-tricks +[2]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals +[3]:https://github.com/typicode/jsonplaceholder +[4]:https://stedolan.github.io/jq/ +[5]:https://conferences.oreilly.com/oscon/oscon-or +[6]:https://conferences.oreilly.com/oscon/oscon-or/public/schedule/detail/67166 +[7]:https://medium.com/@robaboukhalil/the-weird-wondrous-world-of-bash-arrays-a86e5adf2c69 diff --git a/published/20180604 4 cool new projects to try in COPR for June 2018.md b/published/20180604 4 cool new projects to try in COPR for June 2018.md new file mode 100644 index 0000000000..2dad998bbb --- /dev/null +++ b/published/20180604 4 cool new projects to try in COPR for June 2018.md @@ -0,0 +1,86 @@ +2018 年 6 月 COPR 中值得尝试的 4 个很酷的新项目 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-1024x433.jpg) + +COPR 是个人软件仓库[集合][1],它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准。或者它可能不符合其他 Fedora 标准,尽管它是免费和开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不被 Fedora 基础设施不支持或没有被该项目所签名。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。 + +这是 COPR 中一组新的有趣项目。 + +### Ghostwriter + +[Ghostwriter][2] 是 [Markdown][3] 格式的文本编辑器,它有一个最小的界面。它以 HTML 格式提供文档预览,并为 Markdown 提供语法高亮显示。它提供了仅高亮显示当前正在编写的段落或句子的选项。此外,Ghostwriter 可以将文档导出为多种格式,包括 PDF 和 HTML。最后,它有所谓的“海明威”模式,其中删除被禁用,迫使用户现在智能编写,而在稍后编辑。 + +![][4] + +#### 安装说明 + +仓库目前为 Fedora 26、27、28 和 Rawhide 以及 EPEL 7 提供 Ghostwriter。要安装 Ghostwriter,请使用以下命令: + +``` +sudo dnf copr enable scx/ghostwriter +sudo dnf install ghostwriter +``` + +### Lector + +[Lector][5] 是一个简单的电子书阅读器程序。Lector 支持最常见的电子书格式,如 EPUB、MOBI 和 AZW,以及漫画书格式 CBZ 和 CBR。它很容易设置 —— 只需指定包含电子书的目录即可。你可以使用表格或书籍封面浏览 Lector 库内的书籍。Lector 的功能包括书签、用户自定义标签和内置字典。![][6] + +#### 安装说明 + +该仓库目前为 Fedora 26、27、28 和 Rawhide 提供Lector。要安装 Lector,请使用以下命令: + +``` +sudo dnf copr enable bugzy/lector +sudo dnf install lector +``` + +### Ranger + +Ranerger 是一个基于文本的文件管理器,它带有 Vim 键绑定。它以三列显示目录结构。左边显示父目录,中间显示当前目录的内容,右边显示所选文件或目录的预览。对于文本文件,Ranger 将文件的实际内容作为预览。![][7] + +#### 安装说明 + +该仓库目前为 Fedora 27、28 和 Rawhide 提供 Ranger。要安装 Ranger,请使用以下命令: + +``` +sudo dnf copr enable fszymanski/ranger +sudo dnf install ranger +``` + +### PrestoPalette + +PrestoPeralette 是一款帮助创建平衡调色板的工具。PrestoPalette 的一个很好的功能是能够使用光照来影响调色板的亮度和饱和度。你可以将创建的调色板导出为 PNG 或 JSON。 + +![][8] + +#### 安装说明 + +仓库目前为 Fedora 26、27、28 和 Rawhide 以及 EPEL 7 提供 PrestoPalette。要安装 PrestoPalette,请使用以下命令: + +``` +sudo dnf copr enable dagostinelli/prestopalette +sudo dnf install prestopalette +``` + + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/4-try-copr-june-2018/ + +作者:[Dominik Turecek][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org +[1]:https://copr.fedorainfracloud.org/ +[2]:http://wereturtle.github.io/ghostwriter/ +[3]:https://daringfireball.net/ +[4]:https://fedoramagazine.org/wp-content/uploads/2018/05/ghostwriter.png +[5]:https://github.com/BasioMeusPuga/Lector +[6]:https://fedoramagazine.org/wp-content/uploads/2018/05/lector.png +[7]:https://fedoramagazine.org/wp-content/uploads/2018/05/ranger.png +[8]:https://fedoramagazine.org/wp-content/uploads/2018/05/prestopalette.png diff --git a/published/20180606 6 Open Source AI Tools to Know.md b/published/20180606 6 Open Source AI Tools to Know.md new file mode 100644 index 0000000000..8c26e7308c --- /dev/null +++ b/published/20180606 6 Open Source AI Tools to Know.md @@ -0,0 +1,71 @@ +你应该了解的 6 个开源 AI 工具 +====== + +> 让我们来看看几个任何人都能用的自由开源的 AI 工具。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/artificial-intelligence-3382507_1920.jpg?itok=HarDnwVX) + +在开源领域,不管你的想法是多少的新颖独到,先去看一下别人是否已经做成了这个概念,总是一个很明智的做法。对于有兴趣借助不断成长的人工智能Artificial Intelligence(AI)的力量的组织和个人来说,许多优秀的工具不仅是自由开源的,而且在很多的情况下,它们都已经过测试和久经考验的。 + +在领先的公司和非盈利组织中,AI 的优先级都非常高,并且这些公司和组织都开源了很有价值的工具。下面的举例是任何人都可以使用的自由开源的 AI 工具。 + +### Acumos + +[Acumos AI][1] 是一个平台和开源框架,使用它可以很容易地去构建、共享和分发 AI 应用。它规范了运行一个“开箱即用的”通用 AI 环境所需要的基础设施栈infrastructure stack和组件。这使得数据科学家和模型训练者可以专注于它们的核心竞争力,而不用在无止境的定制、建模,以及训练一个 AI 实现上浪费时间。 + +Acumos 是 [LF 深度学习基金会][2] 的一部分,它是 Linux 基金会中的一个组织,它支持在人工智能、机器学习machine learning、以及深度学习deep learning方面的开源创新。它的目标是让这些重大的新技术可用于开发者和数据科学家,包括那些在深度学习和 AI 上经验有限的人。LF 深度学习基金会 [最近批准了一个项目生命周期和贡献流程][3],并且它现在正接受项目贡献的建议。 + +### Facebook 的框架 + +Facebook [开源了][4] 其中心机器学习系统,它设计用于做一些大规模的人工智能任务,以及一系列其它的 AI 技术。这个工具是经过他们公司验证使用的平台的一部分。Facebook 也开源了一个叫 [Caffe2][5] 的深度学习和人工智能的框架。 + +### CaffeOnSpark + +**说到 Caffe**。 Yahoo 也在开源许可证下发布了它自己的关键的 AI 软件。[CaffeOnSpark 工具][6] 是基于深度学习的,它是人工智能的一个分支,在帮助机器识别人类语言,或者照片、视频的内容方面非常有用。同样地,IBM 的机器学习程序 [SystemML][7] 可以通过 Apache 软件基金会自由地共享和修改。 + +### Google 的工具 + +Google 花费了几年的时间开发了它自己的 [TensorFlow][8] 软件框架,用于去支持它的 AI 软件和其它预测和分析程序。TensorFlow 是你可能都已经在使用的一些 Google 工具背后的引擎,包括 Google Photos 和在 Google app 中使用的语言识别。 + +Google 开源了两个 [AIY 套件][9],它可以让个人很容易地使用人工智能,它们专注于计算机视觉和语音助理。这两个套件将用到的所有组件封装到一个盒子中。该套件目前在美国的 Target 中有售,并且它是基于开源的树莓派平台的 —— 有越来越多的证据表明,在开源和 AI 交集中将发生非常多的事情。 + +### H2O.ai + +我 [以前介绍过][10] H2O.ai,它在机器学习和人工智能领域中占有一席之地,因为它的主要工具是自由开源的。你可以获取主要的 H2O 平台和 Sparkling Water,它与 Apache Spark 一起工作,只需要去 [下载][11] 它们即可。这些工具遵循 Apache 2.0 许可证,它是一个非常灵活的开源许可证,你甚至可以在 Amazon Web 服务(AWS)和其它的集群上运行它们,而这仅需要几百美元而已。 + +### Microsoft 入局 + +“我们的目标是让 AI 大众化,让每个人和组织获得更大的成就,“ Microsoft CEO 萨提亚·纳德拉 [说][12]。因此,微软持续迭代它的 [Microsoft Cognitive Toolkit][13](CNTK)。它是一个能够与 TensorFlow 和 Caffe 去竞争的一个开源软件框架。Cognitive Toolkit 可以工作在 64 位的 Windows 和 Linux 平台上。 + +Cognitive Toolkit 团队的报告称,“Cognitive Toolkit 通过允许用户去创建、训练,以及评估他们自己的神经网络,以使企业级的、生产系统级的 AI 成为可能,这些神经网络可能跨多个 GPU 以及多个机器在大量的数据集中高效伸缩。” + +--- + +从来自 Linux 基金会的新电子书中学习更多的有关 AI 知识。Ibrahim Haddad 的 [开源 AI:项目、洞察和趋势][14] 调查了 16 个流行的开源 AI 项目—— 深入研究了他们的历史、代码库、以及 GitHub 的贡献。 [现在可以免费下载这个电子书][14]。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/2018/6/6-open-source-ai-tools-know + +作者:[Sam Dean][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[pityonline](https://github.com/pityonline), [wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/sam-dean +[1]:https://www.acumos.org/ +[2]:https://www.linuxfoundation.org/projects/deep-learning/ +[3]:https://www.linuxfoundation.org/blog/lf-deep-learning-foundation-announces-project-contribution-process/ +[4]:https://code.facebook.com/posts/1687861518126048/facebook-to-open-source-ai-hardware-design/ +[5]:https://venturebeat.com/2017/04/18/facebook-open-sources-caffe2-a-new-deep-learning-framework/ +[6]:http://yahoohadoop.tumblr.com/post/139916563586/caffeonspark-open-sourced-for-distributed-deep +[7]:https://systemml.apache.org/ +[8]:https://www.tensorflow.org/ +[9]:https://www.techradar.com/news/google-assistant-sweetens-raspberry-pi-with-ai-voice-control +[10]:https://www.linux.com/news/sparkling-water-bridging-open-source-machine-learning-and-apache-spark +[11]:http://www.h2o.ai/download +[12]:https://blogs.msdn.microsoft.com/uk_faculty_connection/2017/02/10/microsoft-cognitive-toolkit-cntk/ +[13]:https://www.microsoft.com/en-us/cognitive-toolkit/ +[14]:https://www.linuxfoundation.org/publications/open-source-ai-projects-insights-and-trends/ diff --git a/published/20180606 Getting started with Buildah.md b/published/20180606 Getting started with Buildah.md new file mode 100644 index 0000000000..c1ece0f54e --- /dev/null +++ b/published/20180606 Getting started with Buildah.md @@ -0,0 +1,226 @@ +Buildah 入门 +====== + +> Buildah 提供一种灵活、可脚本编程的方式,来使用你熟悉的工具创建精简、高效的容器镜像。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/blocks_building.png?itok=eMOT-ire) + +[Buildah][1] 是一个命令行工具,可以方便、快捷的构建与[开放容器标准][2]Open Container Initiative(OCI)兼容的容器镜像,这意味着其构建的镜像与 Docker 和 Kubernetes 兼容。该工具可作为 Docker 守护进程 `docker build` 命令(即使用传统的 Dockerfile 构建镜像)的一种简单drop-in替换,而且更加灵活,允许构建镜像时使用你擅长的工具。Buildah 可以轻松与脚本集成并生成流水线pipeline,最好之处在于构建镜像不再需要运行容器守护进程(LCTT 译注:这里主要是指 Docker 守护进程)。 + +### docker build 的简单替换 + +目前你可能使用 Dockerfile 和 `docker build` 命令构建镜像,那么你可以马上使用 Buildah 进行替代。Buildah 的 `build-using-dockerfile` (或 `bud`)子命令与 `docker build` 基本等价,因此可以轻松的与已有脚本结合或构建流水线。 + +类似我的上一篇关于 Buildah 的[文章][3],我也将以使用源码安装 “GNU Hello” 为例进行说明,对应的 Dockerfile 文件如下: + +``` +FROM fedora:28 +LABEL maintainer Chris Collins + +RUN dnf install -y tar gzip gcc make \ +        && dnf clean all + +ADD http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz /tmp/hello-2.10.tar.gz + +RUN tar xvzf /tmp/hello-2.10.tar.gz -C /opt + +WORKDIR /opt/hello-2.10 + +RUN ./configure +RUN make +RUN make install +RUN hello -v +ENTRYPOINT "/usr/local/bin/hello" +``` + +使用 Buildah 从 Dockerfile 构建镜像也很简单,使用 `buildah bud -t hello .` 替换 `docker build -t hello .` 即可: + +``` +[chris@krang] $ sudo buildah bud -t hello . +STEP 1: FROM fedora:28 +Getting image source signatures +Copying blob sha256:e06fd16225608e5b92ebe226185edb7422c3f581755deadf1312c6b14041fe73 + 81.48 MiB / 81.48 MiB [====================================================] 8s +Copying config sha256:30190780b56e33521971b0213810005a69051d720b73154c6e473c1a07ebd609 + 2.29 KiB / 2.29 KiB [======================================================] 0s +Writing manifest to image destination +Storing signatures +STEP 2: LABEL maintainer Chris Collins +STEP 3: RUN dnf install -y tar gzip gcc make    && dnf clean all + +<考虑篇幅,略去后续输出> +``` + +镜像构建完毕后,可以使用 `buildah images` 命令查看这个新镜像: + +``` +[chris@krang] $ sudo buildah images +IMAGE ID        IMAGE NAME                              CREATED AT              SIZE +30190780b56e    docker.io/library/fedora:28             Mar 7, 2018 16:53       247 MB +6d54bef73e63    docker.io/library/hello:latest    May 3, 2018 15:24     391.8 MB +``` + +新镜像的标签为 `hello:latest`,我们可以将其推送至远程镜像仓库,可以使用 [CRI-O][4] 或其它 Kubernetes CRI 兼容的运行时来运行该镜像,也可以推送到远程仓库。如果你要测试对 Docker build 命令的替代性,你可以将镜像拷贝至 docker 守护进程的本地镜像存储中,这样 Docker 也可以使用该镜像。使用 `buildah push` 可以很容易的完成推送操作: + +``` +[chris@krang] $ sudo buildah push hello:latest docker-daemon:hello:latest +Getting image source signatures +Copying blob sha256:72fcdba8cff9f105a61370d930d7f184702eeea634ac986da0105d8422a17028 + 247.02 MiB / 247.02 MiB [==================================================] 2s +Copying blob sha256:e567905cf805891b514af250400cc75db3cb47d61219750e0db047c5308bd916 + 144.75 MiB / 144.75 MiB [==================================================] 1s +Copying config sha256:6d54bef73e638f2e2dd8b7bf1c4dfa26e7ed1188f1113ee787893e23151ff3ff + 1.59 KiB / 1.59 KiB [======================================================] 0s +Writing manifest to image destination +Storing signatures + +[chris@krang] $ sudo docker images | head -n2 +REPOSITORY              TAG             IMAGE ID        CREATED                 SIZE +docker.io/hello      latest       6d54bef73e63  2 minutes ago   398 MB + +[chris@krang] $ sudo docker run -t hello:latest +Hello, world! +``` + +### 若干差异 + +与 Docker build 不同,Buildah 不会自动的将 Dockerfile 中的每条指令产生的变更提到新的分层layer中,只是简单的每次从头到尾执行构建。类似于自动化automation流水线构建build pipeline,这种无缓存构建non-cached方式的好处是可以提高构建速度,在指令较多时尤为明显。从自动部署automated deployment持续交付continuous delivery的视角来看,使用这种方式可以快速的将新变更落实到生产环境中。 + +但从实际角度出发,缓存机制的缺乏对镜像开发不利,毕竟缓存层可以避免一遍遍的执行构建,从而显著的节省时间。自动分层只在 `build-using-dockerfile` 命令中生效。但我们在下面会看到,Buildah 原生命令允许我们选择将变更提交到硬盘的时间,提高了开发的灵活性。 + +### Buildah 原生命令 + +Buildah _真正_ 有趣之处在于它的原生命令,你可以在容器构建过程中使用这些命令进行交互。相比与使用 `build-using-dockerfile/bud` 命令执行每次构建,Buildah 提供命令让你可以与构建过程中的临时容器进行交互。(Docker 也使用临时或 _中间_ intermediate容器,但你无法在镜像构建过程中与其交互。) + +还是使用 “GNU Hello” 为例,考虑使用如下 Buildah 命令构建的镜像: + +``` +#!/usr/bin/env bash + +set -o errexit + +# Create a container +container=$(buildah from fedora:28) + +# Labels are part of the "buildah config" command +buildah config --label maintainer="Chris Collins " $container + +# Grab the source code outside of the container +curl -sSL http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz -o hello-2.10.tar.gz + +buildah copy $container hello-2.10.tar.gz /tmp/hello-2.10.tar.gz + +buildah run $container dnf install -y tar gzip gcc make +buildah run $container dnf clean all +buildah run $container tar xvzf /tmp/hello-2.10.tar.gz -C /opt + +# Workingdir is also a "buildah config" command +buildah config --workingdir /opt/hello-2.10 $container + +buildah run $container ./configure +buildah run $container make +buildah run $container make install +buildah run $container hello -v + +# Entrypoint, too, is a “buildah config” command +buildah config --entrypoint /usr/local/bin/hello $container + +# Finally saves the running container to an image +buildah commit --format docker $container hello:latest +``` + +我们可以一眼看出这是一个 Bash 脚本而不是 Dockerfile。基于 Buildah 的原生命令,可以轻易的使用任何脚本语言或你擅长的自动化工具编写脚本。形式可以是 makefile、Python 脚本或其它你擅长的类型。 + +这个脚本做了哪些工作呢?首先,Buildah 命令 `container=$(buildah from fedora:28)` 基于 fedora:28 镜像创建了一个正在运行的容器,将容器名(`buildah from` 命令的返回值)保存到变量中,便于后续使用。后续所有命令都是有 `$container` 变量指明需要操作的容器。这些命令的功能大多可以从名称看出:`buildah copy` 将文件拷贝至容器,`buildah run` 会在容器中执行命令。可以很容易的将上述命令与 Dockerfile 中的指令对应起来。 + +最后一条命令 `buildah commit` 将容器提交到硬盘上的镜像中。当不使用 Dockerfile 而是使用 Buildah 命令构建镜像时,你可以使用 `commit` 命令决定何时保存变更。在上例中,所有的变更是一起提交的;但也可以增加中间提交,让你可以选择作为起点的缓存点cache point。(例如,执行完 `dnf install` 命令后将变更缓存到硬盘是特别有意义的,一方面因为该操作耗时较长,另一方面每次执行的结果也确实相同。) + +### 挂载点,安装目录以及 chroot + +另一个可以大大增加构建镜像灵活性的 Buildah 命令是 `buildah mount`,可以将容器的根目录挂载到你主机的一个挂载点上。例如: + +``` +[chris@krang] $ container=$(sudo buildah from fedora:28) +[chris@krang] $ mountpoint=$(sudo buildah mount ${container}) +[chris@krang] $ echo $mountpoint +/var/lib/containers/storage/overlay2/463eda71ec74713d8cebbe41ee07da5f6df41c636f65139a7bd17b24a0e845e3/merged +[chris@krang] $ cat ${mountpoint}/etc/redhat-release +Fedora release 28 (Twenty Eight) +[chris@krang] $ ls ${mountpoint} +bin   dev  home  lib64          media  opt   root  sbin  sys  usr +boot  etc  lib   lost+found  mnt        proc  run   srv   tmp  var +``` + +这太棒了,你可以通过与挂载点交互对容器镜像进行修改。这允许你使用主机上的工具进行构建和安装软件,不用将这些构建工具打包到容器镜像本身中。例如,在我们上面的 Bash 脚本中,我们需要安装 tar、Gzip、GCC 和 make,在容器内编译 “GNU Hello”。如果使用挂载点,我仍使用同样的工具进行构建,但下载的压缩包和 tar、Gzip 等 RPM 包都在主机而不是容器和生成的镜像内: + +``` +#!/usr/bin/env bash + +set -o errexit + +# Create a container +container=$(buildah from fedora:28) +mountpoint=$(buildah mount $container) + +buildah config --label maintainer="Chris Collins " $container + +curl -sSL http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz \ +     -o /tmp/hello-2.10.tar.gz +tar xvzf src/hello-2.10.tar.gz -C ${mountpoint}/opt + +pushd ${mountpoint}/opt/hello-2.10 +./configure +make +make install DESTDIR=${mountpoint} +popd + +chroot $mountpoint bash -c "/usr/local/bin/hello -v" + +buildah config --entrypoint "/usr/local/bin/hello" $container +buildah commit --format docker $container hello +buildah unmount $container +``` + +在上述脚本中,需要提到如下几点: + + 1. `curl` 命令将压缩包下载到主机中,而不是镜像中; + 2. (主机中的) `tar` 命令将压缩包中的源代码解压到容器的 `/opt` 目录; + 3. `configure`,`make` 和 `make install` 命令都在主机的挂载点目录中执行,而不是在容器内; + 4. 这里的 `chroot` 命令用于将挂载点本身当作根路径并测试 "hello" 是否正常工作;类似于前面例子中用到的 `buildah run` 命令。 + + +这个脚本更加短小,使用大多数 Linux 爱好者都很熟悉的工具,最后生成的镜像也更小(没有 tar 包,没有额外的软件包等)。你甚至可以使用主机系统上的包管理器为容器安装软件。例如,(出于某种原因)你希望安装 GNU Hello 的同时在容器中安装 [NGINX][5]: + +``` +[chris@krang] $ mountpoint=$(sudo buildah mount ${container}) +[chris@krang] $ sudo dnf install nginx --installroot $mountpoint +[chris@krang] $ sudo chroot $mountpoint nginx -v +nginx version: nginx/1.12.1 +``` + +在上面的例子中,DNF 使用 `--installroot` 参数将 NGINX 安装到容器中,可以通过 chroot 进行校验。 + +### 快来试试吧! + +Buildah 是一种轻量级、灵活的容器镜像构建方法,不需要在主机上运行完整的 Docker 守护进程。除了提供基于 Dockerfile 构建容器的开箱即用支持,Buildah 还可以很容易的与脚本或你喜欢的构建工具相结合,特别是可以使用主机上已有的工具构建容器镜像。Buildah 生成的容器体积更小,更便于网络传输,占用更小的存储空间,而且潜在的受攻击面更小。快来试试吧! + +**[阅读相关的故事,[使用 Buildah 创建小体积的容器][6]]** + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/6/getting-started-buildah + +作者:[Chris Collins][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[pinewall](https://github.com/pinewall) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/clcollins +[1]:https://github.com/projectatomic/buildah +[2]:https://www.opencontainers.org/ +[3]:http://chris.collins.is/2017/08/17/buildah-a-new-way-to-build-container-images/ +[4]:http://cri-o.io/ +[5]:https://www.nginx.com/ +[6]:https://linux.cn/article-9719-1.html diff --git a/translated/tech/20180607 3 journaling applications for the Linux desktop.md b/published/20180607 3 journaling applications for the Linux desktop.md similarity index 54% rename from translated/tech/20180607 3 journaling applications for the Linux desktop.md rename to published/20180607 3 journaling applications for the Linux desktop.md index 23d7435e21..daa4d97ab3 100644 --- a/translated/tech/20180607 3 journaling applications for the Linux desktop.md +++ b/published/20180607 3 journaling applications for the Linux desktop.md @@ -1,10 +1,13 @@ 3 款 Linux 桌面的日记程序 ====== -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/desk_clock_job_work.jpg?itok=Nj4fuhl6) -保持记日记,即使是不定期,也可以带来很多好处。这不仅是治疗和宣泄,而且还可以很好地记录你所处的位置以及你去过的地方。它可以帮助你展示你在生活中的进步,并提醒你自己做对了什么,做错了什么。 +> 用轻量、灵活的数字日记工具来记录你的活动。 -无论你记日记的原因是什么,都有多种方法可以做到这一点。你可以去读书,使用笔和纸。你可以使用基于 Web 的程序。或者你可以使用[简单的文本文件][1]。 +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/desk_clock_job_work.jpg?itok=Nj4fuhl6) + +保持记日记的习惯,即使是不定期地记,也可以带来很多好处。这不仅是治疗和宣泄,而且还可以很好地记录你所在的位置以及你去过的地方。它可以帮助你展示你在生活中的进步,并提醒你自己做对了什么,做错了什么。 + +无论你记日记的原因是什么,都有多种方法可以做到这一点。你可以使用传统的笔和纸,也可以使用基于 Web 的程序,或者你可以使用[简单的文本文件][1]。 另一种选择是使用专门的日记程序。Linux 桌面有几种非常灵活且非常有用的日记工具。我们来看看其中的三个。 @@ -12,11 +15,11 @@ ![](https://opensource.com/sites/default/files/uploads/red-notebook.png) -在这里描述的三个日记程序中,[RedNotebook][2] 是最灵活的。大部分灵活性来自其模板。这些模板可让莫记录个人想法或会议记录、计划旅程或记录电话。你还可以编辑现有模板或创建自己的模板。 +在这里描述的三个日记程序中,[RedNotebook][2] 是最灵活的。大部分灵活性来自其模板。这些模板可让你记录个人想法或会议记录、计划旅程或记录电话。你还可以编辑现有模板或创建自己的模板。 -你使用与 Markdown 非常相似的标记语言记录日记。你还可以在日记中添加标签,以便于查找。只需在程序的左窗格中单击或输入标记,右窗格中将显示相应日记的列表。 +你可以使用与 Markdown 非常相似的标记语言来记录日记。你还可以在日记中添加标签,以便于查找。只需在程序的左窗格中单击或输入标记,右窗格中将显示相应日记的列表。 -最重要的是,你可以将全部或部分或仅一个日记录导出为纯文本、HTML、LaTeX 或 PDF。在执行此操作之前,你可以通过单击工具栏上的“预览”按钮了解日志在 PDF 或 HTML 中的显示情况。 +最重要的是,你可以将全部、部分或仅一个日记导出为纯文本、HTML、LaTeX 或 PDF。在执行此操作之前,你可以通过单击工具栏上的“预览”按钮了解日志在 PDF 或 HTML 中的显示情况。 总的来说,RedNotebook 是一款易于使用且灵活的程序。它需要习惯,但一旦你这样做,它是一个有用的工具。 @@ -24,9 +27,9 @@ ![](https://opensource.com/sites/default/files/uploads/lifeograph.png) -[Lifeograph][3] 与 RedNotebook 有相似的外观和感觉。它没有那么多功能,但 Lifeograph 可以完成工作。 +[Lifeograph][3] 与 RedNotebook 有相似的外观和感觉。它没有那么多功能,但 Lifeograph 也够了。 -该程序通过保持简单和整洁来简化记日记。你有一个很大的区域可以记录,你可以为日记添加一些基本格式。这包括通常的粗体和斜体,以及箭头和高亮显示。你可以在日记中添加标签,以便更好地组织和查找它们。 +该程序通过保持简单和整洁性来简化记日记这件事。你有一个很大的区域可以记录,你可以为日记添加一些基本格式。这包括通常的粗体和斜体,以及箭头和高亮显示。你可以在日记中添加标签,以便更好地组织和查找它们。 Lifeograph 有一个我觉得特别有用的功能。首先,你可以创建多个日记 - 例如,工作日记和个人日记。其次是密码保护你的日记的能力。虽然该网站声称 Lifeograph 使用“真正的加密”,但没有关于它的详细信息。尽管如此,设置密码仍然会阻止大多数窥探者。 @@ -34,15 +37,15 @@ Lifeograph 有一个我觉得特别有用的功能。首先,你可以创建多 ![](https://opensource.com/sites/default/files/uploads/almanah.png) -[Almanah Diary][4] 是另一种非常简单的日记工具。但不要因为它缺乏功能就关闭它。这很简单,但完成了工作。 +[Almanah Diary][4] 是另一种非常简单的日记工具。但不要因为它缺乏功能就丢掉它。虽简单,但足够。 -有多简单?它差多是一个区域包含了日记输入和日历。你可以做更多的事情 - 比如添加一些基本格式(粗体、斜体和下划线)并将文本转换为超链接。Almanah 还允许你加密日记。 +有多简单?它差不多只是一个包含了日记输入和日历的区域而已。你可以做更多的事情 —— 比如添加一些基本格式(粗体、斜体和下划线)并将文本转换为超链接。Almanah 还允许你加密日记。 -虽然有一个功能可以将纯文本文件导入程序,但我无法使其正常工作。尽管如此,如果你喜欢一个简单,能够快速记日记的软件,那么 Almanah 日记值得一看。 +虽然有一个可以将纯文本文件导入该程序的功能,但我无法使其正常工作。尽管如此,如果你喜欢一个简单,能够快速记日记的软件,那么 Almanah 日记值得一看。 ### 命令行怎么样? -如果你不想用 GUI 则可以不必去做。命令行是保存日记的绝佳选择。 +如果你不想用 GUI 则可以不必用。命令行是保存日记的绝佳选择。 我尝试过并且喜欢的是 [jrnl][5]。或者你可以使用[此方案][6],它使用命令行别名格式化并将日记保存到文本文件中。 @@ -55,7 +58,7 @@ via: https://opensource.com/article/18/6/linux-journaling-applications 作者:[Scott Nesbitt][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/) 荣誉推出 diff --git a/published/20180607 GitLab-s Ultimate - Gold Plans Are Now Free For Open-Source Projects.md b/published/20180607 GitLab-s Ultimate - Gold Plans Are Now Free For Open-Source Projects.md new file mode 100644 index 0000000000..fb1f925c0a --- /dev/null +++ b/published/20180607 GitLab-s Ultimate - Gold Plans Are Now Free For Open-Source Projects.md @@ -0,0 +1,77 @@ +GitLab 的付费套餐现在可以免费用于开源项目 +====== + +最近在开源社区发生了很多事情。首先,[微软收购了 GitHub][1],然后人们开始寻找 [GitHub 替代套餐][2],甚至在 Linus Torvalds 发布 [Linux Kernel 4.17][3] 时没有花一点时间考虑它。好吧,如果你一直关注我们,我认为你知道这一切。 + +但是,如今,GitLab 做出了一个明智的举措,为教育机构和开源项目免费提供高级套餐。当许多开发人员有兴趣将他们的开源项目迁移到 GitLab 时,没有更好的时机来提供这些了。 + +### GitLab 的高级套餐现在对开源项目和教育机构免费 + +![GitLab Logo][4] + +在今天(2018/6/7)[发布的博客][5]中,GitLab 宣布其**旗舰**和黄金套餐现在对教育机构和开源项目免费。虽然我们已经知道为什么 GitLab 做出这个举动(一个完美的时机!),但他们还是解释了他们让它免费的动机: + +> 我们让 GitLab 对教育机构免费,因为我们希望学生使用我们最先进的功能。许多大学已经运行了 GitLab。如果学生使用 GitLab 旗舰和黄金套餐的高级功能,他们将把这些高级功能的经验带到他们的工作场所。 +> +> 我们希望有更多的开源项目使用 GitLab。GitLab.com 上的公共项目已经拥有 GitLab 旗舰套餐的所有功能。像 [Gnome][6] 和 [Debian][7] 这样的项目已经在自己的服务器运行开源版 GitLab 。随着今天的宣布,在专有软件上运行的开源项目可以使用 GitLab 提供的所有功能,同时我们通过向非开源组织收费来建立可持续的业务模式。 + +### GitLab 提供的这些“免费”套餐是什么? + +![GitLab Pricing][8] + +GitLab 有两类产品。一个是你可以在自己的云托管服务如 [Digital Ocean][9] 上运行的软件。另一个是 Gitlab 软件既服务,其中托管由 GitLab 本身管理,你在 GitLab.com 上获得一个帐户。 + +![GitLab Pricing for hosted service][10] + +黄金套餐是托管类别中最高的产品,而旗舰套餐是自托管类别中的最高产品。 + +你可以在 GitLab 定价页面上获得有关其功能的更多详细信息。请注意,支持服务不包括在套餐中。你必须单独购买。 + +### 你必须符合某些条件才能使用此优惠 + +GitLab 还提到 —— 该优惠对谁有效。以下是他们在博客文章中写的内容: + +> 1. **教育机构:**任何为了学习、教育的机构,并且/或者由合格的教育机构、教职人员、学生训练。教育目的不包括商业,专业或任何其他营利目的。 +> +> 2. **开源项目:**任何使用[标准开源许可证][11]且非商业性的项目。它不应该有付费支持或付费贡献者。 +> + + +虽然免费套餐不包括支持,但是当你迫切需要专家帮助解决问题时,你仍然可以支付每用户每月 4.95 美元的额外费用 —— 当你特别需要一个专家来解决问题时,这是一个非常合理的价格。 + +GitLab 还为学生们添加了一条说明: + +> 为减轻 GitLab 的管理负担,只有教育机构才能代表学生申请。如果你是学生并且你的教育机构不申请,你可以在 GitLab.com 上使用公共项目的所有功能,使用私人项目的免费功能,或者自己付费。 + +### 总结 + +现在 GitLab 正在加快脚步,你如何看待它? + +你有 [GitHub][12] 上的项目吗?你会切换么?或者,幸运的是,你从一开始就碰巧使用 GitLab? + +请在下面的评论栏告诉我们你的想法。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/gitlab-free-open-source/ + +作者:[Ankush Das][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://itsfoss.com/author/ankush/ +[1]:https://itsfoss.com/microsoft-github/ +[2]:https://itsfoss.com/github-alternatives/ +[3]:https://itsfoss.com/linux-kernel-4-17/ +[4]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/GitLab-logo-800x450.png +[5]:https://about.gitlab.com/2018/06/05/gitlab-ultimate-and-gold-free-for-education-and-open-source/ +[6]:https://www.gnome.org/news/2018/05/gnome-moves-to-gitlab-2/ +[7]:https://salsa.debian.org/public +[8]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/gitlab-pricing.jpeg +[9]:https://m.do.co/c/d58840562553 +[10]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/gitlab-hosted-service-800x273.jpeg +[11]:https://itsfoss.com/open-source-licenses-explained/ +[12]:https://github.com/ diff --git a/translated/tech/20180607 Mesos and Kubernetes- It-s Not a Competition.md b/published/20180607 Mesos and Kubernetes- It-s Not a Competition.md similarity index 57% rename from translated/tech/20180607 Mesos and Kubernetes- It-s Not a Competition.md rename to published/20180607 Mesos and Kubernetes- It-s Not a Competition.md index 27c9924b08..8420ca41aa 100644 --- a/translated/tech/20180607 Mesos and Kubernetes- It-s Not a Competition.md +++ b/published/20180607 Mesos and Kubernetes- It-s Not a Competition.md @@ -1,15 +1,17 @@ Mesos 和 Kubernetes:不是竞争者 ====== +> 人们经常用 x 相对于 y 这样的术语来考虑问题,但是它并不是一个技术对另一个技术的问题。Ben Hindman 在这里解释了 Mesos 是如何对另外一种技术进行补充的。 + ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/architecture-barge-bay-161764_0.jpg?itok=vNChG5fb) -Mesos 的起源可以追溯到 2009 年,当时,Ben Hindman 还是加州大学伯克利分校研究并行编程的博士生。他们在 128 核的芯片上做大规模的并行计算,并尝试去解决多个问题,比如怎么让软件和库在这些芯片上运行更高效。他与同学们讨论能否借鉴并行处理和多线程的思想,并将它们应用到集群管理上。 +Mesos 的起源可以追溯到 2009 年,当时,Ben Hindman 还是加州大学伯克利分校研究并行编程的博士生。他们在 128 核的芯片上做大规模的并行计算,以尝试去解决多个问题,比如怎么让软件和库在这些芯片上运行更高效。他与同学们讨论能否借鉴并行处理和多线程的思想,并将它们应用到集群管理上。 -Hindman 说 "最初,我们专注于大数据” 。那时,大数据非常热门,并且 Hadoop 是其中一个热门技术。“我们发现,人们在集群上运行像 Hadoop 这样的程序与运行多线程应用和并行应用很相似。Hindman 说。 +Hindman 说 “最初,我们专注于大数据” 。那时,大数据非常热门,而 Hadoop 就是其中的一个热门技术。“我们发现,人们在集群上运行像 Hadoop 这样的程序与运行多线程应用及并行应用很相似。”Hindman 说。 -但是,它们的效率并不高,因此,他们开始去思考,如何通过集群管理和资源管理让它们运行的更好。”我们查看了那个时间很多的不同技术“ Hindman 回忆道。 +但是,它们的效率并不高,因此,他们开始去思考,如何通过集群管理和资源管理让它们运行的更好。“我们查看了那个时期很多的各种技术” Hindman 回忆道。 -然而,Hindman 和他的同事们,决定去采用一种全新的方法。”我们决定去对资源管理创建一个低级的抽象,然后在此之上运行调度服务和做其它的事情。“ Hindman 说,“基本上,这就是 Mesos 的本质 —— 将资源管理部分从调度部分中分离出来。” +然后,Hindman 和他的同事们决定去采用一种全新的方法。“我们决定对资源管理创建一个低级的抽象,然后在此之上运行调度服务和做其它的事情。” Hindman 说,“基本上,这就是 Mesos 的本质 —— 将资源管理部分从调度部分中分离出来。” 他成功了,并且 Mesos 从那时开始强大了起来。 @@ -17,21 +19,21 @@ Hindman 说 "最初,我们专注于大数据” 。那时,大数据非常热 这个项目发起于 2009 年。在 2010 年时,团队决定将这个项目捐献给 Apache 软件基金会(ASF)。它在 Apache 孵化,并于 2013 年成为顶级项目(TLP)。 -为什么 Mesos 社区选择 Apache 软件基金会有很多的原因,比如,Apache 许可证,以及他们已经拥有了一个充满活力的此类项目的许多其它社区。 +为什么 Mesos 社区选择 Apache 软件基金会有很多的原因,比如,Apache 许可证,以及基金会已经拥有了一个充满活力的其它此类项目的社区。 -与影响力也有关系。许多在 Mesos 上工作的人,也参与了 Apache,并且许多人也致力于像 Hadoop 这样的项目。同时,来自 Mesos 社区的许多人也致力于其它大数据项目,比如 Spark。这种交叉工作使得这三个项目 —— Hadoop、Mesos、以及 Spark —— 成为 ASF 的项目。 +与影响力也有关系。许多在 Mesos 上工作的人也参与了 Apache,并且许多人也致力于像 Hadoop 这样的项目。同时,来自 Mesos 社区的许多人也致力于其它大数据项目,比如 Spark。这种交叉工作使得这三个项目 —— Hadoop、Mesos,以及 Spark —— 成为 ASF 的项目。 与商业也有关系。许多公司对 Mesos 很感兴趣,并且开发者希望它能由一个中立的机构来维护它,而不是让它成为一个私有项目。 ### 谁在用 Mesos? -更好的问题应该是,谁不在用 Mesos?从 Apple 到 Netflix 每个都在用 Mesos。但是,Mesos 也面临任何技术在早期所面对的挑战。”最初,我要说服人们,这是一个很有趣的新技术。它叫做“容器”,因为它不需要使用虚拟机“ Hindman 说。 +更好的问题应该是,谁不在用 Mesos?从 Apple 到 Netflix 每个都在用 Mesos。但是,Mesos 也面临任何技术在早期所面对的挑战。“最初,我要说服人们,这是一个很有趣的新技术。它叫做‘容器’,因为它不需要使用虚拟机” Hindman 说。 -从那以后,这个行业发生了许多变化,现在,只要与别人聊到基础设施,必然是从”容器“开始的 —— 感谢 Docker 所做出的工作。今天再也不需要说服工作了,而在 Mesos 出现的早期,前面提到的像 Apple、Netflix、以及 PayPal 这样的公司。他们已经知道了容器化替代虚拟机给他们带来的技术优势。”这些公司在容器化成为一种现象之前,已经明白了容器化的价值所在“, Hindman 说。 +从那以后,这个行业发生了许多变化,现在,只要与别人聊到基础设施,必然是从”容器“开始的 —— 感谢 Docker 所做出的工作。今天再也不需要做说服工作了,而在 Mesos 出现的早期,前面提到的像 Apple、Netflix,以及 PayPal 这样的公司。他们已经知道了容器替代虚拟机给他们带来的技术优势。“这些公司在容器成为一种现象之前,已经明白了容器的价值所在”, Hindman 说。 -可以在这些公司中看到,他们有大量的容器而不是虚拟机。他们所做的全部工作只是去管理和运行这些容器,并且他们欣然接受了 Mesos。在 Mesos 早期就使用它的公司有 Apple、Netflix、PayPal、Yelp、OpenTable、和 Groupon。 +可以在这些公司中看到,他们有大量的容器而不是虚拟机。他们所做的全部工作只是去管理和运行这些容器,并且他们欣然接受了 Mesos。在 Mesos 早期就使用它的公司有 Apple、Netflix、PayPal、Yelp、OpenTable 和 Groupon。 -“大多数组织使用 Mesos 来运行任意需要的服务” Hindman 说,“但也有些公司用它做一些非常有趣的事情,比如,数据处理、数据流、分析负载和应用程序。“ +“大多数组织使用 Mesos 来运行各种服务” Hindman 说,“但也有些公司用它做一些非常有趣的事情,比如,数据处理、数据流、分析任务和应用程序。“ 这些公司采用 Mesos 的其中一个原因是,资源管理层之间有一个明晰的界线。当公司运营容器的时候,Mesos 为他们提供了很好的灵活性。 @@ -43,11 +45,11 @@ Hindman 说 "最初,我们专注于大数据” 。那时,大数据非常热 人们经常用 x 相对于 y 这样的术语来考虑问题,但是它并不是一个技术对另一个技术的问题。大多数的技术在一些领域总是重叠的,并且它们可以是互补的。“我不喜欢将所有的这些东西都看做是竞争者。我认为它们中的一些与另一个在工作中是互补的,” Hindman 说。 -“事实上,名字 Mesos 表示它处于 ‘中间’;它是一种中间的 OS,” Hindman 说,“我们有一个容器调度器的概念,它能够运行在像 Mesos 这样的东西之上。当 Kubernetes 刚出现的时候,我们实际上在 Mesos 的生态系统中接受它的,并将它看做是运行在 Mesos 之上、DC/OS 之中的另一种方式的容器。” +“事实上,名字 Mesos 表示它处于 ‘中间’;它是一种中间的操作系统”, Hindman 说,“我们有一个容器调度器的概念,它能够运行在像 Mesos 这样的东西之上。当 Kubernetes 刚出现的时候,我们实际上在 Mesos 的生态系统中接受了它,并将它看做是在 Mesos 上的 DC/OS 中运行容器的另一种方式。” -Mesos 也复活了一个名为 [Marathon][1](一个用于 Mesos 和 DC/OS 的容器编排器)的项目,它在 Mesos 生态系统中是做的最好的容器编排器。但是,Marathon 确实无法与 Kubernetes 相比较。“Kubernetes 比 Marathon 做的更多,因此,你不能将它们简单地相互交换,” Hindman 说,“与此同时,我们在 Mesos 中做了许多 Kubernetes 中没有的东西。因此,这些技术之间是互补的。” +Mesos 也复活了一个名为 [Marathon][1](一个用于 Mesos 和 DC/OS 的容器编排器)的项目,它成为了 Mesos 生态系统中最重要的成员。但是,Marathon 确实无法与 Kubernetes 相比较。“Kubernetes 比 Marathon 做的更多,因此,你不能将它们简单地相互交换,” Hindman 说,“与此同时,我们在 Mesos 中做了许多 Kubernetes 中没有的东西。因此,这些技术之间是互补的。” -不要将这些技术视为相互之间是敌对的关系,它们应该被看做是对行业有益的技术。它们不是技术上的重复;它们是多样化的。据 Hindman 说,“对于开源领域的终端用户来说,这可能会让他们很困惑,因为他们很难去知道哪个技术适用于哪种负载,但这是被称为开源的这种东西最令人讨厌的本质所在。“ +不要将这些技术视为相互之间是敌对的关系,它们应该被看做是对行业有益的技术。它们不是技术上的重复;它们是多样化的。据 Hindman 说,“对于开源领域的终端用户来说,这可能会让他们很困惑,因为他们很难去知道哪个技术适用于哪种任务,但这是这个被称之为开源的本质所在。“ 这只是意味着有更多的选择,并且每个都是赢家。 @@ -58,7 +60,7 @@ via: https://www.linux.com/blog/2018/6/mesos-and-kubernetes-its-not-competition 作者:[Swapnil Bhartiya][a] 选题:[lujun9972](https://github.com/lujun9972) 译者:[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/) 荣誉推出 diff --git a/translated/tech/20180611 Turn Your Raspberry Pi into a Tor Relay Node.md b/published/20180611 Turn Your Raspberry Pi into a Tor Relay Node.md similarity index 69% rename from translated/tech/20180611 Turn Your Raspberry Pi into a Tor Relay Node.md rename to published/20180611 Turn Your Raspberry Pi into a Tor Relay Node.md index 53296cd8c3..7ccbee05eb 100644 --- a/translated/tech/20180611 Turn Your Raspberry Pi into a Tor Relay Node.md +++ b/published/20180611 Turn Your Raspberry Pi into a Tor Relay Node.md @@ -1,9 +1,11 @@ 将你的树莓派打造成一个 Tor 中继节点 ====== +> 在此教程中学习如何将你的旧树莓派打造成一个完美的 Tor 中继节点。 + ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/tor-onion-router.jpg?itok=6WUl0ElH) -你是否和我一样,在第一代或者第二代树莓派发布时买了一个,玩了一段时间就把它搁置“吃灰”了。毕竟,除非你是机器人爱好者,否则一般不太可能去长时间使用一个处理器很慢的并且内存只有 256 MB 的计算机的。这并不是说你不能用它去做一件很酷的东西,但是在工作和其它任务之间,我还没有看到用一些旧的物件发挥新作用的机会。 +你是否和我一样,在第一代或者第二代树莓派发布时买了一个,玩了一段时间就把它搁置“吃灰”了。毕竟,除非你是机器人爱好者,否则一般不太可能去长时间使用一个处理器很慢的、并且内存只有 256 MB 的计算机。这并不是说你不能用它去做一件很酷的东西,但是在工作和其它任务之间,我还没有看到用一些旧的物件发挥新作用的机会。 然而,如果你想去好好利用它并且不想花费你太多的时间和资源的话,可以将你的旧树莓派打造成一个完美的 Tor 中继节点。 @@ -11,18 +13,13 @@ 在此之前你或许听说过 [Tor 项目][1],如果恰好你没有听说过,我简单给你介绍一下,“Tor” 是 “The Onion Router(洋葱路由器)” 的缩写,它是用来对付在线追踪和其它违反隐私行为的技术。 -不论你在因特网上做什么事情,都会在你的 IP 包通过的设备上留下一些数字“脚印”:所有的交换机、路由器、负载均衡,以及目标网络记录的来自你的原始会话的 IP 地址,以及你访问的因特网资源(经常是主机名、[甚至是在使用 HTTPS 时][2])的 IP 地址。如何你是在家中上因特网,那么你的 IP 地址可以直接映射到你的家庭所在地。如果你使用了 VPN 服务([你应该使用][3]),那么你的 IP 地址是映射到你的 VPN 提供商那里,而 VPN 提供商是可以映射到你的家庭所在地的。无论如何,有可能在某个地方的某个人正在根据你访问的网络和在网站上呆了多长时间来为你建立一个个人的在线资料。然后将这个资料进行出售,并与从其它服务上收集的资料进行聚合,然后利用广告网络进行赚钱。至少,这是乐观主义者对如何利用这些数据的一些看法 —— 我相信你还可以找到更多的更恶意地使用这些数据的例子。 - -Tor 项目尝试去提供一个解决这种问题的方案,使它们不可能(或者至少是更加困难)追踪到你的终端 IP 地址。Tor 是通过让你的连接在一个由匿名的入口节点、中继节点、和出口节点组成的匿名中继链上反复跳转的方式来实现防止追踪的目的: - - 1. **入口节点** 只知道你的 IP 地址和中继节点的 IP 地址,但是不知道你最终要访问的目标 IP 地址 - - 2. **中继节点** 只知道入口节点和出口节点的 IP 地址,以及即不是源也不是最终目标的 IP 地址 - - 3. **出口节点** 仅知道中继节点和最终目标地址,它是在到达最终目标地址之前解密流量的节点 - +不论你在互联网上做什么事情,都会在你的 IP 包通过的设备上留下一些数字“脚印”:所有的交换机、路由器、负载均衡,以及目标网络记录的来自你的原始会话的 IP 地址,以及你访问的互联网资源(通常是它的主机名,[即使是在使用 HTTPS 时][2])的 IP 地址。如过你是在家中上互联网,那么你的 IP 地址可以直接映射到你的家庭所在地。如果你使用了 VPN 服务([你应该使用][3]),那么你的 IP 地址映射到你的 VPN 提供商那里,而 VPN 提供商是可以映射到你的家庭所在地的。无论如何,有可能在某个地方的某个人正在根据你访问的网络和在网站上呆了多长时间来为你建立一个个人的在线资料。然后将这个资料进行出售,并与从其它服务上收集的资料进行聚合,然后利用广告网络进行赚钱。至少,这是乐观主义者对如何利用这些数据的一些看法 —— 我相信你还可以找到更多的更恶意地使用这些数据的例子。 +Tor 项目尝试去提供一个解决这种问题的方案,使它们不可能(或者至少是更加困难)追踪到你的终端 IP 地址。Tor 是通过让你的连接在一个由匿名的入口节点、中继节点和出口节点组成的匿名中继链上反复跳转的方式来实现防止追踪的目的: +1. **入口节点** 只知道你的 IP 地址和中继节点的 IP 地址,但是不知道你最终要访问的目标 IP 地址 +2. **中继节点** 只知道入口节点和出口节点的 IP 地址,以及既不是源也不是最终目标的 IP 地址 +3. **出口节点** 仅知道中继节点和最终目标地址,它是在到达最终目标地址之前解密流量的节点 中继节点在这个交换过程中扮演一个关键的角色,因为它在源请求和目标地址之间创建了一个加密的障碍。甚至在意图偷窥你数据的对手控制了出口节点的情况下,在他们没有完全控制整个 Tor 中继链的情况下仍然无法知道请求源在哪里。 @@ -30,81 +27,68 @@ Tor 项目尝试去提供一个解决这种问题的方案,使它们不可能 #### 考虑去做 Tor 中继时要记住的一些事情 -一个 Tor 中继节点仅发送和接收加密流量 —— 它从不访问任何其它站点或者在线资源,因此你不用担心有人会利用你的家庭 IP 地址去直接浏览一些令人担心的站点。话虽如此,但是如果你居住在一个提供匿名增强服务(anonymity-enhancing services)是违法行为的司法管辖区的话,那么你还是不要运营你的 Tor 中继节点了。你还需要去查看你的因特网服务提供商的服务条款是否允许你去运营一个 Tor 中继。 +一个 Tor 中继节点仅发送和接收加密流量 —— 它从不访问任何其它站点或者在线资源,因此你不用担心有人会利用你的家庭 IP 地址去直接浏览一些令人担心的站点。话虽如此,但是如果你居住在一个提供匿名增强服务anonymity-enhancing services是违法行为的司法管辖区的话,那么你还是不要运营你的 Tor 中继节点了。你还需要去查看你的互联网服务提供商的服务条款是否允许你去运营一个 Tor 中继。 ### 需要哪些东西 * 一个带完整外围附件的树莓派(任何型号/代次都行) - * 一张有 [Raspbian Stretch Lite][4] 的 SD 卡 - * 一根以太网线缆 - * 一根用于供电的 micro-USB 线缆 - * 一个键盘和带 HDMI 接口的显示器(在配置期间使用) - - - 本指南假设你已经配置好了你的家庭网络连接的线缆或者 ADSL 路由器,它用于运行 NAT 转换(它几乎是必需的)。大多数型号的树莓派都有一个可用于为树莓派供电的 USB 端口,如果你只是使用路由器的 WiFi 功能,那么路由器应该有空闲的以太网口。但是在我们将树莓派设置为一个“配置完不管”的 Tor 中继之前,我们还需要一个键盘和显示器。 ### 引导脚本 -我改编了一个很流行的 Tor 中继节点引导脚本以适配树莓派上使用 —— 你可以在我的 GitHub 仓库 上找到它。你用它引导树莓派并使用缺省的用户 “pi” 登入之后,做如下的工作: +我改编了一个很流行的 Tor 中继节点引导脚本以适配树莓派上使用 —— 你可以在我的 GitHub 仓库 上找到它。你用它引导树莓派并使用缺省的用户 `pi` 登入之后,做如下的工作: + ``` sudo apt-get install -y git git clone https://github.com/mricon/tor-relay-bootstrap-rpi cd tor-relay-bootstrap-rpi sudo ./bootstrap.sh - ``` 这个脚本将做如下的工作: 1. 安装最新版本的操作系统更新以确保树莓派打了所有的补丁 - 2. 将系统配置为无人值守自动更新,以确保有可用更新时会自动接收并安装 - 3. 安装 Tor 软件 + 4. 告诉你的 NAT 路由器去转发所需要的端口(端口一般是 443 和 8080,因为这两个端口最不可能被互联网提供商过滤掉)上的数据包到你的中继节点 - 4. 告诉你的 NAT 路由器去转发所需要的端口(端口一般是 443 和 8080,因为这两个端口最不可能被因特网提供商过滤掉)上的数据包到你的中继节点 - - - - -脚本运行完成后,你需要去配置 torrc 文件 —— 但是首先,你需要决定打算贡献给 Tor 流量多大带宽。首先,在 Google 中输入 “[Speed Test][5]”,然后点击 “Run Speed Test” 按钮。你可以不用管 “Download speed” 的结果,因为你的 Tor 中继能处理的速度不会超过最大的上行带宽。 +脚本运行完成后,你需要去配置 `torrc` 文件 —— 但是首先,你需要决定打算贡献给 Tor 流量多大带宽。首先,在 Google 中输入 “[Speed Test][5]”,然后点击 “Run Speed Test” 按钮。你可以不用管 “Download speed” 的结果,因为你的 Tor 中继能处理的速度不会超过最大的上行带宽。 所以,将 “Mbps upload” 的数字除以 8,然后再乘以 1024,结果就是每秒多少 KB 的宽带速度。比如,如果你得到的上行带宽是 21.5 Mbps,那么这个数字应该是: + ``` 21.5 Mbps / 8 * 1024 = 2752 KBytes per second - ``` -你可以限制你的中继带宽为那个数字的一半,并允许突发带宽为那个数字的四分之三。确定好之后,使用喜欢的文本编辑器打开 /etc/tor/torrc 文件,调整好带宽设置。 +你可以限制你的中继带宽为那个数字的一半,并允许突发带宽为那个数字的四分之三。确定好之后,使用喜欢的文本编辑器打开 `/etc/tor/torrc` 文件,调整好带宽设置。 + ``` RelayBandwidthRate 1300 KBytes RelayBandwidthBurst 2400 KBytes - ``` 当然,如果你想更慷慨,你可以将那几个设置的数字调的更大,但是尽量不要设置为最大的出口带宽 —— 如果设置的太高,它会影响你的日常使用。 你打开那个文件之后,你应该去设置更多的东西。首先是昵称 —— 只是为了你自己保存记录,第二个是联系信息,只需要一个电子邮件地址。由于你的中继是运行在无人值守模式下的,你应该使用一个定期检查的电子邮件地址 —— 如果你的中继节点离线超过 48 个小时,你将收到 “Tor Weather” 服务的告警信息。 + ``` Nickname myrpirelay ContactInfo you@example.com - ``` 保存文件并重引导系统去启动 Tor 中继。 ### 测试它确认有 Tor 流量通过 -如果你想去确认中继节点的功能,你可以运行 “arm” 工具: +如果你想去确认中继节点的功能,你可以运行 `arm` 工具: + ``` sudo -u debian-tor arm - ``` 它需要一点时间才显示,尤其是在老板子上。它通常会给你显示一个表示入站和出站流量(或者是错误信息,它将有助于你去排错)的柱状图。 @@ -120,7 +104,7 @@ via: https://www.linux.com/blog/intro-to-linux/2018/6/turn-your-raspberry-pi-tor 作者:[Konstantin Ryabitsev][a] 选题:[lujun9972](https://github.com/lujun9972) 译者:[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/) 荣誉推出 diff --git a/published/20180615 BLUI- An easy way to create game UI.md b/published/20180615 BLUI- An easy way to create game UI.md new file mode 100644 index 0000000000..f6514e9578 --- /dev/null +++ b/published/20180615 BLUI- An easy way to create game UI.md @@ -0,0 +1,59 @@ +BLUI:创建游戏 UI 的简单方法 +====== + +> 开源游戏开发插件运行虚幻引擎的用户使用基于 Web 的编程方式创建独特的用户界面元素。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/gaming_plugin_blui_screenshot.jpg?itok=91nnYCt_) + +游戏开发引擎在过去几年中变得越来越易于​​使用。像 Unity 这样一直免费使用的引擎,以及最近从基于订阅的服务切换到免费服务的虚幻引擎Unreal Engine,允许独立开发者使用 AAA 发行商相同达到行业标准的工具。虽然这些引擎都不是开源的,但每个引擎都能够促进其周围的开源生态系统的发展。 + +这些引擎中可以包含插件以允许开发人员通过添加特定程序来增强引擎的基本功能。这些程序的范围可以从简单的资源包到更复杂的事物,如人工智能 (AI) 集成。这些插件来自不同的创作者。有些是由引擎开发工作室和有些是个人提供的。后者中的很多是开源插件。 + +### 什么是 BLUI? + +作为独立游戏开发工作室的一员,我体验到了在专有游戏引擎上使用开源插件的好处。Aaron Shea 开发的一个开源插件 [BLUI][1] 对我们团队的开发过程起到了重要作用。它允许我们使用基于 Web 的编程(如 HTML/CSS 和 JavaScript)创建用户界面 (UI) 组件。尽管虚幻引擎Unreal Engine(我们选择的引擎)有一个实现了类似目的的内置 UI 编辑器,我们也选择使用这个开源插件。我们选择使用开源替代品有三个主要原因:它们的可访问性、易于实现以及伴随的开源程序活跃的、支持性好的在线社区。 + +在虚幻引擎的最早版本中,我们在游戏中创建 UI 的唯一方法是通过引擎的原生 UI 集成,使用 Autodesk 的 Scaleform 程序,或通过在虚幻社区中传播的一些选定的基于订阅的虚幻引擎集成。在这些情况下,这些解决方案要么不能为独立开发者提供有竞争力的 UI 解决方案,对于小型团队来说太昂贵,要么只能为大型团队和 AAA 开发者提供。 + +在商业产品和虚幻引擎的原生整合失败后,我们向独立社区寻求解决方案。我们在那里发现了 BLUI。它不仅与虚幻引擎无缝集成,而且还保持了一个强大且活跃的社区,经常推出更新并确保独立开发人员可以轻松访问文档。BLUI 使开发人员能够将 HTML 文件导入虚幻引擎,并在程序内部对其进行编程。这使得通过 web 语言创建的 UI 能够集成到游戏的代码、资源和其他元素中,并拥有所有 HTML、CSS、Javascript 和其他网络语言的能力。它还为开源 [Chromium Embedded Framework][2] 提供全面支持。 + +### 安装和使用 BLUI + +使用 BLUI 的基本过程包括首先通过 HTML 创建 UI。开发人员可以使用任何工具来实现此目的,包括自举bootstrapped JavaScript 代码、外部 API 或任何数据库代码。一旦这个 HTML 页面完成,你可以像安装任何虚幻引擎插件那样安装它,并加载或创建一个项目。项目加载后,你可以将 BLUI 函数放在虚幻引擎 UI 图纸中的任何位置,或者通过 C++ 进行硬编码。开发人员可以通过其 HTML 页面调用函数,或使用 BLUI 的内部函数轻松更改变量。 + +![Integrating BLUI into Unreal Engine 4 blueprints][4] + +*将 BLUI 集成到虚幻 4 图纸中。* + +在我们当前的项目中,我们使用 BLUI 将 UI 元素与游戏中的音轨同步,为游戏机制的节奏方面提供视觉反馈。将定制引擎编程与 BLUI 插件集成很容易。 + +![Using BLUI to sync UI elements with the soundtrack.][6] + +*使用 BLUI 将 UI 元素与音轨同步。* + +通过 BLUI GitHub 页面上的[文档][7],将 BLUI 集成到虚幻 4 中是一个轻松的过程。还有一个由支持虚幻引擎开发人员组成的[论坛][8],他们乐于询问和回答关于插件以及实现该工具时出现的任何问题。 + +### 开源优势 + +开源插件可以在专有游戏引擎的范围内扩展创意。他们继续降低进入游戏开发的障碍,并且可以产生前所未有的游戏内的机制和资源。随着对专有游戏开发引擎的访问持续增长,开源插件社区将变得更加重要。不断增长的创造力必将超过专有软件,开源代码将会填补这些空白,并促进开发真正独特的游戏。而这种新颖性正是让独立游戏如此美好的原因! + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/6/blui-game-development-plugin + +作者:[Uwana lkaiddi][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/uwikaiddi +[1]:https://github.com/AaronShea/BLUI +[2]:https://bitbucket.org/chromiumembedded/cef +[3]:/file/400616 +[4]:https://opensource.com/sites/default/files/uploads/blui_gaming_plugin-integratingblui.png (Integrating BLUI into Unreal Engine 4 blueprints) +[5]:/file/400621 +[6]:https://opensource.com/sites/default/files/uploads/blui_gaming_plugin-syncui.png (Using BLUI to sync UI elements with the soundtrack.) +[7]:https://github.com/AaronShea/BLUI/wiki +[8]:https://forums.unrealengine.com/community/released-projects/29036-blui-open-source-html5-js-css-hud-ui diff --git a/published/20180618 5 open source alternatives to Dropbox.md b/published/20180618 5 open source alternatives to Dropbox.md new file mode 100644 index 0000000000..e181b37ca5 --- /dev/null +++ b/published/20180618 5 open source alternatives to Dropbox.md @@ -0,0 +1,122 @@ +可代替 Dropbox 的 5 个开源软件 +===== + +> 寻找一个不会破坏你的安全、自由或银行资产的文件共享应用。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/dropbox.jpg?itok=qFwcqboT) + +Dropbox 在文件共享应用中是个 800 磅的大猩猩。尽管它是个极度流行的工具,但你可能仍想使用一个软件去替代它。 + +也行你出于各种好的理由,包括安全和自由,这使你决定用[开源方式][1]。亦或是你已经被数据泄露吓坏了,或者定价计划不能满足你实际需要的存储量。 + +幸运的是,有各种各样的开源文件共享应用,可以提供给你更多的存储容量,更好的安全性,并且以低于 Dropbox 很多的价格来让你掌控你自己的数据。有多低呢?如果你有一定的技术和一台 Linux 服务器可供使用,那尝试一下免费的应用吧。 + +这里有 5 个最好的可以代替 Dropbox 的开源应用,以及其他一些,你可能想考虑使用。 + +### ownCloud + +![](https://opensource.com/sites/default/files/uploads/owncloud.png) + +[ownCloud][2] 发布于 2010 年,是本文所列应用中最老的,但是不要被这件事蒙蔽:它仍然十分流行(根据该公司统计,有超过 150 万用户),并且由由 1100 个参与者的社区积极维护,定期发布更新。 + +它的主要特点——文件共享和文档写作功能和 Dropbox 的功能相似。它们的主要区别(除了它的[开源协议][3])是你的文件可以托管在你的私人 Linux 服务器或云上,给予用户对自己数据完全的控制权。(自托管是本文所列应用的一个普遍的功能。) + +使用 ownCloud,你可以通过 Linux、MacOS 或 Windows 的客户端和安卓、iOS 的移动应用程序来同步和访问文件。你还可以通过带有密码保护的链接分享给其他人来协作或者上传和下载。数据传输通过端到端加密(E2EE)和 SSL 加密来保护安全。你还可以通过使用它的 [市场][4] 中的各种各样的第三方应用来扩展它的功能。当然,它也提供付费的、商业许可的企业版本。 + +ownCloud 提供了详尽的[文档][5],包括安装指南和针对用户、管理员、开发者的手册。你可以从 GitHub 仓库中获取它的[源码][6]。 + +### NextCloud + +![](https://opensource.com/sites/default/files/uploads/nextcloud.png) + +[NextCloud][7] 在 2016 年从 ownCloud 分裂出来,并且具有很多相同的功能。 NextCloud 以它的高安全性和法规遵从性作为它的一个独特的[推崇的卖点][8]。它具有 HIPAA (医疗) 和 GDPR (隐私)法规遵从功能,并提供广泛的数据策略约束、加密、用户管理和审核功能。它还在传输和存储期间对数据进行加密,并且集成了移动设备管理和身份验证机制 (包括 LDAP/AD、单点登录、双因素身份验证等)。 + +像本文列表里的其他应用一样, NextCloud 是自托管的,但是如果你不想在自己的 Linux 上安装 NextCloud 服务器,该公司与几个[提供商][9]达成了伙伴合作,提供安装和托管,并销售服务器、设备和服务支持。在[市场][10]中提供了大量的apps 来扩展它的功能。 + +NextCloud 的[文档][11]为用户、管理员和开发者提供了详细的信息,并且它的论坛、IRC 频道和社交媒体提供了基于社区的支持。如果你想贡献或者获取它的源码、报告一个错误、查看它的 AGPLv3 许可,或者想了解更多,请访问它的[GitHub 项目主页][12]。 + +### Seafile + +![](https://opensource.com/sites/default/files/uploads/seafile.png) + +与 ownCloud 或 NextCloud 相比,[Seafile][13] 或许没有花里胡哨的卖点(app 生态),但是它能完成任务。实质上, 它充当了 Linux 服务器上的虚拟驱动器,以扩展你的桌面存储,并允许你使用密码保护和各种级别的权限(即只读或读写) 有选择地共享文件。 + +它的协作功能包括文件夹权限控制,密码保护的下载链接和像 Git 一样的版本控制和记录。文件使用双因素身份验证、文件加密和 AD/LDAP 集成进行保护,并且可以从 Windows、MacOS、Linux、iOS 或 Android 设备进行访问。 + +更多详细信息, 请访问 Seafile 的 [GitHub 仓库][14]、[服务手册][15]、[wiki][16] 和[论坛][17]。请注意, Seafile 的社区版在 [GPLv2][18] 下获得许可,但其专业版不是开源的。 + +### OnionShare + +![](https://opensource.com/sites/default/files/uploads/onionshare.png) + +[OnionShare][19] 是一个很酷的应用:如果你想匿名,它允许你安全地共享单个文件或文件夹。不需要设置或维护服务器,所有你需要做的就是[下载和安装][20],无论是在 MacOS, Windows 还是 Linux 上。文件始终在你自己的计算机上; 当你共享文件时,OnionShare 创建一个 web 服务器,使其可作为 Tor 洋葱服务访问,并生成一个不可猜测的 .onion URL,这个 URL 允许收件人通过 [Tor 浏览器][21]获取文件。 + +你可以设置文件共享的限制,例如限制可以下载的次数或使用自动停止计时器,这会设置一个严格的过期日期/时间,超过这个期限便不可访问(即使尚未访问该文件)。 + +OnionShare 在 [GPLv3][22] 之下被许可;有关详细信息,请查阅其 [GitHub 仓库][22],其中还包括[文档][23],介绍了这个易用的文件共享软件的特点。 + +### Pydio Cells + +![](https://opensource.com/sites/default/files/uploads/pydiochat.png) + +[Pydio Cells][24] 在 2018 年 5 月推出了稳定版,是对 Pydio 共享应用程序的核心服务器代码的彻底大修。由于 Pydio 的基于 PHP 的后端的限制,开发人员决定用 Go 服务器语言和微服务体系结构重写后端。(前端仍然是基于 PHP 的)。 + +Pydio Cells 包括通常的共享和版本控制功能,以及应用程序中的消息接受、移动应用程序(Android 和 iOS),以及一种社交网络风格的协作方法。安全性包括基于 OpenID 连接的身份验证、rest 加密、安全策略等。企业发行版中包含着高级功能,但在社区(家庭)版本中,对于大多数中小型企业和家庭用户来说,依然是足够的。 + +您可以 在 Linux 和 MacOS 里[下载][25] Pydio Cells。有关详细信息, 请查阅 [文档常见问题][26]、[源码库][27] 和 [AGPLv3 许可证][28] + +### 其他 + +如果以上选择不能满足你的需求,你可能想考虑其他开源的文件共享型应用。 + +* 如果你的主要目的是在设备间同步文件而不是分享文件,考察一下 [Syncthing][29]。 +* 如果你是一个 Git 的粉丝而不需要一个移动应用。你可能更喜欢 [SparkleShare][30]。 +* 如果你主要想要一个地方聚合所有你的个人数据, 看看 [Cozy][31]。 +* 如果你想找一个轻量级的或者专注于文件共享的工具,考察一下 [Scott Nesbitt's review][32]——一个罕为人知的工具。 + +哪个是你最喜欢的开源文件共享应用?在评论中让我们知悉。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/alternatives/dropbox + +作者:[Opensource.com][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[distant1219](https://github.com/distant1219) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com +[1]:https://opensource.com/open-source-way +[2]:https://owncloud.org/ +[3]:https://www.gnu.org/licenses/agpl-3.0.html +[4]:https://marketplace.owncloud.com/ +[5]:https://doc.owncloud.com/ +[6]:https://github.com/owncloud +[7]:https://nextcloud.com/ +[8]:https://nextcloud.com/secure/ +[9]:https://nextcloud.com/providers/ +[10]:https://apps.nextcloud.com/ +[11]:https://nextcloud.com/support/ +[12]:https://github.com/nextcloud +[13]:https://www.seafile.com/en/home/ +[14]:https://github.com/haiwen/seafile +[15]:https://manual.seafile.com/ +[16]:https://seacloud.cc/group/3/wiki/ +[17]:https://forum.seafile.com/ +[18]:https://github.com/haiwen/seafile/blob/master/LICENSE.txt +[19]:https://onionshare.org/ +[20]:https://onionshare.org/#downloads +[21]:https://www.torproject.org/ +[22]:https://github.com/micahflee/onionshare/blob/develop/LICENSE +[23]:https://github.com/micahflee/onionshare/wiki +[24]:https://pydio.com/en +[25]:https://pydio.com/download/ +[26]:https://pydio.com/en/docs/faq +[27]:https://github.com/pydio/cells +[28]:https://github.com/pydio/pydio-core/blob/develop/LICENSE +[29]:https://syncthing.net/ +[30]:http://www.sparkleshare.org/ +[31]:https://cozy.io/en/ +[32]:https://opensource.com/article/17/3/file-sharing-tools diff --git a/published/20180619 Getting started with Open edX to host your course.md b/published/20180619 Getting started with Open edX to host your course.md new file mode 100644 index 0000000000..7324079e8f --- /dev/null +++ b/published/20180619 Getting started with Open edX to host your course.md @@ -0,0 +1,91 @@ +使用 Open edX 托管课程 +====== + +> Open edX 为各种规模和类型的组织提供了一个强大而多功能的开源课程管理的解决方案。要不要了解一下。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003588_01_rd3os.combacktoschoolseriesgen_rh_032x_0.png?itok=cApG9aB4) + +[Open edX 平台][2] 是一个自由开源的课程管理系统,它是 [全世界][3] 都在使用的大规模网络公开课(MOOC)以及小型课程和培训模块的托管平台。在 Open edX 的 [第七个主要发行版][1] 中,到现在为止,它已经提供了超过 8,000 个原创课程和 5000 万个课程注册数。你可以使用你自己的本地设备或者任何行业领先的云基础设施服务提供商来安装这个平台,而且,随着项目的[服务提供商][4]名单越来越长,来自它们中的软件即服务(SaaS)的可用模型也越来越多了。 + +Open edX 平台被来自世界各地的顶尖教育机构、私人公司、公共机构、非政府组织、非营利机构,以及教育技术初创企业广泛地使用,并且该项目的服务提供商全球社区不断地让甚至更小的组织也可以访问这个平台。如果你打算向广大的读者设计和提供教育内容,你应该考虑去使用 Open edX 平台。 + +### 安装 + +安装这个软件有多种方式,这可能有点让你难以选择,至少刚开始是这样。但是不管你是以何种方式 [安装 Open edX][5],最终你都得到的是有相同功能的应用程序。默认安装包含一个为在线学习者提供的、全功能的学习管理系统(LMS),和一个全功能的课程管理工作室(CMS),CMS 可以让你的讲师团队用它来编写原创课程内容。你可以把 CMS 当做是课程内容设计和管理的 “[Wordpress][6]”,把 LMS 当做是课程销售、分发、和消费的 “[Magento][7]”。 + +Open edX 是设备无关的、完全响应式的应用软件,并且不用花费很多的努力就可发布一个原生的 iOS 和 Android 应用,它可以无缝地集成到你的实例后端。Open edX 平台的代码库、原生移动应用、以及安装脚本都发布在 [GitHub][8] 上。 + +#### 有何期望 + +Open edX 平台的 [GitHub 仓库][9] 包含适用于各种类型的组织的、性能很好的、产品级的代码。来自数百个机构的数千名程序员经常为 edX 仓库做贡献,并且这个平台是一个名副其实的、研究如何去构建和管理一个复杂的企业级应用的好案例。因此,尽管你可能会遇到大量的类似“如何将平台迁移到生产环境中”的问题,但是你无需对 Open edX 平台代码库本身的质量和健状性担忧。 + +通过少量的培训,你的讲师就可以去设计不错的在线课程。但是请记住,Open edX 是通过它的 [XBlock][10] 组件架构进行扩展的,因此,通过他们和你的努力,你的讲师将有可能将不错的课程变成精品课程。 + +这个平台在单服务器环境下也运行的很好,并且它是高度模块化的,几乎可以进行无限地水平扩展。它也是主题化的和本地化的,平台的功能和外观可以根据你的需要进行几乎无限制地调整。平台在你的设备上可以按需安装并可靠地运行。 + +#### 需要一些封装 + +请记住,有大量的 edX 软件模块是不包含在默认安装中的,并且这些模块提供的经常都是各种组织所需要的功能。比如,分析模块、电商模块,以及课程的通知/公告模块都是不包含在默认安装中的,并且这些单独的模块都是值得安装的。另外,在数据备份/恢复和系统管理方面要完全依赖你自己去处理。幸运的是,有关这方面的内容,社区有越来越多的文档和如何去做的文章。你可以通过 Google 和 Bing 去搜索,以帮助你在生产环境中安装它们。 + +虽然有很多文档良好的程序,但是根据你的技能水平,配置 [oAuth][11] 和 [SSL/TLS][12],以及使用平台的 [REST API][13] 可能对你是一个挑战。另外,一些组织要求将 MySQL 和/或 MongoDB 数据库在中心化环境中管理,如果你正好是这种情况,你还需要将这些服务从默认平台安装中分离出来。edX 设计团队已经尽可能地为你做了简化,但是由于它是一个非常重大的更改,因此可能需要一些时间去实现。 + +如果你面临资源和/或技术上的困难 —— 不要气馁,Open edX 社区 SaaS 提供商,像 [appsembler][14] 和 [eduNEXT][15],提供了引人入胜的替代方案去进行 DIY 安装,尤其是如果你只想简单购买就行。 + +### 技术栈 + +在 Open edX 平台的安装上探索是件令人兴奋的事情,从架构的角度来说,这个项目是一个典范。应用程序模块是 [Django][16] 应用,它利用了大量的开源社区的顶尖项目,包括 [Ubuntu][17]、[MySQL][18]、[MongoDB][19]、[RabbitMQ][20]、[Elasticsearch][21]、[Hadoop][22]、等等。 + +![edx-architecture.png][24] + +*Open edX 技术栈(CC BY,来自 edX)* + +将这些组件安装并配置好本身就是一件非常不容易的事情,但是以这样的一种方式将所有的组件去打包,并适合于任意规模和复杂性的组织,并且能够按他们的需要进行任意调整搭配而无需在代码上做重大改动,看起来似乎是不可能的事情 —— 它就是这种情况,直到你看到主要的平台配置参数安排和命名是多少的巧妙和直观。请注意,平台的组织结构有一个学习曲线,但是,你所学习的一切都是值的去学习的,不仅是对这个项目,对一般意义上的大型 IT 项目都是如此。 + +提醒一点:这个平台的 UI 是在不断变动的,最终的目标是在 [React][25] 和 [Bootstrap][26] 上实现标准化。与此同时,你将会发现基本主题有多个实现的样式,这可能会让你感到困惑。 + +### 采用 + +edX 项目能够迅速得到世界范围内的采纳,很大程度上取决于该软件的运行情况。这一点也不奇怪,这个项目成功地吸引了大量才华卓越的人参与其中,他们作为程序员、项目顾问、翻译者、技术作者、以及博客作者参与了项目的贡献。一年一次的 [Open edX 会议][27]、[官方的 edX Google Group][28]、以及 [Open edX 服务提供商名单][4] 是了解这个多样化的、不断成长的生态系统的非常好的起点。我作为相对而言的新人,我发现参与和直接从事这个项目的各个方面是非常容易的。 + +祝你学习之旅一切顺利,并且当你构思你的项目时,你可以随时联系我。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/6/getting-started-open-edx + +作者:[Lawrence Mc Daniel][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/mcdaniel0073 +[1]:https://openedx.atlassian.net/wiki/spaces/DOC/pages/11108700/Open+edX+Releases +[2]:https://open.edx.org/about-open-edx +[3]:https://www.edx.org/schools-partners +[4]:https://openedx.atlassian.net/wiki/spaces/COMM/pages/65667081/Open+edX+Service+Providers +[5]:https://openedx.atlassian.net/wiki/spaces/OpenOPS/pages/60227779/Open+edX+Installation+Options +[6]:https://wordpress.com/ +[7]:https://magento.com/ +[8]:https://github.com/edx +[9]:https://github.com/edx/edx-platform +[10]:https://open.edx.org/xblocks +[11]:https://oauth.net/ +[12]:https://en.wikipedia.org/wiki/Transport_Layer_Security +[13]:https://en.wikipedia.org/wiki/Representational_state_transfer +[14]:https://www.appsembler.com/ +[15]:https://www.edunext.co/ +[16]:https://www.djangoproject.com/ +[17]:https://www.ubuntu.com/ +[18]:https://www.mysql.com/ +[19]:https://www.mongodb.com/ +[20]:https://www.rabbitmq.com/ +[21]:https://www.elastic.co/ +[22]:http://hadoop.apache.org/ +[23]:/file/400696 +[24]:https://opensource.com/sites/default/files/uploads/edx-architecture_0.png "edx-architecture.png" +[25]:%E2%80%9Chttps://reactjs.org/%E2%80%9C +[26]:%E2%80%9Chttps://getbootstrap.com/%E2%80%9C +[27]:https://con.openedx.org/ +[28]:https://groups.google.com/forum/#!forum/openedx-ops diff --git a/published/20180619 How To Check Which Groups A User Belongs To On Linux.md b/published/20180619 How To Check Which Groups A User Belongs To On Linux.md new file mode 100644 index 0000000000..97ceab20e2 --- /dev/null +++ b/published/20180619 How To Check Which Groups A User Belongs To On Linux.md @@ -0,0 +1,160 @@ +如何在 Linux 上检查用户所属组 +====== + +将用户添加到现有组是 Linux 管理员的常规活动之一。这是一些在大环境中工作的管理员的日常活动。 + +甚至我会因为业务需求而在我的环境中每天都在进行这样的活动。它是帮助你识别环境中现有组的重要命令之一。 + +此外,这些命令还可以帮助你识别用户所属的组。所有用户都列在 `/etc/passwd` 中,组列在 `/etc/group` 中。 + +无论我们使用什么命令,都将从这些文件中获取信息。此外,每个命令都有其独特的功能,可帮助用户单独获取所需的信息。 + +### 什么是 /etc/passwd? + +`/etc/passwd` 是一个文本文件,其中包含登录 Linux 系统所必需的每个用户信息。它维护有用的用户信息,如用户名、密码、用户 ID、组 ID、用户 ID 信息、家目录和 shell。passwd 每行包含了用户的详细信息,共有如上所述的 7 个字段。 + +``` +$ grep "daygeek" /etc/passwd +daygeek:x:1000:1000:daygeek,,,:/home/daygeek:/bin/bash +``` + +### 什么是 /etc/group? + +`/etc/group` 是一个文本文件,用于定义用户所属的组。我们可以将多个用户添加到单个组中。它允许用户访问其他用户文件和文件夹,因为 Linux 权限分为三类:用户、组和其他。它维护有关组的有用信息,例如组名、组密码,组 ID(GID)和成员列表。每个都在一个单独的行。组文件每行包含了每个组的详细信息,共有 4 个如上所述字段。 + +这可以通过使用以下方法来执行。 + + * `groups`: 显示一个组的所有成员。 + * `id`: 打印指定用户名的用户和组信息。 + * `lid`: 显示用户的组或组的用户。 + * `getent`: 从 Name Service Switch 库中获取条目。 + * `grep`: 代表“全局正则表达式打印global regular expression print”,它能打印匹配的模式。 + +### 什么是 groups 命令? + +`groups` 命令打印每个给定用户名的主要组和任何补充组的名称。 + +``` +$ groups daygeek +daygeek : daygeek adm cdrom sudo dip plugdev lpadmin sambashare +``` + +如果要检查与当前用户关联的组列表。只需运行 `groups` 命令,无需带任何用户名。 + +``` +$ groups +daygeek adm cdrom sudo dip plugdev lpadmin sambashare +``` + +### 什么是 id 命令? + +id 代表 “身份identity”。它打印真实有效的用户和组 ID。打印指定用户或当前用户的用户和组信息。 + +``` +$ id daygeek +uid=1000(daygeek) gid=1000(daygeek) groups=1000(daygeek),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),118(lpadmin),128(sambashare) +``` + +如果要检查与当前用户关联的组列表。只运行 `id` 命令,无需带任何用户名。 + +``` +$ id +uid=1000(daygeek) gid=1000(daygeek) groups=1000(daygeek),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),118(lpadmin),128(sambashare) +``` + +### 什么是 lid 命令? + +它显示用户的组或组的用户。显示有关包含用户名的组或组名称中包含的用户的信息。此命令需要管理员权限。 + +``` +$ sudo lid daygeek + adm(gid=4) + cdrom(gid=24) + sudo(gid=27) + dip(gid=30) + plugdev(gid=46) + lpadmin(gid=108) + daygeek(gid=1000) + sambashare(gid=124) +``` + +### 什么是 getent 命令? + +`getent` 命令显示 Name Service Switch 库支持的数据库中的条目,它们在 `/etc/nsswitch.conf` 中配置。 + +``` +$ getent group | grep daygeek +adm:x:4:syslog,daygeek +cdrom:x:24:daygeek +sudo:x:27:daygeek +dip:x:30:daygeek +plugdev:x:46:daygeek +lpadmin:x:118:daygeek +daygeek:x:1000: +sambashare:x:128:daygeek +``` + +如果你只想打印关联的组名称,请在上面的命令中使用 `awk`。 + +``` +$ getent group | grep daygeek | awk -F: '{print $1}' +adm +cdrom +sudo +dip +plugdev +lpadmin +daygeek +sambashare +``` + +运行以下命令仅打印主群组信息。 + +``` +$ getent group daygeek +daygeek:x:1000: + +``` + +### 什么是 grep 命令? + +`grep` 代表 “全局正则表达式打印global regular expression print”,它能打印文件匹配的模式。 + +``` +$ grep "daygeek" /etc/group +adm:x:4:syslog,daygeek +cdrom:x:24:daygeek +sudo:x:27:daygeek +dip:x:30:daygeek +plugdev:x:46:daygeek +lpadmin:x:118:daygeek +daygeek:x:1000: +sambashare:x:128:daygeek +``` + +如果你只想打印关联的组名称,请在上面的命令中使用 `awk`。 + +``` +$ grep "daygeek" /etc/group | awk -F: '{print $1}' +adm +cdrom +sudo +dip +plugdev +lpadmin +daygeek +sambashare +``` + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/how-to-check-which-groups-a-user-belongs-to-on-linux/ + +作者:[Prakash Subramanian][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/prakash/ diff --git a/translated/tech/20180622 Automatically Change Wallpapers in Linux with Little Simple Wallpaper Changer.md b/published/20180622 Automatically Change Wallpapers in Linux with Little Simple Wallpaper Changer.md similarity index 71% rename from translated/tech/20180622 Automatically Change Wallpapers in Linux with Little Simple Wallpaper Changer.md rename to published/20180622 Automatically Change Wallpapers in Linux with Little Simple Wallpaper Changer.md index 983719867b..69408c1ab1 100644 --- a/translated/tech/20180622 Automatically Change Wallpapers in Linux with Little Simple Wallpaper Changer.md +++ b/published/20180622 Automatically Change Wallpapers in Linux with Little Simple Wallpaper Changer.md @@ -1,17 +1,17 @@ -使用 LSWC(Little Simple Wallpaper Changer) 在 Linux 中自动更改壁纸 +使用 LSWC 在 Linux 中自动更改壁纸 ====== -**简介:这是一个小脚本,可以在 Linux 桌面上定期自动更改壁纸。** +> 简介:这是一个小脚本,可以在 Linux 桌面上定期自动更改壁纸。 -顾名思义,LittleSimpleWallpaperChanger 是一个小脚本,可以定期地随机更改壁纸。 +顾名思义,LittleSimpleWallpaperChanger (LSWC)是一个小脚本,可以定期地随机更改壁纸。 -我知道在“外观”或“更改桌面背景”设置中有一个随机壁纸选项。但那是随机更改预置壁纸而不是你添加的壁纸。 +我知道在“外观”或“更改桌面背景”设置中有一个随机壁纸选项。但那是随机更改预置的壁纸而不是你添加的壁纸。 因此,在本文中,我们将看到如何使用 LittleSimpleWallpaperChanger 设置包含照片的随机桌面壁纸。 ### Little Simple Wallpaper Changer (LSWC) -[LittleSimpleWallpaperChanger][1] 或 LSWC 是一个非常轻量级的脚本,它在后台运行,从用户指定的文件夹中更改壁纸。壁纸以 1 至 5 分钟的随机间隔变化。该软件设置起来相当简单,设置完后,用户就可以忘掉它。 +[LittleSimpleWallpaperChanger][1] (LSWC) 是一个非常轻量级的脚本,它在后台运行,从用户指定的文件夹中更改壁纸。壁纸以 1 至 5 分钟的随机间隔变化。该软件设置起来相当简单,设置完后,用户就可以不用再操心了。 ![Little Simple Wallpaper Changer to change wallpapers in Linux][2] @@ -22,13 +22,10 @@ * 进入下载位置。 * 右键单击下载的 .zip 文件,然后选择“在此处解压”。 * 打开解压后的文件夹,右键单击并选择“在终端中打开”。 - * 在终端中复制粘贴命令并按 Enter 键。 -`bash ./README_and_install.sh` + * 在终端中复制粘贴命令 `bash ./README_and_install.sh` 并按回车键。 * 然后会弹出一个对话框,要求你选择包含壁纸的文件夹。单击它,然后选择你存放壁纸的文件夹。 * 就是这样。然后重启计算机。 - - ![Little Simple Wallpaper Changer for Linux][4] #### 使用 LSWC @@ -36,26 +33,24 @@ 安装时,LSWC 会要求你选择包含壁纸的文件夹。因此,我建议你在安装 LSWC 之前创建一个文件夹并将你想要的壁纸全部移动到那。或者你可以使用图片文件夹中的“壁纸”文件夹。**所有壁纸都必须是 .jpg 格式。** 你可以添加更多壁纸或从所选文件夹中删除当前壁纸。要更改壁纸文件夹位置,你可以从以下文件中编辑壁纸的位置。 + ``` .config/lswc/homepath.conf - ``` #### 删除 LSWC -打开终端并运行以下命令以停止 LSWC +打开终端并运行以下命令以停止 LSWC: + ``` pkill lswc - ``` -在文件管理器中打开家目录,然后按 ctrl+H 显示隐藏文件,接着删除以下文件: - - * .local 中的 “scripts” 文件夹 - * .config 中的 “lswc” 文件夹 - * .config/autostart 中的 “lswc.desktop” 文件 - +在文件管理器中打开家目录,然后按 `Ctrl+H` 显示隐藏文件,接着删除以下文件: + * `.local` 中的 `scripts` 文件夹 + * `.config` 中的 `lswc` 文件夹 + * `.config/autostart` 中的 `lswc.desktop` 文件 这就完成了。创建自己的桌面背景幻灯片。LSWC 非常轻巧,易于使用。安装它然后忘记它。 @@ -70,7 +65,7 @@ via: https://itsfoss.com/little-simple-wallpaper-changer/ 作者:[Aquil Roshan][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/) 荣誉推出 diff --git a/published/20180625 How To Upgrade Everything Using A Single Command In Linux.md b/published/20180625 How To Upgrade Everything Using A Single Command In Linux.md new file mode 100644 index 0000000000..8ef6fb9ff8 --- /dev/null +++ b/published/20180625 How To Upgrade Everything Using A Single Command In Linux.md @@ -0,0 +1,120 @@ +如何在 Linux 中使用一个命令升级所有软件 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/06/topgrade-720x340.png) + +众所周知,让我们的 Linux 系统保持最新状态会用到多种包管理器。比如说,在 Ubuntu 中,你无法使用 `sudo apt update` 和 `sudo apt upgrade` 命令升级所有软件。此命令仅升级使用 APT 包管理器安装的应用程序。你有可能使用 `cargo`、[pip][1]、`npm`、`snap` 、`flatpak` 或 [Linuxbrew][2] 包管理器安装了其他软件。你需要使用相应的包管理器才能使它们全部更新。 + +再也不用这样了!跟 `topgrade` 打个招呼,这是一个可以一次性升级系统中所有软件的工具。 + +你无需运行每个包管理器来更新包。这个 `topgrade` 工具通过检测已安装的软件包、工具、插件并运行相应的软件包管理器来更新 Linux 中的所有软件,用一条命令解决了这个问题。它是自由而开源的,使用 **rust 语言**编写。它支持 GNU/Linux 和 Mac OS X. + +### 在 Linux 中使用一个命令升级所有软件 + +`topgrade` 存在于 AUR 中。因此,你可以在任何基于 Arch 的系统中使用 [Yay][3] 助手程序安装它。 + +``` +$ yay -S topgrade +``` + +在其他 Linux 发行版上,你可以使用 `cargo` 包管理器安装 `topgrade`。要安装 cargo 包管理器,请参阅以下链接: + +- [在 Linux 安装 rust 语言][12] + +然后,运行以下命令来安装 `topgrade`。 + +``` +$ cargo install topgrade +``` + +安装完成后,运行 `topgrade` 以升级 Linux 系统中的所有软件。 + +``` +$ topgrade +``` + +一旦调用了 `topgrade`,它将逐个执行以下任务。如有必要,系统会要求输入 root/sudo 用户密码。 + +1、 运行系统的包管理器: + + * Arch:运行 `yay` 或者回退到 [pacman][4] + * CentOS/RHEL:运行 `yum upgrade` + * Fedora :运行 `dnf upgrade` + * Debian/Ubuntu:运行 `apt update` 和 `apt dist-upgrade` + * Linux/macOS:运行 `brew update` 和 `brew upgrade` + +2、 检查 Git 是否跟踪了以下路径。如果有,则拉取它们: + + * `~/.emacs.d` (无论你使用 Spacemacs 还是自定义配置都应该可用) + * `~/.zshrc` + * `~/.oh-my-zsh` + * `~/.tmux` + * `~/.config/fish/config.fish` + * 自定义路径 + +3、 Unix:运行 `zplug` 更新 + +4、 Unix:使用 TPM 升级 `tmux` 插件 + +5、 运行 `cargo install-update` + +6、 升级 Emacs 包 + +7、 升级 Vim 包。对以下插件框架均可用: + + * NeoBundle + * [Vundle][5] + * Plug + +8、 升级 [npm][6] 全局安装的包 + +9、 升级 Atom 包 + +10、 升级 [Flatpak][7] 包 + +11、 升级 [snap][8] 包 + +12、 Linux:运行 `fwupdmgr` 显示固件升级。 (仅查看​​。实际不会执行升级) + +13、 运行自定义命令。 + +最后,`topgrade` 将运行 `needrestart` 以重新启动所有服务。在 Mac OS X 中,它会升级 App Store 程序。 + +我的 Ubuntu 18.04 LTS 测试环境的示例输出: + +![][10] + +好处是如果一个任务失败,它将自动运行下一个任务并完成所有其他后续任务。最后,它将显示摘要,其中包含运行的任务数量,成功的数量和失败的数量等详细信息。 + +![][11] + +**建议阅读:** + +就个人而言,我喜欢创建一个像 `topgrade` 程序的想法,并使用一个命令升级使用各种包管理器安装的所有软件。我希望你也觉得它有用。还有更多的好东西。敬请关注! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-upgrade-everything-using-a-single-command-in-linux/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/ +[1]:https://www.ostechnix.com/manage-python-packages-using-pip/ +[2]:https://www.ostechnix.com/linuxbrew-common-package-manager-linux-mac-os-x/ +[3]:https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/ +[4]:https://www.ostechnix.com/getting-started-pacman/ +[5]:https://www.ostechnix.com/manage-vim-plugins-using-vundle-linux/ +[6]:https://www.ostechnix.com/manage-nodejs-packages-using-npm/ +[7]:https://www.ostechnix.com/flatpak-new-framework-desktop-applications-linux/ +[8]:https://www.ostechnix.com/install-snap-packages-arch-linux-fedora/ +[9]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[10]:http://www.ostechnix.com/wp-content/uploads/2018/06/topgrade-1.png +[11]:http://www.ostechnix.com/wp-content/uploads/2018/06/topgrade-2.png +[12]:https://www.ostechnix.com/install-rust-programming-language-in-linux/ \ No newline at end of file diff --git a/published/20180625 How to install Pipenv on Fedora.md b/published/20180625 How to install Pipenv on Fedora.md new file mode 100644 index 0000000000..3e95f2b089 --- /dev/null +++ b/published/20180625 How to install Pipenv on Fedora.md @@ -0,0 +1,92 @@ +如何在 Fedora 上安装 Pipenv +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/06/pipenv-install-816x345.jpg) + +Pipenv 的目标是将打包界(bundler、composer、npm、cargo、yarn 等)最好的东西带到 Python 世界来。它试图解决一些问题,并简化整个管理过程。 + +目前,Python 程序依赖项的管理有时似乎是一个挑战。开发人员通常为每个新项目创建一个[虚拟环境][1],并使用 [pip][2] 将依赖项安装到其中。此外,他们必须将已安装的软件包的集合保存到 `requirements.txt` 文件中。我们看到过许多旨在自动化此工作流程的工具和包装程序。但是,仍然需要结合多个程序,并且 `requirements.txt` 格式本身并不适用于更复杂的场景。 + +### 一个统治它们的工具 + +Pipenv 可以正确地管理复杂的相互依赖关系,它还提供已安装包的手动记录。例如,开发、测试和生产环境通常需要一组不同的包。过去,每个项目需要维护多个 `requirements.txt`。Pipenv 使用 [TOML][4] 语法引入了新的 [Pipfile][3] 格式。多亏这种格式,你终于可以在单个文件中维护不同环境的多组需求。 + +在将第一行代码提交到项目中仅一年后,Pipenv 已成为管理 Python 程序依赖关系的官方推荐工具。现在它终于在 Fedora 仓库中提供。 + +### 在 Fedora 上安装 Pipenv + +在全新安装 Fedora 28 及更高版本后,你只需在终端上运行此命令即可安装 Pipenv: + +``` +$ sudo dnf install pipenv +``` + +现在,你的系统已准备好在 Pipenv 的帮助下开始使用新的 Python 3 程序。 + +重要的是,虽然这个工具为程序提供了很好的解决方案,但它并不是为处理库需求而设计的。编写 Python 库时,不需要固定依赖项。你应该在 `setup.py` 文件中指定 `install_requires`。 + +### 基本依赖管理 + +首先为项目创建一个目录: + +``` +$ mkdir new-project && cd new-project +``` + +接下来是为此项目创建虚拟环境: + +``` +$ pipenv --three +``` + +这里的 `-three` 选项将虚拟环境的 Python 版本设置为 Python 3。 + +安装依赖项: + +``` +$ pipenv install requests +Installing requests… +Adding requests to Pipfile's [packages]… +Pipfile.lock not found, creating… +Locking [dev-packages] dependencies… +Locking [packages] dependencies… +``` + +最后生成 lockfile: + +``` +$ pipenv lock +Locking [dev-packages] dependencies… +Locking [packages] dependencies… +Updated Pipfile.lock (b14837) +``` + +你还可以检查依赖关系图: + +``` +$ pipenv graph +- certifi [required: >=2017.4.17, installed: 2018.4.16] +- chardet [required: <3.1.0,>=3.0.2, installed: 3.0.4] +- idna [required: <2.8,>=2.5, installed: 2.7] +- urllib3 [required: >=1.21.1,<1.24, installed: 1.23] +``` + +有关 Pipenv 及其命令的更多详细信息,请参见[文档][5]。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/install-pipenv-fedora/ + +作者:[Michal Cyprian][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org/author/mcyprian/ +[1]:https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments +[2]:https://developer.fedoraproject.org/tech/languages/python/pypi-installation.html +[3]:https://github.com/pypa/pipfile +[4]:https://github.com/toml-lang/toml +[5]:https://docs.pipenv.org/ diff --git a/published/20180626 TrueOS Doesnt Want to Be BSD for Desktop Anymore.md b/published/20180626 TrueOS Doesnt Want to Be BSD for Desktop Anymore.md new file mode 100644 index 0000000000..6df9fe975b --- /dev/null +++ b/published/20180626 TrueOS Doesnt Want to Be BSD for Desktop Anymore.md @@ -0,0 +1,73 @@ +TrueOS 不再想要成为“桌面 BSD”了 +============================================================ + + +[TrueOS][9] 很快会有一些非常重大的变化。今天,我们将了解桌面 BSD 领域将会发生什么。 + +### 通告 + +![TrueOS: Core Operating System BSD](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/true-os-bsd-desktop.jpeg) + +[TrueOS][10] 背后的团队[宣布][11],他们将改变项目的重点。到目前为止,TrueOS 使用开箱即用的图形用户界面来轻松安装 BSD。然而,它现在将成为“一个先进的操作系统,保留你所知道和喜欢的 ZFS([OpenZFS][12])和 [FreeBSD][13]的所有稳定性,并添加额外的功能来创造一个全新的、创新的操作系统。我们的目标是创建一个核心操作系统,该系统具有模块化、实用性,非常适合自己动手和高级用户。“ + +从本质上讲,TrueOs 将成为 FreeBSD 的下游分支。他们将集成更新一些的软件到系统中,例如 [OpenRC][14] 和 [LibreSSL][15]。他们希望能坚持 6 个月的发布周期。 + +其目标是使 TrueOS 成为可以作为其他项目构建的基础。缺少图形部分以使其更加地与发行版无关。 + +### 桌面用户如何? + +如果你读过我的[TrueOS 评论][17]并且有兴趣尝试使用桌面 BSD 或已经使用 TrueOS,请不要担心(这对于生活来说也是一个很好的建议)。TrueOS 的所有桌面元素都将剥离到 [Project Trident][18]。目前,Project Trident 网站的细节不多。他们仿佛还在进行剥离的幕后工作。 + +如果你目前拥有 TrueOS,则无需担心迁移。TrueOS 团队表示,“对于那些希望迁移到其他基于 FreeBSD 的发行版,如 Project Trident 或 [GhostBSD][19] 的人而言将会有迁移方式。” + +### 想法 + +当我第一次阅读该公告时,坦率地说有点担心。改变名字可能是一个坏主意。客户将习惯使用一个名称,但如果产品名称发生变化,他们可能很容易失去对项目的跟踪。TrueOS 经历过名称更改。该项目于 2006 年启动时,它被命名为 PC-BSD,但在 2016 年,名称更改为 TrueOS。它让我想起了[ArchMerge 和 Arcolinux 传奇][21]。 + +话虽这么说,我认为这对 BSD 的桌面用户来说是一件好事。我常听见对 PC-BSD 和 TrueOS 的一个批评是它不是很精致。剥离项目的两个部分将有助于提高相关开发人员的关注度。TrueOS 团队将能够为缓慢进展的 FreeBSD 添加更新的功能,Project Trident 团队将能够改善用户的桌面体验。 + +我希望两个团队都好。请记住,当有人为开源而努力时,即使是我们不会使用的部分,我们也都会受益。 + +你对 TrueOS 和 Project Trident 的未来有何看法?请在下面的评论中告诉我们。 + + +------------------------------ + +关于作者: + +我叫 John Paul Wohlscheid。我是一个有抱负的神秘作家,喜欢玩技术,尤其是 Linux。你可以在[我的个人网站][23]关注我。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/trueos-plan-change/ + +作者:[John Paul Wohlscheid][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://itsfoss.com/author/john/ +[1]:https://itsfoss.com/author/john/ +[2]:https://itsfoss.com/trueos-plan-change/#comments +[3]:https://itsfoss.com/category/bsd/ +[4]:https://itsfoss.com/category/news/ +[5]:https://itsfoss.com/tag/bsd/ +[6]:https://itsfoss.com/tag/freebsd/ +[7]:https://itsfoss.com/tag/project-trident/ +[8]:https://itsfoss.com/tag/trueos/ +[9]:https://www.trueos.org/ +[10]:https://www.trueos.org/ +[11]:https://www.trueos.org/blog/trueosdownstream/ +[12]:http://open-zfs.org/wiki/Main_Page +[13]:https://www.freebsd.org/ +[14]:https://en.wikipedia.org/wiki/OpenRC +[15]:http://www.libressl.org/ +[16]:https://itsfoss.com/midnightbsd-founder-lucas-holt/ +[17]:https://itsfoss.com/trueos-bsd-review/ +[18]:http://www.project-trident.org/ +[19]:https://www.ghostbsd.org/ +[20]:https://itsfoss.com/interview-freedos-jim-hall/ +[21]:https://itsfoss.com/archlabs-vs-archmerge/ +[22]:http://reddit.com/r/linuxusersgroup +[23]:http://johnpaulwohlscheid.work/ diff --git a/published/20180628 Blockchain evolution- A quick guide and why open source is at the heart of it.md b/published/20180628 Blockchain evolution- A quick guide and why open source is at the heart of it.md new file mode 100644 index 0000000000..a91a1d4cda --- /dev/null +++ b/published/20180628 Blockchain evolution- A quick guide and why open source is at the heart of it.md @@ -0,0 +1,100 @@ +区块链进化简史:为什么开源是其核心所在 +====== + +> 从比特币到下一代区块链。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/block-quilt-chain.png?itok=mECoDbrc) + +当开源项目开发下一个新版本时,用后缀 “-ng” 表示 “下一代”的情况并不鲜见。幸运的是,到目前为止,快速演进的区块链成功地避开了这个命名陷阱。但是在这个开源生态系统的演进过程中,改变是不断发生的,而好的创意以典型的开源方式在许多不同的项目中被采用、交融和演进。 + +在本文中,我将审视不同代次的区块链,并且看一看在处理这个生态系统遇到的问题时出现什么创意。当然,任何对生态系统进行分类的尝试都有其局限性的 —— 和不同意见者的 —— 但是这也将为混乱的区块链项目提供了一个粗略的指南。 + +### 始作俑者:比特币 + +第一代的区块链起源于 [比特币][1]Bitcoin 区块链,这是以去中心化、点对点加密货币为基础的总帐ledger,它从 [Slashdot][2] 网站上的杂谈变成了一个主流话题。 + +这个区块链是一个分布式总帐,它对所有用户的交易transaction保持跟踪,以避免他们双重支付double-spending(双花)货币(在历史上,这个任务是委托给第三方—— 银行 ——来做的)。为防范攻击者在系统上捣乱,总帐被复制到每个参与到比特币网络的计算机上,并且每次只允许一台计算机去更新总帐。为决定哪台计算机能够获得更新总帐的权力,系统安排在比特币网络上的计算机之间每 10 分钟进行一场竞赛,这将消耗它们的(许多)能源才能参与竞赛。赢家将获得将前 10 分钟发生的交易写入到总帐(区块链中的“区块”)的权力,并且为赢家写入区块链的工作给予一些比特币奖励。这种方式被称为工作量证明proof of work(PoW)共识机制。 + +这就是区块链最有趣的地方。比特币以[开源项目][3]的方式发布于 2009 年 1 月 。在 2010 年,由于意识到这些元素中的许多是可以调整的,围绕比特币聚集起了一个社区 —— [bitcointalk 论坛][4],来开始各种实验。 + +起初,看到的比特币区块链是一个分布式数据库的形式, [Namecoin][5] 项目出现后,建议去保存任意数据到它的事务数据库中。如果区块链能够记录金钱的转移,那么它也应该能够记录其它资产的转移,比如域名。这正是 Namecoin 的主要使用场景,它上线于 2011 年 4 月 —— 也就是比特币出现两年后。 + +Namecoin 调整的地方是区块链的内容,[莱特币][6]Litecoin 调整的是两个技术部分:一是将两个区块的时间间隔从 10 分钟减少到 2.5 分钟,二是改变了竞赛方式(用 [scrypt][7] 来替换了 SHA-256 安全哈希算法)。这是能够做到的,因为比特币是以开源软件的方式来发布的,而莱特币本质上与比特币在其它部分是完全相同的。莱特币是修改了比特币共识机制的第一个分叉,这也为其它的更多“币”铺平了道路。 + +沿着这条道路,基于比特币代码库的各种变种越来越多。其中一些扩展了比特币的用途,比如 [Zerocash][8] 协议,它专注于提供交易的匿名性和可替换性,但它最终分拆为它自己的货币 —— [Zcash][9]。 + +虽然 Zcash 带来了它自己的创新,使用了最近被称为“零知识证明zero-knowledge proof”的加密技术,但它维持着与大多数主要的比特币代码库的兼容性,这意味着它能够从上游的比特币创新中获益。 + +另外的项目 —— [CryptoNote][10],它萌芽于相同的社区,但是并没有使用相同的代码,它以比特币为背景来构建的,但又与之不同。它发布于 2012 年 12 月,由于它的出现,导致了几种加密货币的诞生,最著名的 [门罗币][11]Monero (2014)就是其中之一。门罗币与 Zcash 使用了不同的方法,但解决了相同的问题:隐私性和可替换性。 + +就像在开源世界中经常出现的案例一样,做同样的工作有不止一个的工具可用。 + +### 下一代:“Blockchain-ng” + +但是,到目前为止,所有的这些变体只是改进加密货币或者扩展它们去支持其它类型的事务。因此,这就引出了第二代区块链。 + +一旦社区开始去修改区块链的用法和调整技术部分时,对于一些想去扩展和重新思考它们未来的人来说,这种调整花费不了多长时间的。比特币的长期追随者 —— [Vitalik Buterin][12] 在 2013 年底建议,区域链的事务应该能够表示一个状态机的状态变化,将区域链视为能够运行应用程序(“智能合约smart contract”)的分布式计算机。这个项目 —— [以太坊][13]Ethereum,上线于 2015 年 4 月。它在运行分布式应用程序方面取得了巨大的成功,它的一些非常流行的分布式应用程序([加密猫][14]CryptoKitties)甚至导致以太坊区块链变慢。 + +这证明了目前的区块链存在一个很大的局限性:速度和容量。(速度通常用每秒事务数来测量,简称 TPS)有几个提议都建议去解决这个速度问题,从分片sharding侧链sidechain,以及一个被称为“第二层second-layer”的解决方案。这里需要更多的创新。 + +随着“智能合约”这个词开始流行起来,并且用已经被证实仍然很慢的技术去运行它们,那么就需要实现其它的思路:许可区块链Permissioned blockchain。到目前为止,我们所介绍的所有区块链网络有两个没有明说的特征:一是它们是公开的(任何人都可以看到它们的功能),二是它们不需要许可(任何人都可以加入它们)。这两个部分是运行一个分布式的、非基于第三方的货币应该具有的和必需具有的条件。 + +随着区块链被认为出现与加密货币越来越明显的分离趋势,开始去考虑一些隐私、许可场景是很有意义的。一个有业务关系但不需要彼此完全信任的财团类型的参与者,能够从这些区块链类型中获益 —— 比如,物流链上的参与者,定期进行双边结算或者使用一个清算中心的金融、保险、或医疗保健机构。 + +一旦你将设置从“任何人都可以加入”变为“仅邀请者方可加入”,进一步对区块链构建区块的方式进行改变和调整将变得可能,那么对一些人来说,结果将变得非常有趣。 + +首先,设计用来保护网络不受恶意或者垃圾参与者的影响的工作量证明(PoW)可以被替换为更简单的和更少资源消耗的一些东西,比如,基于 [Raft][15] 的共识协议。在更高级别的安全性和更快的速度之间进行权衡,采用更简单的共识算法。对于更多群体来说这样更理想,因为他们可以用基于加密技术的担保来取代其它的基于法律关系的担保,例如为避免由于竞争而产生的大量能源消耗,而工作量证明就是这种情况。另外一个创新的地方是,使用 [股权证明][16]Proof of Stake(PoS),它是公共网络共识机制的一个重量级的竞争者。它将可能像许可链网络一样找到它自己的实现方式。 + +有几个项目可以让创建许可区块链变得更简单,包括 [Quorum][17] (以太坊的一个分叉)和 [Hyperledger][18] 的 [Fabric][19] 和 [Sawtooth][20],这是基于新代码的两个开源项目。 + +许可区块链可以避免公共的、非许可方式的区块链中某些错综复杂的问题,但是它自己也存在一些问题。正确地管理参与者是其中的一个问题:谁可以加入?如何辨别他们?如何将他们从网络上移除?网络上的一个实体是否去管理一个中央公共密钥基础设施(PKI)? + +### 区块链的开放本质 + +到目前为止的所有案例中,有一件事情是很明确的:使用一个区块链的目标是去提升网络中的参与者和它产生的数据的信任水平,理想情况下,不需要做进一步的工作即可足以使用它。 + +只有为这个网络提供动力的软件是自由和开源的,才能达到这种信任水平。即便是一个正确的、专用的、分布式区块链,它的本质仍然是运行着相同的第三方代码的私有代理的集合。从本质上来说,区块链的源代码必须是开源的,但仅是开源还不够。随着生态系统持续成长,这既是最低限度的担保也是进一步创新的源头。 + +最后,值得一提的是,虽然区块链的开放本质被认为是创新和变化的源头,它也被认为是一种治理形式:代码治理,用户期望运行的任何一个特定版本,都应该包含他们认为的整个网络应该包含的功能和方法。在这方面,需要说明的一点是,一些区块链的开放本质正在“变味”。但是这一问题正在解决。 + +### 第三和第四代:治理 + +接下来,我正在考虑第三代和第四代区块链:区块链将内置治理工具,并且项目将去解决棘手的大量不同区块链之间互连互通的问题,以便于它们之间可以交换信息和价值。 + +--- +关于作者 + +axel simon: 长期的自由及开源软件爱好者,就职于 Red Hat ,关注安全和区块链技术,以及分布式系统和协议。致力于保护互联网及其成就(知识分享、信息访问、去中心化和网络中立)。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/6/blockchain-guide-next-generation + +作者:[Axel Simon][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/axel +[1]:https://bitcoin.org +[2]:https://slashdot.org/ +[3]:https://github.com/bitcoin/bitcoin +[4]:https://bitcointalk.org/ +[5]:https://www.namecoin.org/ +[6]:https://litecoin.org/ +[7]:https://en.wikipedia.org/wiki/Scrypt +[8]:http://zerocash-project.org/index +[9]:https://z.cash +[10]:https://cryptonote.org/ +[11]:https://en.wikipedia.org/wiki/Monero_(cryptocurrency) +[12]:https://en.wikipedia.org/wiki/Vitalik_Buterin +[13]:https://ethereum.org +[14]:http://cryptokitties.co/ +[15]:https://en.wikipedia.org/wiki/Raft_(computer_science) +[16]:https://www.investopedia.com/terms/p/proof-stake-pos.asp +[17]:https://www.jpmorgan.com/global/Quorum +[18]:https://hyperledger.org/ +[19]:https://www.hyperledger.org/projects/fabric +[20]:https://www.hyperledger.org/projects/sawtooth diff --git a/translated/tech/20180628 Sosreport - A Tool To Collect System Logs And Diagnostic Information.md b/published/20180628 Sosreport - A Tool To Collect System Logs And Diagnostic Information.md similarity index 74% rename from translated/tech/20180628 Sosreport - A Tool To Collect System Logs And Diagnostic Information.md rename to published/20180628 Sosreport - A Tool To Collect System Logs And Diagnostic Information.md index 73b73b97c8..d7c728778e 100644 --- a/translated/tech/20180628 Sosreport - A Tool To Collect System Logs And Diagnostic Information.md +++ b/published/20180628 Sosreport - A Tool To Collect System Logs And Diagnostic Information.md @@ -1,41 +1,42 @@ -Sosreport - 收集系统日志和诊断信息的工具 +Sosreport:收集系统日志和诊断信息的工具 ====== ![](https://www.ostechnix.com/wp-content/uploads/2018/06/sos-720x340.png) -如果你是 RHEL 管理员,你可能肯定听说过 **Sosreport** - 一个可扩展、可移植和支持的数据收集工具。它是一个从类 Unix 操作系统收集系统配置详细信息和诊断信息的工具。当用户提出支持服务单时,他/她必须运行此工具并将由 Sosreport 工具生成的结果报告发送给 Red Hat 支持人员。然后,执行人员将根据报告进行初步分析,并尝试找出系统中的问题。不仅在 RHEL 系统上,你可以在任何类 Unix 操作系统上使用它来收集系统日志和其他调试信息。 +如果你是 RHEL 管理员,你可能肯定听说过 **Sosreport** :一个可扩展、可移植的支持数据收集工具。它是一个从类 Unix 操作系统中收集系统配置详细信息和诊断信息的工具。当用户提出支持服务单时,他/她必须运行此工具并将由 Sosreport 工具生成的结果报告发送给 Red Hat 支持人员。然后,执行人员将根据报告进行初步分析,并尝试找出系统中的问题。不仅在 RHEL 系统上,你可以在任何类 Unix 操作系统上使用它来收集系统日志和其他调试信息。 ### 安装 Sosreport Sosreport 在 Red Hat 官方系统仓库中,因此你可以使用 Yum 或 DNF 包管理器安装它,如下所示。 + ``` $ sudo yum install sos - ``` 要么, + ``` $ sudo dnf install sos - ``` 在 Debian、Ubuntu 和 Linux Mint 上运行: + ``` $ sudo apt install sosreport - ``` ### 用法 安装后,运行以下命令以收集系统配置详细信息和其他诊断信息。 + ``` $ sudo sosreport - ``` -系统将要求你输入系统的一些详细信息,例如系统名称、案例 ID 等。相应地输入详细信息,然后按 ENTER 键生成报告。如果你不想更改任何内容并使用默认值,只需按 ENTER 键即可。 +系统将要求你输入系统的一些详细信息,例如系统名称、案例 ID 等。相应地输入详细信息,然后按回车键生成报告。如果你不想更改任何内容并使用默认值,只需按回车键即可。 我的 CentOS 7 服务器的示例输出: + ``` sosreport (version 3.5) @@ -79,51 +80,49 @@ Please send this file to your support representative. ``` 如果你不希望系统提示你输入此类详细信息,请如下使用批处理模式。 + ``` $ sudo sosreport --batch - ``` -正如你在上面的输出中所看到的,生成了一个归档报告并保存在 **/var/tmp/sos.DiJXi7** 中。在 RHEL 6/CentOS 6 中,报告将在 **/tmp** 中生成。你现在可以将此报告发送给你的支持人员,以便他可以进行初步分析并找出问题所在。 +正如你在上面的输出中所看到的,生成了一个归档报告并保存在 `/var/tmp/sos.DiJXi7` 中。在 RHEL 6/CentOS 6 中,报告将在 `/tmp` 中生成。你现在可以将此报告发送给你的支持人员,以便他可以进行初步分析并找出问题所在。 你可能会担心或想知道报告中的内容。如果是这样,你可以通过运行以下命令来查看它: + ``` $ sudo tar -tf /var/tmp/sosreport-server.ostechnix.local-20180628171844.tar.xz - ``` 要么, + ``` $ sudo vim /var/tmp/sosreport-server.ostechnix.local-20180628171844.tar.xz - ``` 请注意,上述命令不会解压存档,而只显示存档中的文件和文件夹列表。如果要查看存档中文件的实际内容,请首先使用以下命令解压存档: + ``` $ sudo tar -xf /var/tmp/sosreport-server.ostechnix.local-20180628171844.tar.xz - ``` -存档的所有内容都将解压当前工作目录中 “ssosreport-server.ostechnix.local-20180628171844/” 目录中。进入目录并使用 cat 命令或任何其他文本浏览器查看文件内容: +存档的所有内容都将解压当前工作目录中 `ssosreport-server.ostechnix.local-20180628171844/` 目录中。进入目录并使用 `cat` 命令或任何其他文本浏览器查看文件内容: + ``` $ cd sosreport-server.ostechnix.local-20180628171844/ $ cat uptime 17:19:02 up 1:03, 2 users, load average: 0.50, 0.17, 0.10 - ``` 有关 Sosreport 的更多详细信息,请参阅手册页。 + ``` $ man sosreport - ``` 就是这些了。希望这些有用。还有更多好东西。敬请关注! -干杯! - - +干杯! -------------------------------------------------------------------------------- @@ -132,7 +131,7 @@ via: https://www.ostechnix.com/sosreport-a-tool-to-collect-system-logs-and-diagn 作者:[SK][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/) 荣誉推出 diff --git a/published/20180702 My first sysadmin mistake.md b/published/20180702 My first sysadmin mistake.md new file mode 100644 index 0000000000..3d9c64b3f0 --- /dev/null +++ b/published/20180702 My first sysadmin mistake.md @@ -0,0 +1,43 @@ +我的第一个系统管理员错误 +====== + +> 如何在崩溃的局面中集中精力寻找解决方案。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_mistakes.png?itok=dN0OoIl5) + +如果你在 IT 领域工作,你知道事情永远不会像你想象的那样完好。在某些时候,你会遇到错误或出现问题,你最终必须解决问题。这就是系统管理员的工作。 + +作为人类,我们都会犯错误。我们不是已经犯错,就是即将犯错。结果,我们最终还必须解决自己的错误。总是这样。我们都会失误、敲错字母或犯错。 + +作为一名年轻的系统管理员,我艰难地学到了这一课。我犯了一个大错。但是多亏了上级的指导,我学会了不去纠缠于我的错误,而是制定一个“错误策略”来做正确的事情。从错误中吸取教训。克服它,继续前进。 + +我的第一份工作是一家小公司的 Unix 系统管理员。真的,我是一名生嫩的系统管理员,但我大部分时间都独自工作。我们是一个小型 IT 团队,只有我们三个人。我是 20 或 30 台 Unix 工作站和服务器的唯一系统管理员。另外两个支持 Windows 服务器和桌面。 + +任何阅读这篇文章的系统管理员都不会对此感到意外,作为一个不成熟的初级系统管理员,我最终在错误的目录中运行了 `rm` 命令——作为 root 用户。我以为我正在为我们的某个程序删除一些陈旧的缓存文件。相反,我错误地清除了 `/etc` 目录中的所有文件。糟糕。 + +我意识到犯了错误是看到了一条错误消息,“`rm` 无法删除某些子目录”。但缓存目录应该只包含文件!我立即停止了 `rm` 命令,看看我做了什么。然后我惊慌失措。一下子,无数个想法涌入了我的脑中。我刚刚销毁了一台重要的服务器吗?系统会怎么样?我会被解雇吗? + +幸运的是,我运行的是 `rm *` 而不是 `rm -rf *`,因此我只删除了文件。子目录仍在那里。但这并没有让我感觉更好。 + +我立刻去找我的主管告诉她我做了什么。她看到我对自己的错误感到愚蠢,但这是我犯的。尽管紧迫,她花了几分钟时间跟我做了一些指导。她说:“你不是第一个这样做的人,在你这种情况下,别人会怎么做?”这帮助我平静下来并专注。我开始更少考虑我刚刚做的愚蠢事情,而更多地考虑我接下来要做的事情。 + +我做了一个简单的策略:不要重启服务器。使用相同的系统作为模板,并重建 `/etc` 目录。 + +制定了行动计划后,剩下的就很容易了。只需运行正确的命令即可从另一台服务器复制 `/etc` 文件并编辑配置,使其与系统匹配。多亏了我对所有东西都做记录的习惯,我使用已有的文档进行最后的调整。我避免了完全恢复服务器,这意味着一个巨大的宕机事件。 + +可以肯定的是,我从这个错误中吸取了教训。在接下来作为系统管理员的日子中,我总是在运行任何命令之前确认我所在的目录。 + +我还学习了构建“错误策略”的价值。当事情出错时,恐慌并思考接下来可能发生的所有坏事是很自然的。这是人性。但是制定一个“错误策略”可以帮助我不再担心出了什么问题,而是专注于让事情变得更好。我仍然会想一下,但是知道我接下来的步骤可以让我“克服它”。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/my-first-sysadmin-mistake + +作者:[Jim Hall][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/jim-hall diff --git a/published/20180704 Install an NVIDIA GPU on almost any machine.md b/published/20180704 Install an NVIDIA GPU on almost any machine.md new file mode 100644 index 0000000000..4731d0ae8f --- /dev/null +++ b/published/20180704 Install an NVIDIA GPU on almost any machine.md @@ -0,0 +1,147 @@ +如何在绝大部分类型的机器上安装 NVIDIA 显卡驱动 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/06/nvidia-816x345.jpg) + +无论是研究还是娱乐,安装一个最新的显卡驱动都能提升你的计算机性能,并且使你能全方位地实现新功能。本安装指南使用 Fedora 28 的新的第三方仓库来安装 NVIDIA 驱动。它将引导您完成硬件和软件两方面的安装,并且涵盖需要让你的 NVIDIA 显卡启动和运行起来的一切知识。这个流程适用于任何支持 UEFI 的计算机和任意新的 NVIDIA 显卡。 + +### 准备 + +本指南依赖于下面这些材料: + + * 一台使用 [UEFI][1] 的计算机,如果你不确定你的电脑是否有这种固件,请运行 `sudo dmidecode -t 0`。如果输出中出现了 “UEFI is supported”,你的安装过程就可以继续了。不然的话,虽然可以在技术上更新某些电脑来支持 UEFI,但是这个过程的要求很苛刻,我们通常不建议你这么使用。 + * 一个现代的、支持 UEFI 的 NVIDIA 的显卡 + * 一个满足你的 NVIDIA 显卡的功率和接线要求的电源(有关详细信息,请参考“硬件和修改”的章节) + * 网络连接 + * Fedora 28 系统 + +### 安装实例 + +这个安装示例使用的是: + + * 一台 Optiplex 9010 的主机(一台相当老的机器) + * [NVIDIA GeForce GTX 1050 Ti XLR8 游戏超频版 4 GB GDDR5 PCI Express 3.0 显卡][2] + * 为了满足新显卡的电源要求,电源升级为 [EVGA – 80 PLUS 600 W ATX 12V/EPS 12V][3],这个最新的电源(PSU)比推荐的最低要求高了 300 W,但在大部分情况下,满足推荐的最低要求就足够了。 + * 然后,当然的,Fedora 28 也别忘了. + +### 硬件和修改 + +#### 电源(PSU) + +打开你的台式机的机箱,检查印刷在电源上的最大输出功率。然后,查看你的 NVIDIA 显卡的文档,确定推荐的最小电源功率要求(以瓦特为单位)。除此之外,检查你的显卡,看它是否需要额外的接线,例如 6 针连接器,大多数的入门级显卡只从主板获取电力,但是有一些显卡需要额外的电力,如果出现以下情况,你需要升级你的电源: + + 1. 你的电源的最大输出功率低于显卡建议的最小电源功率。注意:根据一些显卡厂家的说法,比起推荐的功率,预先构建的系统可能会需要更多或更少的功率,而这取决于系统的配置。如果你使用的是一个特别耗电或者特别节能的配置,请灵活决定你的电源需求。 + 2. 你的电源没有提供必须的接线口来为你的显卡供电。 + +电源的更换很容易,但是在你拆除你当前正在使用的电源之前,请务必注意你的接线布局。除此之外,请确保你选择的电源适合你的机箱。 + +#### CPU + +虽然在大多数老机器上安装高性能的 NVIDIA 显卡是可能的,但是一个缓慢或受损的 CPU 会阻碍显卡性能的发挥,如果要计算在你的机器上瓶颈效果的影响,请点击[这里][4]。了解你的 CPU 性能来避免高性能的显卡和 CPU 无法保持匹配是很重要的。升级你的 CPU 是一个潜在的考虑因素。 + +#### 主板 + +在继续进行之前,请确认你的主板和你选择的显卡是兼容的。你的显卡应该插在最靠近散热器的 PCI-E x16 插槽中。确保你的设置为显卡预留了足够的空间。此外,请注意,现在大部分的显卡使用的都是 PCI-E 3.0 技术。虽然这些显卡如果插在 PCI-E 3.0 插槽上会运行地最好,但如果插在一个旧版的插槽上的话,性能也不会受到太大的影响。 + +### 安装 + +1、 首先,打开终端更新你的包管理器(如果没有更新的话): + +``` +sudo dnf update +``` + +2、 然后,使用这条简单的命令进行重启: + +``` +reboot +``` + +3、 在重启之后,安装 Fedora 28 的工作站的仓库: + +``` +sudo dnf install fedora-workstation-repositories +``` + +4、 接着,设置 NVIDIA 驱动的仓库: + +``` +sudo dnf config-manager --set-enabled rpmfusion-nonfree-nvidia-driver +``` + +5、 然后,再次重启。 + +6、 在这次重启之后,通过下面这条命令验证是否添加了仓库: + +``` +sudo dnf repository-packages rpmfusion-nonfree-nvidia-driver info +``` + +如果加载了多个 NVIDIA 工具和它们各自的 spec 文件,请继续进行下一步。如果没有,你可能在添加新仓库的时候遇到了一个错误。你应该再试一次。 + +7、 登录,连接到互联网,然后打开“软件”应用程序。点击“加载项>硬件驱动> NVIDIA Linux 图形驱动>安装”。 + +如果你使用更老的显卡或者想使用多个显卡,请进一步查看 [RPMFusion 指南][8]。最后,要确保启动成功,设置 `/etc/gdm/custom.conf` 中的 `WaylandEnable=false`,确认避免使用安全启动。 +接着,再一次重启。 + +8、这个过程完成后,关闭所有的应用并**关机**。拔下电源插头,然后按下电源按钮以释放余电,避免你被电击。如果你对电源有开关,关闭它。 + +9、 最后,安装显卡,拔掉老的显卡并将新的显卡插入到正确的 PCI-E x16 插槽中。成功安装新的显卡之后,关闭你的机箱,插入电源 ,然后打开计算机,它应该会成功启动。 + +**注意:** 要禁用此安装中使用的 NVIDIA 驱动仓库,或者要禁用所有的 Fedora 工作站仓库,请参考这个 [Fedora Wiki 页面][6]。 + +### 验证 + +1、 如果你新安装的 NVIDIA 显卡已连接到你的显示器并显示正确,则表明你的 NVIDIA 驱动程序已成功和显卡建立连接。 + +如果你想去查看你的设置,或者验证驱动是否在正常工作(这里,主板上安装了两块显卡),再次打开 “NVIDIA X 服务器设置应用程序”。这次,你应该不会得到错误信息提示,并且系统会给出有关 X 的设置文件和你的 NVIDIA 显卡的信息。(请参考下面的屏幕截图) + +![NVIDIA X Server Settings][7] + +通过这个应用程序,你可以根据你的需要需改 X 配置文件,并可以监控显卡的性能,时钟速度和温度信息。 + +2、 为确保新显卡以满功率运行,显卡性能测试是非常必要的。GL Mark 2,是一个提供后台处理、构建、照明、纹理等等有关信息的标准工具。它提供了一个优秀的解决方案。GL Mark 2 记录了各种各样的图形测试的帧速率,然后输出一个总体的性能评分(这被称为 glmark2 分数)。 + +**注意:** glxgears 只会测试你的屏幕或显示器的性能,不会测试显卡本身,请使用 GL Mark 2。 + +要运行 GLMark2: + + 1. 打开终端并关闭其他所有的应用程序 + 2. 运行 `sudo dnf install glmark2` 命令 + 3. 运行 `glmark2` 命令 + 4. 允许运行完整的测试来得到最好的结果。检查帧速率是否符合你对这块显卡的预期。如果你想要额外的验证,你可以查阅网站来确认是否已有你这块显卡的 glmark2 测试评分被公布到网上,你可以比较这个分数来评估你这块显卡的性能。 + 5. 如果你的帧速率或者 glmark2 评分低于预期,请思考潜在的因素。CPU 造成的瓶颈?其他问题导致? + + +如果诊断的结果很好,就开始享受你的新显卡吧。 + +### 参考链接 + +- [How to benchmark your GPU on Linux][9] +- [How to install a graphics card][10] +- [The Fedora Wiki Page][6] +- [The Bottlenecker][4] +- [What Is Unified Extensible Firmware Interface (UEFI)][1] + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/install-nvidia-gpu/ + +作者:[Justice del Castillo][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[hopefully2333](https://github.com/hopefully2333) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org/author/justice/ +[1]:https://whatis.techtarget.com/definition/Unified-Extensible-Firmware-Interface-UEFI +[2]:https://www.cnet.com/products/pny-geforce-gtx-xlr8-gaming-1050-ti-overclocked-edition-graphics-card-gf-gtx-1050-ti-4-gb/specs/ +[3]:https://www.evga.com/products/product.aspx?pn=100-B1-0600-KR +[4]:http://thebottlenecker.com (Home: The Bottle Necker) +[5]:https://bytebucket.org/kenneym/fedora-28-nvidia-gpu-installation/raw/7bee7dc6effe191f1f54b0589fa818960a8fa18b/nvidia_xserver_error.jpg?token=c6a7effe35f1c592a155a4a46a068a19fd060a91 (NVIDIA X Sever Prompt) +[6]:https://fedoraproject.org/wiki/Workstation/Third_Party_Software_Repositories +[7]:https://bytebucket.org/kenneym/fedora-28-nvidia-gpu-installation/raw/7bee7dc6effe191f1f54b0589fa818960a8fa18b/NVIDIA_XCONFIG.png?token=64e1a7be21e5e9ba157f029b65e24e4eef54d88f (NVIDIA X Server Settings) +[8]:https://rpmfusion.org/Howto/NVIDIA?highlight=%28CategoryHowto%29 +[9]: https://www.howtoforge.com/tutorial/linux-gpu-benchmark/ +[10]: https://www.pcworld.com/article/2913370/components-graphics/how-to-install-a-graphics-card.html \ No newline at end of file diff --git a/published/20180704 What is the Difference Between the macOS and Linux Kernels.md b/published/20180704 What is the Difference Between the macOS and Linux Kernels.md new file mode 100644 index 0000000000..bfade197ad --- /dev/null +++ b/published/20180704 What is the Difference Between the macOS and Linux Kernels.md @@ -0,0 +1,60 @@ +macOS 和 Linux 的内核有什么区别 +====== + +有些人可能会认为 macOS 和 Linux 内核之间存在相似之处,因为它们可以处理类似的命令和类似的软件。有些人甚至认为苹果公司的 macOS 是基于 Linux 的。事实上是,两个内核有着截然不同的历史和特征。今天,我们来看看 macOS 和 Linux 的内核之间的区别。 + +![macOS vs Linux][1] + +### macOS 内核的历史 + +我们将从 macOS 内核的历史开始。1985 年,由于与首席执行官 John Sculley 和董事会不和,史蒂夫·乔布斯Steve Jobs离开了苹果公司。然后,他成立了一家名为 [NeXT][2] 的新电脑公司。乔布斯希望将一款(带有新操作系统的)新计算机快速推向市场。为了节省时间,NeXT 团队使用了卡耐基梅隆大学的 [Mach 内核][3] 和部分 BSD 代码库来创建 [NeXTSTEP 操作系统][4]。 + +NeXT 从来没有取得过财务上的成功,部分归因于乔布斯花钱的习惯,就像他还在苹果公司一样。与此同时,苹果公司曾多次试图更新其操作系统,甚至与 IBM 合作,但从未成功。1997年,苹果公司以 4.29 亿美元收购了 NeXT。作为交易的一部分,史蒂夫·乔布斯回到了苹果公司,同时 NeXTSTEP 成为了 macOS 和 iOS 的基础。 + +### Linux 内核的历史 + +与 macOS 内核不同,Linux 的创建并非源于商业尝试。相反,它是由[芬兰计算机科学专业学生林纳斯·托瓦兹Linus Torvalds于 1991 年创建的][5]。最初,内核是按照林纳斯自己的计算机的规格编写的,因为他想利用其新的 80386 处理器(的特性)。林纳斯[于 1991 年 8 月在 Usenet 上][6]发布了他的新内核代码。很快,他就收到了来自世界各地的代码和功能建议。次年,Orest Zborowski 将 X Window 系统移植到 Linux,使其能够支持图形用户界面。 + +在过去的 27 年中,Linux 已经慢慢成长并增加了不少功能。这不再是一个学生的小型项目。现在它运行在[世界上][7]大多数的[计算设备][8]和[超级计算机][9]上。不错! + +### macOS 内核的特性 + +macOS 内核被官方称为 XNU。这个[首字母缩写词][10]代表“XNU is Not Unix”。根据 [苹果公司的 Github 页面][10],XNU 是“将卡耐基梅隆大学开发的 Mach 内核和 FreeBSD 组件整合而成的混合内核,加上用于编写驱动程序的 C++ API”。代码的 BSD 子系统部分[“在微内核系统中通常实现为用户空间的服务”][11]。Mach 部分负责底层工作,例如多任务、内存保护、虚拟内存管理、内核调试支持和控制台 I/O。 + +### Linux 内核的特性 + +虽然 macOS 内核结合了微内核([Mach][12])和宏内核([BSD][13])的特性,但 Linux 只是一个宏内核。[宏内核][14]负责管理 CPU、内存、进程间通信、设备驱动程序、文件系统和系统服务调用( LCTT 译注:原文为 system server calls,但结合 Linux 内核的构成,译者认为这里翻译成系统服务调用更合适,即 system service calls)。 + +### 用一句话总结 Linux 和 Mac 的区别 + +macOS 内核(XNU)比 Linux 历史更悠久,并且基于两个更古老一些的代码库的结合;另一方面,Linux 新一些,是从头开始编写的,并且在更多设备上使用。 + +如果您发现这篇文章很有趣,请花一点时间在社交媒体,黑客新闻或 [Reddit][15] 上分享。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/mac-linux-difference/ + +作者:[John Paul][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[stephenxs](https://github.com/stephenxs) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/john/ +[1]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/macos-vs-linux-kernels.jpeg +[2]:https://en.wikipedia.org/wiki/NeXT +[3]:https://en.wikipedia.org/wiki/Mach_(kernel) +[4]:https://en.wikipedia.org/wiki/NeXTSTEP +[5]:https://www.cs.cmu.edu/%7Eawb/linux.history.html +[6]:https://groups.google.com/forum/#!original/comp.os.minix/dlNtH7RRrGA/SwRavCzVE7gJ +[7]:https://www.zdnet.com/article/sorry-windows-android-is-now-the-most-popular-end-user-operating-system/ +[8]:https://www.linuxinsider.com/story/31855.html +[9]:https://itsfoss.com/linux-supercomputers-2017/ +[10]:https://github.com/apple/darwin-xnu +[11]:http://osxbook.com/book/bonus/ancient/whatismacosx/arch_xnu.html +[12]:https://en.wikipedia.org/wiki/Mach_(kernel +[13]:https://en.wikipedia.org/wiki/FreeBSD +[14]:https://www.howtogeek.com/howto/31632/what-is-the-linux-kernel-and-what-does-it-do/ +[15]:http://reddit.com/r/linuxusersgroup diff --git a/published/20180705 How to use dd in Linux without destroying your disk.md b/published/20180705 How to use dd in Linux without destroying your disk.md new file mode 100644 index 0000000000..1af60d4593 --- /dev/null +++ b/published/20180705 How to use dd in Linux without destroying your disk.md @@ -0,0 +1,97 @@ +如何在 Linux 系统中使用 dd 命令而不会损毁你的磁盘 +=========== + +> 使用 Linux 中的 dd 工具安全、可靠地制作一个驱动器、分区和文件系统的完整镜像。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_happy_sad_developer_programming.png?itok=72nkfSQ_) + +*这篇文章节选自 Manning 出版社出版的图书 [Linux in Action][1]的第 4 章。* + +你是否正在从一个即将损坏的存储驱动器挽救数据,或者要把本地归档进行远程备份,或者要把一个别处的活动分区做个完整的副本,那么你需要懂得如何安全而可靠的复制驱动器和文件系统。幸运的是,`dd` 是一个可以使用的简单而又功能强大的镜像复制命令,从现在到未来很长的时间内,也许直到永远都不会出现比 `dd` 更好的工具了。 + +### 对驱动器和分区做个完整的副本 + +仔细研究后,你会发现你可以使用 `dd` 做各种任务,但是它最重要的功能是处理磁盘分区。当然,你可以使用 `tar` 命令或者 `scp` 命令从一台计算机复制整个文件系统的文件,然后把这些文件原样粘贴在另一台刚刚安装好 Linux 操作系统的计算机中。但是,因为那些文件系统归档不是完整的映像文件,所以在复制文件的过程中需要计算机操作系统的运行作为基础。 + +另一方面,使用 `dd` 可以对任何数字信息完美的进行逐个字节的镜像。但是不论何时何地,当你要对分区进行操作时,我要告诉你早期的 Unix 管理员曾开过这样的玩笑:“ dd 的意思是磁盘毁灭者disk destroyer”(LCTT 译注:`dd` 原意是磁盘复制disk dump)。 在使用 `dd` 命令的时候,如果你输入了哪怕是一个字母,也可能立即永久性的擦除掉整个磁盘驱动器里的所有重要的数据。因此,一定要注意命令的拼写格式规范。 + +**记住:** 在按下回车键执行 `dd` 命令之前,暂时停下来仔细的认真思考一下。 + +### dd 命令的基本操作 + +现在你已经得到了适当的提醒,我们将从简单的事情开始。假设你要对代号为 `/dev/sda` 的整个磁盘数据创建精确的映像,你已经插入了一块空的磁盘驱动器 (理想情况下具有与代号为 `/dev/sda` 的磁盘驱动器相同的容量)。语法很简单: `if=` 定义源驱动器,`of=` 定义你要将数据保存到的文件或位置: + +``` +# dd if=/dev/sda of=/dev/sdb +``` + +接下来的例子将要对 `/dev/sda` 驱动器创建一个 .img 的映像文件,然后把该文件保存的你的用户帐号家目录: + +``` +# dd if=/dev/sda of=/home/username/sdadisk.img +``` + +上面的命令针对整个驱动器创建映像文件,你也可以针对驱动器上的单个分区进行操作。下面的例子针对驱动器的单个分区进行操作,同时使用了一个 `bs` 参数用于设置单次拷贝的字节数量 (此例中是 4096)。设定 `bs` 参数值可能会影响 `dd` 命令的整体操作速度,该参数的理想设置取决于你的硬件配置和其它考虑。 + +``` +# dd if=/dev/sda2 of=/home/username/partition2.img bs=4096 +``` + +数据的恢复非常简单:通过颠倒 `if` 和 `of` 参数可以有效的完成任务。在此例中,`if=` 使用你要恢复的映像,`of=` 使用你想要写入映像的目标驱动器: + +``` +# dd if=sdadisk.img of=/dev/sdb +``` + +你也可以在一条命令中同时完成创建和拷贝任务。下面的例子中将使用 SSH 从远程驱动器创建一个压缩的映像文件,并把该文件保存到你的本地计算机中: + +``` +# ssh username@54.98.132.10 "dd if=/dev/sda | gzip -1 -" | dd of=backup.gz +``` + +你应该经常测试你的归档,确保它们可正常使用。如果它是你创建的启动驱动器,将它粘贴到计算机中,看看它是否能够按预期启动。如果它是普通分区的数据,挂载该分区,确保文件都存在而且可以正常的访问。 + +### 使用 dd 擦除磁盘数据 + +多年以前,我的一个负责政府海外大使馆安全的朋友曾经告诉我,在他当时在任的时候, 政府会给每一个大使馆提供一个官方版的锤子。为什么呢? 一旦大使馆设施可能被不友善的人员侵占,就会使用这个锤子毁坏所有的硬盘. + +为什么要那样做?为什么不是删除数据就好了?你在开玩笑,对吧?所有人都知道从存储设备中删除包含敏感信息的文件实际上并没有真正移除这些数据。除非使用锤子彻底的毁坏这些存储介质,否则,只要有足够的时间和动机, 几乎所有的内容都可以从几乎任何数字存储介质重新获取。 + +但是,你可以使用 `dd` 命令让坏人非常难以获得你的旧数据。这个命令需要花费一些时间在 `/dev/sda1` 分区的每个扇区写入数百万个 `0`(LCTT 译注:是指 0x0 字节,意即 NUL ,而不是数字 0 ): + +``` +# dd if=/dev/zero of=/dev/sda1 +``` + +还有更好的方法。通过使用 `/dev/urandom` 作为源文件,你可以在磁盘上写入随机字符: + +``` +# dd if=/dev/urandom of=/dev/sda1 +``` + +### 监控 dd 的操作 + +由于磁盘或磁盘分区的归档可能需要很长的时间,因此你可能需要在命令中添加进度查看器。安装管道查看器(在 Ubuntu 系统上安装命令为 `sudo apt install pv`),然后把 `pv` 命令和 `dd` 命令结合在一起。使用 `pv`,最终的命令是这样的: + +``` +# dd if=/dev/urandom | pv | dd of=/dev/sda1 + +4,14MB 0:00:05 [ 98kB/s] [ <=> ] +``` + +想要推迟备份和磁盘管理工作?有了 `dd` 工具,你不会有太多的借口。它真的非常简单,但是要小心。祝你好运! + +---------------- + +via:https://opensource.com/article/18/7/how-use-dd-linux + +作者:[David Clinton][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[SunWave](https://github.com/SunWave) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + + +[a]: https://opensource.com/users/remyd +[1]: https://www.manning.com/books/linux-in-action?a_aid=bootstrap-it&a_bid=4ca15fc9&chan=opensource diff --git a/published/20180706 6 RFCs for understanding how the internet works.md b/published/20180706 6 RFCs for understanding how the internet works.md new file mode 100644 index 0000000000..12413c0770 --- /dev/null +++ b/published/20180706 6 RFCs for understanding how the internet works.md @@ -0,0 +1,79 @@ +6 个可以帮你理解互联网工作原理的 RFC +====== + +> 以及 3 个有趣的 RFC。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW-Internet_construction_9401467_520x292_0512_dc.png?itok=RPkPPtDe) + +阅读源码是开源软件的重要组成部分。这意味着用户可以查看代码并了解做了什么。 + +但“阅读源码”并不仅适用于代码。理解代码实现的标准同样重要。这些标准编写在由[互联网工程任务组][1]Internet Engineering Task Force(IETF)发布的称为“意见征集Requests for Comment”(RFC)的文档中。多年来已经发布了数以千计的 RFC,因此我们收集了一些我们的贡献者认为必读的内容。 + +### 6 个必读的 RFC + +#### RFC 2119 - 在 RFC 中用于指示需求级别的关键字 + +这是一个快速阅读,但它对了解其它 RFC 非常重要。 [RFC 2119][2] 定义了后续 RFC 中使用的需求级别。 “MAY” 究竟意味着什么?如果标准说 “SHOULD”,你*真的*必须这样做吗?通过为需求提供明确定义的分类,RFC 2119 有助于避免歧义。 + +#### RFC 3339 - 互联网上的日期和时间:时间戳 + +时间是全世界程序员的祸根。 [RFC 3339][3] 定义了如何格式化时间戳。基于 [ISO 8601][4] 标准,3339 为我们提供了一种表达时间的常用方法。例如,像星期几这样的冗余信息不应该包含在存储的时间戳中,因为它很容易计算。 + +#### RFC 1918 - 私有互联网的地址分配 + +有属于每个人的互联网,也有只属于你的互联网。私有网络一直在使用,[RFC 1918][5] 定义了这些网络。当然,你可以在路由器上设置在内部使用公网地址,但这是一个坏主意。或者,你可以将未使用的公共 IP 地址视为内部网络。在任何一种情况下都表明你从未阅读过 RFC 1918。 + +#### RFC 1912 - 常见的 DNS 操作和配置错误 + +一切都是 #@%@ 的 DNS 问题,对吧? [RFC 1912][6] 列出了管理员在试图保持互联网运行时所犯的错误。虽然它是在 1996 年发布的,但 DNS(以及人们犯的错误)并没有真正改变这么多。为了理解我们为什么首先需要 DNS,如今我们再来看看 [RFC 289 - 我们希望正式的主机列表是什么样子的][7] 就知道了。 + +#### RFC 2822 — 互联网邮件格式 + +想想你知道什么是有效的电子邮件地址么?如果你知道有多少个站点不接受我邮件地址中 “+” 的话,你就知道你知道不知道了。 [RFC 2822][8] 定义了有效的电子邮件地址。它还详细介绍了电子邮件的其余部分。 + +#### RFC 7231 - 超文本传输​​协议(HTTP/1.1):语义和内容 + +想想看,几乎我们在网上做的一切都依赖于 HTTP。 [RFC 7231][9] 是该协议的最新更新。它有超过 100 页,定义了方法、请求头和状态代码。 + +### 3 个应该阅读的 RFC + +好吧,并非每个 RFC 都是严肃的。 + +#### RFC 1149 - 在禽类载体上传输 IP 数据报的标准 + +网络以多种不同方式传递数据包。 [RFC 1149][10] 描述了鸽子载体的使用。当我距离州际高速公路一英里以外时,它们的可靠性不会低于我的移动提供商。 + +#### RFC 2324 — 超文本咖啡壶控制协议(HTCPCP/1.0) + +咖啡对于完成工作非常重要,当然,我们需要一个用于管理咖啡壶的程序化界面。 [RFC 2324][11] 定义了一个用于与咖啡壶交互的协议,并添加了 HTTP 418(“我是一个茶壶”)。 + +#### RFC 69 — M.I.T.的分发列表更改 + +[RFC 69][12] 是否是第一个误导取消订阅请求的发布示例? + +你必须阅读的 RFC 是什么(无论它们是否严肃)?在评论中分享你的列表。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/requests-for-comments-to-know + +作者:[Ben Cotton][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/bcotton +[1]:https://www.ietf.org +[2]:https://www.rfc-editor.org/rfc/rfc2119.txt +[3]:https://www.rfc-editor.org/rfc/rfc3339.txt +[4]:https://www.iso.org/iso-8601-date-and-time-format.html +[5]:https://www.rfc-editor.org/rfc/rfc1918.txt +[6]:https://www.rfc-editor.org/rfc/rfc1912.txt +[7]:https://www.rfc-editor.org/rfc/rfc289.txt +[8]:https://www.rfc-editor.org/rfc/rfc2822.txt +[9]:https://www.rfc-editor.org/rfc/rfc7231.txt +[10]:https://www.rfc-editor.org/rfc/rfc1149.txt +[11]:https://www.rfc-editor.org/rfc/rfc2324.txt +[12]:https://www.rfc-editor.org/rfc/rfc69.txt diff --git a/published/20180706 How to Run Windows Apps on Android with Wine.md b/published/20180706 How to Run Windows Apps on Android with Wine.md new file mode 100644 index 0000000000..ca6eeadcfd --- /dev/null +++ b/published/20180706 How to Run Windows Apps on Android with Wine.md @@ -0,0 +1,127 @@ +如何在 Android 上借助 Wine 来运行 Windows Apps +====== + +![](https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-featured-image.jpg) + +Wine(一种 Linux 上的程序,不是你喝的葡萄酒)是在类 Unix 操作系统上运行 Windows 程序的一个自由开源的兼容层。创建于 1993 年,借助它你可以在 Linux 和 macOS 操作系统上运行很多 Windows 程序,虽然有时可能还需要做一些小修改。现在,Wine 项目已经发布了 3.0 版本,这个版本兼容 Android 设备。 + +在本文中,我们将向你展示,在你的 Android 设备上如何借助 Wine 来运行 Windows Apps。 + +**相关阅读** : [如何使用 Winepak 在 Linux 上轻松安装 Windows 游戏][1] + +### 在 Wine 上你可以运行什么? + +Wine 只是一个兼容层,而不是一个全功能的仿真器,因此,你需要一个 x86 的 Android 设备才能完全发挥出它的优势。但是,大多数消费者手中的 Android 设备都是基于 ARM 的。 + +因为大多数人使用的是基于 ARM 的 Android 设备,所以有一个限制,只有适配在 Windows RT 上运行的那些 App 才能够使用 Wine 在基于 ARM 的 Android 上运行。但是随着发展,能够在 ARM 设备上运行的 App 数量越来越多。你可以在 XDA 开发者论坛上的这个 [帖子][2] 中找到兼容的这些 App 的清单。 + +在 ARM 上能够运行的一些 App 的例子如下: + + * [Keepass Portable][3]: 一个密码钱包 + * [Paint.NET][4]: 一个图像处理程序 + * [SumatraPDF][5]: 一个 PDF 文档阅读器,也能够阅读一些其它的文档类型 + * [Audacity][6]: 一个数字录音和编辑程序 + +也有一些再度流行的开源游戏,比如,[Doom][7] 和 [Quake 2][8],以及它们的开源克隆,比如 [OpenTTD][9] 和《运输大亨》的一个版本。 + +随着 Wine 在 Android 上越来越普及,能够在基于 ARM 的 Android 设备上的 Wine 中运行的程序越来越多。Wine 项目致力于在 ARM 上使用 QEMU 去仿真 x86 的 CPU 指令,在该项目完成后,能够在 Android 上运行的 App 将会迅速增加。 + +### 安装 Wine + +在安装 Wine 之前,你首先需要去确保你的设备的设置 “允许从 Play 商店之外的其它源下载和安装 APK”。对于本文的用途,你需要去许可你的设备从未知源下载 App。 + +1、 打开你手机上的设置,然后选择安全选项。 + +![wine-android-security][10] + +2、 向下拉并点击 “Unknown Sources” 的开关。 + +![wine-android-unknown-sources][11] + +3、 接受风险警告。 + +![wine-android-unknown-sources-warning][12] + +4、 打开 [Wine 安装站点][13],并点选列表中的第一个选择框。下载将自动开始。 + +![wine-android-download-button][14] + +5、 下载完成后,从下载目录中打开它,或者下拉通知菜单并点击这里的已完成的下载。 + +6、 开始安装程序。它将提示你它需要访问和记录音频,并去修改、删除、和读取你的 SD 卡。你也可为程序中使用的一些 App 授予访问音频的权利。 + +![wine-android-app-access][15] + +7、 安装完成后,点击程序图标去打开它。 + +![wine-android-icon-small][16] + +当你打开 Wine 后,它模仿的是 Windows 7 的桌面。 + +![wine-android-desktop][17] + +Wine 有一个缺点是,你得有一个外接键盘去进行输入。如果你在一个小屏幕上运行它,并且触摸非常小的按钮很困难,你也可以使用一个外接鼠标。 + +你可以通过触摸 “开始” 按钮去打开两个菜单 —— “控制面板”和“运行”。 + +![wine-android-start-button][18] + +### 使用 Wine 来工作 + +当你触摸 “控制面板” 后你将看到三个选项 —— 添加/删除程序、游戏控制器、和 Internet 设定。 + +使用 “运行”,你可以打开一个对话框去运行命令。例如,通过输入 `iexplore` 来启动 “Internet Explorer”。 + +![wine-android-run][19] + +### 在 Wine 中安装程序 + +1、 在你的 Android 设备上下载应用程序(或通过云来同步)。一定要记住下载的程序保存的位置。 + +2、 打开 Wine 命令提示符窗口。 + +3、 输入程序的位置路径。如果你把下载的文件保存在 SD 卡上,输入: + +``` +cd sdcard/Download/[filename.exe] +``` + +4、 在 Android 上运行 Wine 中的文件,只需要简单地输入 EXE 文件的名字即可。 + +如果这个支持 ARM 的文件是兼容的,它将会运行。如果不兼容,你将看到一大堆错误信息。在这种情况下,在 Android 上的 Wine 中安装的 Windows 软件可能会损坏或丢失。 + +这个在 Android 上使用的新版本的 Wine 仍然有许多问题。它并不能在所有的 Android 设备上正常工作。它可以在我的 Galaxy S6 Edge 上运行的很好,但是在我的 Galaxy Tab 4 上却不能运行。许多游戏也不能正常运行,因为图形驱动还不支持 Direct3D。因为触摸屏还不是全扩展的,所以你需要一个外接的键盘和鼠标才能很轻松地操作它。 + +即便是在早期阶段的发布版本中存在这样那样的问题,但是这种技术还是值得深思的。当然了,你要想在你的 Android 智能手机上运行 Windows 程序而不出问题,可能还需要等待一些时日。 + +-------------------------------------------------------------------------------- + +via: https://www.maketecheasier.com/run-windows-apps-android-with-wine/ + +作者:[Tracey Rosenberger][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.maketecheasier.com/author/traceyrosenberger/ +[1]:https://www.maketecheasier.com/winepak-install-windows-games-linux/ "How to Easily Install Windows Games on Linux with Winepak" +[2]:https://forum.xda-developers.com/showthread.php?t=2092348 +[3]:http://downloads.sourceforge.net/keepass/KeePass-2.20.1.zip +[4]:http://forum.xda-developers.com/showthread.php?t=2411497 +[5]:http://forum.xda-developers.com/showthread.php?t=2098594 +[6]:http://forum.xda-developers.com/showthread.php?t=2103779 +[7]:http://forum.xda-developers.com/showthread.php?t=2175449 +[8]:http://forum.xda-developers.com/attachment.php?attachmentid=1640830&amp;d=1358070370 +[9]:http://forum.xda-developers.com/showpost.php?p=36674868&amp;postcount=151 +[10]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-security.png "wine-android-security" +[11]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-unknown-sources.jpg "wine-android-unknown-sources" +[12]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-unknown-sources-warning.png "wine-android-unknown-sources-warning" +[13]:https://dl.winehq.org/wine-builds/android/ +[14]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-download-button.png "wine-android-download-button" +[15]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-app-access.jpg "wine-android-app-access" +[16]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-icon-small.jpg "wine-android-icon-small" +[17]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-desktop.png "wine-android-desktop" +[18]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-start-button.png "wine-android-start-button" +[19]:https://www.maketecheasier.com/assets/uploads/2018/07/Wine-Android-Run.png "wine-android-run" diff --git a/published/20180708 Getting Started with Debian Packaging.md b/published/20180708 Getting Started with Debian Packaging.md new file mode 100644 index 0000000000..108dd69a97 --- /dev/null +++ b/published/20180708 Getting Started with Debian Packaging.md @@ -0,0 +1,215 @@ +Debian 打包入门 +====== + +> 创建 CardBook 软件包、本地 Debian 仓库,并修复错误。 + +![](http://minkush.me/img/posts/12.jpg) + +我在 GSoC(LCTT 译注:Google Summer Of Code,一项针对学生进行的开源项目训练营,一般在夏季进行。)的任务中有一项是为用户构建 Thunderbird 扩展add-ons。一些非常流行的扩展,比如 [Lightning][1] (日历行事历)已经拥有了 deb 包。 + +另外一个重要的用于管理基于 CardDav 和 vCard 标准的联系人的扩展 [Cardbook][2] ,还没有一个 deb 包。 + +我的导师, [Daniel][3] 鼓励我去为它制作一个包,并上传到 [mentors.debian.net][4]。因为这样就可以使用 `apt-get` 来安装,简化了安装流程。这篇博客描述了我是如何从头开始学习为 CardBook 创建一个 Debian 包的。 + +首先,我是第一次接触打包,我在从源码构建包的基础上进行了大量研究,并检查它的协议是是否与 [DFSG][5] 兼容。 + +我从多个 Debian Wiki 中的指南中进行学习,比如 [打包介绍][6]、 [构建一个包][7],以及一些博客。 + +我还研究了包含在 [Lightning 扩展包][8]的 amd64 文件。 + +我创建的包可以在[这里][9]找到。 + +![Debian Package!][10] + +*Debian 包* + +### 创建一个空的包 + +我从使用 `dh_make` 来创建一个 `debian` 目录开始。 + +``` +# Empty project folder +$ mkdir -p Debian/cardbook +``` + +``` +# create files +$ dh_make\ +> --native \ +> --single \ +> --packagename cardbook_1.0.0 \ +> --email minkush@example.com +``` + +一些重要的文件,比如 `control`、`rules`、`changelog`、`copyright` 等文件被初始化其中。 + +所创建的文件的完整列表如下: + +``` +$ find /debian +debian/ +debian/rules +debian/preinst.ex +debian/cardbook-docs.docs +debian/manpage.1.ex +debian/install +debian/source +debian/source/format +debian/cardbook.debhelper.lo +debian/manpage.xml.ex +debian/README.Debian +debian/postrm.ex +debian/prerm.ex +debian/copyright +debian/changelog +debian/manpage.sgml.ex +debian/cardbook.default.ex +debian/README +debian/cardbook.doc-base.EX +debian/README.source +debian/compat +debian/control +debian/debhelper-build-stamp +debian/menu.ex +debian/postinst.ex +debian/cardbook.substvars +debian/files +``` + +我了解了 Debian 系统中 [Dpkg][11] 包管理器及如何用它安装、删除和管理包。 + +我使用 `dpkg` 命令创建了一个空的包。这个命令创建一个空的包文件以及四个名为 `.changes`、`.deb`、 `.dsc`、 `.tar.gz` 的文件。 + +- `.dsc` 文件包含了所发生的修改和签名 +- `.deb` 文件是用于安装的主要包文件。 +- `.tar.gz` (tarball)包含了源代码 + +这个过程也在 `/usr/share` 目录下创建了 `README` 和 `changelog` 文件。它们包含了关于这个包的基本信息比如描述、作者、版本。 + +我安装这个包,并检查这个包安装的内容。我的新包中包含了版本、架构和描述。 + +``` +$ dpkg -L cardbook +/usr +/usr/share +/usr/share/doc +/usr/share/doc/cardbook +/usr/share/doc/cardbook/README.Debian +/usr/share/doc/cardbook/changelog.gz +/usr/share/doc/cardbook/copyright +``` + +### 包含 CardBook 源代码 + +在成功的创建了一个空包以后,我在包中添加了实际的 CardBook 扩展文件。 CardBook 的源代码托管在 [Gitlab][12] 上。我将所有的源码文件包含在另外一个目录,并告诉打包命令哪些文件需要包含在这个包中。 + +我使用 `vi` 编辑器创建一个 `debian/install` 文件并列举了需要被安装的文件。在这个过程中,我花费了一些时间去学习基于 Linux 终端的文本编辑器,比如 `vi` 。这让我熟悉如何在 `vi` 中编辑、创建文件和快捷方式。 + +当这些完成后,我在变更日志中更新了包的版本并记录了我所做的改变。 + +``` +$ dpkg -l | grep cardbook +ii cardbook 1.1.0 amd64 Thunderbird add-on for address book +``` + +![Changelog][13] + +*更新完包的变更日志* + +在重新构建完成后,重要的依赖和描述信息可以被加入到包中。 Debian 的 `control` 文件可以用来添加额外的必须项目和依赖。 + +### 本地 Debian 仓库 + +在不创建本地存储库的情况下,CardBook 可以使用如下的命令来安装: + +``` +$ sudo dpkg -i cardbook_1.1.0.deb +``` + +为了实际测试包的安装,我决定构建一个本地 Debian 存储库。没有它,`apt-get` 命令将无法定位包,因为它没有在 Debian 的包软件列表中。 + +为了配置本地 Debian 存储库,我复制我的包 (.deb)为放在 `/tmp` 目录中的 `Packages.gz` 文件。 + +![Packages-gz][14] + +*本地 Debian 仓库* + +为了使它工作,我了解了 `apt` 的配置和它查找文件的路径。 + +我研究了一种在 `apt-config` 中添加文件位置的方法。最后,我通过在 APT 中添加 `*.list` 文件来添加包的路径,并使用 `apt-cache` 更新APT缓存来完成我的任务。 + +因此,最新的 CardBook 版本可以成功的通过 `apt-get install cardbook` 来安装了。 + +![Package installation!][15] + +*使用 apt-get 安装 CardBook* + +### 修复打包错误和 Bugs + +我的导师 Daniel 在这个过程中帮了我很多忙,并指导我如何进一步进行打包。他告诉我使用 [Lintian][16] 来修复打包过程中出现的常见错误和最终使用 [dput][17] 来上传 CardBook 包。 + +> Lintian 是一个用于发现策略问题和 Bug 的包检查器。它是 Debian 维护者们在上传包之前广泛使用的自动化检查 Debian 策略的工具。 + +我上传了该软件包的第二个更新版本到 Debian 目录中的 [Salsa 仓库][18] 的一个独立分支中。 + +我从 Debian backports 上安装 Lintian 并学习在一个包上用它来修复错误。我研究了它用在其错误信息中的缩写,和如何查看 Lintian 命令返回的详细内容。 + +``` +$ lintian -i -I --show-overrides cardbook_1.2.0.changes +``` + +最初,在 `.changes` 文件上运行命令时,我惊讶地看到显示出来了大量错误、警告和注释! + +![Package Error Brief!][19] + +*在包上运行 Lintian 时看到的大量报错* + +![Lintian error1!][20] + +*详细的 Lintian 报错* + +![Lintian error2!][23] + +*详细的 Lintian 报错 (2) 以及更多* + +我花了几天时间修复与 Debian 包策略违例相关的一些错误。为了消除一个简单的错误,我必须仔细研究每一项策略和 Debian 的规则。为此,我参考了 [Debian 策略手册][21] 以及 [Debian 开发者参考][22]。 + +我仍然在努力使它变得完美无暇,并希望很快可以将它上传到 mentors.debian.net! + +如果 Debian 社区中使用 Thunderbird 的人可以帮助修复这些报错就太感谢了。 + +-------------------------------------------------------------------------------- + +via: http://minkush.me/cardbook-debian-package/ + +作者:[Minkush Jain][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[Bestony](https://github.com/bestony) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://minkush.me/cardbook-debian-package/# +[1]:https://addons.mozilla.org/en-US/thunderbird/addon/lightning/ +[2]:https://addons.mozilla.org/nn-NO/thunderbird/addon/cardbook/?src=hp-dl-featured +[3]:https://danielpocock.com/ +[4]:https://mentors.debian.net/ +[5]:https://wiki.debian.org/DFSGLicenses +[6]:https://wiki.debian.org/Packaging/Intro +[7]:https://wiki.debian.org/BuildingAPackage +[8]:https://packages.debian.org/stretch/amd64/lightning/filelist +[9]:https://salsa.debian.org/minkush-guest/CardBook/tree/debian-package/Debian +[10]:http://minkush.me/img/posts/13.png +[11]:https://packages.debian.org/stretch/dpkg +[12]:https://gitlab.com/CardBook/CardBook +[13]:http://minkush.me/img/posts/15.png +[14]:http://minkush.me/img/posts/14.png +[15]:http://minkush.me/img/posts/11.png +[16]:https://packages.debian.org/stretch/lintian +[17]:https://packages.debian.org/stretch/dput +[18]:https://salsa.debian.org/minkush-guest/CardBook/tree/debian-package +[19]:http://minkush.me/img/posts/16.png (Running Lintian on package) +[20]:http://minkush.me/img/posts/10.png +[21]:https://www.debian.org/doc/debian-policy/ +[22]:https://www.debian.org/doc/manuals/developers-reference/ +[23]:http://minkush.me/img/posts/17.png \ No newline at end of file diff --git a/published/20180709 Boost your typing with emoji in Fedora 28 Workstation.md b/published/20180709 Boost your typing with emoji in Fedora 28 Workstation.md new file mode 100644 index 0000000000..0419275816 --- /dev/null +++ b/published/20180709 Boost your typing with emoji in Fedora 28 Workstation.md @@ -0,0 +1,67 @@ +在 Fedora 28 Workstation 使用 emoji 加速输入 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/07/emoji-typing-816x345.jpg) + +Fedora 28 Workstation 添加了一个功能允许你使用键盘快速搜索、选择和输入 emoji。emoji,这种可爱的表意文字是 Unicode 的一部分,在消息传递中使用得相当广泛,特别是在移动设备上。你可能听过这样的成语:“一图胜千言”。这正是 emoji 所提供的:简单的图像供你在交流中使用。Unicode 的每个版本都增加了更多 emoji,在最近的 Unicode 版本中添加了 200 多个 emoji。本文向你展示如何使它们在你的 Fedora 系统中易于使用。 + +很高兴看到 emoji 的数量在增长。但与此同时,它带来了如何在计算设备中输入它们的挑战。许多人已经将这些符号用于移动设备或社交网站中的输入。 + +[**编者注:**本文是对此主题以前发表过的文章的更新]。 + +### 在 Fedora 28 Workstation 上启用 emoji 输入 + +新的 emoji 输入法默认出现在 Fedora 28 Workstation 中。要使用它,必须使用“区域和语言设置”对话框启用它。从 Fedora Workstation 设置打开“区域和语言”对话框,或在“概要”中搜索它。 + +[![Region & Language settings tool][1]][2] + +选择 `+` 控件添加输入源。出现以下对话框: + +[![Adding an input source][3]][4] + +选择最后选项(三个点)来完全展开选择。然后,在列表底部找到“Other”并选择它: + +[![Selecting other input sources][5]][6] + +在下面的对话框中,找到 “Typing Booster” 选项并选择它: + +[![][7]][8] + +这个高级输入法由 iBus 在背后支持。该高级输入法可通过列表右侧的齿轮图标在列表中识别。 + +输入法下拉菜单自动出现在 GNOME Shell 顶部栏中。确认你的默认输入法 —— 在此示例中为英语(美国) - 被选为当前输入法,你就可以输入了。 + +[![Input method dropdown in Shell top bar][9]][10] + +### 使用新的表情符号输入法 + +现在 emoji 输入法启用了,按键盘快捷键 `Ctrl+Shift+E` 搜索 emoji。将出现一个弹出对话框,你可以在其中输入搜索词,例如 “smile” 来查找匹配的符号。 + +[![Searching for smile emoji][11]][12] + +使用箭头键翻页列表。然后按回车进行选择,字形将替换输入内容。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/boost-typing-emoji-fedora-28-workstation/ + +作者:[Paul W. Frields][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org/author/pfrields/ +[1]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-15-02-41-1024x718.png +[2]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-15-02-41.png +[3]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-33-46-1024x839.png +[4]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-33-46.png +[5]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-34-15-1024x839.png +[6]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-34-15.png +[7]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-34-41-1024x839.png +[8]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-34-41.png +[9]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-15-05-24-300x244.png +[10]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-15-05-24.png +[11]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-36-31-290x300.png +[12]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-08-14-36-31.png diff --git a/published/20180709 Malware Found On The Arch User Repository (AUR).md b/published/20180709 Malware Found On The Arch User Repository (AUR).md new file mode 100644 index 0000000000..6e10a14fc5 --- /dev/null +++ b/published/20180709 Malware Found On The Arch User Repository (AUR).md @@ -0,0 +1,40 @@ +在 Arch 用户仓库(AUR)中发现恶意软件 +====== + +7 月 7 日,有一个 AUR 软件包被改入了一些恶意代码,提醒 [Arch Linux][1] 用户(以及一般的 Linux 用户)在安装之前应该尽可能检查所有由用户生成的软件包。 + +[AUR][3](即 Arch(Linux)用户仓库)包含包描述,也称为 PKGBUILD,它使得从源代码编译包变得更容易。虽然这些包非常有用,但它们永远不应被视为安全的,并且用户应尽可能在使用之前检查其内容。毕竟,AUR 在网页中以粗体显示 “**AUR 包是用户制作的内容。任何使用该提供的文件的风险由你自行承担。**” + +这次[发现][4]包含恶意代码的 AUR 包证明了这一点。[acroread][5] 于 7 月 7 日(看起来它以前是“孤儿”,意思是它没有维护者)被一位名为 “xeactor” 的用户修改,它包含了一行从 pastebin 使用 `curl` 下载脚本的命令。然后,该脚本下载了另一个脚本并安装了一个 systemd 单元以定期运行该脚本。 + +**看来有[另外两个][2] AUR 包以同样的方式被修改。所有违规软件包都已删除,并暂停了用于上传它们的用户帐户(它们注册在更新软件包的同一天)。** + +这些恶意代码没有做任何真正有害的事情 —— 它只是试图上传一些系统信息,比如机器 ID、`uname -a` 的输出(包括内核版本、架构等)、CPU 信息、pacman 信息,以及 `systemctl list-units`(列出 systemd 单元信息)的输出到 pastebin.com。我说“试图”是因为第二个脚本中存在错误而没有实际上传系统信息(上传函数为 “upload”,但脚本试图使用其他名称 “uploader” 调用它)。 + +此外,将这些恶意脚本添加到 AUR 的人将脚本中的个人 Pastebin API 密钥以明文形式留下,再次证明他们真的不明白他们在做什么。(LCTT 译注:意即这是一个菜鸟“黑客”,还不懂得如何有经验地隐藏自己。) + +尝试将此信息上传到 Pastebin 的目的尚不清楚,特别是原本可以上传更加敏感信息的情况下,如 GPG / SSH 密钥。 + +**更新:** Reddit用户 u/xanaxdroid_ [提及][6]同一个名为 “xeactor” 的用户也发布了一些加密货币挖矿软件包,因此他推测 “xeactor” 可能正计划添加一些隐藏的加密货币挖矿软件到 AUR([两个月][7]前的一些 Ubuntu Snap 软件包也是如此)。这就是 “xeactor” 可能试图获取各种系统信息的原因。此 AUR 用户上传的所有包都已删除,因此我无法检查。 + +**另一个更新:**你究竟应该在那些用户生成的软件包检查什么(如 AUR 中发现的)?情况各有不同,我无法准确地告诉你,但你可以从寻找任何尝试使用 `curl`、`wget`和其他类似工具下载内容的东西开始,看看他们究竟想要下载什么。还要检查从中下载软件包源的服务器,并确保它是官方来源。不幸的是,这不是一个确切的“科学做法”。例如,对于 Launchpad PPA,事情变得更加复杂,因为你必须懂得 Debian 如何打包,并且这些源代码是可以直接更改的,因为它托管在 PPA 中并由用户上传的。使用 Snap 软件包会变得更加复杂,因为在安装之前你无法检查这些软件包(据我所知)。在后面这些情况下,作为通用解决方案,我觉得你应该只安装你信任的用户/打包器生成的软件包。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxuprising.com/2018/07/malware-found-on-arch-user-repository.html + +作者:[Logix][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://plus.google.com/118280394805678839070 +[1]:https://www.archlinux.org/ +[2]:https://lists.archlinux.org/pipermail/aur-general/2018-July/034153.html +[3]:https://aur.archlinux.org/ +[4]:https://lists.archlinux.org/pipermail/aur-general/2018-July/034152.html +[5]:https://aur.archlinux.org/cgit/aur.git/commit/?h=acroread&id=b3fec9f2f16703c2dae9e793f75ad6e0d98509bc +[6]:https://www.reddit.com/r/archlinux/comments/8x0p5z/reminder_to_always_read_your_pkgbuilds/e21iugg/ +[7]:https://www.linuxuprising.com/2018/05/malware-found-in-ubuntu-snap-store.html diff --git a/published/20180710 15 open source applications for MacOS.md b/published/20180710 15 open source applications for MacOS.md new file mode 100644 index 0000000000..9d4c9e1c0a --- /dev/null +++ b/published/20180710 15 open source applications for MacOS.md @@ -0,0 +1,74 @@ +15 个适用于 MacOS 的开源应用程序 +====== + +> 钟爱开源的用户不会觉得在非 Linux 操作系统上使用他们喜爱的应用有多难。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_keyboard_laptop_development_blue.png?itok=IfckxN48) + +只要有可能的情况下,我都会去选择使用开源工具。不久之前,我回到大学去攻读教育领导学硕士学位。即便是我将喜欢的 Linux 笔记本电脑换成了一台 MacBook Pro(因为我不能确定校园里能够接受 Linux),我还是决定继续使用我喜欢的工具,哪怕是在 MacOS 上也是如此。 + +幸运的是,它很容易,并且没有哪个教授质疑过我用的是什么软件。即然如此,我就不能秘而不宣。 + +我知道,我的一些同学最终会在学区担任领导职务,因此,我与我的那些使用 MacOS 或 Windows 的同学分享了关于下面描述的这些开源软件。毕竟,开源软件是真正地自由和友好的。我也希望他们去了解它,并且愿意以很少的一些成本去提供给他们的学生去使用这些世界级的应用程序。他们中的大多数人都感到很惊讶,因为,众所周知,开源软件除了有像你和我这样的用户之外,压根就没有销售团队。 + +### 我的 MacOS 学习曲线 + +虽然大多数的开源工具都能像以前我在 Linux 上使用的那样工作,只是需要不同的安装方法。但是,经过这个过程,我学习了这些工具在 MacOS 上的一些细微差别。像 [yum][1]、[DNF][2]、和 [APT][3] 在 MacOS 的世界中压根不存在 —— 我真的很怀念它们。 + +一些 MacOS 应用程序要求依赖项,并且安装它们要比我在 Linux 上习惯的方法困难很多。尽管如此,我仍然没有放弃。在这个过程中,我学会了如何在我的新平台上保留最好的软件。即便是 MacOS 大部分的核心也是 [开源的][4]。 + +此外,我的 Linux 的知识背景让我使用 MacOS 的命令行很轻松很舒适。我仍然使用命令行去创建和拷贝文件、添加用户、以及使用其它的像 `cat`、`tac`、`more`、`less` 和 `tail` 这样的 [实用工具][5]。 + +### 15 个适用于 MacOS 的非常好的开源应用程序 + + * 在大学里,要求我使用 DOCX 的电子版格式来提交我的工作,而这其实很容易,最初我使用的是 [OpenOffice][6],而后来我使用的是 [LibreOffice][7] 去完成我的论文。 + * 当我因为演示需要去做一些图像时,我使用的是我最喜欢的图像应用程序 [GIMP][8] 和 [Inkscape][9]。 + * 我喜欢的播客创建工具是 [Audacity][10]。它比起 Mac 上搭载的专有应用程序更加简单。我使用它去录制访谈和为视频演示创建配乐。 + * 在 MacOS 上我最早发现的多媒体播放器是 [VideoLan][11] (VLC)。 + * MacOS 内置的专有视频创建工具是一个非常好的产品,但是你也可以很轻松地去安装和使用 [OpenShot][12],它是一个非常好的内容创建工具。 + * 当我需要在我的客户端上分析网络时,我在我的 Mac 上使用了易于安装的 [Nmap][13] (Network Mapper) 和 [Wireshark][14] 工具。 + * 当我为图书管理员和其它教育工作者提供培训时,我在 MacOS 上使用 [VirtualBox][15] 去做 Raspbian、Fedora、Ubuntu 和其它 Linux 发行版的示范操作。 + * 我使用 [Etcher.io][16] 在我的 MacBook 上制作了一个引导盘,下载 ISO 文件,将它刻录到一个 U 盘上。 + * 我认为 [Firefox][17] 比起 MacBook Pro 自带的专有浏览器更易用更安全,并且它允许我跨操作系统去同步我的书签。 + * 当我使用电子书阅读器时,[Calibre][18] 是当之无愧的选择。它很容易去下载和安装,你甚至只需要几次点击就能将它配置为一台 [教室中使用的电子书服务器][19]。 + * 最近我给中学的学生教 Python 课程,我发现它可以很容易地从 [Python.org][20] 上下载和安装 Python 3 及 IDLE3 编辑器。我也喜欢学习数据科学,并与学生分享。不论你是对 Python 还是 R 感兴趣,我都建议你下载和 [安装][21] [Anaconda 发行版][22]。它包含了非常好的 iPython 编辑器、RStudio、Jupyter Notebooks、和 JupyterLab,以及其它一些应用程序。 + * [HandBrake][23] 是一个将你家里的旧的视频 DVD 转成 MP4 的工具,这样你就可以将它们共享到 YouTube、Vimeo、或者你的 MacOS 上的 [Kodi][24] 服务器上。 + +现在轮到你了:你在 MacOS(或 Windows)上都使用什么样的开源软件?在下面的评论区共享出来吧。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/open-source-tools-macos + +作者:[Don Watkins][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/don-watkins +[1]:https://en.wikipedia.org/wiki/Yum_(software) +[2]:https://en.wikipedia.org/wiki/DNF_(software) +[3]:https://en.wikipedia.org/wiki/APT_(Debian) +[4]:https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/OSX_Technology_Overview/SystemTechnology/SystemTechnology.html +[5]:https://www.gnu.org/software/coreutils/coreutils.html +[6]:https://www.openoffice.org/ +[7]:https://www.libreoffice.org/ +[8]:https://www.gimp.org/ +[9]:https://inkscape.org/en/ +[10]:https://www.audacityteam.org/ +[11]:https://www.videolan.org/index.html +[12]:https://www.openshot.org/ +[13]:https://nmap.org/ +[14]:https://www.wireshark.org/ +[15]:https://www.virtualbox.org/ +[16]:https://etcher.io/ +[17]:https://www.mozilla.org/en-US/firefox/new/ +[18]:https://calibre-ebook.com/ +[19]:https://opensource.com/article/17/6/raspberrypi-ebook-server +[20]:https://www.python.org/downloads/release/python-370/ +[21]:https://opensource.com/article/18/4/getting-started-anaconda-python +[22]:https://www.anaconda.com/download/#macos +[23]:https://handbrake.fr/ +[24]:https://kodi.tv/download diff --git a/published/20180710 6 open source cryptocurrency wallets.md b/published/20180710 6 open source cryptocurrency wallets.md new file mode 100644 index 0000000000..2b5aee97e6 --- /dev/null +++ b/published/20180710 6 open source cryptocurrency wallets.md @@ -0,0 +1,94 @@ +6 个开源的数字货币钱包 +====== + +> 想寻找一个可以存储和交易你的比特币、以太坊和其它数字货币的软件吗?这里有 6 个开源的软件可以选择。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus_cash_register.jpg?itok=7NKVKuPa) + +没有数字货币钱包,像比特币和以太坊这样的数字货币只不过是又一个空想罢了。这些钱包对于保存、发送、以及接收数字货币来说是必需的东西。 + +迅速成长的 [数字货币][1] 之所以是革命性的,都归功于它的去中心化,该网络中没有中央权威,每个人都享有平等的权力。开源技术是数字货币和 [区块链][2] 网络的核心所在。它使得这个充满活力的新兴行业能够从去中心化中获益 —— 比如,不可改变、透明和安全。 + +如果你正在寻找一个自由开源的数字货币钱包,请继续阅读,并开始去探索以下的选择能否满足你的需求。 + +### 1、 Copay + +[Copay][3] 是一个能够很方便地存储比特币的开源数字货币钱包。这个软件以 [MIT 许可证][4] 发布。 + +Copay 服务器也是开源的。因此,开发者和比特币爱好者可以在服务器上部署他们自己的应用程序来完全控制他们的活动。 + +Copay 钱包能让你手中的比特币更加安全,而不是去信任不可靠的第三方。它允许你使用多重签名来批准交易,并且支持在同一个 app 钱包内支持存储多个独立的钱包。 + +Copay 可以在多种平台上使用,比如 Android、Windows、MacOS、Linux、和 iOS。 + +### 2、 MyEtherWallet + +正如它的名字所示,[MyEtherWallet][5] (缩写为 MEW) 是一个以太坊钱包。它是开源的(遵循 [MIT 许可证][6])并且是完全在线的,可以通过 web 浏览器来访问它。 + +这个钱包的客户端界面非常简洁,它可以让你自信而安全地参与到以太坊区块链中。 + +### 3、 mSIGNA + +[mSIGNA][7] 是一个功能强大的桌面版应用程序,用于在比特币网络上完成交易。它遵循 [MIT 许可证][8] 并且在 MacOS、Windows、和 Linux 上可用。 + +这个区块链钱包可以让你完全控制你存储的比特币。其中一些特性包括用户友好性、灵活性、去中心化的离线密钥生成能力、加密的数据备份,以及多设备同步功能。 + +### 4、 Armory + +[Armory][9] 是一个在你的计算机上产生和保管比特币私钥的开源钱包(遵循 [GNU AGPLv3][10])。它通过使用冷存储和支持多重签名的能力增强了安全性。 + +使用 Armory,你可以在完全离线的计算机上设置一个钱包;你将通过仅查看watch-only功能在因特网上查看你的比特币具体信息,这样有助于改善安全性。这个钱包也允许你去创建多个地址,并使用它们去完成不同的事务。 + +Armory 可用于 MacOS、Windows、和几个比较有特色的 Linux 平台上(包括树莓派)。 + +### 5、 Electrum + +[Electrum][11] 是一个既对新手友好又具备专家功能的比特币钱包。它遵循 [MIT 许可证][12] 来发行。 + +Electrum 可以在你的本地机器上使用较少的资源来实现本地加密你的私钥,支持冷存储,并且提供多重签名能力。 + +它在各种操作系统和设备上都可以使用,包括 Windows、MacOS、Android、iOS 和 Linux,并且也可以在像 [Trezor][13] 这样的硬件钱包中使用。 + +### 6、 Etherwall + +[Etherwall][14] 是第一款可以在桌面计算机上存储和发送以太坊的钱包。它是一个遵循 [GPLv3 许可证][15] 的开源钱包。 + +Etherwall 非常直观而且速度很快。更重要的是,它增加了你的私钥安全性,你可以在一个全节点或瘦节点上来运行它。它作为全节点客户端运行时,可以允许你在本地机器上下载整个以太坊区块链。 + +Etherwall 可以在 MacOS、Linux 和 Windows 平台上运行,并且它也支持 Trezor 硬件钱包。 + +### 智者之言 + +自由开源的数字钱包在让更多的人快速上手数字货币方面扮演至关重要的角色。 + +在你使用任何数字货币软件钱包之前,你一定要确保你的安全,而且一定要记住并完全遵循确保你的资金安全的最佳实践。 + +如果你喜欢的开源数字货币钱包不在以上的清单中,请在下面的评论区共享出你所知道的开源钱包。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/crypto-wallets + +作者:[Dr.Michael J.Garbade][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/drmjg +[1]:https://www.liveedu.tv/guides/cryptocurrency/ +[2]:https://opensource.com/tags/blockchain +[3]:https://copay.io/ +[4]:https://github.com/bitpay/copay/blob/master/LICENSE +[5]:https://www.myetherwallet.com/ +[6]:https://github.com/kvhnuke/etherwallet/blob/mercury/LICENSE.md +[7]:https://ciphrex.com/ +[8]:https://github.com/ciphrex/mSIGNA/blob/master/LICENSE +[9]:https://www.bitcoinarmory.com/ +[10]:https://github.com/etotheipi/BitcoinArmory/blob/master/LICENSE +[11]:https://electrum.org/#home +[12]:https://github.com/spesmilo/electrum/blob/master/LICENCE +[13]:https://trezor.io/ +[14]:https://www.etherwall.com/ +[15]:https://github.com/almindor/etherwall/blob/master/LICENSE diff --git a/published/20180710 Display Weather Forecast In Your Terminal With Wttr.in.md b/published/20180710 Display Weather Forecast In Your Terminal With Wttr.in.md new file mode 100644 index 0000000000..e97d5afdd1 --- /dev/null +++ b/published/20180710 Display Weather Forecast In Your Terminal With Wttr.in.md @@ -0,0 +1,110 @@ +使用 Wttr.in 在你的终端中显示天气预报 +====== + +![](https://4.bp.blogspot.com/-NcP3j1tomlo/W0SIxp79cZI/AAAAAAAAA3Q/pmF3f2eeW_czoGuGgOu_MLudAUD_sVKIQCLcBGAs/s640/wttr-in-weather-console.png) + +[wttr.in][1] 是一个功能丰富的天气预报服务,它支持在命令行显示天气。它可以(根据你的 IP 地址)自动检测你的位置,也支持指定位置或搜索地理位置(如城市、山区等)等。哦,另外**你不需要安装它 —— 你只需要使用 cURL 或 Wget**(见下文)。 + +wttr.in 功能包括: + + * **显示当前天气以及 3 天内的天气预报,分为早晨、中午、傍晚和夜晚**(包括温度范围、风速和风向、可见度、降水量和概率) + * **可以显示月相** + * **基于你的 IP 地址自动检测位置** + * **允许指定城市名称、3 字母的机场代码、区域代码、GPS 坐标、IP 地址或域名**。你还可以指定地理位置,如湖泊、山脉、地标等) + * **支持多语言位置名称**(查询字符串必须以 Unicode 指定) + * **支持指定**天气预报显示的语言(它支持超过 50 种语言) + * **来自美国的查询使用 USCS 单位用于,世界其他地方使用公制系统**,但你可以通过附加 `?u` 使用 USCS,附加 `?m` 使用公制系统。 ) + * **3 种输出格式:终端的 ANSI,浏览器的 HTML 和 PNG** + +就像我在文章开头提到的那样,使用 wttr.in,你只需要 cURL 或 Wget,但你也可以在你的服务器上[安装它][3]。 或者你可以安装 [wego][4],这是一个使用 wtter.in 的终端气候应用,虽然 wego 要求注册一个 API 密钥来安装。 + +**在使用 wttr.in 之前,请确保已安装 cURL。**在 Debian、Ubuntu 或 Linux Mint(以及其他基于 Debian 或 Ubuntu 的 Linux 发行版)中,使用以下命令安装 cURL: + +``` +sudo apt install curl +``` + +### wttr.in 命令行示例 + +获取你所在位置的天气(wttr.in 会根据你的 IP 地址猜测你的位置): + +``` +curl wttr.in +``` + +通过在 `curl` 之后添加 `-4`,强制 cURL 将名称解析为 IPv4 地址(如果你用 IPv6 访问 wttr.in 有问题): + +``` +curl -4 wttr.in +``` + +如果你想检索天气预报保存为 png,**还可以使用 Wget**(而不是 cURL),或者你想这样使用它: + +``` +wget -O- -q wttr.in +``` + +如果相对 cURL 你更喜欢 Wget ,可以在下面的所有命令中用 `wget -O- -q` 替换 `curl`。 + +指定位置: + +``` +curl wttr.in/Dublin +``` + +显示地标的天气信息(本例中为艾菲尔铁塔): + +``` +curl wttr.in/~Eiffel+Tower +``` + +获取 IP 地址位置的天气信息(以下 IP 属于 GitHub): + +``` +curl wttr.in/@192.30.253.113 +``` + +使用 USCS 单位检索天气: + +``` +curl wttr.in/Paris?u +``` + +如果你在美国,强制 wttr.in 使用公制系统(SI): + +``` +curl wttr.in/New+York?m +``` + +使用 Wget 将当前天气和 3 天预报下载为 PNG 图像: + +``` +wget wttr.in/Istanbul.png +``` + +你可以指定 PNG 的[透明度][5],这在你要使用一个脚本自动添加天气信息到某些图片(比如墙纸)上有用。 + +**对于其他示例,请查看 wttr.in [项目页面][2]或在终端中输入:** + +``` +curl wttr.in/:help +``` + + +-------------------------------------------------------------------------------- + +via: https://www.linuxuprising.com/2018/07/display-weather-forecast-in-your.html + +作者:[Logix][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://plus.google.com/118280394805678839070 +[1]:https://wttr.in/ +[2]:https://github.com/chubin/wttr.in +[3]:https://github.com/chubin/wttr.in#installation +[4]:https://github.com/schachmat/wego +[5]:https://github.com/chubin/wttr.in#supported-formats diff --git a/published/20180710 Getting started with Perlbrew.md b/published/20180710 Getting started with Perlbrew.md new file mode 100644 index 0000000000..8d85de4527 --- /dev/null +++ b/published/20180710 Getting started with Perlbrew.md @@ -0,0 +1,88 @@ +Perlbrew 入门 +====== + +> 用 Perlbrew 在你系统上安装多个版本的 Perl。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_cafe_brew_laptop_desktop.jpg?itok=G-n1o1-o) + +有比在系统上安装了 Perl 更好的事情吗?那就是在系统中安装了多个版本的 Perl。使用 [Perlbrew][1] 你可以做到这一点。但是为什么呢,除了让你包围在 Perl 下之外,有什么好处吗? + +简短的回答是,不同版本的 Perl 是......不同的。程序 A 可能依赖于较新版本中不推荐使用的行为,而程序 B 需要去年无法使用的新功能。如果你安装了多个版本的 Perl,则每个脚本都可以使用最适合它的版本。如果您是开发人员,这也会派上用场,你可以针对多个版本的 Perl 测试你的程序,这样无论你的用户运行什么,你都知道它能否工作。 + +### 安装 Perlbrew + +另一个好处是 Perlbrew 会安装 Perl 到用户的家目录。这意味着每个用户都可以管理他们的 Perl 版本(以及相关的 CPAN 包),而无需与系统管理员联系。自助服务意味着为用户提供更快的安装,并为系统管理员提供更多时间来解决难题。 + +第一步是在你的系统上安装 Perlbrew。许多 Linux 发行版已经在包仓库中拥有它,因此你只需要 `dnf install perlbrew`(或者适用于你的发行版的命令)。你还可以使用 `cpan App::perlbrew` 从 CPAN 安装 `App::perlbrew` 模块。或者你可以在 [install.perlbrew.pl][2] 下载并运行安装脚本。 + +要开始使用 Perlbrew,请运行 `perlbrew init`。 + +### 安装新的 Perl 版本 + +假设你想尝试最新的开发版本(撰写本文时为 5.27.11)。首先,你需要安装包: + +``` +perlbrew install 5.27.11 +``` + +### 切换 Perl 版本 + +现在你已经安装了新版本,你可以将它用于该 shell: + +``` +perlbrew use 5.27.11 +``` + +或者你可以将其设置为你帐户的默认 Perl 版本(假设你按照 `perlbrew init` 的输出设置了你的配置文件): + +``` +perlbrew switch 5.27.11 +``` + +### 运行单个脚本 + +你也可以用特定版本的 Perl 运行单个命令: + +``` +perlberew exec 5.27.11 myscript.pl +``` + +或者,你可以针对所有已安装的版本运行命令。如果你想针对各种版本运行测试,这尤其方便。在这种情况下,请指定版本为 `perl`: + +``` +plperlbrew exec perl myscriptpl +``` + +### 安装 CPAN 模块 + +如果你想安装 CPAN 模块,`cpanm` 包是一个易于使用的界面,可以很好地与 Perlbrew 一起使用。用下面命令安装它: + +``` +perlbrew install-cpanm +``` + +然后,你可以使用 `cpanm` 命令安装 CPAN 模块: + +``` +cpanm CGI::simple +``` + +### 但是等下,还有更多! + +本文介绍了基本的 Perlbrew 用法。还有更多功能和选项可供选择。从查看 `perlbrew help` 的输出开始,或查看[App::perlbrew 文档][3]。你还喜欢 Perlbrew 的其他什么功能?让我们在评论中知道。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/perlbrew + +作者:[Ben Cotton][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/bcotton +[1]:https://perlbrew.pl/ +[2]:https://raw.githubusercontent.com/gugod/App-perlbrew/master/perlbrew-install +[3]:https://metacpan.org/pod/App::perlbrew diff --git a/published/20180710 Python Sets What Why and How.md b/published/20180710 Python Sets What Why and How.md new file mode 100644 index 0000000000..26100e251b --- /dev/null +++ b/published/20180710 Python Sets What Why and How.md @@ -0,0 +1,366 @@ +Python 集合是什么,为什么应该使用以及如何使用? +===== + +![Python Sets: What, Why and How](https://raw.githubusercontent.com/wilfredinni/pysheetComments/master/2018-july/python_sets/sets.png) + +Python 配备了几种内置数据类型来帮我们组织数据。这些结构包括列表、字典、元组和集合。 + +根据 Python 3 文档: + +> 集合是一个*无序*集合,没有*重复元素*。基本用途包括*成员测试*和*消除重复的条目*。集合对象还支持数学运算,如*并集*、*交集*、*差集*和*对等差分*。 + +在本文中,我们将回顾并查看上述定义中列出的每个要素的示例。让我们马上开始,看看如何创建它。 + +### 初始化一个集合 + +有两种方法可以创建一个集合:一个是给内置函数 `set()` 提供一个元素列表,另一个是使用花括号 `{}`。 + +使用内置函数 `set()` 来初始化一个集合: + +``` +>>> s1 = set([1, 2, 3]) +>>> s1 +{1, 2, 3} +>>> type(s1) + +``` + +使用 `{}`: + + +``` +>>> s2 = {3, 4, 5} +>>> s2 +{3, 4, 5} +>>> type(s2) + +>>> +``` + +如你所见,这两种方法都是有效的。但问题是,如果我们想要一个空的集合呢? + +``` +>>> s = {} +>>> type(s) + +``` + +没错,如果我们使用空花括号,我们将得到一个字典而不是一个集合。=) + +值得一提的是,为了简单起见,本文中提供的所有示例都将使用整数集合,但集合可以包含 Python 支持的所有 [可哈希的][6]hashable 数据类型。换句话说,即整数、字符串和元组,而不是*列表*或*字典*这样的可变类型。 + +``` +>>> s = {1, 'coffee', [4, 'python']} +Traceback (most recent call last): + File "", line 1, in +TypeError: unhashable type: 'list' +``` + +既然你知道了如何创建一个集合以及它可以包含哪些类型的元素,那么让我们继续看看*为什么*我们总是应该把它放在我们的工具箱中。 + +### 为什么你需要使用它 + +写代码时,你可以用不止一种方法来完成它。有些被认为是相当糟糕的,另一些则是清晰的、简洁的和可维护的,或者是 “[Python 式的][7]pythonic”。 + +根据 [Hitchhiker 对 Python 的建议][8]: + +> 当一个经验丰富的 Python 开发人员(Python 人Pythonista)调用一些不够 “Python 式的pythonic” 的代码时,他们通常认为着这些代码不遵循通用指南,并且无法被认为是以一种好的方式(可读性)来表达意图。 + +让我们开始探索 Python 集合那些不仅可以帮助我们提高可读性,还可以加快程序执行时间的方式。 + +#### 无序的集合元素 + +首先你需要明白的是:你无法使用索引访问集合中的元素。 + +``` +>>> s = {1, 2, 3} +>>> s[0] +Traceback (most recent call last): + File "", line 1, in +TypeError: 'set' object does not support indexing +``` + +或者使用切片修改它们: + +``` +>>> s[0:2] +Traceback (most recent call last): + File "", line 1, in +TypeError: 'set' object is not subscriptable +``` + +但是,如果我们需要删除重复项,或者进行组合列表(与)之类的数学运算,那么我们可以,并且*应该*始终使用集合。 + +我不得不提一下,在迭代时,集合的表现优于列表。所以,如果你需要它,那就加深对它的喜爱吧。为什么?好吧,这篇文章并不打算解释集合的内部工作原理,但是如果你感兴趣的话,这里有几个链接,你可以阅读它: + +* [时间复杂度][1] +* [set() 是如何实现的?][2] +* [Python 集合 vs 列表][3] +* [在列表中使用集合是否有任何优势或劣势,以确保独一无二的列表条目?][4] + +#### 没有重复项 + +写这篇文章的时候,我总是不停地思考,我经常使用 `for` 循环和 `if` 语句检查并删除列表中的重复元素。记得那时我的脸红了,而且不止一次,我写了类似这样的代码: + +``` +>>> my_list = [1, 2, 3, 2, 3, 4] +>>> no_duplicate_list = [] +>>> for item in my_list: +... if item not in no_duplicate_list: +... no_duplicate_list.append(item) +... +>>> no_duplicate_list +[1, 2, 3, 4] +``` + +或者使用列表解析: + +``` +>>> my_list = [1, 2, 3, 2, 3, 4] +>>> no_duplicate_list = [] +>>> [no_duplicate_list.append(item) for item in my_list if item not in no_duplicate_list] +[None, None, None, None] +>>> no_duplicate_list +[1, 2, 3, 4] +``` + +但没关系,因为我们现在有了武器装备,没有什么比这更重要的了: + +``` +>>> my_list = [1, 2, 3, 2, 3, 4] +>>> no_duplicate_list = list(set(my_list)) +>>> no_duplicate_list +[1, 2, 3, 4] +>>> +``` + +现在让我们使用 `timeit` 模块,查看列表和集合在删除重复项时的执行时间: + +``` +>>> from timeit import timeit +>>> def no_duplicates(list): +... no_duplicate_list = [] +... [no_duplicate_list.append(item) for item in list if item not in no_duplicate_list] +... return no_duplicate_list +... +>>> # 首先,让我们看看列表的执行情况: +>>> print(timeit('no_duplicates([1, 2, 3, 1, 7])', globals=globals(), number=1000)) +0.0018683355819786227 +``` + +``` +>>> from timeit import timeit +>>> # 使用集合: +>>> print(timeit('list(set([1, 2, 3, 1, 2, 3, 4]))', number=1000)) +0.0010220493243764395 +>>> # 快速而且干净 =) +``` + +使用集合而不是列表推导不仅让我们编写*更少的代码*,而且还能让我们获得*更具可读性*和*高性能*的代码。 + +注意:请记住集合是无序的,因此无法保证在将它们转换回列表时,元素的顺序不变。 + +[Python 之禅][9]: + +> 优美胜于丑陋Beautiful is better than ugly. + +> 明了胜于晦涩Explicit is better than implicit. + +> 简洁胜于复杂Simple is better than complex. + +> 扁平胜于嵌套Flat is better than nested. + +集合不正是这样美丽、明了、简单且扁平吗? + +#### 成员测试 + +每次我们使用 `if` 语句来检查一个元素,例如,它是否在列表中时,意味着你正在进行成员测试: + +``` +my_list = [1, 2, 3] +>>> if 2 in my_list: +... print('Yes, this is a membership test!') +... +Yes, this is a membership test! +``` + +在执行这些操作时,集合比列表更高效: + +``` +>>> from timeit import timeit +>>> def in_test(iterable): +... for i in range(1000): +... if i in iterable: +... pass +... +>>> timeit('in_test(iterable)', +... setup="from __main__ import in_test; iterable = list(range(1000))", +... number=1000) +12.459663048726043 +``` + +``` +>>> from timeit import timeit +>>> def in_test(iterable): +... for i in range(1000): +... if i in iterable: +... pass +... +>>> timeit('in_test(iterable)', +... setup="from __main__ import in_test; iterable = set(range(1000))", +... number=1000) +.12354438152988223 +``` + +注意:上面的测试来自于[这个][10] StackOverflow 话题。 + +因此,如果你在巨大的列表中进行这样的比较,尝试将该列表转换为集合,它应该可以加快你的速度。 + +### 如何使用 + +现在你已经了解了集合是什么以及为什么你应该使用它,现在让我们快速浏览一下,看看我们如何修改和操作它。 + +#### 添加元素 + +根据要添加的元素数量,我们要在 `add()` 和 `update()` 方法之间进行选择。 + +`add()` 适用于添加单个元素: + +``` +>>> s = {1, 2, 3} +>>> s.add(4) +>>> s +{1, 2, 3, 4} +``` + +`update()` 适用于添加多个元素: + +``` +>>> s = {1, 2, 3} +>>> s.update([2, 3, 4, 5, 6]) +>>> s +{1, 2, 3, 4, 5, 6} +``` + +请记住,集合会移除重复项。 + +#### 移除元素 + +如果你希望在代码中尝试删除不在集合中的元素时收到警报,请使用 `remove()`。否则,`discard()` 提供了一个很好的选择: + +``` +>>> s = {1, 2, 3} +>>> s.remove(3) +>>> s +{1, 2} +>>> s.remove(3) +Traceback (most recent call last): + File "", line 1, in +KeyError: 3 +``` + +`discard()` 不会引起任何错误: + +``` +>>> s = {1, 2, 3} +>>> s.discard(3) +>>> s +{1, 2} +>>> s.discard(3) +>>> # 什么都不会发生 +``` + +我们也可以使用 `pop()` 来随机丢弃一个元素: + +``` +>>> s = {1, 2, 3, 4, 5} +>>> s.pop() # 删除一个任意的元素 +1 +>>> s +{2, 3, 4, 5} +``` + +或者 `clear()` 方法来清空一个集合: + +``` +>>> s = {1, 2, 3, 4, 5} +>>> s.clear() # 清空集合 +>>> s +set() +``` + +#### union() + +`union()` 或者 `|` 将创建一个新集合,其中包含我们提供集合中的所有元素: + +``` +>>> s1 = {1, 2, 3} +>>> s2 = {3, 4, 5} +>>> s1.union(s2) # 或者 's1 | s2' +{1, 2, 3, 4, 5} +``` + +#### intersection() + +`intersection` 或 `&` 将返回一个由集合共同元素组成的集合: + +``` +>>> s1 = {1, 2, 3} +>>> s2 = {2, 3, 4} +>>> s3 = {3, 4, 5} +>>> s1.intersection(s2, s3) # 或者 's1 & s2 & s3' +{3} +``` + +#### difference() + +使用 `diference()` 或 `-` 创建一个新集合,其值在 “s1” 中但不在 “s2” 中: + +``` +>>> s1 = {1, 2, 3} +>>> s2 = {2, 3, 4} +>>> s1.difference(s2) # 或者 's1 - s2' +{1} +``` + +#### symmetric_diference() + +`symetric_difference` 或 `^` 将返回集合之间的不同元素。 + +``` +>>> s1 = {1, 2, 3} +>>> s2 = {2, 3, 4} +>>> s1.symmetric_difference(s2) # 或者 's1 ^ s2' +{1, 4} +``` + +### 结论 + +我希望在阅读本文之后,你会知道集合是什么,如何操纵它的元素以及它可以执行的操作。知道何时使用集合无疑会帮助你编写更清晰的代码并加速你的程序。 + +如果你有任何疑问,请发表评论,我很乐意尝试回答。另外,不要忘记,如果你已经理解了集合,它们在 [Python Cheatsheet][12] 中有自己的[一席之地][11],在那里你可以快速参考并重新认知你已经知道的内容。 + +-------------------------------------------------------------------------------- + +via: https://www.pythoncheatsheet.org/blog/python-sets-what-why-how + +作者:[wilfredinni][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.pythoncheatsheet.org/author/wilfredinni +[1]:https://wiki.python.org/moin/TimeComplexity +[2]:https://stackoverflow.com/questions/3949310/how-is-set-implemented +[3]:https://stackoverflow.com/questions/2831212/python-sets-vs-lists +[4]:https://mail.python.org/pipermail/python-list/2011-June/606738.html +[5]:https://www.pythoncheatsheet.org/author/wilfredinni +[6]:https://docs.python.org/3/glossary.html#term-hashable +[7]:http://docs.python-guide.org/en/latest/writing/style/ +[8]:http://docs.python-guide.org/en/latest/ +[9]:https://www.python.org/dev/peps/pep-0020/ +[10]:https://stackoverflow.com/questions/2831212/python-sets-vs-lists +[11]:https://www.pythoncheatsheet.org/#sets +[12]:https://www.pythoncheatsheet.org/ +  diff --git a/published/20180711 4 add-ons to improve your privacy on Thunderbird.md b/published/20180711 4 add-ons to improve your privacy on Thunderbird.md new file mode 100644 index 0000000000..3fb7d3f7a8 --- /dev/null +++ b/published/20180711 4 add-ons to improve your privacy on Thunderbird.md @@ -0,0 +1,64 @@ +4 个提高你在 Thunderbird 上隐私的加载项 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2017/08/tb-privacy-addons-816x345.jpg) + +Thunderbird 是由 [Mozilla][1] 开发的流行的免费电子邮件客户端。与 Firefox 类似,Thunderbird 提供了大量加载项来用于额外功能和自定义。本文重点介绍四个加载项,以改善你的隐私。 + +### Enigmail + +使用 GPG(GNU Privacy Guard)加密电子邮件是保持其内容私密性的最佳方式。如果你不熟悉 GPG,请[查看我们在这里的入门介绍][2]。 + +[Enigmail][3] 是使用 OpenPGP 和 Thunderbird 的首选加载项。实际上,Enigmail 与 Thunderbird 集成良好,可让你加密、解密、数字签名和验证电子邮件。 + +### Paranoia + +[Paranoia][4] 可让你查看有关收到的电子邮件的重要信息。用一个表情符号显示电子邮件在到达收件箱之前经过的服务器之间的加密状态。 + +黄色、快乐的表情告诉你所有连接都已加密。蓝色、悲伤的表情意味着有一个连接未加密。最后,红色的、害怕的表情表示在多个连接上该消息未加密。 + +还有更多有关这些连接的详细信息,你可以用来检查哪台服务器用于投递邮件。 + +### Sensitivity Header + +[Sensitivity Header][5] 是一个简单的加载项,可让你选择外发电子邮件的隐私级别。使用选项菜单,你可以选择敏感度:正常、个人、隐私和机密。 + +添加此标头不会为电子邮件添加额外的安全性。但是,某些电子邮件客户端或邮件传输/用户代理(MTA/MUA)可以使用此标头根据敏感度以不同方式处理邮件。 + +请注意,开发人员将此加载项标记为实验性的。 + +### TorBirdy + +如果你真的担心自己的隐私,[TorBirdy][6] 就是给你设计的加载项。它将 Thunderbird 配置为使用 [Tor][7] 网络。 + +据其[文档][8]所述,TorBirdy 为以前没有使用 Tor 的电子邮件帐户提供了少量隐私保护。 + +> 请记住,跟之前使用 Tor 访问的电子邮件帐户相比,之前没有使用 Tor 访问的电子邮件帐户提供**更少**的隐私/匿名/更弱的假名。但是,TorBirdy 仍然对现有帐户或实名电子邮件地址有用。例如,如果你正在寻求隐匿位置 —— 你经常旅行并且不想通过发送电子邮件来披露你的所有位置 —— TorBirdy 非常有效! + +请注意,要使用此加载项,必须在系统上安装 Tor。 + +照片由 [Braydon Anderson][9] 在 [Unsplash][10] 上发布。 + + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/4-addons-privacy-thunderbird/ + +作者:[Clément Verna][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org +[1]:https://www.mozilla.org/en-US/ +[2]:https://fedoramagazine.org/gnupg-a-fedora-primer/ +[3]:https://addons.mozilla.org/en-US/thunderbird/addon/enigmail/ +[4]:https://addons.mozilla.org/en-US/thunderbird/addon/paranoia/?src=cb-dl-users +[5]:https://addons.mozilla.org/en-US/thunderbird/addon/sensitivity-header/?src=cb-dl-users +[6]:https://addons.mozilla.org/en-US/thunderbird/addon/torbirdy/?src=cb-dl-users +[7]:https://www.torproject.org/ +[8]:https://trac.torproject.org/projects/tor/wiki/torbirdy +[9]:https://unsplash.com/photos/wOHH-NUTvVc?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText +[10]:https://unsplash.com/search/photos/privacy?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText diff --git a/published/20180711 Install Microsoft Windows Fonts In Ubuntu 18.04 LTS.md b/published/20180711 Install Microsoft Windows Fonts In Ubuntu 18.04 LTS.md new file mode 100644 index 0000000000..767db534c6 --- /dev/null +++ b/published/20180711 Install Microsoft Windows Fonts In Ubuntu 18.04 LTS.md @@ -0,0 +1,174 @@ +在 Ubuntu 18.04 LTS 上安装 Microsoft Windows 字体 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2016/07/Install-Microsoft-Windows-Fonts-in-Ubuntu-1-720x340.png) + +大多数教育机构仍在使用 Microsoft 字体, 我不清楚其他国家是什么情况。但在泰米尔纳德邦(印度的一个州), **Times New Roman** 和 **Arial** 字体主要被用于大学和学校的几乎所有文档工作、项目和作业。不仅是教育机构,而且一些小型组织、办公室和商店仍在使用 MS Windows 字体。以防万一,如果你需要在 Ubuntu 桌面版上使用 Microsoft 字体,请按照以下步骤安装。 + +**免责声明**: Microsoft 已免费发布其核心字体。 但**请注意 Microsoft 字体是禁止使用在其他操作系统中**。在任何 Linux 操作系统中安装 MS 字体之前请仔细阅读 EULA 。我们不负责这种任何种类的盗版行为。 + +(LCTT 译注:本文只做技术探讨,并不代表作者、译者和本站鼓励任何行为。) + +### 在 Ubuntu 18.04 LTS 桌面版上安装 MS 字体 + +如下所示安装 MS TrueType 字体: + +``` +$ sudo apt update +$ sudo apt install ttf-mscorefonts-installer +``` + +然后将会出现 Microsoft 的最终用户协议向导,点击 **OK** 以继续。 + +![][2] + +点击 **Yes** 已接受 Microsoft 的协议: + +![][3] + +安装字体之后, 我们需要使用命令行来更新字体缓存: + +``` +$ sudo fc-cache -f -v +``` + +**示例输出:** + +``` +/usr/share/fonts: caching, new cache contents: 0 fonts, 6 dirs +/usr/share/fonts/X11: caching, new cache contents: 0 fonts, 4 dirs +/usr/share/fonts/X11/Type1: caching, new cache contents: 8 fonts, 0 dirs +/usr/share/fonts/X11/encodings: caching, new cache contents: 0 fonts, 1 dirs +/usr/share/fonts/X11/encodings/large: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/X11/misc: caching, new cache contents: 89 fonts, 0 dirs +/usr/share/fonts/X11/util: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/cMap: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/cmap: caching, new cache contents: 0 fonts, 5 dirs +/usr/share/fonts/cmap/adobe-cns1: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/cmap/adobe-gb1: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/cmap/adobe-japan1: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/cmap/adobe-japan2: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/cmap/adobe-korea1: caching, new cache contents: 0 fonts, 0 dirs +/usr/share/fonts/opentype: caching, new cache contents: 0 fonts, 2 dirs +/usr/share/fonts/opentype/malayalam: caching, new cache contents: 3 fonts, 0 dirs +/usr/share/fonts/opentype/noto: caching, new cache contents: 24 fonts, 0 dirs +/usr/share/fonts/truetype: caching, new cache contents: 0 fonts, 46 dirs +/usr/share/fonts/truetype/Gargi: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/Gubbi: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/Nakula: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/Navilu: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/Sahadeva: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/Sarai: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/abyssinica: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/dejavu: caching, new cache contents: 6 fonts, 0 dirs +/usr/share/fonts/truetype/droid: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/fonts-beng-extra: caching, new cache contents: 6 fonts, 0 dirs +/usr/share/fonts/truetype/fonts-deva-extra: caching, new cache contents: 3 fonts, 0 dirs +/usr/share/fonts/truetype/fonts-gujr-extra: caching, new cache contents: 5 fonts, 0 dirs +/usr/share/fonts/truetype/fonts-guru-extra: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/fonts-kalapi: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/fonts-orya-extra: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/fonts-telu-extra: caching, new cache contents: 2 fonts, 0 dirs +/usr/share/fonts/truetype/freefont: caching, new cache contents: 12 fonts, 0 dirs +/usr/share/fonts/truetype/kacst: caching, new cache contents: 15 fonts, 0 dirs +/usr/share/fonts/truetype/kacst-one: caching, new cache contents: 2 fonts, 0 dirs +/usr/share/fonts/truetype/lao: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/liberation: caching, new cache contents: 16 fonts, 0 dirs +/usr/share/fonts/truetype/liberation2: caching, new cache contents: 12 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-assamese: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-bengali: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-devanagari: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-gujarati: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-kannada: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-malayalam: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-oriya: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-punjabi: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-tamil: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-tamil-classical: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/lohit-telugu: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/malayalam: caching, new cache contents: 11 fonts, 0 dirs +/usr/share/fonts/truetype/msttcorefonts: caching, new cache contents: 60 fonts, 0 dirs +/usr/share/fonts/truetype/noto: caching, new cache contents: 2 fonts, 0 dirs +/usr/share/fonts/truetype/openoffice: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/padauk: caching, new cache contents: 4 fonts, 0 dirs +/usr/share/fonts/truetype/pagul: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/samyak: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/samyak-fonts: caching, new cache contents: 3 fonts, 0 dirs +/usr/share/fonts/truetype/sinhala: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/tibetan-machine: caching, new cache contents: 1 fonts, 0 dirs +/usr/share/fonts/truetype/tlwg: caching, new cache contents: 58 fonts, 0 dirs +/usr/share/fonts/truetype/ttf-khmeros-core: caching, new cache contents: 2 fonts, 0 dirs +/usr/share/fonts/truetype/ubuntu: caching, new cache contents: 13 fonts, 0 dirs +/usr/share/fonts/type1: caching, new cache contents: 0 fonts, 1 dirs +/usr/share/fonts/type1/gsfonts: caching, new cache contents: 35 fonts, 0 dirs +/usr/local/share/fonts: caching, new cache contents: 0 fonts, 0 dirs +/home/sk/.local/share/fonts: skipping, no such directory +/home/sk/.fonts: skipping, no such directory +/var/cache/fontconfig: cleaning cache directory +/home/sk/.cache/fontconfig: cleaning cache directory +/home/sk/.fontconfig: not cleaning non-existent cache directory +fc-cache: succeeded +``` + +### 在 Linux 和 Windows 双启动的机器上安装 MS 字体 + +如果你有 Linux 和 Windows 的双启动系统,你可以轻松地从 Windows C 驱动器上安装 MS 字体。 +你所要做的就是挂载 Windows 分区(C:/windows)。 + +我假设你已经在 Linux 中将 `C:\Windows` 分区挂载在了 `/Windowsdrive` 目录下。 + +现在,将字体位置链接到你的 Linux 系统的字体文件夹,如下所示: + +``` +ln -s /Windowsdrive/Windows/Fonts /usr/share/fonts/WindowsFonts +``` + +链接字体文件之后,使用命令行重新生成 fontconfig 缓存: + +``` +fc-cache +``` + +或者,将所有的 Windows 字体复制到 `/usr/share/fonts` 目录下并使用一下命令安装字体: + +``` +mkdir /usr/share/fonts/WindowsFonts +cp /Windowsdrive/Windows/Fonts/* /usr/share/fonts/WindowsFonts +chmod 755 /usr/share/fonts/WindowsFonts/* +``` + +最后,使用命令行重新生成 fontconfig 缓存: + +``` +fc-cache +``` + + +### 测试 Windows 字体 + +安装 MS 字体后打开 LibreOffice 或 GIMP。 现在,你将会看到 Microsoft coretype 字体。 + +![][4] + +就是这样, 希望这本指南有用。我再次警告你,在其他操作系统中使用 MS 字体是被禁止的。在安装 MS 字体之前请先阅读 Microsoft 许可协议。 + +如果你觉得我们的指南有用,请在你的社区、专业网络上分享并支持我们。还有更多好东西在等着我们。持续访问! + +庆祝吧!! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/install-microsoft-windows-fonts-ubuntu-16-04/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[Auk7F7](https://github.com/Auk7F7) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2016/07/ms-fonts-1.png +[3]:http://www.ostechnix.com/wp-content/uploads/2016/07/ms-fonts-2.png +[4]:http://www.ostechnix.com/wp-content/uploads/2016/07/ms-fonts-3.png diff --git a/published/20180718 How To Force User To Change Password On Next Login In Linux.md b/published/20180718 How To Force User To Change Password On Next Login In Linux.md new file mode 100644 index 0000000000..5608feb816 --- /dev/null +++ b/published/20180718 How To Force User To Change Password On Next Login In Linux.md @@ -0,0 +1,157 @@ +如何强制用户在下次登录 Linux 时更改密码 +====== + +当你使用默认密码创建用户时,你必须强制用户在下一次登录时更改密码。 + +当你在一个组织中工作时,此选项是强制性的。因为老员工可能知道默认密码,他们可能会也可能不会尝试不当行为。 + +这是安全投诉之一,所以,确保你必须以正确的方式处理此事而无任何失误。即使是你的团队成员也要一样做。 + +大多数用户都很懒,除非你强迫他们更改密码,否则他们不会这样做。所以要做这个实践。 + +出于安全原因,你需要经常更改密码,或者至少每个月更换一次。 + +确保你使用的是难以猜测的密码(大小写字母,数字和特殊字符的组合)。它至少应该为 10-15 个字符。 + +我们运行了一个 shell 脚本来在 Linux 服务器中创建一个用户账户,它会自动为用户附加一个密码,密码是实际用户名和少量数字的组合。 + +我们可以通过使用以下两种方法来实现这一点: + + * passwd 命令 + * chage 命令 + +**建议阅读:** + +- [如何在 Linux 上检查用户所属的组][1] +- [如何在 Linux 上检查创建用户的日期][2] +- [如何在 Linux 中重置/更改用户密码][3] +- [如何使用 passwd 命令管理密码过期和老化][4] + +### 方法 1:使用 passwd 命令 + +`passwd` 的意思是“密码”。它用于更新用户的身份验证令牌。`passwd` 命令/实用程序用于设置、修改或更改用户的密码。 + +普通的用户只能更改自己的账户,但超级用户可以更改任何账户的密码。 + +此外,我们还可以使用其他选项,允许用户执行其他活动,例如删除用户密码、锁定或解锁用户账户、设置用户账户的密码过期时间等。 + +在 Linux 中这可以通过调用 Linux-PAM 和 Libuser API 执行。 + +在 Linux 中创建用户时,用户详细信息将存储在 `/etc/passwd` 文件中。`passwd` 文件将每个用户的详细信息保存为带有七个字段的单行。 + +此外,在 Linux 系统中创建新用户时,将更新以下四个文件。 + + * `/etc/passwd`: 用户详细信息将在此文件中更新。 + * `/etc/shadow`: 用户密码信息将在此文件中更新。 + * `/etc/group`: 新用户的组详细信息将在此文件中更新。 + * `/etc/gshadow`: 新用户的组密码信息将在此文件中更新。 + +#### 如何使用 passwd 命令执行此操作 + +我们可以使用 `passwd` 命令并添加 `-e` 选项来执行此操作。 + +为了测试这一点,让我们创建一个新用户账户,看看它是如何工作的。 + +``` +# useradd -c "2g Admin - Magesh M" magesh && passwd magesh +Changing password for user magesh. +New password: +Retype new password: +passwd: all authentication tokens updated successfully. +``` + +使用户账户的密码失效,那么在下次登录尝试期间,用户将被迫更改密码。 + +``` +# passwd -e magesh +Expiring password for user magesh. +passwd: Success +``` + +当我第一次尝试使用此用户登录系统时,它要求我设置一个新密码。 + +``` +login as: magesh +[email protected]'s password: +You are required to change your password immediately (root enforced) +WARNING: Your password has expired. +You must change your password now and login again! +Changing password for user magesh. +Changing password for magesh. +(current) UNIX password: +New password: +Retype new password: +passwd: all authentication tokens updated successfully. +Connection to localhost closed. +``` + +### 方法 2:使用 chage 命令 + +`chage` 意即“改变时间”。它会更改用户密码过期信息。 + +`chage` 命令会改变上次密码更改日期之后需要修改密码的天数。系统使用此信息来确定用户何时必须更改他/她的密码。 + +它允许用户执行其他活动,例如设置帐户到期日期,到期后设置密码失效,显示帐户过期信息,设置密码更改前的最小和最大天数以及设置到期警告天数。 + +#### 如何使用 chage 命令执行此操作 + +让我们在 `chage` 命令的帮助下,通过添加 `-d` 选项执行此操作。 + +为了测试这一点,让我们创建一个新用户帐户,看看它是如何工作的。我们将创建一个名为 `thanu` 的用户帐户。 + +``` +# useradd -c "2g Editor - Thanisha M" thanu && passwd thanu +Changing password for user thanu. +New password: +Retype new password: +passwd: all authentication tokens updated successfully. +``` + +要实现这一点,请使用 `chage` 命令将用户的上次密码更改日期设置为 0。 + +``` +# chage -d 0 thanu + +# chage -l thanu +Last password change : Jul 18, 2018 +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 +``` + +当我第一次尝试使用此用户登录系统时,它要求我设置一个新密码。 + +``` +login as: thanu +[email protected]'s password: +You are required to change your password immediately (root enforced) +WARNING: Your password has expired. +You must change your password now and login again! +Changing password for user thanu. +Changing password for thanu. +(current) UNIX password: +New password: +Retype new password: +passwd: all authentication tokens updated successfully. +Connection to localhost closed. +``` + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/how-to-force-user-to-change-password-on-next-login-in-linux/ + +作者:[Prakash Subramanian][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/prakash/ +[1]:https://www.2daygeek.com/how-to-check-which-groups-a-user-belongs-to-on-linux/ +[2]:https://www.2daygeek.com/how-to-check-user-created-date-on-linux/ +[3]:https://www.2daygeek.com/passwd-command-examples/ +[4]:https://www.2daygeek.com/passwd-command-examples-part-l/ diff --git a/published/20180718 How to check free disk space in Linux.md b/published/20180718 How to check free disk space in Linux.md new file mode 100644 index 0000000000..88a9d7ae73 --- /dev/null +++ b/published/20180718 How to check free disk space in Linux.md @@ -0,0 +1,71 @@ +如何检查 Linux 中的可用磁盘空间 +====== + +> 用这里列出的方便的工具来跟踪你的磁盘利用率。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/find-file-linux-code_magnifying_glass_zero.png?itok=E2HoPDg0) + +跟踪磁盘利用率信息是系统管理员(和其他人)的日常待办事项列表之一。Linux 有一些内置的使用程序来帮助提供这些信息。 + +### df + +`df` 命令意思是 “disk-free”,显示 Linux 系统上可用和已使用的磁盘空间。 + +`df -h` 以人类可读的格式显示磁盘空间。 + +`df -a` 显示文件系统的完整磁盘使用情况,即使 Available(可用) 字段为 0。 + +![](https://opensource.com/sites/default/files/uploads/df-ha.png) + +`df -T` 显示磁盘使用情况以及每个块的文件系统类型(例如,xfs、ext2、ext3、btrfs 等)。 + +`df -i` 显示已使用和未使用的 inode。 + +![](https://opensource.com/sites/default/files/uploads/df-ti.png) + +### du + +`du` 显示文件,目录等的磁盘使用情况,默认情况下以 kb 为单位显示。 + +`du -h` 以人类可读的方式显示所有目录和子目录的磁盘使用情况。 + +`du -a` 显示所有文件的磁盘使用情况。 + +`du -s` 提供特定文件或目录使用的总磁盘空间。 + +![](https://opensource.com/sites/default/files/uploads/du-has.png) + +### ls -al + +`ls -al` 列出了特定目录的全部内容及大小。 + +![](https://opensource.com/sites/default/files/uploads/ls-al.png) + +### stat + +`stat <文件/目录> `显示文件/目录或文件系统的大小和其他统计信息。 + +![](https://opensource.com/sites/default/files/uploads/stat.png) + +### fdisk -l + +`fdisk -l` 显示磁盘大小以及磁盘分区信息。 + +![](https://opensource.com/sites/default/files/uploads/fdisk.png) + +这些是用于检查 Linux 文件空间的大多数内置实用程序。有许多类似的工具,如 [Disks][1](GUI 工具),[Ncdu][2] 等,它们也显示磁盘空间的利用率。你有你最喜欢的工具而它不在这个列表上吗?请在评论中分享。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/how-check-free-disk-space-linux + +作者:[Archit Modi][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[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/architmodi +[1]:https://wiki.gnome.org/Apps/Disks +[2]:https://dev.yorhel.nl/ncdu diff --git a/published/20180724 Learn how to build your own Twitter bot with Python.md b/published/20180724 Learn how to build your own Twitter bot with Python.md new file mode 100644 index 0000000000..4b96a80563 --- /dev/null +++ b/published/20180724 Learn how to build your own Twitter bot with Python.md @@ -0,0 +1,137 @@ +学习如何使用 Python 构建你自己的 Twitter 机器人 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/07/twitterbot-816x345.jpg) + +Twitter 允许用户将博客帖子和文章[分享][1]给全世界。使用 Python 和 Tweepy 库使得创建一个 Twitter 机器人来接管你的所有的推特变得非常简单。这篇文章告诉你如何去构建这样一个机器人。希望你能将这些概念也同样应用到其他的在线服务的项目中去。 + +### 开始 + +[tweepy][2] 库可以让创建一个 Twitter 机器人的过程更加容易上手。它包含了 Twitter 的 API 调用和一个很简单的接口。 + +下面这些命令使用 `pipenv` 在一个虚拟环境中安装 tweepy。如果你没有安装 `pipenv`,可以看一看我们之前的文章[如何在 Fedora 上安装 Pipenv][3]。 + +``` +$ mkdir twitterbot +$ cd twitterbot +$ pipenv --three +$ pipenv install tweepy +$ pipenv shell +``` + +### Tweepy —— 开始 + +要使用 Twitter API ,机器人需要通过 Twitter 的授权。为了解决这个问题, tweepy 使用了 OAuth 授权标准。你可以通过在 创建一个新的应用来获取到凭证。 + + +#### 创建一个新的 Twitter 应用 + +当你填完了表格并点击了“创建你自己的 Twitter 应用Create your Twitter application”的按钮后,你可以获取到该应用的凭证。 Tweepy 需要用户密钥API Key用户密码API Secret,这些都可以在 “密钥和访问令牌Keys and Access Tokens” 中找到。 + +![][4] + +向下滚动页面,使用“创建我的访问令牌Create my access token”按钮生成一个“访问令牌Access Token” 和一个“访问令牌密钥Access Token Secret”。 + +#### 使用 Tweppy —— 输出你的时间线 + +现在你已经有了所需的凭证了,打开一个文件,并写下如下的 Python 代码。 + +``` +import tweepy +auth = tweepy.OAuthHandler("your_consumer_key", "your_consumer_key_secret") +auth.set_access_token("your_access_token", "your_access_token_secret") +api = tweepy.API(auth) +public_tweets = api.home_timeline() +for tweet in public_tweets: + print(tweet.text) +``` + +在确保你正在使用你的 Pipenv 虚拟环境后,执行你的程序。 + +``` +$ python tweet.py +``` + +上述程序调用了 `home_timeline` 方法来获取到你时间线中的 20 条最近的推特。现在这个机器人能够使用 tweepy 来获取到 Twitter 的数据,接下来尝试修改代码来发送 tweet。 + +#### 使用 Tweepy —— 发送一条推特 + +要发送一条推特 ,有一个容易上手的 API 方法 `update_status` 。它的用法很简单: + +``` +api.update_status("The awesome text you would like to tweet") +``` + +Tweepy 拓展为制作 Twitter 机器人准备了非常多不同有用的方法。要获取 API 的详细信息,请查看[文档][5]。 + + +### 一个杂志机器人 + +接下来我们来创建一个搜索 Fedora Magazine 的推特并转推这些的机器人。 + +为了避免多次转推相同的内容,这个机器人存放了最近一条转推的推特的 ID 。 两个助手函数 `store_last_id` 和 `get_last_id` 将会帮助存储和保存这个 ID。 + +然后,机器人使用 tweepy 搜索 API 来查找 Fedora Magazine 的最近的推特并存储这个 ID。 + +``` +import tweepy + +def store_last_id(tweet_id): + """ Stores a tweet id in text file """ + with open('lastid', 'w') as fp: + fp.write(str(tweet_id)) + + +def get_last_id(): + """ Retrieve the list of tweets that were + already retweeted """ + + with open('lastid') as fp: + return fp.read() + +if __name__ == '__main__': + + auth = tweepy.OAuthHandler("your_consumer_key", "your_consumer_key_secret") + auth.set_access_token("your_access_token", "your_access_token_secret") + + api = tweepy.API(auth) + + try: + last_id = get_last_id() + except FileNotFoundError: + print("No retweet yet") + last_id = None + + for tweet in tweepy.Cursor(api.search, q="fedoramagazine.org", since_id=last_id).items(): + if tweet.user.name == 'Fedora Project': + store_last_id(tweet.id) + #tweet.retweet() + print(f'"{tweet.text}" was retweeted') +``` + +为了只转推 Fedora Magazine 的推特 ,机器人搜索内容包含 fedoramagazine.org 和由 「Fedora Project」 Twitter 账户发布的推特。 + +### 结论 + +在这篇文章中你看到了如何使用 tweepy 的 Python 库来创建一个自动阅读、发送和搜索推特的 Twitter 应用。现在,你能使用你自己的创造力来创造一个你自己的 Twitter 机器人。 + +这篇文章的演示源码可以在 [Github][6] 找到。 + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/learn-build-twitter-bot-python/ + +作者:[Clément Verna][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[Bestony](https://github.com/bestony) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org +[1]:https://twitter.com +[2]:https://tweepy.readthedocs.io/en/v3.5.0/ +[3]:https://linux.cn/article-9827-1.html +[4]:https://fedoramagazine.org/wp-content/uploads/2018/07/Screenshot-from-2018-07-19-20-17-17.png +[5]:http://docs.tweepy.org/en/v3.5.0/api.html#id1 +[6]:https://github.com/cverna/magabot diff --git a/sources/talk/20180306 Try, learn, modify- The new IT leader-s code.md b/sources/talk/20180306 Try, learn, modify- The new IT leader-s code.md deleted file mode 100644 index bcc0729f77..0000000000 --- a/sources/talk/20180306 Try, learn, modify- The new IT leader-s code.md +++ /dev/null @@ -1,59 +0,0 @@ -Try, learn, modify: The new IT leader's code -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/ship_wheel_gear_devops_kubernetes.png?itok=xm4a74Kv) - -Just about every day, new technological developments threaten to destabilize even the most intricate and best-laid business plans. Organizations often find themselves scrambling to adapt to new conditions, and that's created a shift in how they plan for the future. - -According to a 2017 [study][1] by CompTIA, only 34% of companies are currently developing IT architecture plans that extend beyond 12 months. One reason for that shift away from a longer-term plan is that business contexts are changing so quickly that planning any further into the future is nearly impossible. "If your company is trying to set a plan that will last five to 10 years down the road," [CIO.com writes][1], "forget it." - -I've heard similar statements from countless customers and partners around the world. Technological innovations are occurring at an unprecedented pace. - -The result is that long-term planning is dead. We need to be thinking differently about the way we run our organizations if we're going to succeed in this new world. - -### How planning died - -As I wrote in The Open Organization, traditionally-run organizations are optimized for industrial economies. They embrace hierarchical structures and rigidly prescribed processes as they work to achieve positional competitive advantage. To be successful, they have to define the strategic positions they want to achieve. Then they have to formulate and dictate plans for getting there, and execute on those plans in the most efficient ways possible—by coordinating activities and driving compliance. - -Management's role is to optimize this process: plan, prescribe, execute. It consists of saying: Let's think of a competitively advantaged position; let's configure our organization to ultimately get there; and then let's drive execution by making sure all aspects of the organization comply. It's what I'll call "mechanical management," and it's a brilliant solution for a different time. - -In today's volatile and uncertain world, our ability to predict and define strategic positions is diminishing—because the pace of change, the rate of introduction of new variables, is accelerating. Classic, long-term, strategic planning and execution isn't as effective as it used to be. - -If long-term planning has become so difficult, then prescribing necessary behaviors is even more challenging. And measuring compliance against a plan is next to impossible. - -All this dramatically affects the way people work. Unlike workers in the traditionally-run organizations of the past—who prided themselves on being able to act repetitively, with little variation and comfortable certainty—today's workers operate in contexts of abundant ambiguity. Their work requires greater creativity, intuition, and critical judgment—there is a greater demand to deviate from yesterday's "normal" and adjust to today's new conditions. - -In today's volatile and uncertain world, our ability to predict and define strategic positions is diminishing—because the pace of change, the rate of introduction of new variables, is accelerating. - -Working in this new way has become more critical to value creation. Our management systems must focus on building structures, systems, and processes that help create engaged, motivated workers—people who are enabled to innovate and act with speed and agility. - -We need to come up with a different solution for optimizing organizations for a very different economic era, one that works from the bottom up rather than the top down. We need to replace that old three-step formula for success—plan, prescribe, execute—with one much better suited to today's tumultuous climate: try, learn, modify. - -### Try, learn, modify - -Because conditions can change so rapidly and with so little warning—and because the steps we need to take next are no longer planned in advance—we need to cultivate environments that encourage creative trial and error, not unyielding allegiance to a five-year schedule. Here are just a few implications of beginning to work this way: - - * **Shorter planning cycles (try).** Rather than agonize over long-term strategic directions, managers need to be thinking of short-term experiments they can try quickly. They should be seeking ways to help their teams take calculated risks and leverage the data at their disposal to make best guesses about the most beneficial paths forward. They can do this by lowering overhead and giving teams the freedom to try new approaches quickly. - * **Higher tolerance for failure (learn).** Greater frequency of experimentation means greater opportunity for failure. Creative and resilient organizations have a[significantly higher tolerance for failure][2] than traditional organizations do. Managers should treat failures as learning opportunities—moments to gather feedback on the tests their teams are running. - * **More adaptable structures (modify).** An ability to easily modify organizational structures and strategic directions—and the willingness to do it when conditions necessitate—is the key to ensuring that organizations can evolve in line with rapidly changing environmental conditions. Managers can't be wedded to any idea any longer than that idea proves itself to be useful for accomplishing a short-term goal. - - - -If long-term planning is dead, then long live shorter-term experimentation. Try, learn, and modify—that's the best path forward during uncertain times. - -[Subscribe to our weekly newsletter][3] to learn more about open organizations. - --------------------------------------------------------------------------------- - -via: https://opensource.com/open-organization/18/3/try-learn-modify - -作者:[Jim Whitehurst][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/remyd -[1]:https://www.cio.com/article/3246027/enterprise-architecture/the-death-of-long-term-it-planning.html?upd=1515780110970 -[2]:https://opensource.com/open-organization/16/12/building-culture-innovation-your-organization -[3]:https://opensource.com/open-organization/resources/newsletter diff --git a/sources/talk/20180308 What is open source programming.md b/sources/talk/20180308 What is open source programming.md index 4eeef6d9fd..a8a09ddd25 100644 --- a/sources/talk/20180308 What is open source programming.md +++ b/sources/talk/20180308 What is open source programming.md @@ -1,3 +1,5 @@ +Translating by Valoniakim + What is open source programming? ====== diff --git a/sources/talk/20180402 Understanding Linux filesystems- ext4 and beyond.md b/sources/talk/20180402 Understanding Linux filesystems- ext4 and beyond.md index 9e1b37b043..52b6367455 100644 --- a/sources/talk/20180402 Understanding Linux filesystems- ext4 and beyond.md +++ b/sources/talk/20180402 Understanding Linux filesystems- ext4 and beyond.md @@ -1,3 +1,5 @@ +Translating by HardworkFish + Understanding Linux filesystems: ext4 and beyond ====== diff --git a/sources/talk/20180419 3 tips for organizing your open source project-s workflow on GitHub.md b/sources/talk/20180419 3 tips for organizing your open source project-s workflow on GitHub.md index 29e4ea2f48..1f9b80cd13 100644 --- a/sources/talk/20180419 3 tips for organizing your open source project-s workflow on GitHub.md +++ b/sources/talk/20180419 3 tips for organizing your open source project-s workflow on GitHub.md @@ -1,3 +1,4 @@ +translating by aiwhj 3 tips for organizing your open source project's workflow on GitHub ====== diff --git a/sources/talk/20180626 How to build a professional network when you work in a bazaar.md b/sources/talk/20180626 How to build a professional network when you work in a bazaar.md deleted file mode 100644 index 0fa3323b0c..0000000000 --- a/sources/talk/20180626 How to build a professional network when you work in a bazaar.md +++ /dev/null @@ -1,95 +0,0 @@ - 翻译中 by ZenMoore -How to build a professional network when you work in a bazaar -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/connection_people_team_collaboration.png?itok=0_vQT8xV) - -Professional social networking—creating interpersonal connections between work colleagues or professionals—can take many forms and span organizations across industries. Establishing professional networks takes time and effort, and when someone either joins or departs an organization, that person's networks often need to be rebuilt in a new work environment. - -Professional social networks perform similar functions in different organizations—information sharing, mentorship, opportunities, work interests, and more—but the methods and reasons for making particular connections in an organization can vary between conventional and open organizations. And these differences make a difference: to the way colleagues relate, to how they build trust, to the amount and kinds of diversity within the organization, and to the forces that create collaboration. All these elements are interrelated, and they contribute to and shape the social networks people form. - -An open organization's emphasis on inclusivity can produce networks more effective at solving business problems than those that emerge in conventional, hierarchical organizations. This notion has a long history in open source thinking. For example, in [The Cathedral and the Bazaar][1], Eric Raymond writes that "Sociologists years ago discovered that the averaged opinion of a mass of equally expert (or equally ignorant) observers is quite a bit more reliable a predictor than the opinion of a single randomly-chosen one of the observers." So let's examine how the structure and purpose of social networks impact what each type of organization values. - -### Social networks in conventional organizations - -When I worked in conventional organizations and would describe what I do for work, the first thing people asked me was how I was related to someone else, usually a director-level leader. "Is that under Hira?" they'd say. "Do you work for Malcolm?" That makes sense considering conventional organizations function in a "top-down" way; when trying to situate work or an employee, people wanted to understand the structure of the network from that top-down perspective. - -In other words, in conventional organizations the social network depends upon the hierarchical structure, so they track one another. In fact, even figuring out where an employee exists within a network is a very "top-down organization" kind of concern. - -But that isn't all that the underlying hierarchy does. It also vets associates. A focus on the top-down network can determine an employee's "value" in the network because the network itself is a system of ongoing power relations that grants people placed in its different locations varying levels of value. It downplays the value of individual talents and skills. Therefore, a person's connections in the conventional organization facilitate that person's ability to be proactive, heard, influential, and supported in their careers. - -An open organization's emphasis on inclusivity can produce networks more effective at solving business problems than those that emerge in conventional, hierarchical organizations. - -The conventional organization's formal structure defines employees' social networks in particular ways—some of which might be benefits, some of which might be disadvantages, depending on one's context—such as: - - * It's easier to know "who's who" and see how people are related more quickly (often this builds trusted networks within the particular hierarchy). - * Often, this increased understanding of relationships means there's less redundancy of work (projects have a clear owner embedded in a particular network) and communication (people know who is responsible for communicating what). - * Associates can feel "stuck" in a power structure, or like they can't "break into" power structures that sometimes (too often?) don't work, diminishing meritocracy. - * Crossing silos of work and effort is difficult and collaboration suffers. - * Power transfers slowly; a person's ability to engage is determined more in alignment with network created by the hierarchical structure than by other factors (like individual abilities), reducing what is considered "community" and the benefits of its membership. - * Competition seems more clear; understanding "who is vying for what" usually occurs within a recognized and delimited hierarchical structure (and the scarcity of positions in the power network increase competition so competition can be more fierce). - * Adaptability can suffer when a more rigid network defines the limits of flexibility; what the network "wants" and the limits of collaboration can be affected this same way. - * Execution occurs much more easily in rigid networks, where direction is clear and often leaders manage by overdirecting. - * Risk is decreased when the social networks are less flexible; people know what needs to happen, how, and when (but this isn't always "bad" considering the wide range of work in an organization; some job functions require less risk, such as HR, mergers and acquisitions, legal, etc.). - * Trust within the network is greater, especially when an employee is part of the formal network (when someone is not part of the network, exclusion can be particularly difficult to manage or to rectify). - - - -### Social networks in open organizations - -While open organizations can certainly have hierarchical structures, they don't operate only according to that network. Their professional networking structure is more flexible (or "all over and whenever"). - -An open organization is more associate-centric than leader-centric. - -In an open organization, when I've described what I do for work virtually no one asks "for whom?" An open organization is more associate-centric than leader-centric. Open values like inclusivity and specific governance systems like meritocracy contribute to this; it's not who you know but rather it's what you know and how you use it (e.g., "bottom-up"). In an open organization, I don't feel like I'm fighting to show my value; my ideas are inherently valuable. I sometimes have to demonstrate how using my idea is more valuable than using someone else's idea―but that means I'm vetting myself within the community of my associates (including leadership), rather than being vetted solely by top-down leadership. - -In this way, an open organization doesn't assess employees based on the network but rather on what they know of the associate as an individual. Does this person have good ideas? Does she work toward those ideas (lead them) by using the open organization values (that is, share those ideas and work across the organization to include others and work transparently, etc.)? - -Open organizations also structure social networks in particular ways (which, again, could be advantageous or disadvantageous depending on one's goals and desires), including: - - * People are more responsible for their networks, reputations, skills, and careers. - * Competition (for resources, power, promotions, etc.) decreases because these organizations are by nature more collaborative (even during a "collision," the best outcome is negotiation, not winning, and competition hones the ideas instead of creating wedges between people). - * Power is more fluid and dynamic, flowing from person to person (but this also means there can be a misunderstanding about accountability or responsibility and activities can go undone or unfinished because there is not a clear [sense of ownership][2]). - * Trust is created "one associate at a time," rather than through the reputation of the network in which the person is situated. - * Networks self-configure around a variety of work and activities, rising reactively around opportunity (this aids innovation but can add to confusion because who makes decisions, and who is in "control" is less clear). - * Rate of execution can decrease in confusing contexts because what to do and how and when to do it requires leadership skills in setting direction and creating engaged and skilled associates. - * Flexible social networks also increase innovation and risk; ideas circulate faster and are more novel, and execution is less assured. - * Trust is based on associate relationships (as it should be!), rather than on sheer deference to structure. - - - -### Making it work - -If you're thinking of transitioning from one type of organizational structure to another, consider the following when building and maintaining your professional social networks. - -#### Tips from conventional organizations - - * Structure and control around decision-making isn't a bad thing; operational frameworks need to be clear and transparent, and decision-makers need to account for their decisions. - * Excelling at execution requires managers to provide focus and the ability to provide sufficient context while filtering out anything that could distract or confuse. - * Established networks help large groups of people work in concert and manage risk. - - - -#### Tips from open organizations - - * Strong leaders are those who can provide different levels of clarity and guidance according to the various styles and preferences of associates and teams without creating inflexible networks. - * Great ideas win more, not established networks. - * People are more responsible for their reputations. - * The circulation of ideas and information is key to innovation. Loosening the networks in your organization can help these two elements occur with increased frequency and breadth. - - - --------------------------------------------------------------------------------- - -via: https://opensource.com/open-organization/18/6/building-professional-social-networks-openly - -作者:[Heidi Hess;von Ludewig][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/heidi-hess-von-ludewig -[1]:http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s04.html -[2]:https://opensource.com/open-organization/18/4/rethinking-ownership-across-organization diff --git a/sources/talk/20180627 CIP- Keeping the Lights On with Linux.md b/sources/talk/20180627 CIP- Keeping the Lights On with Linux.md deleted file mode 100644 index 73b9c14be6..0000000000 --- a/sources/talk/20180627 CIP- Keeping the Lights On with Linux.md +++ /dev/null @@ -1,52 +0,0 @@ -CIP: Keeping the Lights On with Linux -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/cip-lights.jpg?itok=6LAUoIzt) - -Modern civil infrastructure is all around us -- in power plants, radar systems, traffic lights, dams, weather systems, and so on. Many of these infrastructure projects exist for decades, if not longer, so security and longevity are paramount. - -And, many of these systems are powered by Linux, which offers technology providers more control over these issues. However, if every provider is building their own solution, this can lead to fragmentation and duplication of effort. Thus, the primary goal of [Civil Infrastructure Platform (CIP)][1] is to create an open source base layer for industrial use-cases in these systems, such as embedded controllers and gateway devices. - -“We have a very conservative culture in this area because once we create a system, it has to be supported for more than ten years; in some cases for over 60 years. That’s why this project was created, because every player in this industry had the same issue of being able to use Linux for a long time,” says Yoshitake Kobayashi is Technical Steering Committee Chair of CIP. - -CIP’s concept is to create a very fundamental system to use open source software on controllers. This base layer comprises the Linux kernel and a small set of common open source software like libc, busybox, and so on. Because longevity of software is a primary concern, CIP chose Linux kernel 4.4, which is the LTS release of the kernel maintained by Greg Kroah-Hartman. - -### Collaboration - -Since CIP has an upstream first policy, the code that they want in the project must be in the upstream kernel. To create a proactive feedback loop with the kernel community, CIP hired Ben Hutchings as the official maintainer of CIP. Hutchings is known for the work he has done on Debian LTS release, which also led to an official collaboration between CIP and the Debian project. - -Under the newly forged collaboration, CIP will use Debian LTS to build the platform. CIP will also help Debian Long Term Support (LTS) to extend the lifetime of all Debian stable releases. CIP will work closely with Freexian, a company that offers commercial services around Debian LTS. The two organizations will focus on interoperability, security, and support for open source software for embedded systems. CIP will also provide funding for some of the Debian LTS activities. - -“We are excited about this collaboration as well as the CIP’s support of the Debian LTS project, which aims to extend the support lifetime to more than five years. Together, we are committed to long-term support for our users and laying the ‘foundation’ for the cities of the future.” said Chris Lamb, Debian Project Leader. - -### Security - -Security is the biggest concern, said Kobayashi. Although most of the civil infrastructure is not connected to the Internet for obvious security reasons (you definitely don’t want a nuclear power plant to be connected to the Internet), there are many other risks. - -Just because the system itself is not connected to the Internet, that doesn’t mean it’s immune to all threats. Other systems -- like user’s laptops -- may connect to the Internet and then be plugged into the local systems. If someone receives a malicious file as an attachment with email, it can “contaminate” the internal infrastructure. - -Thus, it’s critical to keep all software running on such controllers up to date and fully patched. To ensure security, CIP has also backported many components of the Kernel Self Protection project. CIP also follows one of the strictest cybersecurity standards -- IEC 62443 -- which defines processes and tests to ensure the system is more secure. - -### Going forward - -As CIP is maturing, it's extending its collaboration with providers of Linux. In addition to collaboration with Debian and freexian, CIP recently added Cybertrust Japan Co, Ltd., a supplier of enterprise Linux operating system, as a new Silver member. - -Cybertrust joins other industry leaders, such as Siemens, Toshiba, Codethink, Hitachi, Moxa, Plat’Home, and Renesas, in their work to create a reliable and secure Linux-based embedded software platform that is sustainable for decades to come. - -The ongoing work of these companies under the umbrella of CIP will ensure the integrity of the civil infrastructure that runs our modern society. - -Learn more at the [Civil Infrastructure Platform][1] website. - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/2018/6/cip-keeping-lights-linux - -作者:[Swapnil Bhartiya][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/arnieswap -[1]:https://www.cip-project.org/ diff --git a/sources/talk/20180702 My first sysadmin mistake.md b/sources/talk/20180702 My first sysadmin mistake.md deleted file mode 100644 index efc3fec5ac..0000000000 --- a/sources/talk/20180702 My first sysadmin mistake.md +++ /dev/null @@ -1,42 +0,0 @@ -My first sysadmin mistake -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_mistakes.png?itok=dN0OoIl5) - -If you work in IT, you know that things never go completely as you think they will. At some point, you'll hit an error or something will go wrong, and you'll end up having to fix things. That's the job of a systems administrator. - -As humans, we all make mistakes. Sometimes, we are the error in the process, or we are what went wrong. As a result, we end up having to fix our own mistakes. That happens. We all make mistakes, typos, or errors. - -As a young systems administrator, I learned this lesson the hard way. I made a huge blunder. But thanks to some coaching from my supervisor, I learned not to dwell on my errors, but to create a "mistake strategy" to set things right. Learn from your mistakes. Get over it, and move on. - -My first job was a Unix systems administrator for a small company. Really, I was a junior sysadmin, but I worked alone most of the time. We were a small IT team, just the three of us. I was the only sysadmin for 20 or 30 Unix workstations and servers. The other two supported the Windows servers and desktops. - -Any systems administrators reading this probably won't be surprised to know that, as an unseasoned, junior sysadmin, I eventually ran the `rm` command in the wrong directory. As root. I thought I was deleting some stale cache files for one of our programs. Instead, I wiped out all files in the `/etc` directory by mistake. Ouch. - -My clue that I'd done something wrong was an error message that `rm` couldn't delete certain subdirectories. But the cache directory should contain only files! I immediately stopped the `rm` command and looked at what I'd done. And then I panicked. All at once, a million thoughts ran through my head. Did I just destroy an important server? What was going to happen to the system? Would I get fired? - -Fortunately, I'd run `rm *` and not `rm -rf *` so I'd deleted only files. The subdirectories were still there. But that didn't make me feel any better. - -Immediately, I went to my supervisor and told her what I'd done. She saw that I felt really dumb about my mistake, but I owned it. Despite the urgency, she took a few minutes to do some coaching with me. "You're not the first person to do this," she said. "What would someone else do in your situation?" That helped me calm down and focus. I started to think less about the stupid thing I had just done, and more about what I was going to do next. - -I put together a simple strategy: Don't reboot the server. Use an identical system as a template, and re-create the `/etc` directory. - -Once I had my plan of action, the rest was easy. It was just a matter of running the right commands to copy the `/etc` files from another server and edit the configuration so it matched the system. Thanks to my practice of documenting everything, I used my existing documentation to make any final adjustments. I avoided having to completely restore the server, which would have meant a huge disruption. - -To be sure, I learned from that mistake. For the rest of my years as a systems administrator, I always confirmed what directory I was in before running any command. - -I also learned the value of building a "mistake strategy." When things go wrong, it's natural to panic and think about all the bad things that might happen next. That's human nature. But creating a "mistake strategy" helps me stop worrying about what just went wrong and focus on making things better. I may still think about it, but knowing my next steps allows me to "get over it." - - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/7/my-first-sysadmin-mistake - -作者:[Jim Hall][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/jim-hall diff --git a/sources/talk/20180703 How to make a career move from proprietary to open source technology.md b/sources/talk/20180703 How to make a career move from proprietary to open source technology.md deleted file mode 100644 index b59b8d6678..0000000000 --- a/sources/talk/20180703 How to make a career move from proprietary to open source technology.md +++ /dev/null @@ -1,60 +0,0 @@ -Translating by vk - -How to make a career move from proprietary to open source technology -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/open%20source_collaboration_0.png?itok=YEl_GXbv) - -I started my journey as a software engineer at Northern Telecom, where I developed proprietary software for carrier-grade telephone switches. Although I learned Pascal while in college, at Northern Telecom I was trained in a proprietary programming language based on C. I also used a proprietary operating system and a proprietary version-control software. - -I enjoyed working in the proprietary environment and had opportunities to do some interesting work. Then I had a turning point in my career that made me think about things. It happened at a career fair. I was invited to speak at a STEM career panel at a local middle school. I shared with the students my day-to-day responsibilities as a software engineer, and one of the students asked me a question: "Is this really what you always wanted to do in life? Do you enjoy and love what you are doing?" - -Whenever my manager asked me this question, I would safely answer, "Yes, of course, I do!" But I had never been asked this by an innocent 6th grader who is interested in STEM. My response to the student was the same: "Of course I do!" - -The truth was I did enjoy my career, but that student had me thinking… I had to reassess where I was in my career. I thought about the proprietary environment. I was an expert in my specialty, but that was one of the downsides: I was only modifying my area of code. Was I learning about different types of technology in a closed system? Was my skillset still marketable? Was I going through the motions? Is this what I really want to continue to do? - -I thought all of those things, and I wondered: Was the challenge and creativity still there? - -Life went on, and I had major life changes. I left Nortel Networks and took a career break to focus on my family. - -When I was ready to re-enter the workforce, that 6th-grader's questions lingered in my mind. Is this want I've always wanted to do? I applied for several jobs that appeared to be a good match, but the feedback I received from recruiters was that they were looking for people with five or more years of Java and Python skills. It seemed that the skills and knowledge I had acquired over the course of my 15-year career at Nortel were no longer in demand or in use. - -### Challenges - -My first challenge was figuring out how to leverage the skills I gained while working at a proprietary company. I noticed there had been a huge shift in IT from proprietary to open source. I decided to learn and teach myself Python because it was the most in-demand language. Once I started to learn Python, I realized I needed a project to gain experience and make myself more marketable. - -The next challenge was figuring out how to gain project experience with my new knowledge of Python. Former colleagues and my husband directed me toward open source software. When I googled "open source project," I discovered there were hundreds of open source projects, ranging from very small (one contributor) ones, to communities of less than 50 people, to huge projects with hundreds of contributors all over the world. - -I did a keyword search in GitHub of technical terms that fit my skillset and found several projects that matched. I decided to leverage my interests and networking background to make my first contribution to OpenStack. I also discovered the [Outreachy][1] program, which offers three-month paid internships to people who are under-represented in tech. - -### Lessons learned - -One of the first things I learned is that I could contribute in many different ways. I could contribute to documentation and user design. I could also contribute by writing test cases. These are skillsets I developed over my career, and I didn't need five years of experience to contribute. All I needed was the commitment and drive to make a contribution. - -After my first contribution to OpenStack was merged into the release, I was accepted into the Outreachy program. One of the best things about Outreachy is the mentor I was assigned to help me navigate the open source world. - -Here are three other valuable lessons I learned that might help others who are interested in breaking into the open source world: - -**Be persistent.** Be persistent in finding the right open source projects. Look for projects that match your core skillset. Also, look for ones that have a code of conduct and that are welcoming to newcomers—especially those with a getting started guide for newcomers. Be persistent in engaging in the community. - -**Be patient.** Adjusting to open source takes time. Engagingin the community takes time. Giving thoughtful and meaningful feedback takes time, and reading and considering feedback you receive takes time. - -**Participate in the community.** You don't have to have permission to work on a certain technology or a certain area. You can decide what you would like to work on and dive in. - -Petra Sargent will present [You Can Teach an Old Dog New Tricks: Moving From Proprietary to Open Source][2] at the 20th annual [OSCON][3] event, July 16-19 in Portland, Oregon. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/7/career-move - -作者:[Petra Sargent][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/psargent -[1]:https://www.outreachy.org/ -[2]:https://conferences.oreilly.com/oscon/oscon-or/public/schedule/speaker/307631 -[3]:https://conferences.oreilly.com/oscon/oscon-or diff --git a/sources/talk/20180710 How I Fully Quit Google And You Can Too.md b/sources/talk/20180710 How I Fully Quit Google And You Can Too.md new file mode 100644 index 0000000000..b284fa916d --- /dev/null +++ b/sources/talk/20180710 How I Fully Quit Google And You Can Too.md @@ -0,0 +1,218 @@ +martin2011qi is translating + +How I Fully Quit Google (And You Can, Too) +============================================================ + +>My enlightening quest to break free of a tech giant + +Over the past six months, I have gone on a surprisingly tough, time-intensive, and enlightening quest — to quit using, entirely, the products of just one company — Google. What should be a simple task was, in reality, many hours of research and testing. But I did it. Today, I am Google free, part of the western world’s ultimate digital minority, someone who does not use products from the world’s two most valuable technology companies (yes, I don’t use [Facebook either][6]). + +This guide is to show you how I quit the Googleverse, and the alternatives I choose based on my own research and personal needs. I’m not a technologist or a coder, but my work as a journalist requires me to be aware of security and privacy issues. + +I chose all of these alternatives based solely on their merit, usability, cost, and whether or not they had the functionality I desired. My choices are not universal as they reflect my own needs and desires. Nor do they reflect any commercial interests. None of the alternatives listed below paid me or are giving me any commission whatsoever for citing their services. + +### But First: Why? + +Here’s the thing. I don’t hate Google. In fact, not too long ago, I was a huge fan of Google. I remember the moment when I first discovered one amazing search engine back in the late 1990’s, when I was still in high school. Google was light years ahead of alternatives such as Yahoo, Altavista, or Ask Jeeves. It really did help users find what they were seeking on a web that was, at that time, a mess of broken websites and terrible indexes. + +Google soon moved from just search to providing other services, many of which I embraced. I was an early adopter of Gmail back in 2005, when you could only join [via invites][7]. It introduced threaded conversations, archiving, labels, and was without question the best email service I had ever used. When Google introduced its Calendar tool in 2006, it was revolutionary in how easy it was to color code different calendars, search for events, and send shareable invites. And Google Docs, launched in 2007, was similarly amazing. During my first full time job, I pushed my team to do everything as a Google spreadsheet, document, or presentation that could be edited by many of us simultaneously. + +Like many, I was a victim of Google creep. Search led to email, to documents, to analytics, photos, and dozens of other services all built on top of and connected to each other. Google turned from a company releasing useful products to one that has ensnared us, and the internet as a whole, into its money-making, data gathering apparatus. Google is pervasive in our digital lives in a way no other corporation is or ever has been. It’s relatively easy to quit using the products of other tech giants. With Apple, you’re either in the iWorld, or out. Same with Amazon, and even Facebook owns only a few platforms and quitting is more of a [psychological challenge][8] than actually difficult. + +Google, however, is embedded everywhere. No matter what laptop, smartphone, or tablet you have, chances are you have at least one Google app on there. Google is synonymous for search, maps, email, our browser, the operating system on most of our smartphones. It even provides the “[services][9]” and analytics that other apps and websites rely on, such as Uber’s use of Google Maps to operate its ride-hailing service. + +Google is now a word in many languages, and its global dominance means there are not many well-known, or well-used alternatives to its behemoth suite of tools — especially if you are privacy minded. We all started using Google because it, in many ways, provided better alternatives to existing products. But now, we can’t quit because either Google has become a default, or because its dominance means that alternatives can’t get enough traction. + +The truth is, alternatives do exist, many of which have launched in the years since Edward Snowden revealed Google’s participation in [Prism][10]. I embarked on this project late last year. After six months of research, testing, and a lot of trial and error, I was able to find privacy minded alternatives to all the Google products I was using. Some, to my surprise, were even better. + +### A Few Caveats + +One of the biggest challenges to quitting is the fact that most alternatives, particularly those in the open source of privacy space, are really not user friendly. I’m not a techie. I have a website, understand how to manage Wordpress, and can do some basic troubleshooting, but I can’t use Command Line or do anything that requires coding. + +These alternatives are ones you can easily use with most, if not all, the functionality of their Google alternatives. For some, though, you’ll need your own web host or access to a server. + +Also, [Google Takeout][11] is your friend. Being able to download my entire email history and upload it on my computer to access via Thunderbird meant I have easy access to over a decade of emails. The same can be said about Calendar or Docs, the latter of which I converted to ODT format and now keep on my cloud alternative, further detailed below. + +### The Easy Ones + +#### Search + +[DuckDuckGo][12] and [Startpage][13] are both privacy-centric search engines that do not collect any of your search data. Together, they take care of everything I was previously using Google search for. + + _Other Alternatives: _ Really not many when Google has 74% global market share, with the remainder mostly due to it’s being blocked in China. Ask.com is still around. And there’s Bing… + +#### Chrome + +[Mozilla Firefox][14] — it recently got [a big upgrade][15], which is a huge improvement from earlier versions. It’s created by a non-profit foundation that actively works to protect privacy. There’s really no reason at all to use Chrome. + + _Other Alternatives: _ Avoid Opera and Vivaldi, as they use Chrome as their base. [Brave][16] is my secondary browser. + +#### Hangouts and Google Chat + +[Jitsi Meet][17] — an open source, free alternative to Google Hangouts. You can use it directly from a browser or download the app. It’s fast, secure, and works on nearly every platform. + + _Other Alternatives: Z_ oom has become popular among those in the professional space, but requires you to pay for most features. [Signal][18], an open source, secure messaging app, also has a call function but only on mobile. Avoid Skype, as it’s both a data hog and has a terrible interface. + +#### Google Maps + +Desktop: [Here WeGo][19] — it loads faster and can find nearly everything that Google Maps can. For some reason, they’re missing some countries, like Japan. + +Mobile: [Maps.me][20] — here Maps was my initial choice here too, but became less useful once they modified the app to focus on driver navigation. Maps.me is pretty good, and has far better offline functionality than Google, something very useful to a frequent traveler like me. + + _Other alternatives_ : [OpenStreetMap][21] is a project I wholeheartedly support, but it’s functionality was severely lacking. It couldn’t even find my home address in Oakland. + +### Easy but Not Free + +Some of this was self-inflicted. For example, when looking for an alternative to Gmail, I did not just want to switch to an alternative from another tech giant. That meant no Yahoo Mail, or Microsoft Outlook as that would not address my privacy concerns. + +Remember, the fact that so many of Google’s services are free (not to mention those of its competitors including Facebook) is because they are actively monetizing our data. For alternatives to survive without this level of data monetization, they have to charge us. I am willing to pay to protect my privacy, but do understand that not everyone is able to make this choice. + +Think of it this way: Remember when you used to send letters and had to pay for stamps? Or when you bought weekly planners from the store? Essentially, this is the cost to use a privacy-focused email or calendar app. It’s not that bad. + +#### Gmail + +[ProtonMail][22] — it was founded by former CERN scientists and is based in Switzerland, a country with strong privacy protections. But what really appealed to me about ProtonMail was that it, unlike most other privacy minded email programs, was user friendly. The interface is similar to Gmail, with labels, filters, and folders, and you don’t need to know anything about security or privacy to use it. + +The free version only gives you 500MB of storage space. I opted for a paid 5GB account along with their VPN service. + + _Other alternatives_ : [Fastmail][23] is not as privacy oriented but also has a great interface. There’s also [Hushmail][24] and [Tutanota][25], both with similar features to ProtonMail. + +#### Calendar + +[Fastmail][26] Calendar — this was surprisingly tough, and brings up another issue. Google products have become so ubiquitous in so many spaces that start-ups don’t even bother to create alternatives anymore. After trying a few other mediocre options, I ended getting a recommendation and choose Fastmail as a dual second-email and calendar option. + +### More Technical + +These require some technical knowledge or access to your web host service. I do include simpler alternatives that I researched but did not end up choosing. + +#### Google Docs, Drive, Photos, and Contacts + +[NextCloud ][27]— a fully featured, secure, open source cloud suite with an intuitive, user-friendly interface. The catch is that you’ll need your own host to use Nextcloud. I already had one for my own website and was able to quickly install NextCloud using Softaculous on my host’s C-Panel. You’ll need a HTTPS certificate, which I got for free from[ Let’s Encrypt][28]. Not as easy as opening a Google Drive account but not too challenging either. + +I also use Nextcloud as an alternative for Google’s photo storage and contacts, which I sync with my phone using CalDev. + + _Other alternative_ s: There are other open source options such as [OwnCloud][29] or [Openstack][30]. Some for-profit options are good too, as top choices Dropbox and Box are independent entities that don’t profit off of your data. + +#### Google Analytics + +[Matomo ][31]— formally called Piwic, this is a self-hosted analytics platform. While not as feature rich as Google Analytics, it is plenty fine for understanding basic website traffic, with the added bonus that you aren’t gifting that traffic data to Google. + + _Other alternatives: _ Not much really. [OpenWebAnalytics][32] is another open source option, and there are some for-profit alternatives too, such as GoStats and Clicky. + +#### Android + +[LineageOS][33] + [F-Droid App Store][34]. Sadly, the smartphone world has become a literal duopoly, with Google’s Android and Apple’s iOS controlling the entire market. The few usable alternatives that existed a few years ago, such as Blackberry OS or Mozilla’s Firefox OS, are no longer being maintained. + +So the next best option is Lineage OS: a privacy minded, open source version of Android that can be installed without Google services or Apps. It requires some technical knowledge as the installation process is not completely straightforward, but it works really well, and lacks the bloatware that comes with most Android installations. + + _Other alternatives: _ Ummm…Windows 10 Mobile? [PureOS][35] looks promising, as does [UbuntuTouch][36]. + +### Unexpected Challenges + +Firstly, this took much longer than I planned due to the lack of good resources about usable alternatives, and the challenge in moving data from Google to other platforms. + +But the toughest thing was email, and it has nothing to do with ProtonMail or Google. + +Before I joined Gmail in 2004, I probably switched emails once a year. My first account was with Hotmail, and I then used Mail.com, Yahoo Mail, and long-forgotten services like Bigfoot. I never recall having an issue when I changed email providers. I would just tell all my friends to update their address books and change the email address on other web accounts. It used to be necessary to change email addresses regularly — remember how spam would take over older inboxes? + +In fact, one of Gmail’s best innovations was its ability to filter out spam. That meant no longer needing to change emails. + +Email is key to using the internet. You need it to open a Facebook account, to use online banking, to post on message boards, and many more. So when you switch accounts, you need to update your email address on all these different services. + +To my surprise, changing from Gmail today is a major hassle because of all the places that require email addresses to set up an account. Several sites no longer let you do it from the backend on your own. One service actually required me to close my account and open a new one as they were unable to change my email, and then they transferred over my account data manually. Others forced me to call customer service and request an email account change, meaning time wasted on hold. + +Even more amazingly, others accepted my change, and then continued to send messages to my old Gmail account, requiring another phone call. Others were even more annoying, sending some messages to my new email, but still using my old account for other emails. This became such a cumbersome process that I ended up leaving my Gmail account open for several months alongside my new ProtonMail account just to make sure important emails did not get lost. This was the main reason this took me six months. + +People so rarely change their emails these days that most companies’ platforms are not designed to deal with the possibility. It’s a telling sign of the sad state of the web today that it was easier to change your email back in 2002 than it is in 2018\. Technology does not always move forward. + +### So, Are These Google Alternatives Any Good? + +Some are actually better! Jitsi Meet runs smoother, requires less bandwidth, and is more platform friendly than Hangouts. Firefox is more stable and less of a memory suck than Chrome. Fastmail’s Calendar has far better time zone integration. + +Others are adequate equivalents. ProtonMail has most of the features of Gmail but lacks some useful integrations, such as the Boomerang email scheduler I was using before. It also has a lacking Contacts interface, but I’m using Nextcloud for that. Speaking of Nextcloud, it’s great for hosting files, contacts, and has a nifty notes tool (and lots of other plug-ins). But it does not have the rich multi-editing features of Google Docs. I’ve not yet found a workable alternative in my budget. There is Collabora Office, but it requires me to upgrade my server, something that is not feasible for me. + +Some depend on location. Maps.me is actually better than Google Maps in some countries (such as Indonesia) and far worse in others (including America). + +Others require me to sacrifice some features or functionality. Piwic is a poor man’s Google Analytics, and lacks many of the detailed reports or search functions of the former. DuckDuckGo is fine for general searches but has issues with specific searches, and both it and StartPage sometimes fail when I’m searching for non-English language content. + +### In the End, I Don’t Miss Google at All + +In fact, I feel liberated. To be so dependent on a single company for so many products is a form of servitude, especially when your data is what you’re often paying with. Moreover, many of these alternatives are, in fact, better. And there is real comfort in knowing you are in control of your data. + +If we have no choice but to use Google products, then we lose what little power we have as consumers. + +I want Google, Facebook, Apple, and other tech giants to stop taking users for granted, to stop trying to force us inside their all-encompassing ecosystems. I also want new players to be able to emerge and compete, just as, once upon a time, Google’s new search tool could compete with the then-industry giants Altavista and Yahoo, or Facebook’s social network was able to compete with MySpace and Friendster. The internet was a better place because Google gave us the opportunity to have a better search. Choice is good. As is portability. + +Today, few of us even try other products because we’re just so used to Googling. We don’t change emails cause it’s hard. We don’t even try to use a Facebook alternative because all of our friends are on Facebook. I understand. + +You don’t have to quit Google entirely. But give other alternatives a chance. You might be surprised, and remember why you loved the web way back when. + +* * * + +#### Other Resources + +I created this resource not to be an all-encompassing guide but a story of how I was able to quit Google. Here are some resources that show other alternatives. Some are far too technical for me, and others I just didn’t have time to explore. + +* [Localization Lab][2] has a detailed list of open source or privacy-tech projects — some highly technical, others quite user friendly. + +* [Framasoft ][3]has an entire suite of mostly open-source Google alternatives, though many are just in French. + +* Restore Privacy has also [collected a list of alternatives][4]. + +Your turn. Please share your favorite Google alternatives in the responses or via Twitter. I am sure there are many that I missed and would love to try. I don’t plan to stick with the alternatives listed above forever. + +-------------------------------------------------------------------------------- + +作者简介: + +Nithin Coca + +Freelance journalist covering politics, environment & human rights + social impacts of tech globally. For more http://www.nithincoca.com + +-------------------------------------------------------------------------------- + +via: https://medium.com/s/story/how-i-fully-quit-google-and-you-can-too-4c2f3f85793a + +作者:[Nithin Coca][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://medium.com/@excinit +[1]:https://medium.com/@excinit +[2]:https://www.localizationlab.org/projects/ +[3]:https://framasoft.org/?l=en +[4]:https://restoreprivacy.com/google-alternatives/ +[5]:https://medium.com/@excinit +[6]:https://www.nithincoca.com/2011/11/20/7-months-no-facebook/ +[7]:https://www.quora.com/How-long-was-Gmail-in-private-%28invitation-only%29-beta +[8]:https://www.theverge.com/2018/4/28/17293056/facebook-deletefacebook-social-network-monopoly +[9]:https://en.wikipedia.org/wiki/Google_Play_Services +[10]:https://www.theguardian.com/world/2013/jun/06/us-tech-giants-nsa-data +[11]:https://takeout.google.com/settings/takeout +[12]:https://duckduckgo.com/ +[13]:https://www.startpage.com/ +[14]:https://www.mozilla.org/en-US/firefox/new/ +[15]:https://www.seattletimes.com/business/firefox-is-back-and-its-time-to-give-it-a-try/ +[16]:https://brave.com/ +[17]:https://jitsi.org/jitsi-meet/ +[18]:https://signal.org/ +[19]:https://wego.here.com/ +[20]:https://maps.me/ +[21]:https://www.openstreetmap.org/ +[22]:https://protonmail.com/ +[23]:https://www.fastmail.com/ +[24]:https://www.hushmail.com/ +[25]:https://tutanota.com/ +[26]:https://www.fastmail.com/ +[27]:https://nextcloud.com/ +[28]:https://letsencrypt.org/ +[29]:https://owncloud.org/ +[30]:https://www.openstack.org/ +[31]:https://matomo.org/ +[32]:http://www.openwebanalytics.com/ +[33]:https://lineageos.org/ +[34]:https://f-droid.org/en/ +[35]:https://puri.sm/posts/tag/pureos/ +[36]:https://ubports.com/ diff --git a/sources/talk/20180713 What-s the difference between a fork and a distribution.md b/sources/talk/20180713 What-s the difference between a fork and a distribution.md new file mode 100644 index 0000000000..f7f50e014b --- /dev/null +++ b/sources/talk/20180713 What-s the difference between a fork and a distribution.md @@ -0,0 +1,81 @@ +What's the difference between a fork and a distribution? +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/spoons_forks_520x292_jh.png?itok=DzEzZBuG) + +If you've been around open source software for any length of time, you'll hear the terms fork and distribution thrown around casually in conversation. For many people, the distinction between the two isn't clear, so here I'll try to clear up the confusion. + +### First, some definitions + +Before explaining the nuances of a fork vs. a distribution and the pitfalls thereof, let's define key concepts. + +**[Open source software][1]** is software that: + + * Is freely available to distribute under certain [license][2] restraints + * Permits its source code to be viewable and modified under certain license restraints + + + +Open source software can be **consumed** in the following ways: + + * Downloaded in binary or source code format, often at no charge (e.g., the [Eclipse developer environment][3]) + * As a distribution (product) by a vendor, sometimes at a cost to the user (e.g., [Red Hat products][4]) + * Embedded into proprietary software solutions (e.g., some smartphones and browsers display fonts using the open source [freetype software][5]) + + + +**Free and open source (FOSS)** is not necessarily "free" as in "zero cost." Free and open source simply means the software is free to distribute, modify, study, and use, subject to the software's licensing. The software distributor may attach a purchase price to it. For example, Linux is available at no cost as Fedora, CentOS, Gentoo, etc. or as a paid distribution as Red Hat Enterprise Linux, SUSE, etc. + +**Community** refers to the organizations and individuals that collaboratively work on an open source project. Any individual or organization can contribute to the project by writing or reviewing code, documentation, test suites, managing meetings, updating websites, etc., provided they abide by the license. For example, at [Openhub.net][6], we see government, nonprofit, commercial, and education organizations [contributing to some open source projects][7]. + +**project** is the result of this collaborative development, documentation, and testing. Most projects have a central repository where code, documentation, testing, and so forth are developed. + +An open sourceis the result of this collaborative development, documentation, and testing. Most projects have a central repository where code, documentation, testing, and so forth are developed. + +A **distribution** is a copy, in binary or source code format, of an open source project. For example, CentOS, Fedora, Red Hat Enterprise Linux, SUSE, Ubuntu, and others are distributions of the Linux project. Tectonic, Google Kubernetes Engine, Amazon Container Service, and Red Hat OpenShift are distributions of the Kubernetes project. + +Vendor distributions of open source projects are often called **products** , thus Red Hat OpenStack Platform is the Red Hat OpenStack product that is a distribution of the OpenStack upstream project—and it is still 100% open source. + +The **trunk** is the main workstream in the community where the open source project is developed. + +An open source **fork** is a version of the open source project that is developed along a separate workstream from the main trunk. + +Thus, **a distribution is not the same as a fork**. A distribution is a packaging of the upstream project that is made available by vendors, often as products. However, the core code and documentation in the distribution adhere to the version in the upstream project. A fork—and any distribution based on the fork—results in a version of the code and documentation that are different from the upstream project. Users who have forked upstream open source code have to maintain it on their own, meaning they lose the benefit of the collaboration that takes place in the upstream community. + +To further explain a software fork, let's use the analogy of migrating animals. Whales and sea lions migrate from the Arctic to California and Mexico; Monarch butterflies migrate from Alaska to Mexico; and (in the Northern Hemisphere) swallows and many other birds fly south for the winter. The key to a successful migration is that all animals in the group stick together, follow the leaders, find food and shelter, and don't get lost. + +### Risks of going it on your own + +A bird, butterfly, or whale that strays from the group loses the benefit of remaining with the group and knowing where to find food, shelter, and the desired destination. + +Similarly, users or organizations that fork and modify an upstream project and maintain it on their own run the following risks: + + 1. **They cannot update their code based on the upstream because their code differs.** This is known as technical debt; the more changes made to forked code, the more it costs in time and money to rebase the fork to the upstream project. + 2. **They potentially run less secure code.** If a vulnerability is found in open source code and fixed by the community in the upstream, a forked version of the code may not benefit from this fix because it is different from the upstream. + 3. **They might not benefit from new features.** The upstream community, using input from many organizations and individuals, creates new features for the benefit of all users of the upstream project. If an organization forks the upstream, they potentially cannot incorporate the new features because their code differs. + 4. **They might not integrate with other software packages.** Open source projects are rarely developed as single entities; rather they often are packaged together with other projects to create a solution. Forked code may not be able to be integrated with other projects because the developers of the forked code are not collaborating in the upstream with other participants. + 5. **They might not certify on hardware platforms.** Software packages are often certified to run on hardware platforms so, if problems arise, the hardware and software vendors can collaborate to find the root cause or problem. + + + +In summary, an open source distribution is simply a packaging of an upstream, multi-organizational, collaborative open source project sold and supported by a vendor. A fork is a separate development workstream of an open source project and risks not being able to benefit from the collaborative efforts of the upstream community. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/forks-vs-distributions + +作者:[Jonathan Gershater][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/jgershat +[1]:https://opensource.com/resources/what-open-source +[2]:https://opensource.com/tags/licensing +[3]:https://www.eclipse.org/che/getting-started/download/ +[4]:https://access.redhat.com/downloads +[5]:https://www.freetype.org/ +[6]:http://openhub.net +[7]:https://www.openhub.net/explore/orgs diff --git a/sources/talk/20180724 Open Source Certification- Preparing for the Exam.md b/sources/talk/20180724 Open Source Certification- Preparing for the Exam.md new file mode 100644 index 0000000000..2abcaa7693 --- /dev/null +++ b/sources/talk/20180724 Open Source Certification- Preparing for the Exam.md @@ -0,0 +1,64 @@ +Open Source Certification: Preparing for the Exam +====== +Open source is the new normal in tech today, with open components and platforms driving mission-critical processes at organizations everywhere. As open source has become more pervasive, it has also profoundly impacted the job market. Across industries [the skills gap is widening, making it ever more difficult to hire people][1] with much needed job skills. That’s why open source training and certification are more important than ever, and this series aims to help you learn more and achieve your own certification goals. + +In the [first article in the series][2], we explored why certification matters so much today. In the [second article][3], we looked at the kinds of certifications that are making a difference. This story will focus on preparing for exams, what to expect during an exam, and how testing for open source certification differs from traditional types of testing. + +Clyde Seepersad, General Manager of Training and Certification at The Linux Foundation, stated, “For many of you, if you take the exam, it may well be the first time that you've taken a performance-based exam and it is quite different from what you might have been used to with multiple choice, where the answer is on screen and you can identify it. In performance-based exams, you get what's called a prompt.” + +As a matter of fact, many Linux-focused certification exams literally prompt test takers at the command line. The idea is to demonstrate skills in real time in a live environment, and the best preparation for this kind of exam is practice, backed by training. + +### Know the requirements + +"Get some training," Seepersad emphasized. "Get some help to make sure that you're going to do well. We sometimes find folks have very deep skills in certain areas, but then they're light in other areas. If you go to the website for [Linux Foundation training and certification][4], for the [LFCS][5] and the [LFCE][6] certifications, you can scroll down the page and see the details of the domains and tasks, which represent the knowledge areas you're supposed to know.” + +Once you’ve identified the skills you need, “really spend some time on those and try to identify whether you think there are areas where you have gaps. You can figure out what the right training or practice regimen is going to be to help you get prepared to take the exam," Seepersad said. + +### Practice, practice, practice + +"Practice is important, of course, for all exams," he added. "We deliver the exams in a bit of a unique way -- through your browser. We're using a terminal emulator on your browser and you're being proctored, so there's a live human who is watching you via video cam, your screen is being recorded, and you're having to work through the exam console using the browser window. You're going to be asked to do something live on the system, and then at the end, we're going to evaluate that system to see if you were successful in accomplishing the task" + +What if you run out of time on your exam, or simply don’t pass because you couldn’t perform the required skills? “I like the phrase, exam insurance,” Seepersad said. “The way we take the stress out is by offering a ‘no questions asked’ retake. If you take either exam, LFCS, LFCE and you do not pass on your first attempt, you are automatically eligible to have a free second attempt.” + +The Linux Foundation intentionally maintains separation between its training and certification programs and uses an independent proctoring solution to monitor candidates. It also requires that all certifications be renewed every two years, which gives potential employers confidence that skills are current and have been recently demonstrated. + +### Free certification guide + +Becoming a Linux Foundation Certified System Administrator or Engineer is no small feat, so the Foundation has created [this free certification guide][7] to help you with your preparation. In this guide, you’ll find: + + * Critical things to keep in mind on test day + + + * An array of both free and paid study resources to help you be as prepared as possible + + * A few tips and tricks that could make the difference at exam time + + * A checklist of all the domains and competencies covered in the exam + + + + +With certification playing a more important role in securing a rewarding long-term career, careful planning and preparation are key. Stay tuned for the next article in this series that will answer frequently asked questions pertaining to open source certification and training. + +[Learn more about Linux training and certification.][8] + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/sysadmin-cert/2018/7/open-source-certification-preparing-exam + +作者:[Sam Dean][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/sam-dean +[1]:https://www.linux.com/blog/os-jobs-report/2017/9/demand-open-source-skills-rise +[2]:https://www.linux.com/blog/sysadmin-cert/2018/7/5-reasons-open-source-certification-matters-more-ever +[3]:https://www.linux.com/blog/sysadmin-cert/2018/7/tips-success-open-source-certification +[4]:https://training.linuxfoundation.org/ +[5]:https://training.linuxfoundation.org/certification/linux-foundation-certified-sysadmin-lfcs/ +[6]:https://training.linuxfoundation.org/certification/linux-foundation-certified-engineer-lfce/ +[7]:https://training.linuxfoundation.org/download-free-certification-prep-guide +[8]:https://training.linuxfoundation.org/certification/ diff --git a/sources/talk/20180724 Why moving all your workloads to the cloud is a bad idea.md b/sources/talk/20180724 Why moving all your workloads to the cloud is a bad idea.md new file mode 100644 index 0000000000..1d97805178 --- /dev/null +++ b/sources/talk/20180724 Why moving all your workloads to the cloud is a bad idea.md @@ -0,0 +1,71 @@ +Why moving all your workloads to the cloud is a bad idea +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/cloud-globe.png?itok=_drXt4Tn) + +As we've been exploring in this series, cloud hype is everywhere, telling you that migrating your applications to the cloud—including hybrid cloud and multicloud—is the way to ensure a digital future for your business. This hype rarely dives into the pitfalls of moving to the cloud, nor considers the daily work of enhancing your customer's experience and agile delivery of new and legacy applications. + +In [part one][1] of this series, we covered basic definitions (to level the playing field). We outlined our views on hybrid cloud and multi-cloud, making sure to show the dividing lines between the two. This set the stage for [part two][2], where we discussed the first of three pitfalls: Why cost is not always the obvious motivator for moving to the cloud. + +In part three, we'll look at the second pitfall: Why moving all your workloads to the cloud is a bad idea. + +### Everything's better in the cloud? + +There's a misconception that everything will benefit from running in the cloud. All workloads are not equal, and not all workloads will see a measurable effect on the bottom line from moving to the cloud. + +As [InformationWeek wrote][3], "Not all business applications should migrate to the cloud, and enterprises must determine which apps are best suited to a cloud environment." This is a hard fact that the utility company in part two of this series learned when labor costs rose while trying to move applications to the cloud. Discovering this was not a viable solution, the utility company backed up and reevaluated its applications. It found some applications were not heavily used and others had data ownership and compliance issues. Some of its applications were not certified for use in a cloud environment. + +Sometimes running applications in the cloud is not physically possible, but other times it's not financially viable to run in the cloud. + +Imagine a fictional online travel company. As its business grew, it expanded its on-premises hosting capacity to over 40,000 servers. It eventually became a question of expanding resources by purchasing a data center at a time, not a rack at a time. Its business consumes bandwidth at such volumes that cloud pricing models based on bandwidth usage remain prohibitive. + +### Get a baseline + +Sometimes running applications in the cloud is not physically possible, but other times it's not financially viable to run in the cloud. + +As these examples show, nothing is more important than having a thorough understanding of your application landscape. Along with a having good understanding of what applications need to migrate to the cloud, you also need to understand current IT environments, know your present level of resources, and estimate your costs for moving. + +As these examples show, nothing is more important than having a thorough understanding of your application landscape. Along with a having good understanding of what applications need to migrate to the cloud, you also need to understand current IT environments, know your present level of resources, and estimate your costs for moving. + +Understanding your baseline–each application's current situation and performance requirements (network, storage, CPU, memory, application and infrastructure behavior under load, etc.)–gives you the tools to make the right decision. + +If you're running servers with single-digit CPU utilization due to complex acquisition processes, a cloud with on-demand resourcing might be a great idea. However, first ask these questions: + + * How long did this low-utilization exist? + * Why wasn't it caught earlier? + * Isn't there a process or effective monitoring in place? + * Do you really need a cloud to fix this? Or just a better process for both getting and managing your resources? + * Will you have a better process in the cloud? + + + +### Are containers necessary? + +Many believe you need containers to be successful in the cloud. This popular [catchphrase][4] sums it up nicely, "We crammed this monolith into a container and called it a microservice." + +Containers are a means to an end, and using containers doesn't mean your organization is capable of running maturely in the cloud. It's not about the technology involved, it's about applications that often were written in days gone by with technology that's now outdated. If you put a tire fire into a container and then put that container on a container platform to ship, it's still functionality that someone is using. + +Is that fire easier to extinguish now? These container fires just create more challenges for your DevOps teams, who are already struggling to keep up with all the changes being pushed through an organization moving everything into the cloud. + +Note, it's not necessarily a bad decision to move legacy workloads into the cloud, nor is it a bad idea to containerize them. It's about weighing the benefits and the downsides, assessing the options available, and making the right choices for each of your workloads. + +### Coming up + +In part four of this series, we'll describe the third and final pitfall everyone should avoid with hybrid multi-cloud. Find out what the cloud means for your data. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/why-you-cant-move-everything-cloud + +作者:[Eric D.Schabell][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/eschabell +[1]:https://opensource.com/article/18/4/pitfalls-hybrid-multi-cloud +[2]:https://opensource.com/article/18/6/reasons-move-to-cloud +[3]:https://www.informationweek.com/cloud/10-cloud-migration-mistakes-to-avoid/d/d-id/1318829 +[4]:https://speakerdeck.com/caseywest/containercon-north-america-cloud-anti-patterns?slide=22 diff --git a/sources/talk/20180726 Tech jargon- The good, the bad, and the ugly.md b/sources/talk/20180726 Tech jargon- The good, the bad, and the ugly.md new file mode 100644 index 0000000000..def2701a78 --- /dev/null +++ b/sources/talk/20180726 Tech jargon- The good, the bad, and the ugly.md @@ -0,0 +1,108 @@ +Tech jargon: The good, the bad, and the ugly +====== +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/change_words_scrabble_letters.jpg?itok=mbRFmPJ1) + +One enduring and complex piece of jargon is the use of "free" in relation to software. In fact, the term is so ambiguous that different terms have evolved to describe some of the variants—open source, FOSS, and even phrases such as "free as in speech, not as in beer." But surely this is a good thing, right? We know what we mean; we're sharing shorthand by using a particular word in a particular way. Some people might not understand, and there's some ambiguity. But does that matter? + +### A couple of definitions + +I was involved in an interesting discussion with colleagues recently about the joys (or otherwise) of jargon. It stemmed from a section I wrote in a recent article, [How to talk to security people: a guide for the rest of us][1], where I said: + +> "Jargon has at least two uses: +> +> 1. as an exclusionary mechanism for groups to keep non-members in the dark; +> 2. as a short-hand to exchange information between 'in-the-know' people so that they don't need to explain everything in exhaustive detail every time." +> + + +Given the discussion that arose, I thought it was worth delving more deeply into this question. It's more than an idle interest, as I think there are important lessons around our use of jargon that impact how we interact with our colleagues and peers that deserve some careful thought. These lessons apply particularly to my chosen field, security. + +Before we start, we should define "jargon". It's always nice to have two conflicting versions, so here we go: + + * "Special words or expressions used by a profession or group that are difficult for others to understand." ([Oxford Living Dictionaries][2]) + * "Without a qualifier, denotes informal 'slangy' language peculiar to or predominantly found among hackers." ([The Jargon File][3]) + + + +I should start by pointing out that The Jargon File, which was published in paper form in at least [two versions][4] as The Hacker's Dictionary (ed. Steele) and The New Hacker's Dictionary (ed. Raymond), has a pretty special place in my heart. When I decided that I wanted to properly "take up" geekery,1,2 I read The New Hacker's Dictionary from cover to cover, several times, and when a new edition came out, I bought that and did the same. + +In fact, for more technical readers, I suspect that a fair amount of your cultural background is expressed within its covers (paper or virtual), even if you're not aware of it. If you're interested in delving deeper and like the feel of paper in your hands, I encourage you to purchase a copy—but be careful to get the right one. There are some expensive versions that seem just to be printouts of The Jargon File, rather than properly typeset and edited versions.3 + +But let's get onto the meat of this article: is jargon a force for good or ill? + +### First: Why jargon is good + +The case for jargon is quite simple. We need jargon to enable us to discuss concepts and the use of terms in normal language—like scheduling—as jargon leads to some interesting metaphors that guide us in our practice.4 We absolutely need shared practice, and for that we need shared language—and some of that language is bound to become jargon over time. But consider a lexicon, or an FAQ, or other ways to allow your colleagues to participate: be inclusive, not exclusive. That's the good. The problem, however, is the bad. + +### The case against jargon: Ambiguity + +You would think jargon would serve to provide agreed terms within a particular discipline and help prevent ambiguity around contexts. It may be a surprise, then, that the first problem we often run into with jargon is namespace clashes. Consider the following. There's an old joke about how to distinguish an electrical engineer from a humanities5 graduate: ask them how many syllables are in the word "coax." The point here, of course, is that they come from different disciplines. But there are lots of words—and particularly abbreviations—that have different meanings or expansions depending on context and where disciplines and contexts may collide. + +What do these words mean to you?6 + + * Scheduling: kernel-level CPU allocation to processes OR placement of workloads by an orchestration component + * Comms: I/O in a computer system OR marketing/analyst communications + * Layer: OSI model OR IP suite layer OR another architectural abstraction layer such as host or workload + * SME: subject matter expert OR small/medium enterprise + * SMB: small/medium business OR small message block + * TLS: transport layer security OR Times Literary Supplement + * IP: internet protocol OR intellectual property OR intellectual property as expressed as a silicon component block + * FFS for further study OR …7 + + + +One of the interesting things is that quite a lot of my background is betrayed by the various options that present themselves to me. I wonder how many readers will have thought of the Times Literary Supplement, for example. I'm also more likely to think of SME as the term relating to organisations, because that's the favoured form in Europe, whereas I believe that the US tends to SMB. I'm sure your experiences will all be different—which rather makes my point for me. + +That's the first problem. In a context where jargon is often praised as a way of shortcutting lengthy explanations, it can actually be a significant ambiguating force. + +### The case against jargon: Exclusion + +Intentionally or not—and sometimes it is intentional—groups define themselves through the use of specific terminology. Once this terminology becomes opaque to those outside the group, it becomes "jargon," as per our first definition above. "Good" use of jargon generally allows those within the group to converse using shared context around concepts that do not need to be explained in detail every time they are used. + +An example would be a "smoke test"—a quick test to check that basic functionality is performing correctly (see the Jargon File's [definition][5] for more). If everyone in the group understands what this means, then why go into more detail? But if you are joined at a stand-up meeting8 by a member of marketing who wants to know whether a particular build is ready for release, and you say "well, no—it's only been smoke-tested so far," then it's likely you'll need to explain. + +The problem is that there are occasions when jargon can exclude others, whether that usage is intended or not. There have been times for most of us, I'm sure, when we want to show we're part of a group, so we use terms that we know another person won't understand. On other occasions, the term may be so ingrained in our practice that we use it without thinking, and the other person is unintentionally excluded. I would argue that we need to be careful to avoid both of these uses. + +Intentional exclusion is rarely helpful, but unintentional exclusion can be just as damaging—in some ways more so, as it is typically unremarked and therefore difficult to remedy. + +### What to do? + +First, be aware when you're using jargon, and try to foster an environment where people feel happy to query what you mean. If you see people's eyes glazing over, take a step back and explain the context and the term. Second, be on the lookout for ambiguity: if you're on a project where something can mean more than one thing, disambiguate somewhere in a file or diagram that everyone can access and is easily discoverable. And last, don't use jargon to exclude. We need all the people we can get, so let's bring them in, not push them out. + +1\. "Properly"—really? Although I'm not sure "improperly" is any better. + +2\. I studied English Literature and Theology at university, so this was a conscious decision to embrace a rather different culture. + +3\. The most recent "real" edition of which I'm aware is Raymond, Eric S., 1996, [The New Hacker's Dictionary][6], 3rd ed., MIT University Press, Cambridge, Mass. + +4\. Although metaphors can themselves be constraining as they tend to push us to think in a particular way, even if that way isn't entirely applicable in this context. + +5\. Or "liberal arts". + +6\. I've added the first options that spring to mind when I come across them—I'm aware there are almost certainly others. + +7\. Believe me, when I saw this abbreviation in a research paper for the first time, I was most confused and had to look it up. + +8\. Oh, look: jargon… + +This article originally appeared on [Alice, Eve, and Bob – a security blog][7] and is republished with permission. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/tech-jargon + +作者:[Mike Bursell][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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 +[1]:http://aliceevebob.com/2018/05/08/how-to-talk-to-security-people-a-guide-for-the-rest-of-us/ +[2]:https://en.oxforddictionaries.com/definition/jargon +[3]:http://catb.org/jargon/html/distinctions.html +[4]:https://en.wikipedia.org/wiki/Jargon_File +[5]:http://catb.org/jargon/html/S/smoke-test.html +[6]:https://www.amazon.com/New-Hackers-Dictionary-3rd/dp/0262680920 +[7]:https://aliceevebob.com/2018/06/26/jargon-a-force-for-good-or-ill/ diff --git a/sources/tech/20141127 Keeping (financial) score with Ledger .md b/sources/tech/20141127 Keeping (financial) score with Ledger .md deleted file mode 100644 index 17b36ea1dc..0000000000 --- a/sources/tech/20141127 Keeping (financial) score with Ledger .md +++ /dev/null @@ -1,77 +0,0 @@ -translating---geekpi - -Keeping (financial) score with Ledger – -====== -I’ve used [Ledger CLI][1] to keep track of my finances since 2005, when I moved to Canada. I like the plain-text approach, and its support for virtual envelopes means that I can reconcile both my bank account balances and my virtual allocations to different categories. Here’s how we use those virtual envelopes to manage our finances separately. - -Every month, I have an entry that moves things from my buffer of living expenses to various categories, including an allocation for household expenses. W- doesn’t ask for a lot, so I take care to be frugal with the difference between that and the cost of, say, living on my own. The way we handle it is that I cover a fixed amount, and this is credited by whatever I pay for groceries. Since our grocery total is usually less than the amount I budget for household expenses, any difference just stays on the tab. I used to write him cheques to even it out, but lately I just pay for the occasional additional large expense. - -Here’s a sample envelope allocation: -``` -2014.10.01 * Budget - [Envelopes:Living] - [Envelopes:Household] $500 - ;; More lines go here - -``` - -Here’s one of the envelope rules set up. This one encourages me to classify expenses properly. All expenses are taken out of my “Play” envelope. -``` -= /^Expenses/ - (Envelopes:Play) -1.0 - -``` - -This one reimburses the “Play” envelope for household expenses, moving the amount from the “Household” envelope into the “Play” one. -``` -= /^Expenses:House$/ - (Envelopes:Play) 1.0 - (Envelopes:Household) -1.0 - -``` - -I have a regular set of expenses that simulate the household expenses coming out of my budget. For example, here’s the one for October. -``` -2014.10.1 * House - Expenses:House - Assets:Household $-500 - -``` - -And this is what a grocery transaction looks like: -``` -2014.09.28 * No Frills - Assets:Household:Groceries $70.45 - Liabilities:MBNA:September $-70.45 - -``` - -Then `ledger bal Assets:Household` will tell me if I owe him money (negative balance) or not. If I pay for something large (ex: plane tickets, plumbing), the regular household expense budget gradually reduces that balance. - -I picked up the trick of adding a month label to my credit card transactions from W-, who also uses Ledger to track his transactions. It lets me doublecheck the balance of a statement and see if the previous statement has been properly cleared. - -It’s a bit of a weird use of the assets category, but it works out for me mentally. - -Using Ledger to track it in this way lets me keep track of our grocery expenses and the difference between what I’ve actually paid and what I’ve budgeted for. If I end up spending more than I expected, I can move virtual money from more discretionary envelopes, so my budget always stays balanced. - -Ledger’s a powerful tool. Pretty geeky, but maybe more descriptions of workflow might help people who are figuring things out! - -More posts about: [finance][2] Tags: [ledger][3] | [See in index][4] // **[5 Comments »][5]** - --------------------------------------------------------------------------------- - -via: http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/ - -作者:[Sacha Chua][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://sachachua.com -[1]:http://www.ledger-cli.org/ -[2]:http://sachachua.com/blog/category/finance/ -[3]:http://sachachua.com/blog/tag/ledger/ -[4]:http://pages.sachachua.com/sharing/blog.html?url=http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/ -[5]:http://sachachua.com/blog/2014/11/keeping-financial-score-ledger/#comments diff --git a/sources/tech/20170710 iWant - The Decentralized Peer To Peer File Sharing Commandline Application.md b/sources/tech/20170710 iWant - The Decentralized Peer To Peer File Sharing Commandline Application.md new file mode 100644 index 0000000000..7ecb35e4da --- /dev/null +++ b/sources/tech/20170710 iWant - The Decentralized Peer To Peer File Sharing Commandline Application.md @@ -0,0 +1,200 @@ +iWant – The Decentralized Peer To Peer File Sharing Commandline Application +====== + +![](https://www.ostechnix.com/wp-content/uploads/2017/07/p2p-720x340.jpg) + +A while ago, we have written a guide about two file sharing utilities named [**transfer.sh**][1], a free web service that allows you to share files over Internet easily and quickly, and [**PSiTransfer**][2], a simple open source self-hosted file sharing solution. Today, we will see yet another file sharing utility called **“iWant”**. It is a free and open source CLI-based decentralized peer to peer file sharing application. + +What’s makes it different from other file sharing applications? You might wonder. Here are some prominent features of iWant. + + * It’s commandline application. You don’t need any memory consuming GUI utilities. You need only the Terminal. + * It is decentralized. That means your data will not be stored in any central location. So, there is no central point of failure. + * iWant allows you to pause the download and you can resume it later when you want. You don’t need to download it from beginning, it just resumes the downloads from where you left off. + * Any changes made in the files in the shared directory (such as deletion, addition, modification) will be reflected instantly in the network. + * Just like torrents, iWant downloads the files from multiple peers. If any seeder left the group or failed to respond, it will continue the download from another seeder. + * It is cross-platform, so, you can use it in GNU/Linux, MS Windows, and Mac OS X. + + + +### iWant – A CLI-based Decentralized Peer To Peer File Sharing Solution + +#### Install iWant + +iWant can be easily installed using PIP package manager. Make sure you have pip installed in your Linux distribution. if it is not installed yet, refer the following guide. + +[How To Manage Python Packages Using Pip](https://www.ostechnix.com/manage-python-packages-using-pip/) + +After installing PIP, make sure you have installed the the following dependencies: + + * libffi-dev + * libssl-dev + + + +Say for example, on Ubuntu, you can install these dependencies using command: +``` +$ sudo apt-get install libffi-dev libssl-dev + +``` + +Once all dependencies installed, install iWant using the following command: +``` +$ sudo pip install iwant + +``` + +We have now iWant in our system. Let us go ahead and see how to use it to transfer files over network. + +#### Usage + +First, start iWant server using command: +``` +$ iwanto start + +``` + +At the first time, iWant will ask the Shared and Download folder’s location. Enter the actual location of both folders. Then, choose which interface you want to use: + +Sample output would be: +``` +Shared/Download folder details looks empty.. +Note: Shared and Download folder cannot be the same +SHARED FOLDER(absolute path):/home/sk/myshare +DOWNLOAD FOLDER(absolute path):/home/sk/mydownloads +Network interface available +1. lo => 127.0.0.1 +2. enp0s3 => 192.168.43.2 +Enter index of the interface:2 +now scanning /home/sk/myshare +[Adding] /home/sk/myshare 0.0 +Updating Leader 56f6d5e8-654e-11e7-93c8-08002712f8c1 +[Adding] /home/sk/myshare 0.0 +connecting to 192.168.43.2:1235 for hashdump + +``` + +If you see an output something like above, you can start using iWant right away. + +Similarly, start iWant service on all systems in the network, assign valid Shared and Downloads folder’s location, and select the network interface card. + +The iWant service will keep running in the current Terminal window until you press **CTRL+C** to quit it. You need to open a new tab or new Terminal window to use iWant. + +iWant usage is very simple. It has few commands as listed below. + + * **iwanto start** – Starts iWant server. + * **iwanto search ** – Search for files. + * **iwanto download ** – Download a file. + * **iwanto share ** – Change the Shared folder’s location. + * **iwanto download to ** – Change the Download folder’s location. + * **iwanto view config** – View Shared and Download folders. + * **iwanto –version** – Displays the iWant version. + * **iwanto -h** – Displays the help section. + + + +Allow me to show you some examples. + +**Search files** + +To search for a file, run: +``` +$ iwanto search + +``` + +Please note that you don’t need to specify the accurate name. + +Example: +``` +$ iwanto search command + +``` + +The above command will search for any files that contains the string “command”. + +Sample output from my Ubuntu system: +``` +Filename Size Checksum +------------------------------------------- ------- -------------------------------- +/home/sk/myshare/THE LINUX COMMAND LINE.pdf 3.85757 efded6cc6f34a3d107c67c2300459911 + +``` + +**Download files** + +You can download the files from any system on your network. To download a file, just mention the hash (checksum) of the file as shown below. You can get hash value of a share using “iwanto search” command. +``` +$ iwanto download efded6cc6f34a3d107c67c2300459911 + +``` + +The file will be saved in your Download location (/home/sk/mydownloads/ in my case). +``` +Filename: /home/sk/mydownloads/THE LINUX COMMAND LINE.pdf +Size: 3.857569 MB + +``` + +**View configuration** + +To view the configuration i.e the Shared and Download folders, run: +``` +$ iwanto view config + +``` + +Sample output: +``` +Shared folder:/home/sk/myshare +Download folder:/home/sk/mydownloads + +``` + +**Change Shared and Download folder’s location** + +You can change the Shared folder and Download folder location to some other path like below. +``` +$ iwanto share /home/sk/ostechnix + +``` + +Now, the Shared location has been changed to /home/sk/ostechnix location. + +Also, you can change the Downloads location using command: +``` +$ iwanto download to /home/sk/Downloads + +``` + +To view the changes made, run the config command: +``` +$ iwanto view config + +``` + +**Stop iWant** + +Once you done with iWant, you can quit it by pressing **CTRL+C**. + +If it is not working by any chance, it might be due to Firewall or your router doesn’t support multicast. You can view all logs in** ~/.iwant/.iwant.log** file. For more details, refer the project’s GitHub page provided at the end. + +And, that’s all. Hope this tool helps. I will be here again with another interesting guide. Till then, stay tuned with OSTechNix! + +Cheers! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/iwant-decentralized-peer-peer-file-sharing-commandline-application/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/ +[1]:https://www.ostechnix.com/easy-fast-way-share-files-internet-command-line/ +[2]:https://www.ostechnix.com/psitransfer-simple-open-source-self-hosted-file-sharing-solution/ diff --git a/sources/tech/20170721 Arch Linux Applications Automatic Installation Script.md b/sources/tech/20170721 Arch Linux Applications Automatic Installation Script.md new file mode 100644 index 0000000000..5860fca4d0 --- /dev/null +++ b/sources/tech/20170721 Arch Linux Applications Automatic Installation Script.md @@ -0,0 +1,149 @@ +Arch Linux Applications Automatic Installation Script +====== + +![](https://www.ostechnix.com/wp-content/uploads/2017/07/ArchI0-Arch-Linux-Applications-Automatic-Installation-Script-720x340.png) + +Howdy Archers! Today, I have stumbled upon an useful utility called **“ArchI0”** , a CLI menu-based Arch Linux applications automatic installation script. This script provides an easiest way to install all essential applications for your Arch-based distribution. Please note that **this script is meant for noobs only**. Intermediate and advanced users can easily figure out [**how to use pacman**][1] to get things done. If you want to learn how Arch Linux works, I suggest you to manually install all software one by one. For those who are still noobs and wanted an easy and quick way to install all essential applications for their Arch-based systems, make use of this script. + +### ArchI0 – Arch Linux Applications Automatic Installation Script + +The developer of this script has created two scripts namely **ArchI0live** and **ArchI0**. You can use ArchI0live script to test without installing it. This might be helpful to know what actually is in this script before installing it on your system. + +### Install ArchI0 + +To install this script, Git cone the ArchI0 script repository using command: +``` +$ git clone https://github.com/SifoHamlaoui/ArchI0.git + +``` + +The above command will clone the ArchI0 GtiHub repository contents in a folder called ArchI0 in your current directory. Go to the directory using command: +``` +$ cd ArchI0/ + +``` + +Make the script executable using command: +``` +$ chmod +x ArchI0live.sh + +``` + +Run the script with command: +``` +$ sudo ./ArchI0live.sh + +``` + +We need to run this script as root or sudo user, because installing applications requires root privileges. + +> **Note:** For those wondering what all are those commands for at the beginning of the script, the first command downloads **figlet** , because the script logo is shown using figlet. The 2nd command install **Leafpad** which is used to open and read the license file. The 3rd command install **wget** to download files from sourceforge. The 4th and 5th commands are to download and open the License File on leafpad. And, the final and 6th command is used to close the license file after reading it. + +Type your Arch Linux system’s architecture and hit ENTER key. When it asks to install the script, type y and hit ENTER. + +![][3] + +Once it is installed, you will be redirected to the main menu. + +![][4] + +As you see in the above screenshot, ArchI0 has 13 categories and contains 90 easy-to-install programs under those categories. These 90 programs are just enough to setup a full-fledged Arch Linux desktop to perform day-to-day activities. To know about this script, type **a** and to exit this script type **q**. + +After installing it, you don’t need to run the ArchI0live script. You can directly launch it using the following command: +``` +$ sudo ArchI0 + +``` + +It will ask you each time to choose your Arch Linux distribution architecture. +``` +This script Is under GPLv3 License + +Preparing To Run Script + Checking For ROOT: PASSED + What Is Your OS Architecture? {32/64} 64 + +``` + +From now on, you can install the program of your choice from the categories listed in the main menu. To view the list of available programs under a specific category, enter the category number. Say for example, to view the list of available programs under **Text Editors** category, type **1** and hit ENTER. +``` +This script Is under GPLv3 License + +[ R00T MENU ] +Make A Choice + 1) Text Editors + 2) FTP/Torrent Applications + 3) Download Managers + 4) Network managers + 5) VPN clients + 6) Chat Applications + 7) Image Editors + 8) Video editors/Record + 9) Archive Handlers + 10) Audio Applications + 11) Other Applications + 12) Development Environments + 13) Browser/Web Plugins + 14) Dotfiles + 15) Usefull Links + ------------------------ + a) About ArchI0 Script + q) Leave ArchI0 Script + +Choose An Option: 1 + +``` + +Next, choose the application you want to install. To return to main menu, type **q** and hit ENTER. + +I want to install Emacs, so I type **3**. +``` +This script Is under GPLv3 License + +[ TEXT EDITORS ] + [ Option ] [ Description ] + 1) GEdit + 2) Geany + 3) Emacs + 4) VIM + 5) Kate + --------------------------- + q) Return To Main Menu + +Choose An Option: 3 + +``` + +Now, Emacs will be installed on your Arch Linux system. + +![][5] + +Press ENTER key to return to main menu after installing the applications of your choice. + +### Conclusion + +Undoubtedly, this script makes the Arch Linux user’s life easier, particularly the beginner’s. If you are looking for a fast and easy way to install applications without using pacman, then this script might be a good choice. Give it a try and let us know what you think about this script in the comment section below. + +And, that’s all. Hope this tool helps. We will be posting useful guides every day. If you find our guides useful, please share them on your social, professional networks and support OSTechNix. + +Cheers!! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/archi0-arch-linux-applications-automatic-installation-script/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/ +[1]:http://www.ostechnix.com/getting-started-pacman/ +[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[3]:http://www.ostechnix.com/wp-content/uploads/2017/07/sk@sk-ArchI0_003.png +[4]:http://www.ostechnix.com/wp-content/uploads/2017/07/sk@sk-ArchI0_004-1.png +[5]:http://www.ostechnix.com/wp-content/uploads/2017/07/pacman-as-superuser_005.png diff --git a/sources/tech/20170829 An Advanced System Configuration Utility For Ubuntu Power Users.md b/sources/tech/20170829 An Advanced System Configuration Utility For Ubuntu Power Users.md deleted file mode 100644 index 6652350a1b..0000000000 --- a/sources/tech/20170829 An Advanced System Configuration Utility For Ubuntu Power Users.md +++ /dev/null @@ -1,140 +0,0 @@ -translating by wenwensnow -An Advanced System Configuration Utility For Ubuntu Power Users -====== - -![](https://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-4-1-720x340.png) - -**Ubunsys** is a Qt-based advanced system utility for Ubuntu and its derivatives. Most of the configuration can be easily done from the command-line by the advanced users. Just in case, you don’t want to use CLI all the time, you can use Ubunsys utility to configure your Ubuntu desktop system or its derivatives such as Linux Mint, Elementary OS etc. Ubunsys can be used to modify system configuration, install, remove, update packages and old kernels, enable/disable sudo access, install mainline kernel, update software repositories, clean up junk files, upgrade your Ubuntu to latest version, and so on. All of the aforementioned actions can be done with simple mouse clicks. You don’t need to depend on CLI mode anymore. Here is the list of things you can do with Ubunsys: - - * Install, update, and remove packages. - * Update and upgrade software repositories. - * Install mainline Kernel. - * Remove old and unused Kernels. - * Full system update. - * Complete System upgrade to next available version. - * Upgrade to latest development version. - * Clean up junk files from your system. - * Enable and/or disable sudo access without password. - * Make Sudo Passwords visible when you type them in the Terminal. - * Enable and/or disable hibernation. - * Enable and/or disable firewall. - * Open, backup and import sources.list.d and sudoers files. - * Show/unshow hidden startup items. - * Enable and/or disable Login sounds. - * Configure dual boot. - * Enable/disable Lock screen. - * Smart system update. - * Update and/or run all scripts at once using Scripts Manager. - * Exec normal user installation script from git. - * Check system integrity and missing GPG keys. - * Repair network. - * Fix broken packages. - * And more yet to come. - - - -**Important note:** Ubunsys is not for Ubuntu beginners. It is dangerous and not a stable version yet. It might break your system. If you’re a new to Ubuntu, don’t use it. If you are very curious to use this application, go through each option carefully and proceed at your own risk. Do not forget to backup your important data before using this application. - -### Ubunsys – An Advanced System Configuration Utility For Ubuntu Power Users - -#### Install Ubunsys - -Ubunusys developer has made a PPA to make the installation process much easier. Ubunsys will currently work on Ubuntu 16.04 LTS, Ubuntu 17.04 64bit editions. - -Run the following commands one by one to add Ubunsys PPA and install it. -``` -sudo add-apt-repository ppa:adgellida/ubunsys - -sudo apt-get update - -sudo apt-get install ubunsys - -``` - -If the PPA doesn’t work, head over to the [**releases page**][1], download and install the Ubunsys package depending upon the architecture you use. - -#### Usage - -Once installed, launch Ubunsys from Menu. This is how Ubunsys main interface looks like. - -![][3] - -As you can see, Ubunusys has four main sections namely **Packages** , **Tweaks** , **System** , and **Repair**. There are one or more sub-sections available for each main tab to do different operations. - -**Packages** - -This section allows you to install, remove, update packages. - -![][4] - -**Tweaks** - -In this section, we can do various various system tweaks such as, - - * Open, backup, import sources.list and sudoers file; - * Configure dual boot; - * Enable/disable login sound, firewall, lock screen, hibernation, sudo access without password. You can also enable or disable for sudo access without password to specific users. - * Can make the passwords visible while typing them in Terminal (Disable Asterisks). - - - -![][5] - -**System** - -This section further categorized into three sub-categories, each for distinct user type. - -The **Normal user** tab allows us to, - - * Update, upgrade packages and software repos. - * Clean system. - * Exec normal user installation script. - - - -The **Advanced user** section allows us to, - - * Clean Old/Unused Kernels. - * Install mainline Kernel. - * do smart packages update. - * Upgrade system. - - - -The **Developer** section allows us to upgrade the Ubuntu system to latest development version. - -![][6] - -**Repair** - -This is the fourth and last section of Ubunsys. As the name says, this section allows us to do repair our system, network, missing GPG keys, and fix broken packages. - -![][7] - -As you can see, Ubunsys helps you to do any system configuration, maintenance and software management tasks with few mouse clicks. You don’t need to depend on Terminal anymore. Ubunsys can help you to accomplish any advanced tasks. Again, I warn you, It’s not for beginners and it is not stable yet. So, you can expect bugs and crashes when using it. Use it with care after studying options and impact. - -Cheers! - -**Resource:** - - - --------------------------------------------------------------------------------- - -via: https://www.ostechnix.com/ubunsys-advanced-system-configuration-utility-ubuntu-power-users/ - -作者:[SK][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/ -[1]:https://github.com/adgellida/ubunsys/releases -[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 -[3]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-1.png -[4]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-2.png -[5]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-5.png -[6]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-9.png -[7]:http://www.ostechnix.com/wp-content/uploads/2017/08/Ubunsys-11.png diff --git a/sources/tech/20171130 Google launches TensorFlow-based vision recognition kit for RPi Zero W.md b/sources/tech/20171130 Google launches TensorFlow-based vision recognition kit for RPi Zero W.md deleted file mode 100644 index 46967604d5..0000000000 --- a/sources/tech/20171130 Google launches TensorFlow-based vision recognition kit for RPi Zero W.md +++ /dev/null @@ -1,86 +0,0 @@ -Transating by qhwdw -# [Google launches TensorFlow-based vision recognition kit for RPi Zero W][26] - - -![](http://linuxgizmos.com/files/google_aiyvisionkit-thm.jpg) -Google’s $45 “AIY Vision Kit” for the Raspberry Pi Zero W performs TensorFlow-based vision recognition using a “VisionBonnet” board with a Movidius chip. - -Google’s AIY Vision Kit for on-device neural network acceleration follows an earlier [AIY Projects][7] voice/AI kit for the Raspberry Pi that shipped to MagPi subscribers back in May. Like the voice kit and the older Google Cardboard VR viewer, the new AIY Vision Kit has a cardboard enclosure. The kit differs from the [Cloud Vision API][8], which was demo’d in 2015 with a Raspberry Pi based GoPiGo robot, in that it runs entirely on local processing power rather than requiring a cloud connection. The AIY Vision Kit is available now for pre-order at $45, with shipments due in early December. - - - [![](http://linuxgizmos.com/files/google_aiyvisionkit-sm.jpg)][9]   [![](http://linuxgizmos.com/files/rpi_zerow-sm.jpg)][10] -**AIY Vision Kit, fully assembled (left) and Raspberry Pi Zero W** -(click images to enlarge) - - -The kit’s key processing element, aside from the 1GHz ARM11-based Broadcom BCM2836 SoC found on the required [Raspberry Pi Zero W][21] SBC, is Google’s new VisionBonnet RPi accessory board. The VisionBonnet pHAT board uses a Movidius MA2450, a version of the [Movidius Myriad 2 VPU][22] processor. On the VisionBonnet, the processor runs Google’s open source [TensorFlow][23]machine intelligence library for neural networking. The chip enables visual perception processing at up to 30 frames per second. - -The AIY Vision Kit requires a user-supplied RPi Zero W, a [Raspberry Pi Camera v2][11], and a 16GB micro SD card for downloading the Linux-based image. The kit includes the VisionBonnet, an RGB arcade-style button, a piezo speaker, a macro/wide lens kit, and the cardboard enclosure. You also get flex cables, standoffs, a tripod mounting nut, and connecting components. - - - [![](http://linuxgizmos.com/files/google_aiyvisionkit_pieces-sm.jpg)][12]   [![](http://linuxgizmos.com/files/google_visionbonnet-sm.jpg)][13] -**AIY Vision Kit kit components (left) and VisonBonnet accessory board** -(click images to enlarge) - - -Three neural network models are available. There’s a general-purpose model that can recognize 1,000 common objects, a facial detection model that can also score facial expression on a “joy scale” that ranges from “sad” to “laughing,” and a model that can identify whether the image contains a dog, cat, or human. The 1,000-image model derives from Google’s open source [MobileNets][24], a family of TensorFlow based computer vision models designed for the restricted resources of a mobile or embedded device. - -MobileNet models offer low latency and low power consumption, and are parameterized to meet the resource constraints of different use cases. The models can be built for classification, detection, embeddings, and segmentation, says Google. Earlier this month, Google released a developer preview of a mobile-friendly [TensorFlow Lite][14] library for Android and iOS that is compatible with MobileNets and the Android Neural Networks API. - - - [![](http://linuxgizmos.com/files/google_aiyvisionkit_assembly-sm.jpg)][15] -**AIY Vision Kit assembly views** -(click image to enlarge) - - -In addition to providing the three models, the AIY Vision Kit provides basic TensorFlow code and a compiler, so users can develop their own models. In addition, Python developers can write new software to customize RGB button colors, piezo element sounds, and 4x GPIO pins on the VisionBonnet that can add additional lights, buttons, or servos. Potential models include recognizing food items, opening a dog door based on visual input, sending a text when your car leaves the driveway, or playing particular music based on facial recognition of a person entering the camera’s viewpoint. - - - [![](http://linuxgizmos.com/files/movidius_myriad2vpu_block-sm.jpg)][16]   [![](http://linuxgizmos.com/files/movidius_myriad2_reference_board-sm.jpg)][17] -**Myriad 2 VPU block diagram (left) and reference board** -(click image to enlarge) - - -The Movidius Myriad 2 processor provides TeraFLOPS of performance within a nominal 1 Watt power envelope. The chip appeared on early Project Tango reference platforms, and is built into the Ubuntu-driven [Fathom][25] neural processing USB stick that Movidius debuted in May 2016, prior to being acquired by Intel. According to Movidius, the Myriad 2 is available “in millions of devices on the market today.” - -**Further information** - -The AIY Vision Kit is available for pre-order from Micro Center at $44.99, with shipments due in early December. More information may be found in the AIY Vision Kit [announcement][18], [Google Blog notice][19], and [Micro Center shopping page][20]. - --------------------------------------------------------------------------------- - -via: http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ - -作者:[ Eric Brown][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ -[1]:http://twitter.com/share?url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/&text=Google%20launches%20TensorFlow-based%20vision%20recognition%20kit%20for%20RPi%20Zero%20W%20 -[2]:https://plus.google.com/share?url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ -[3]:http://www.facebook.com/sharer.php?u=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ -[4]:http://www.linkedin.com/shareArticle?mini=true&url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ -[5]:http://reddit.com/submit?url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/&title=Google%20launches%20TensorFlow-based%20vision%20recognition%20kit%20for%20RPi%20Zero%20W -[6]:mailto:?subject=Google%20launches%20TensorFlow-based%20vision%20recognition%20kit%20for%20RPi%20Zero%20W&body=%20http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ -[7]:http://linuxgizmos.com/free-raspberry-pi-voice-kit-taps-google-assistant-sdk/ -[8]:http://linuxgizmos.com/google-releases-cloud-vision-api-with-demo-for-pi-based-robot/ -[9]:http://linuxgizmos.com/files/google_aiyvisionkit.jpg -[10]:http://linuxgizmos.com/files/rpi_zerow.jpg -[11]:http://linuxgizmos.com/raspberry-pi-cameras-jump-to-8mp-keep-25-dollar-price/ -[12]:http://linuxgizmos.com/files/google_aiyvisionkit_pieces.jpg -[13]:http://linuxgizmos.com/files/google_visionbonnet.jpg -[14]:https://developers.googleblog.com/2017/11/announcing-tensorflow-lite.html -[15]:http://linuxgizmos.com/files/google_aiyvisionkit_assembly.jpg -[16]:http://linuxgizmos.com/files/movidius_myriad2vpu_block.jpg -[17]:http://linuxgizmos.com/files/movidius_myriad2_reference_board.jpg -[18]:https://blog.google/topics/machine-learning/introducing-aiy-vision-kit-make-devices-see/ -[19]:https://developers.googleblog.com/2017/11/introducing-aiy-vision-kit-add-computer.html -[20]:http://www.microcenter.com/site/content/Google_AIY.aspx?ekw=aiy&rd=1 -[21]:http://linuxgizmos.com/raspberry-pi-zero-w-adds-wifi-and-bluetooth-for-only-5-more/ -[22]:https://www.movidius.com/solutions/vision-processing-unit -[23]:https://www.tensorflow.org/ -[24]:https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html -[25]:http://linuxgizmos.com/usb-stick-brings-neural-computing-functions-to-devices/ -[26]:http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ diff --git a/sources/tech/20180126 Running a Python application on Kubernetes.md b/sources/tech/20180126 Running a Python application on Kubernetes.md deleted file mode 100644 index c6ba6f1140..0000000000 --- a/sources/tech/20180126 Running a Python application on Kubernetes.md +++ /dev/null @@ -1,281 +0,0 @@ -Translating by qhwdw -Running a Python application on Kubernetes -============================================================ - -### This step-by-step tutorial takes you through the process of deploying a simple Python application on Kubernetes. - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/build_structure_tech_program_code_construction.png?itok=nVsiLuag) -Image by : opensource.com - -Kubernetes is an open source platform that offers deployment, maintenance, and scaling features. It simplifies management of containerized Python applications while providing portability, extensibility, and self-healing capabilities. - -Whether your Python applications are simple or more complex, Kubernetes lets you efficiently deploy and scale them, seamlessly rolling out new features while limiting resources to only those required. - -In this article, I will describe the process of deploying a simple Python application to Kubernetes, including: - -* Creating Python container images - -* Publishing the container images to an image registry - -* Working with persistent volume - -* Deploying the Python application to Kubernetes - -### Requirements - -You will need Docker, kubectl, and this [source code][10]. - -Docker is an open platform to build and ship distributed applications. To install Docker, follow the [official documentation][11]. To verify that Docker runs your system: - -``` -$ docker info -Containers: 0 -Images: 289 -Storage Driver: aufs - Root Dir: /var/lib/docker/aufs - Dirs: 289 -Execution Driver: native-0.2 -Kernel Version: 3.16.0-4-amd64 -Operating System: Debian GNU/Linux 8 (jessie) -WARNING: No memory limit support -WARNING: No swap limit support -``` - -kubectl is a command-line interface for executing commands against a Kubernetes cluster. Run the shell script below to install kubectl: - -``` -curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl -``` - -Deploying to Kubernetes requires a containerized application. Let's review containerizing Python applications. - -### Containerization at a glance - -Containerization involves enclosing an application in a container with its own operating system. This full machine virtualization option has the advantage of being able to run an application on any machine without concerns about dependencies. - -Roman Gaponov's [article][12] serves as a reference. Let's start by creating a container image for our Python code. - -### Create a Python container image - -To create these images, we will use Docker, which enables us to deploy applications inside isolated Linux software containers. Docker is able to automatically build images using instructions from a Docker file. - -This is a Docker file for our Python application: - -``` -FROM python:3.6 -MAINTAINER XenonStack - -# Creating Application Source Code Directory -RUN mkdir -p /k8s_python_sample_code/src - -# Setting Home Directory for containers -WORKDIR /k8s_python_sample_code/src - -# Installing python dependencies -COPY requirements.txt /k8s_python_sample_code/src -RUN pip install --no-cache-dir -r requirements.txt - -# Copying src code to Container -COPY . /k8s_python_sample_code/src/app - -# Application Environment variables -ENV APP_ENV development - -# Exposing Ports -EXPOSE 5035 - -# Setting Persistent data -VOLUME ["/app-data"] - -# Running Python Application -CMD ["python", "app.py"] -``` - -This Docker file contains instructions to run our sample Python code. It uses the Python 3.5 development environment. - -### Build a Python Docker image - -We can now build the Docker image from these instructions using this command: - -``` -docker build -t k8s_python_sample_code . -``` - -This command creates a Docker image for our Python application. - -### Publish the container images - -We can publish our Python container image to different private/public cloud repositories, like Docker Hub, AWS ECR, Google Container Registry, etc. For this tutorial, we'll use Docker Hub. - -Before publishing the image, we need to tag it to a version: - -``` -docker tag k8s_python_sample_code:latest k8s_python_sample_code:0.1 -``` - -### Push the image to a cloud repository - -Using a Docker registry other than Docker Hub to store images requires you to add that container registry to the local Docker daemon and Kubernetes Docker daemons. You can look up this information for the different cloud registries. We'll use Docker Hub in this example. - -Execute this Docker command to push the image: - -``` -docker push k8s_python_sample_code -``` - -### Working with CephFS persistent storage - -Kubernetes supports many persistent storage providers, including AWS EBS, CephFS, GlusterFS, Azure Disk, NFS, etc. I will cover Kubernetes persistence storage with CephFS. - -To use CephFS for persistent data to Kubernetes containers, we will create two files: - -persistent-volume.yml - -``` -apiVersion: v1 -kind: PersistentVolume -metadata: -  name: app-disk1 -  namespace: k8s_python_sample_code -spec: -  capacity: -  storage: 50Gi -  accessModes: -  - ReadWriteMany -  cephfs: -  monitors: -    - "172.17.0.1:6789" -  user: admin -  secretRef: -    name: ceph-secret -  readOnly: false -``` - -persistent_volume_claim.yaml - -``` -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: -  name: appclaim1 -  namespace: k8s_python_sample_code -spec: -  accessModes: -  - ReadWriteMany -  resources: -  requests: -    storage: 10Gi -``` - -We can now use kubectl to add the persistent volume and claim to the Kubernetes cluster: - -``` -$ kubectl create -f persistent-volume.yml -$ kubectl create -f persistent-volume-claim.yml -``` - -We are now ready to deploy to Kubernetes. - -### Deploy the application to Kubernetes - -To manage the last mile of deploying the application to Kubernetes, we will create two important files: a service file and a deployment file. - -Create a file and name it `k8s_python_sample_code.service.yml` with the following content: - -``` -apiVersion: v1 -kind: Service -metadata: -  labels: -  k8s-app: k8s_python_sample_code -  name: k8s_python_sample_code -  namespace: k8s_python_sample_code -spec: -  type: NodePort -  ports: -  - port: 5035 -  selector: -  k8s-app: k8s_python_sample_code -``` - -Create a file and name it `k8s_python_sample_code.deployment.yml` with the following content: - -``` -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: -  name: k8s_python_sample_code -  namespace: k8s_python_sample_code -spec: -  replicas: 1 -  template: -  metadata: -    labels: -    k8s-app: k8s_python_sample_code -  spec: -    containers: -    - name: k8s_python_sample_code -      image: k8s_python_sample_code:0.1 -      imagePullPolicy: "IfNotPresent" -      ports: -      - containerPort: 5035 -      volumeMounts: -        - mountPath: /app-data -          name: k8s_python_sample_code -     volumes:  -         - name: -           persistentVolumeClaim: -             claimName: appclaim1 -``` - -Finally, use kubectl to deploy the application to Kubernetes: - -``` -$ kubectl create -f k8s_python_sample_code.deployment.yml $ kubectl create -f k8s_python_sample_code.service.yml -``` - -Your application was successfully deployed to Kubernetes. - -You can verify whether your application is running by inspecting the running services: - -``` -kubectl get services -``` - -May Kubernetes free you from future deployment hassles! - - _Want to learn more about Python? Nanjekye's book, [Python 2 and 3 Compatibility][7]offers clean ways to write code that will run on both Python 2 and 3, including detailed examples of how to convert existing Python 2-compatible code to code that will run reliably on both Python 2 and 3._ - - -### About the author - - [![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/joannah-nanjekye.jpg?itok=F4RqEjoA)][13] Joannah Nanjekye - Straight Outta 256 , I choose Results over Reasons, Passionate Aviator, Show me the code.[More about me][8] - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/1/running-python-application-kubernetes - -作者:[Joannah Nanjekye ][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/nanjekyejoannah -[1]:https://opensource.com/resources/python?intcmp=7016000000127cYAAQ -[2]:https://opensource.com/resources/python/ides?intcmp=7016000000127cYAAQ -[3]:https://opensource.com/resources/python/gui-frameworks?intcmp=7016000000127cYAAQ -[4]:https://opensource.com/tags/python?intcmp=7016000000127cYAAQ -[5]:https://developers.redhat.com/?intcmp=7016000000127cYAAQ -[6]:https://opensource.com/article/18/1/running-python-application-kubernetes?rate=D9iKksKbd9q9vOVb92Mg-v0Iyqn0QVO5fbIERTbSHz4 -[7]:https://www.apress.com/gp/book/9781484229545 -[8]:https://opensource.com/users/nanjekyejoannah -[9]:https://opensource.com/user/196386/feed -[10]:https://github.com/jnanjekye/k8s_python_sample_code/tree/master -[11]:https://docs.docker.com/engine/installation/ -[12]:https://hackernoon.com/docker-tutorial-getting-started-with-python-redis-and-nginx-81a9d740d091 -[13]:https://opensource.com/users/nanjekyejoannah -[14]:https://opensource.com/users/nanjekyejoannah -[15]:https://opensource.com/users/nanjekyejoannah -[16]:https://opensource.com/tags/python -[17]:https://opensource.com/tags/kubernetes diff --git a/sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md b/sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md index f846e9486d..5367ccf9db 100644 --- a/sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md +++ b/sources/tech/20180226 Linux Virtual Machines vs Linux Live Images.md @@ -1,3 +1,4 @@ +## sober-wang 翻译中 Linux Virtual Machines vs Linux Live Images ====== I'll be the first to admit that I tend to try out new [Linux distros][1] on a far too frequent basis. Yet the method I use to test them, does vary depending on my goals for each instance. In this article, we're going to look at both running Linux virtual machines and running Linux live images. There are advantages to each method, but there are some hurdles with each method as well. diff --git a/sources/tech/20180313 Migrating to Linux- Using Sudo.md b/sources/tech/20180313 Migrating to Linux- Using Sudo.md deleted file mode 100644 index 7ad9426ab8..0000000000 --- a/sources/tech/20180313 Migrating to Linux- Using Sudo.md +++ /dev/null @@ -1,84 +0,0 @@ -translating---geekpi - -Migrating to Linux: Using Sudo -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ray-hennessy-233438-unsplash.jpg?itok=d4l7QUtF) - -This article is the fifth in our series about migrating to Linux. If you missed earlier ones, you can catch up here: - -[Part 1 - An Introduction][1] - -[Part 2 - Disks, Files, and Filesystems][2] - -[Part 3 - Graphical Environments][3] - -[Part 4 - The Command Line][4] - -You may have been wondering about Linux for a while. Perhaps it's used in your workplace and you'd be more efficient at your job if you used it on a daily basis. Or, perhaps you'd like to install Linux on some computer equipment you have at home. Whatever the reason, this series of articles is here to make the transition easier. - -Linux, like many other operating systems supports multiple users. It even supports multiple users being logged in simultaneously. - -User accounts are typically assigned a home directory where files can be stored. Usually this home directory is in: -``` -/home/ - -``` - -This way, each user has their own separate location for their documents and other files. - -### Admin Tasks - -In a traditional Linux installation, regular user accounts don't have permissions to perform administrative tasks on the system. And instead of assigning rights to each user to perform various tasks, a typical Linux installation will require a user to log in as the admin to do certain tasks. - -The administrator account on Linux is called root. - -### Sudo Explained - -Historically, to perform admin tasks, one would have to login as root, perform the task, and then log back out. This process was a bit tedious, so many folks logged in as root and worked all day long as the admin. This practice could lead to disastrous results, for example, accidentally deleting all the files in the system. The root user, of course, can do anything, so there are no protections to prevent someone from accidentally performing far-reaching actions. - -The sudo facility was created to make it easier to login as your regular user account and occasionally perform admin tasks as root without having to login, do the task, and log back out. Specifically, sudo allows you to run a command as a different user. If you don't specify a specific user, it assumes you mean root. - -Sudo can have complex settings to allow users certain permissions to use sudo for some commands but not for others. Typically, a desktop installation will make it so the first account created has full permissions in sudo, so you as the primary user can fully administer your Linux installation. - -### Using Sudo - -Some Linux installations set up sudo so that you still need to know the password for the root account to perform admin tasks. Others, set up sudo so that you type in your own password. There are different philosophies here. - -When you try to perform an admin task in the graphical environment, it will usually open a dialog box asking for a password. Enter either your own password (e.g., on Ubuntu), or the root account's password (e.g., Red Hat). - -When you try to perform an admin task in the command line, it will usually just give you a "permission denied" error. Then you would re-run the command with sudo in front. For example: -``` -systemctl start vsftpd -Failed to start vsftpd.service: Access denied - -sudo systemctl start vsftpd -[sudo] password for user1: - -``` - -### When to Use Sudo - -Running commands as root (under sudo or otherwise) is not always the best solution to get around permission errors. While will running as root will remove the "permission denied" errors, it's sometimes best to look for the root cause rather than just addressing the symptom. Sometimes files have the wrong owner and permissions. - -Use sudo when you are trying to perform a task or run a program and the program requires root privileges to perform the operation. Don't use sudo if the file just happens to be owned by another user (including root). In this second case, it's better to set the permission on the file correctly. - -Learn more about Linux through the free ["Introduction to Linux" ][5]course from The Linux Foundation and edX. - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/learn/2018/3/migrating-linux-using-sudo - -作者:[John Bonesio][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/johnbonesio -[1]:https://www.linux.com/blog/learn/intro-to-linux/2017/10/migrating-linux-introduction -[2]:https://www.linux.com/blog/learn/intro-to-linux/2017/11/migrating-linux-disks-files-and-filesystems -[3]:https://www.linux.com/blog/learn/2017/12/migrating-linux-graphical-environments -[4]:https://www.linux.com/blog/learn/2018/1/migrating-linux-command-line -[5]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180425 Understanding metrics and monitoring with Python - Opensource.com.md b/sources/tech/20180425 Understanding metrics and monitoring with Python - Opensource.com.md index f181016aba..0982ec8b9d 100644 --- a/sources/tech/20180425 Understanding metrics and monitoring with Python - Opensource.com.md +++ b/sources/tech/20180425 Understanding metrics and monitoring with Python - Opensource.com.md @@ -1,3 +1,4 @@ +Translating by qhwdw # Understanding metrics and monitoring with Python ![Understanding metrics and monitoring with Python](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_graph_stats_blue.png?itok=OKCc_60D "Understanding metrics and monitoring with Python") diff --git a/sources/tech/20180427 An Official Introduction to the Go Compiler.md b/sources/tech/20180427 An Official Introduction to the Go Compiler.md index 65c35fee64..78dbe23cd7 100644 --- a/sources/tech/20180427 An Official Introduction to the Go Compiler.md +++ b/sources/tech/20180427 An Official Introduction to the Go Compiler.md @@ -1,3 +1,4 @@ + // Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/sources/tech/20180428 How to get a core dump for a segfault on Linux.md b/sources/tech/20180428 How to get a core dump for a segfault on Linux.md deleted file mode 100644 index 1fe70221ac..0000000000 --- a/sources/tech/20180428 How to get a core dump for a segfault on Linux.md +++ /dev/null @@ -1,195 +0,0 @@ -translating by stenphenxs -How to get a core dump for a segfault on Linux -============================================================ - -This week at work I spent all week trying to debug a segfault. I’d never done this before, and some of the basic things involved (get a core dump! find the line number that segfaulted!) took me a long time to figure out. So here’s a blog post explaining how to do those things! - -At the end of this blog post, you should know how to go from “oh no my program is segfaulting and I have no idea what is happening” to “well I know what its stack / line number was when it segfaulted at at least!“. - -### what’s a segfault? - -A “segmentation fault” is when your program tries to access memory that it’s not allowed to access, or tries to . This can be caused by: - -* trying to dereference a null pointer (you’re not allowed to access the memory address `0`) - -* trying to dereference some other pointer that isn’t in your memory - -* a C++ vtable pointer that got corrupted and is pointing to the wrong place, which causes the program to try to execute some memory that isn’t executable - -* some other things that I don’t understand, like I think misaligned memory accesses can also segfault - -This “C++ vtable pointer” thing is what was happening to my segfaulting program. I might explain that in a future blog post because I didn’t know any C++ at the beginning of this week and this vtable lookup thing was a new way for a program to segfault that I didn’t know about. - -But! This blog post isn’t about C++ bugs. Let’s talk about the basics, like, how do we even get a core dump? - -### step 1: run valgrind - -I found the easiest way to figure out why my program is segfaulting was to use valgrind: I ran - -``` -valgrind -v your-program - -``` - -and this gave me a stack trace of what happened. Neat! - -But I wanted also wanted to do a more in-depth investigation and find out more than just what valgrind was telling me! So I wanted to get a core dump and explore it. - -### How to get a core dump - -A core dump is a copy of your program’s memory, and it’s useful when you’re trying to debug what went wrong with your problematic program. - -When your program segfaults, the Linux kernel will sometimes write a core dump to disk. When I originally tried to get a core dump, I was pretty frustrated for a long time because – Linux wasn’t writing a core dump!! Where was my core dump???? - -Here’s what I ended up doing: - -1. Run `ulimit -c unlimited` before starting my program - -2. Run `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` - -### ulimit: set the max size of a core dump - -`ulimit -c` sets the maximum size of a core dump. It’s often set to 0, which means that the kernel won’t write core dumps at all. It’s in kilobytes. ulimits are per process – you can see a process’s limits by running `cat /proc/PID/limit` - -For example these are the limits for a random Firefox process on my system: - -``` -$ cat /proc/6309/limits -Limit Soft Limit Hard Limit Units -Max cpu time unlimited unlimited seconds -Max file size unlimited unlimited bytes -Max data size unlimited unlimited bytes -Max stack size 8388608 unlimited bytes -Max core file size 0 unlimited bytes -Max resident set unlimited unlimited bytes -Max processes 30571 30571 processes -Max open files 1024 1048576 files -Max locked memory 65536 65536 bytes -Max address space unlimited unlimited bytes -Max file locks unlimited unlimited locks -Max pending signals 30571 30571 signals -Max msgqueue size 819200 819200 bytes -Max nice priority 0 0 -Max realtime priority 0 0 -Max realtime timeout unlimited unlimited us - -``` - -The kernel uses the soft limit (in this case, “max core file size = 0”) when deciding how big of a core file to write. You can increase the soft limit up to the hard limit using the `ulimit` shell builtin (`ulimit -c unlimited`!) - -### kernel.core_pattern: where core dumps are written - -`kernel.core_pattern` is a kernel parameter or a “sysctl setting” that controls where the Linux kernel writes core dumps to disk. - -Kernel parameters are a way to set global settings on your system. You can get a list of every kernel parameter by running `sysctl -a`, or use `sysctl kernel.core_pattern` to look at the `kernel.core_pattern` setting specifically. - -So `sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` will write core dumps to `/tmp/core-` - -If you want to know more about what these `%e`, `%p` parameters read, see [man core][1]. - -It’s important to know that `kernel.core_pattern` is a global settings – it’s good to be a little careful about changing it because it’s possible that other systems depend on it being set a certain way. - -### kernel.core_pattern & Ubuntu - -By default on Ubuntu systems, this is what `kernel.core_pattern` is set to - -``` -$ sysctl kernel.core_pattern -kernel.core_pattern = |/usr/share/apport/apport %p %s %c %d %P - -``` - -This caused me a lot of confusion (what is this apport thing and what is it doing with my core dumps??) so here’s what I learned about this: - -* Ubuntu uses a system called “apport” to report crashes in apt packages - -* Setting `kernel.core_pattern=|/usr/share/apport/apport %p %s %c %d %P`means that core dumps will be piped to `apport` - -* apport has logs in /var/log/apport.log - -* apport by default will ignore crashes from binaries that aren’t part of an Ubuntu packages - -I ended up just overriding this Apport business and setting `kernel.core_pattern` to `sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` because I was on a dev machine, I didn’t care whether Apport was working on not, and I didn’t feel like trying to convince Apport to give me my core dumps. - -### So you have a core dump. Now what? - -Okay, now we know about ulimits and `kernel.core_pattern` and you have actually have a core dump file on disk in `/tmp`. Amazing! Now what??? We still don’t know why the program segfaulted! - -The next step is to open the core file with `gdb` and get a backtrace. - -### Getting a backtrace from gdb - -You can open a core file with gdb like this: - -``` -$ gdb -c my_core_file - -``` - -Next, we want to know what the stack was when the program crashed. Running `bt` at the gdb prompt will give you a backtrace. In my case gdb hadn’t loaded symbols for the binary, so it was just like `??????`. Luckily, loading symbols fixed it. - -Here’s how to load debugging symbols. - -``` -symbol-file /path/to/my/binary -sharedlibrary - -``` - -This loads symbols from the binary and from any shared libraries the binary uses. Once I did that, gdb gave me a beautiful stack trace with line numbers when I ran `bt`!!! - -If you want this to work, the binary should be compiled with debugging symbols. Having line numbers in your stack traces is extremely helpful when trying to figure out why a program crashed :) - -### look at the stack for every thread - -Here’s how to get the stack for every thread in gdb! - -``` -thread apply all bt full - -``` - -### gdb + core dumps = amazing - -If you have a core dump & debugging symbols and gdb, you are in an amazing situation!! You can go up and down the call stack, print out variables, and poke around in memory to see what happened. It’s the best. - -If you are still working on being a gdb wizard, you can also just print out the stack trace with `bt` and that’s okay :) - -### ASAN - -Another path to figuring out your segfault is to do one compile the program with AddressSanitizer (“ASAN”) (`$CC -fsanitize=address`) and run it. I’m not going to discuss that in this post because this is already pretty long and anyway in my case the segfault disappeared with ASAN turned on for some reason, possibly because the ASAN build used a different memory allocator (system malloc instead of tcmalloc). - -I might write about ASAN more in the future if I ever get it to work :) - -### getting a stack trace from a core dump is pretty approachable! - -This blog post sounds like a lot and I was pretty confused when I was doing it but really there aren’t all that many steps to getting a stack trace out of a segfaulting program: - -1. try valgrind - -if that doesn’t work, or if you want to have a core dump to investigate: - -1. make sure the binary is compiled with debugging symbols - -2. set `ulimit` and `kernel.core_pattern` correctly - -3. run the program - -4. open your core dump with `gdb`, load the symbols, and run `bt` - -5. try to figure out what happened!! - -I was able using gdb to figure out that there was a C++ vtable entry that is pointing to some corrupt memory, which was somewhat helpful and helped me feel like I understood C++ a bit better. Maybe we’ll talk more about how to use gdb to figure things out another day! - --------------------------------------------------------------------------------- - -via: https://jvns.ca/blog/2018/04/28/debugging-a-segfault-on-linux/ - -作者:[Julia Evans ][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://jvns.ca/about/ -[1]:http://man7.org/linux/man-pages/man5/core.5.html diff --git a/sources/tech/20180430 3 practical Python tools- magic methods, iterators and generators, and method magic.md b/sources/tech/20180430 3 practical Python tools- magic methods, iterators and generators, and method magic.md deleted file mode 100644 index 2cb0e5a948..0000000000 --- a/sources/tech/20180430 3 practical Python tools- magic methods, iterators and generators, and method magic.md +++ /dev/null @@ -1,633 +0,0 @@ -3 practical Python tools: magic methods, iterators and generators, and method magic -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/serving-bowl-forks-dinner.png?itok=a3YqPwr5) -Python offers a unique set of tools and language features that help make your code more elegant, readable, and intuitive. By selecting the right tool for the right problem, your code will be easier to maintain. In this article, we'll examine three of those tools: magic methods, iterators and generators, and method magic. - -### Magic methods - - -Magic methods can be considered the plumbing of Python. They're the methods that are called "under the hood" for certain built-in methods, symbols, and operations. A common magic method you may be familiar with is, `__init__()`,which is called when we want to initialize a new instance of a class. - -You may have seen other common magic methods, like `__str__` and `__repr__`. There is a whole world of magic methods, and by implementing a few of them, we can greatly modify the behavior of an object or even make it behave like a built-in datatype, such as a number, list, or dictionary. - -Let's take this `Money` class for example: -``` -class Money: - - - -    currency_rates = { - -        '$': 1, - -        '€': 0.88, - -    } - - - -    def __init__(self, symbol, amount): - -        self.symbol = symbol - -        self.amount = amount - - - -    def __repr__(self): - -        return '%s%.2f' % (self.symbol, self.amount) - - - -    def convert(self, other): - -        """ Convert other amount to our currency """ - -        new_amount = ( - -            other.amount / self.currency_rates[other.symbol] - -            * self.currency_rates[self.symbol]) - - - -        return Money(self.symbol, new_amount) - -``` - -The class defines a currency rate for a given symbol and exchange rate, specifies an initializer (also known as a constructor), and implements `__repr__`, so when we print out the class, we see a nice representation such as `$2.00` for an instance `Money('$', 2.00)` with the currency symbol and amount. Most importantly, it defines a method that allows you to convert between different currencies with different exchange rates. - -Using a Python shell, let's say we've defined the costs for two food items in different currencies, like so: -``` ->>> soda_cost = Money('$', 5.25) - ->>> soda_cost - -    $5.25 - - - ->>> pizza_cost = Money('€', 7.99) - ->>> pizza_cost - -    €7.99 - -``` - -We could use magic methods to help instances of this class interact with each other. Let's say we wanted to be able to add two instances of this class together, even if they were in different currencies. To make that a reality, we could implement the `__add__` magic method on our `Money` class: -``` -class Money: - - - -    # ... previously defined methods ... - - - -    def __add__(self, other): - -        """ Add 2 Money instances using '+' """ - -        new_amount = self.amount + self.convert(other).amount - -        return Money(self.symbol, new_amount) - -``` - -Now we can use this class in a very intuitive way: -``` ->>> soda_cost = Money('$', 5.25) - - - ->>> pizza_cost = Money('€', 7.99) - - - ->>> soda_cost + pizza_cost - -    $14.33 - - - ->>> pizza_cost + soda_cost - -    €12.61 - -``` - -When we add two instances together, we get a result in the first defined currency. All the conversion is done seamlessly under the hood. If we wanted to, we could also implement `__sub__` for subtraction, `__mul__` for multiplication, and many more. Read about [emulating numeric types][1], or read this [guide to magic methods][2] for others. - -We learned that `__add__` maps to the built-in operator `+`. Other magic methods can map to symbols like `[]`. For example, to access an item by index or key (in the case of a dictionary), use the `__getitem__` method: -``` ->>> d = {'one': 1, 'two': 2} - - - ->>> d['two'] - -2 - ->>> d.__getitem__('two') - -2 - -``` - -Some magic methods even map to built-in functions, such as `__len__()`, which maps to `len()`. -``` -class Alphabet: - -    letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - - - -    def __len__(self): - -        return len(self.letters) - - - - - ->>> my_alphabet = Alphabet() - ->>> len(my_alphabet) - -    26 - -``` - -### Custom iterators - -Custom iterators are an incredibly powerful but unfortunately confusing topic to new and seasoned Pythonistas alike. - -Many built-in types, such as lists, sets, and dictionaries, already implement the protocol that allows them to be iterated over under the hood. This allows us to easily loop over them. -``` ->>> for food in ['Pizza', 'Fries']: - -         print(food + '. Yum!') - - - -Pizza. Yum! - -Fries. Yum! - -``` - -How can we iterate over our own custom classes? First, let's clear up some terminology. - - * To be iterable, a class needs to implement `__iter__()` - * The `__iter__()` method needs to return an iterator - * To be an iterator, a class needs to implement `__next__()` (or `next()` [in Python 2][3]), which must raise a `StopIteration` exception when there are no more items to iterate over. - - - -Whew! It sounds complicated, but once you remember these fundamental concepts, you'll be able to iterate in your sleep. - -When might we want to use a custom iterator? Let's imagine a scenario where we have a `Server` instance running different services such as `http` and `ssh` on different ports. Some of these services have an `active` state while others are `inactive`. -``` -class Server: - - - -    services = [ - -        {'active': False, 'protocol': 'ftp', 'port': 21}, - -        {'active': True, 'protocol': 'ssh', 'port': 22}, - -        {'active': True, 'protocol': 'http', 'port': 80}, - -    ] - -``` - -When we loop over our `Server` instance, we only want to loop over `active` services. Let's create a new class, an `IterableServer`: -``` -class IterableServer: - - - -    def __init__(self): - -        self.current_pos = 0 - - - -    def __next__(self): - -        pass  # TODO: Implement and remember to raise StopIteration - -``` - -First, we initialize our current position to `0`. Then, we define a `__next__()` method, which will return the next item. We'll also ensure that we raise `StopIteration` when there are no more items to return. So far so good! Now, let's implement this `__next__()` method. -``` -class IterableServer: - - - -    def __init__(self): - -        self.current_pos = 0.  # we initialize our current position to zero - - - -    def __iter__(self):  # we can return self here, because __next__ is implemented - -        return self - - - -    def __next__(self): - -        while self.current_pos < len(self.services): - -            service = self.services[self.current_pos] - -            self.current_pos += 1 - -            if service['active']: - -                return service['protocol'], service['port'] - -        raise StopIteration - - - -    next = __next__  # optional python2 compatibility - -``` - -We keep looping over the services in our list while our current position is less than the length of the services but only returning if the service is active. Once we run out of services to iterate over, we raise a `StopIteration` exception. - -Because we implement a `__next__()` method that raises `StopIteration` when it is exhausted, we can return `self` from `__iter__()` because the `IterableServer` class adheres to the `iterable` protocol. - -Now we can loop over an instance of `IterableServer`, which will allow us to look at each active service, like so: -``` ->>> for protocol, port in IterableServer(): - -        print('service %s is running on port %d' % (protocol, port)) - - - -service ssh is running on port 22 - -service http is running on port 21 - -``` - -That's pretty great, but we can do better! In an instance like this, where our iterator doesn't need to maintain a lot of state, we can simplify our code and use a [generator][4] instead. -``` -class Server: - - - -    services = [ - -        {'active': False, 'protocol': 'ftp', 'port': 21}, - -        {'active': True, 'protocol': 'ssh', 'port': 22}, - -        {'active': True, 'protocol': 'http', 'port': 21}, - -    ] - - - -    def __iter__(self): - -        for service in self.services: - -            if service['active']: - -                yield service['protocol'], service['port'] - -``` - -What exactly is the `yield` keyword? Yield is used when defining a generator function. It's sort of like a `return`. While a `return` exits the function after returning the value, `yield` suspends execution until the next time it's called. This allows your generator function to maintain state until it resumes. Check out [yield's documentation][5] to learn more. With a generator, we don't have to manually maintain state by remembering our position. A generator knows only two things: what it needs to do right now and what it needs to do to calculate the next item. Once we reach a point of execution where `yield` isn't called again, we know to stop iterating. - -This works because of some built-in Python magic. In the [Python documentation for `__iter__()`][6] we can see that if `__iter__()` is implemented as a generator, it will automatically return an iterator object that supplies the `__iter__()` and `__next__()` methods. Read this great article for a deeper dive of [iterators, iterables, and generators][7]. - -### Method magic - -Due to its unique aspects, Python provides some interesting method magic as part of the language. - -One example of this is aliasing functions. Since functions are just objects, we can assign them to multiple variables. For example: -``` ->>> def foo(): - -       return 'foo' - - - ->>> foo() - -'foo' - - - ->>> bar = foo - - - ->>> bar() - -'foo' - -``` - -We'll see later on how this can be useful. - -Python provides a handy built-in, [called `getattr()`][8], that takes the `object, name, default` parameters and returns the attribute `name` on `object`. This programmatically allows us to access instance variables and methods. For example: -``` ->>> class Dog: - -        sound = 'Bark' - -        def speak(self): - -            print(self.sound + '!', self.sound + '!') - - - ->>> fido = Dog() - - - ->>> fido.sound - -'Bark' - ->>> getattr(fido, 'sound') - -'Bark' - - - ->>> fido.speak - -> - ->>> getattr(fido, 'speak') - -> - - - - - ->>> fido.speak() - -Bark! Bark! - ->>> speak_method = getattr(fido, 'speak') - ->>> speak_method() - -Bark! Bark! - -``` - -Cool trick, but how could we practically use `getattr`? Let's look at an example that allows us to write a tiny command-line tool to dynamically process commands. -``` -class Operations: - -    def say_hi(self, name): - -        print('Hello,', name) - - - -    def say_bye(self, name): - -        print ('Goodbye,', name) - - - -    def default(self, arg): - -        print ('This operation is not supported.') - - - -if __name__ == '__main__': - -    operations = Operations() - - - -    # let's assume we do error handling - -    command, argument = input('> ').split() - -    func_to_call = getattr(operations, command, operations.default) - -    func_to_call(argument) - -``` - -The output of our script is: -``` -$ python getattr.py - - - -> say_hi Nina - -Hello, Nina - - - -> blah blah - -This operation is not supported. - -``` - -Next, we'll look at `partial`. For example, **`functool.partial(func, *args, **kwargs)`** allows you to return a new [partial object][9] that behaves like `func` called with `args` and `kwargs`. If more `args` are passed in, they're appended to `args`. If more `kwargs` are passed in, they extend and override `kwargs`. Let's see it in action with a brief example: -``` ->>> from functools import partial - ->>> basetwo = partial(int, base=2) - ->>> basetwo - - - - - ->>> basetwo('10010') - -18 - - - -# This is the same as - ->>> int('10010', base=2) - -``` - -Let's see how this method magic ties together in some sample code from a library I enjoy using [called][10]`agithub`, which is a (poorly named) REST API client with transparent syntax that allows you to rapidly prototype any REST API (not just GitHub) with minimal configuration. I find this project interesting because it's incredibly powerful yet only about 400 lines of Python. You can add support for any REST API in about 30 lines of configuration code. `agithub` knows everything it needs to about protocol (`REST`, `HTTP`, `TCP`), but it assumes nothing about the upstream API. Let's dive into the implementation. - -Here's a simplified version of how we'd define an endpoint URL for the GitHub API and any other relevant connection properties. View the [full code][11] instead. -``` -class GitHub(API): - - - -    def __init__(self, token=None, *args, **kwargs): - -        props = ConnectionProperties(api_url = kwargs.pop('api_url', 'api.github.com')) - -        self.setClient(Client(*args, **kwargs)) - -        self.setConnectionProperties(props) - -``` - -Then, once your [access token][12] is configured, you can start using the [GitHub API][13]. -``` ->>> gh = GitHub('token') - ->>> status, data = gh.user.repos.get(visibility='public', sort='created') - ->>> # ^ Maps to GET /user/repos - ->>> data - -... ['tweeter', 'snipey', '...'] - -``` - -Note that it's up to you to spell things correctly. There's no validation of the URL. If the URL doesn't exist or anything else goes wrong, the error thrown by the API will be returned. So, how does this all work? Let's figure it out. First, we'll check out a simplified example of the [`API` class][14]: -``` -class API: - - - -    # ... other methods ... - - - -    def __getattr__(self, key): - -        return IncompleteRequest(self.client).__getattr__(key) - -    __getitem__ = __getattr__ - -``` - -Each call on the `API` class ferries the call to the [`IncompleteRequest` class][15] for the specified `key`. -``` -class IncompleteRequest: - - - -    # ... other methods ... - - - -    def __getattr__(self, key): - -        if key in self.client.http_methods: - -            htmlMethod = getattr(self.client, key) - -            return partial(htmlMethod, url=self.url) - -        else: - -            self.url += '/' + str(key) - -            return self - -    __getitem__ = __getattr__ - - - - - -class Client: - -    http_methods = ('get')  # ... and post, put, patch, etc. - - - -    def get(self, url, headers={}, **params): - -        return self.request('GET', url, None, headers) - -``` - -If the last call is not an HTTP method (like 'get', 'post', etc.), it returns an `IncompleteRequest` with an appended path. Otherwise, it gets the right function for the specified HTTP method from the [`Client` class][16] and returns a `partial` . - -What happens if we give a non-existent path? -``` ->>> status, data = this.path.doesnt.exist.get() - ->>> status - -... 404 - -``` - -And because `__getitem__` is aliased to `__getattr__`: -``` ->>> owner, repo = 'nnja', 'tweeter' - ->>> status, data = gh.repos[owner][repo].pulls.get() - ->>> # ^ Maps to GET /repos/nnja/tweeter/pulls - ->>> data - -.... # {....} - -``` - -Now that's some serious method magic! - -### Learn more - -Python provides plenty of tools that allow you to make your code more elegant and easier to read and understand. The challenge is finding the right tool for the job, but I hope this article added some new ones to your toolbox. And, if you'd like to take this a step further, you can read about decorators, context managers, context generators, and `NamedTuple`s on my blog [nnja.io][17]. As you become a better Python developer, I encourage you to get out there and read some source code for well-architected projects. [Requests][18] and [Flask][19] are two great codebases to start with. - - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/4/elegant-solutions-everyday-python-problems - -作者:[Nina Zakharenko][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/nnja -[1]:https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types -[2]:https://rszalski.github.io/magicmethods/ -[3]:https://docs.python.org/2/library/stdtypes.html#iterator.next -[4]:https://docs.python.org/3/library/stdtypes.html#generator-types -[5]:https://docs.python.org/3/reference/expressions.html#yieldexpr -[6]:https://docs.python.org/3/reference/datamodel.html#object.__iter__ -[7]:http://nvie.com/posts/iterators-vs-generators/ -[8]:https://docs.python.org/3/library/functions.html#getattr -[9]:https://docs.python.org/3/library/functools.html#functools.partial -[10]:https://github.com/mozilla/agithub -[11]:https://github.com/mozilla/agithub/blob/master/agithub/GitHub.py -[12]:https://github.com/settings/tokens -[13]:https://developer.github.com/v3/repos/#list-your-repositories -[14]:https://github.com/mozilla/agithub/blob/dbf7014e2504333c58a39153aa11bbbdd080f6ac/agithub/base.py#L30-L58 -[15]:https://github.com/mozilla/agithub/blob/dbf7014e2504333c58a39153aa11bbbdd080f6ac/agithub/base.py#L60-L100 -[16]:https://github.com/mozilla/agithub/blob/dbf7014e2504333c58a39153aa11bbbdd080f6ac/agithub/base.py#L102-L231 -[17]:http://nnja.io -[18]:https://github.com/requests/requests -[19]:https://github.com/pallets/flask -[20]:https://us.pycon.org/2018/schedule/presentation/164/ -[21]:https://us.pycon.org/2018/ diff --git a/sources/tech/20180502 Customizing your text colors on the Linux command line.md b/sources/tech/20180502 Customizing your text colors on the Linux command line.md deleted file mode 100644 index 381df0e53a..0000000000 --- a/sources/tech/20180502 Customizing your text colors on the Linux command line.md +++ /dev/null @@ -1,163 +0,0 @@ -Customizing your text colors on the Linux command line -====== - -![](https://images.idgesg.net/images/article/2018/05/numbers-100756457-large.jpg) -If you spend much time on the Linux command line (and you probably wouldn't be reading this if you didn't), you've undoubtedly noticed that the ls command displays your files in a number of different colors. You've probably also come to recognize some of the distinctions — directories appearing in one color, executable files in another, etc. - -How that all happens and what options are available for you to change the color assignments might not be so obvious. - -One way to get a big dose of data showing how these colors are assigned is to run the **dircolors** command. It will show you something like this: -``` -$ dircolors -LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do -=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg -=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01 -;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01 -;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=0 -1;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31 -:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*. -xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.t -bz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.j -ar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.a -lz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.r -z=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*. -mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35: -*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35: -*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;3 -5:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01; -35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01 -;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01 -;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01 -;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;3 -5:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;3 -5:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;3 -6:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00; -36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00; -36:*.spx=00;36:*.xspf=00;36:'; -export LS_COLORS - -``` - -If you're good at parsing, you probably noticed that there's a pattern to this listing. Break it on the colons, and you'll see something like this: -``` -$ dircolors | tr ":" "\n" | head -10 -LS_COLORS='rs=0 -di=01;34 -ln=01;36 -mh=00 -pi=40;33 -so=01;35 -do=01;35 -bd=40;33;01 -cd=40;33;01 -or=40;31;01 - -``` - -OK, so we have a pattern here — a series of definitions that have one to three numeric components. Let's hone in on one of definition. -``` -pi=40;33 - -``` - -The first question someone is likely to ask is "What is pi?" We're working with colors and file types here, so this clearly isn't the intriguing number that starts with 3.14. No, this "pi" stands for "pipe" — a particular type of file on Linux systems that makes it possible to send data from one program to another. So, let's set one up. -``` -$ mknod /tmp/mypipe p -$ ls -l /tmp/mypipe -prw-rw-r-- 1 shs shs 0 May 1 14:00 /tmp/mypipe - -``` - -When we look at our pipe and a couple other files in a terminal window, the color differences are quite obvious. - -![font colors][1] Sandra Henry-Stocker - -The "40" in the definition of pi (shown above) makes the file show up in the terminal (or PuTTY) window with a black background. The 31 makes the font color red. Pipes are special files, and this special handling makes them stand out in a directory listing. - -The **bd** and **cd** definitions are identical to each other — 40;33;01 and have an extra setting. The settings cause block (bd) and character (cd) devices to be displayed with a black background, an orange font, and one other effect — the characters will be in bold. - -The following list shows the color and font assignments that are made by **file type** : -``` -setting file type -======= ========= -rs=0 reset to no color -di=01;34 directory -ln=01;36 link -mh=00 multi-hard link -pi=40;33 pipe -so=01;35 socket -do=01;35 door -bd=40;33;01 block device -cd=40;33;01 character device -or=40;31;01 orphan -mi=00 missing? -su=37;41 setuid -sg=30;43 setgid -ca=30;41 file with capability -tw=30;42 directory with sticky bit and world writable -ow=34;42 directory that is world writable -st=37;44 directory with sticky bit -ex=01;93 executable - -``` - -You may have noticed that in our **dircolors** command output, most of our definitions started with asterisks (e.g., *.wav=00;36). These define display attributes by **file extension** rather than file type. Here's a sampling: -``` -$ dircolors | tr ":" "\n" | tail -10 -*.mpc=00;36 -*.ogg=00;36 -*.ra=00;36 -*.wav=00;36 -*.oga=00;36 -*.opus=00;36 -*.spx=00;36 -*.xspf=00;36 -'; -export LS_COLORS - -``` - -These settings (all 00:36 in the listing above) would have these file names displaying in cyan. The available colors are shown below. - -![all colors][2] Sandra Henry-Stocker - -### How to change your settings - -The colors and font changes described require that you use an alias for ls that turns on the color feature. This is usually the default on Linux systems and will look like this: -``` -alias ls='ls --color=auto' - -``` - -If you wanted to turn off font colors, you could run the **unalias ls** command and your file listings would then show in only the default font color. - -You can alter your text colors by modifying your $LS_COLORS settings and exporting the modified setting: -``` -$ export LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;... - -``` - -NOTE: The command above is truncated. - -If you want your modified text colors to be permanent, you would need to add your modified LS_COLORS definition to one of your startup files (e.g., .bashrc). - -### More on command line text - -You can find additional information on text colors in this [November 2016][3] post on NetworkWorld. - - --------------------------------------------------------------------------------- - -via: https://www.networkworld.com/article/3269587/linux/customizing-your-text-colors-on-the-linux-command-line.html - -作者:[Sandra Henry-Stocker][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/ -[1]:https://images.idgesg.net/images/article/2018/05/font-colors-100756483-large.jpg -[2]:https://images.techhive.com/images/article/2016/11/all-colors-100691990-large.jpg -[3]:https://www.networkworld.com/article/3138909/linux/coloring-your-world-with-ls-colors.html diff --git a/sources/tech/20180508 Everything old is new again- Microservices - DXC Blogs.md b/sources/tech/20180508 Everything old is new again- Microservices - DXC Blogs.md deleted file mode 100644 index 1e9922643f..0000000000 --- a/sources/tech/20180508 Everything old is new again- Microservices - DXC Blogs.md +++ /dev/null @@ -1,58 +0,0 @@ -Everything old is new again: Microservices – DXC Blogs -====== -![](https://csccommunity.files.wordpress.com/2018/05/old-building-with-modern-addition.jpg?w=610) - -If I told you about a software architecture in which components of an application provided services to other components via a communications protocol over a network you would say it was… - -Well, it depends. If you got your start programming in the 90s, you’d say I just defined a [Service-Oriented Architecture (SOA)][1]. But, if you’re younger and cut your developer teeth on the cloud, you’d say: “Oh, you’re talking about [microservices][2].” - -You’d both be right. To really understand the differences, you need to dive deeper into these architectures. - -In SOA, a service is a function, which is well-defined, self-contained, and doesn’t depend on the context or state of other services. There are two kinds of services. A service consumer, which requests a service from the other type, a service provider. An SOA service can play both roles. - -SOA services can trade data with each other. Two or more services can also coordinate with each other. These services carry out basic jobs such as creating a user account, providing login functionality, or validating a payment. - -SOA isn’t so much about modularizing an application as it is about composing an application by integrating distributed, separately-maintained and deployed components. These components run on servers. - -Early versions of SOA used object-oriented protocols to communicate with each other. For example, Microsoft’s [Distributed Component Object Model (DCOM)][3] and [Object Request Brokers (ORBs)][4] use the [Common Object Request Broker Architecture (CORBA)][5] specification. - -Later versions used messaging services such as [Java Message Service (JMS)][6] or [Advanced Message Queuing Protocol (AMQP)][7]. These service connections are called Enterprise Service Buses (ESB). Over these buses, data, almost always in eXtensible Markup Language (XML) format, is transmitted and received. - -[Microservices][2] is an architectural style where applications are made up from loosely coupled services or modules. It lends itself to the Continuous Integration/Continuous Deployment (CI/CD) model of developing large, complex applications. An application is the sum of its modules. - -Each microservice provides an application programming interface (API) endpoint. These are connected by lightweight protocols such as [REpresentational State Transfer (REST)][8], or [gRPC][9]. Data tends to be represented by [JavaScript Object Notation (JSON)][10] or [Protobuf][11]. - -Both architectures stand as an alternative to the older, monolithic style of architecture where applications are built as single, autonomous units. For example, in a client-server model, a typical Linux, Apache, MySQL, PHP/Python/Perl (LAMP) server-side application would deal with HTTP requests, run sub-programs and retrieves/updates from the underlying MySQL database. These are all tied closely together. When you change anything, you must build and deploy a new version. - -With SOA, you may need to change several components, but never the entire application. With microservices, though, you can make changes one service at a time. With microservices, you’re working with a true decoupled architecture. - -Microservices are also lighter than SOA. While SOA services are deployed to servers and virtual machines (VMs), microservices are deployed in containers. The protocols are also lighter. This makes microservices more flexible than SOA. Hence, it works better with Agile shops. - -So what does this mean? The long and short of it is that microservices are an SOA variation for container and cloud computing. - -Old style SOA isn’t going away, but as we continue to move applications to containers, the microservice architecture will only grow more popular. - - --------------------------------------------------------------------------------- - -via: https://blogs.dxc.technology/2018/05/08/everything-old-is-new-again-microservices/ - -作者:[Cloudy Weather][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://blogs.dxc.technology/author/steven-vaughan-nichols/ -[1]:https://www.service-architecture.com/articles/web-services/service-oriented_architecture_soa_definition.html -[2]:http://microservices.io/ -[3]:https://technet.microsoft.com/en-us/library/cc958799.aspx -[4]:https://searchmicroservices.techtarget.com/definition/Object-Request-Broker-ORB -[5]:http://www.corba.org/ -[6]:https://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html -[7]:https://www.amqp.org/ -[8]:https://www.service-architecture.com/articles/web-services/representational_state_transfer_rest.html -[9]:https://grpc.io/ -[10]:https://www.json.org/ -[11]:https://github.com/google/protobuf/ diff --git a/sources/tech/20180508 How To Check Ubuntu Version and Other System Information Easily.md b/sources/tech/20180508 How To Check Ubuntu Version and Other System Information Easily.md deleted file mode 100644 index 9395b7708a..0000000000 --- a/sources/tech/20180508 How To Check Ubuntu Version and Other System Information Easily.md +++ /dev/null @@ -1,127 +0,0 @@ -How To Check Ubuntu Version and Other System Information Easily -====== -**Brief: Wondering which Ubuntu version are you using? Here’s how to check Ubuntu version, desktop environment and other relevant system information.** - -You can easily find the Ubuntu version you are using in the command line or via the graphical interface. Knowing the exact Ubuntu version, desktop environment and other system information helps a lot when you are trying to follow a tutorial from the web or seeking help in various forums. - -In this quick tip, I’ll show you various ways to check [Ubuntu][1] version and other common system information. - -### How to check Ubuntu version in terminal - -This is the best way to find Ubuntu version. I could have mentioned the graphical way first but then I chose this method because this one doesn’t depend on the [desktop environment][2] you are using. You can use it on any Ubuntu variant. - -Open a terminal (Ctrl+Alt+T) and type the following command: -``` -lsb_release -a - -``` - -The output of the above command should be like this: -``` -No LSB modules are available. -Distributor ID: Ubuntu -Description: Ubuntu 16.04.4 LTS -Release: 16.04 -Codename: xenial - -``` - -![How to check Ubuntu version in command line][3] - -As you can see, the current Ubuntu installed in my system is Ubuntu 16.04 and its code name is Xenial. - -Wait! Why does it say Ubuntu 16.04.4 in Description and 16.04 in the Release? Which one is it, 16.04 or 16.04.4? What’s the difference between the two? - -The short answer is that you are using Ubuntu 16.04. That’s the base image. 16.04.4 signifies the fourth point release of 16.04. A point release can be thought of as a service pack in Windows era. Both 16.04 and 16.04.4 will be the correct answer here. - -What’s Xenial in the output? That’s the codename of the Ubuntu 16.04 release. You can read this [article to know about Ubuntu naming convention][4]. - -#### Some alternate ways to find Ubuntu version - -Alternatively, you can use either of the following commands to find Ubuntu version: -``` -cat /etc/lsb-release - -``` - -The output of the above command would look like this: -``` -DISTRIB_ID=Ubuntu -DISTRIB_RELEASE=16.04 -DISTRIB_CODENAME=xenial -DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS" - -``` - -![How to check Ubuntu version in command line][5] - -You can also use this command to know Ubuntu version -``` -cat /etc/issue - -``` - -The output of this command will be like this: -``` -Ubuntu 16.04.4 LTS \n \l - -``` - -Forget the \n \l. The Ubuntu version is 16.04.4 in this case or simply Ubuntu 16.04. - -### How to check Ubuntu version graphically - -Checking Ubuntu version graphically is no big deal either. I am going to use screenshots from Ubuntu 18.04 GNOME here. Things may look different if you are using Unity or some other desktop environment. This is why I recommend the command line version discussed in the previous sections because that doesn’t depend on the desktop environment. - -I’ll show you how to find the desktop environment in the next section. - -For now, go to System Settings and look under the Details segment. - -![Finding Ubuntu version graphically][6] - -You should see the Ubuntu version here along with the information about the desktop environment you are using, [GNOME][7] being the case here. - -![Finding Ubuntu version graphically][8] - -### How to know the desktop environment and other system information in Ubuntu - -So you just learned how to find Ubuntu version. What about the desktop environment in use? Which Linux kernel version is being used? - -Of course, there are various commands you can use to get all those information but I’ll recommend a command line utility called [Neofetch][9]. This will show you essential system information in the terminal beautifully with the logo of Ubuntu or any other Linux distribution you are using. - -Install Neofetch using the command below: -``` -sudo apt install neofetch - -``` - -Once installed, simply run the command `neofetch` in the terminal and see a beautiful display of system information. - -![System information in Linux terminal][10] - -As you can see, Neofetch shows you the Linux kernel version, Ubuntu version, desktop environment in use along with its version, themes and icons in use etc. - -I hope it helps you to find Ubuntu version and other system information. If you have suggestions to improve this article, feel free to drop it in the comment section. Ciao :) - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/how-to-know-ubuntu-unity-version/ - -作者:[Abhishek Prakash][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/abhishek/ -[1]:https://www.ubuntu.com/ -[2]:https://en.wikipedia.org/wiki/Desktop_environment -[3]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/check-ubuntu-version-command-line-1-800x216.jpeg -[4]:https://itsfoss.com/linux-code-names/ -[5]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/check-ubuntu-version-command-line-2-800x185.jpeg -[6]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/ubuntu-version-system-settings.jpeg -[7]:https://www.gnome.org/ -[8]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/checking-ubuntu-version-gui.jpeg -[9]:https://itsfoss.com/display-linux-logo-in-ascii/ -[10]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2013/03/ubuntu-system-information-terminal-800x400.jpeg diff --git a/sources/tech/20180508 UKTools - Easy Way To Install Latest Linux Kernel.md b/sources/tech/20180508 UKTools - Easy Way To Install Latest Linux Kernel.md index c85d9c35d4..dc0963d132 100644 --- a/sources/tech/20180508 UKTools - Easy Way To Install Latest Linux Kernel.md +++ b/sources/tech/20180508 UKTools - Easy Way To Install Latest Linux Kernel.md @@ -1,3 +1,6 @@ +Translating by MjSeven + + UKTools - Easy Way To Install Latest Linux Kernel ====== There are multiple utilities is available for Ubuntu to upgrade Linux kernel to latest stable version. We had already wrote about those utility in the past such as Linux Kernel Utilities (LKU), Ubuntu Kernel Upgrade Utility (UKUU) and Ubunsys. diff --git a/sources/tech/20180510 Splicing the Cloud Native Stack, One Floor at a Time.md b/sources/tech/20180510 Splicing the Cloud Native Stack, One Floor at a Time.md index 6515b3e193..b9ec11efba 100644 --- a/sources/tech/20180510 Splicing the Cloud Native Stack, One Floor at a Time.md +++ b/sources/tech/20180510 Splicing the Cloud Native Stack, One Floor at a Time.md @@ -1,3 +1,4 @@ +Translating by qhwdw Splicing the Cloud Native Stack, One Floor at a Time ====== At Packet, our value (automated infrastructure) is super fundamental. As such, we spend an enormous amount of time looking up at the players and trends in all the ecosystems above us - as well as the very few below! diff --git a/sources/tech/20180515 Give Your Linux Desktop a Stunning Makeover With Xenlism Themes.md b/sources/tech/20180515 Give Your Linux Desktop a Stunning Makeover With Xenlism Themes.md deleted file mode 100644 index f76a483199..0000000000 --- a/sources/tech/20180515 Give Your Linux Desktop a Stunning Makeover With Xenlism Themes.md +++ /dev/null @@ -1,92 +0,0 @@ -Give Your Linux Desktop a Stunning Makeover With Xenlism Themes -============================================================ - - - _Brief: Xenlism theme pack provides an aesthetically pleasing GTK theme, colorful icons, and minimalist wallpapers to transform your Linux desktop into an eye-catching setup._ - -It’s not every day that I dedicate an entire article to a theme unless I find something really awesome. I used to cover themes and icons regularly. But lately, I preferred having lists of [best GTK themes][6] and icon themes. This is more convenient for me and for you as well as you get to see many beautiful themes in one place. - -After [Pop OS theme][7] suit, Xenlism is another theme that has left me awestruck by its look.  - -![Xenlism GTK theme for Ubuntu and Other Linux](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/xenlishm-minimalism-gtk-theme-800x450.jpeg) - -Xenlism GTK theme is based on the Arc theme, an inspiration behind so many themes these days. The GTK theme provides Windows buttons similar to macOS which I neither like nor dislike. The GTK theme has a flat, minimalist layout and I like that. - -There are two icon themes in the Xenlism suite. Xenlism Wildfire is an old one and had already made to our list of [best icon themes][8]. - -![Beautiful Xenlism Wildfire theme for Ubuntu and Other Linux](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/xenlism-wildfire-theme-800x450.jpeg) -Xenlism Wildfire Icons - -Xenlsim Storm is the relatively new icon theme but is equally beautiful. - -![Beautiful Xenlism Storm theme for Ubuntu and Other Linux](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/05/xenlism-storm-theme-1-800x450.jpeg) -Xenlism Storm Icons - -Xenlism themes are open source under GPL license. - -### How to install Xenlism theme pack on Ubuntu 18.04 - -Xenlism dev provides an easier way of installing the theme pack through a PPA. Though the PPA is available for Ubuntu 16.04, I found the GTK theme wasn’t working with Unity. It works fine with the GNOME desktop in Ubuntu 18.04. - -Open a terminal (Ctrl+Alt+T) and use the following commands one by one: - -``` -sudo add-apt-repository ppa:xenatt/xenlism -sudo apt update -``` - -This PPA offers four packages: - -* xenlism-finewalls: for a set of wallpapers that will be available directly in the wallpaper section of Ubuntu. One of the wallpapers has been used in the screenshot. - -* xenlism-minimalism-theme: GTK theme - -* xenlism-storm: an icon theme (see previous screenshots) - -* xenlism-wildfire-icon-theme: another icon theme with several color variants (folder colors get changed in the variants) - -You can decide on your own what theme component you want to install. Personally, I don’t see any harm in installing all the components. - -``` -sudo apt install xenlism-minimalism-theme xenlism-storm-icon-theme xenlism-wildfire-icon-theme xenlism-finewalls -``` - -You can use GNOME Tweaks for changing the theme and icons. If you are not familiar with the procedure already, I suggest reading this tutorial to learn [how to install themes in Ubuntu 18.04 GNOME][9]. - -### Getting Xenlism themes in other Linux distributions - -You can install Xenlism themes on other Linux distributions as well. Installation instructions for various Linux distributions can be found on its website: - -[Install Xenlism Themes][10] - -### What do you think? - -I know not everyone would agree with me but I loved this theme. I think you are going to see the glimpse of Xenlism theme in the screenshots in future tutorials on It’s FOSS. - -Did you like Xenlism theme? If not, what theme do you like the most? Share your opinion in the comment section below. - -#### 关于作者 - -I am a professional software developer, and founder of It's FOSS. I am an avid Linux lover and Open Source enthusiast. I use Ubuntu and believe in sharing knowledge. Apart from Linux, I love classic detective mysteries. I'm a huge fan of Agatha Christie's work. - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/xenlism-theme/ - -作者:[Abhishek Prakash ][a] -译者:[译者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/abhishek/ -[1]:https://itsfoss.com/author/abhishek/ -[2]:https://itsfoss.com/xenlism-theme/#comments -[3]:https://itsfoss.com/category/desktop/ -[4]:https://itsfoss.com/tag/themes/ -[5]:https://itsfoss.com/tag/xenlism/ -[6]:https://itsfoss.com/best-gtk-themes/ -[7]:https://itsfoss.com/pop-icon-gtk-theme-ubuntu/ -[8]:https://itsfoss.com/best-icon-themes-ubuntu-16-04/ -[9]:https://itsfoss.com/install-themes-ubuntu/ -[10]:http://xenlism.github.io/minimalism/#install diff --git a/sources/tech/20180516 How Graphics Cards Work.md b/sources/tech/20180516 How Graphics Cards Work.md index 653ec5ef5d..6e82311149 100644 --- a/sources/tech/20180516 How Graphics Cards Work.md +++ b/sources/tech/20180516 How Graphics Cards Work.md @@ -1,3 +1,5 @@ +pinewall translating + How Graphics Cards Work ====== ![AMD-Polaris][1] diff --git a/sources/tech/20180522 How to Run Your Own Git Server.md b/sources/tech/20180522 How to Run Your Own Git Server.md deleted file mode 100644 index 9a1ee8509a..0000000000 --- a/sources/tech/20180522 How to Run Your Own Git Server.md +++ /dev/null @@ -1,233 +0,0 @@ -translating by wyxplus -How to Run Your Own Git Server -====== -**Learn how to set up your own Git server in this tutorial from our archives.** - -[Git ][1]is a versioning system [developed by Linus Torvalds][2], that is used by millions of users around the globe. Companies like GitHub offer code hosting services based on Git. [According to reports, GitHub, a code hosting site, is the world's largest code hosting service.][3] The company claims that there are 9.2M people collaborating right now across 21.8M repositories on GitHub. Big companies are now moving to GitHub. [Even Google, the search engine giant, is shutting it's own Google Code and moving to GitHub.][4] - -### Run your own Git server - -GitHub is a great service, however there are some limitations and restrictions, especially if you are an individual or a small player. One of the limitations of GitHub is that the free service doesn’t allow private hosting of the code. [You have to pay a monthly fee of $7 to host 5 private repositories][5], and the expenses go up with more repos. - -In cases like these or when you want more control, the best path is to run Git on your own server. Not only do you save costs, you also have more control over your server. In most cases a majority of advanced Linux users already have their own servers and pushing Git on those servers is like ‘free as in beer’. - -In this tutorial we are going to talk about two methods of managing your code on your own server. One is running a bare, basic Git server and and the second one is via a GUI tool called [GitLab][6]. For this tutorial I used a fully patched Ubuntu 14.04 LTS server running on a VPS. - -### Install Git on your server - -In this tutorial we are considering a use-case where we have a remote server and a local server and we will work between these machines. For the sake of simplicity we will call them remote-server and local-server. - -First, install Git on both machines. You can install Git from the packages already available via the repos or your distros, or you can do it manually. In this article we will use the simpler method: -``` -sudo apt-get install git-core - -``` - -Then add a user for Git. -``` -sudo useradd git -passwd git - -``` - -In order to ease access to the server let's set-up a password-less ssh login. First create ssh keys on your local machine: -``` -ssh-keygen -t rsa - -``` - -It will ask you to provide the location for storing the key, just hit Enter to use the default location. The second question will be to provide it with a pass phrase which will be needed to access the remote server. It generates two keys - a public key and a private key. Note down the location of the public key which you will need in the next step. - -Now you have to copy these keys to the server so that the two machines can talk to each other. Run the following command on your local machine: -``` -cat ~/.ssh/id_rsa.pub | ssh git@remote-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" - -``` - -Now ssh into the server and create a project directory for Git. You can use the desired path for the repo. - -Then change to this directory: -``` -cd /home/swapnil/project-1.git - -``` - -Then create an empty repo: -``` -git init --bare -Initialized empty Git repository in /home/swapnil/project-1.git - -``` - -We now need to create a Git repo on the local machine. -``` -mkdir -p /home/swapnil/git/project - -``` - -And change to this directory: -``` -cd /home/swapnil/git/project - -``` - -Now create the files that you need for the project in this directory. Stay in this directory and initiate git: -``` -git init -Initialized empty Git repository in /home/swapnil/git/project - -``` - -Now add files to the repo: -``` -git add . - -``` - -Now every time you add a file or make changes you have to run the add command above. You also need to write a commit message with every change in a file. The commit message basically tells what changes were made. -``` -git commit -m "message" -a -[master (root-commit) 57331ee] message - 2 files changed, 2 insertions(+) - create mode 100644 GoT.txt - create mode 100644 writing.txt - -``` - -In this case I had a file called GoT (Game of Thrones review) and I made some changes, so when I ran the command it specified that changes were made to the file. In the above command '-a' option means commits for all files in the repo. If you made changes to only one you can specify the name of that file instead of using '-a'. - -An example: -``` -git commit -m "message" GoT.txt -[master e517b10] message - 1 file changed, 1 insertion(+) - -``` - -Until now we have been working on the local server. Now we have to push these changes to the server so the work is accessible over the Internet and you can collaborate with other team members. -``` -git remote add origin ssh://git@remote-server/repo->path-on-server..git - -``` - -Now you can push or pull changes between the server and local machine using the 'push' or 'pull' option: -``` -git push origin master - -``` - -If there are other team members who want to work with the project they need to clone the repo on the server to their local machine: -``` -git clone git@remote-server:/home/swapnil/project.git - -``` - -Here /home/swapnil/project.git is the project path on the remote server, exchange the values for your own server. - -Then change directory on the local machine (exchange project with the name of project on your server): -``` -cd /project - -``` - -Now they can edit files, write commit change messages and then push them to the server: -``` -git commit -m 'corrections in GoT.txt story' -a -And then push changes: - -git push origin master - -``` - -I assume this is enough for a new user to get started with Git on their own servers. If you are looking for some GUI tools to manage changes on local machines, you can use GUI tools such as QGit or GitK for Linux. - -### Using GitLab - -This was a pure command line solution for project owner and collaborator. It's certainly not as easy as using GitHub. Unfortunately, while GitHub is the world's largest code hosting service; its own software is not available for others to use. It's not open source so you can't grab the source code and compile your own GitHub. Unlike WordPress or Drupal you can't download GitHub and run it on your own servers. - -As usual in the open source world there is no end to the options. GitLab is a nifty project which does exactly that. It's an open source project which allows users to run a project management system similar to GitHub on their own servers. - -You can use GitLab to run a service similar to GitHub for your team members or your company. You can use GitLab to work on private projects before releasing them for public contributions. - -GitLab employs the traditional Open Source business model. They have two products: free of cost open source software, which users can install on their own servers, and a hosted service similar to GitHub. - -The downloadable version has two editions - the free of cost community edition and the paid enterprise edition. The enterprise edition is based on the community edition but comes with additional features targeted at enterprise customers. It’s more or less similar to what WordPress.org or Wordpress.com offer. - -The community edition is highly scalable and can support 25,000 users on a single server or cluster. Some of the features of GitLab include: Git repository management, code reviews, issue tracking, activity feeds, and wikis. It comes with GitLab CI for continuous integration and delivery. - -Many VPS providers such as Digital Ocean offer GitLab droplets for users. If you want to run it on your own server, you can install it manually. GitLab offers an Omnibus package for different operating systems. Before we install GitLab, you may want to configure an SMTP email server so that GitLab can push emails as and when needed. They recommend Postfix. So, install Postfix on your server: -``` -sudo apt-get install postfix - -``` - -During installation of Postfix it will ask you some questions; don't skip them. If you did miss it you can always re-configure it using this command: -``` -sudo dpkg-reconfigure postfix - -``` - -When you run this command choose "Internet Site" and provide the email ID for the domain which will be used by Gitlab. - -In my case I provided it with: -``` -This e-mail address is being protected from spambots. You need JavaScript enabled to view it - - -``` - -Use Tab and create a username for postfix. The Next page will ask you to provide a destination for mail. - -In the rest of the steps, use the default options. Once Postfix is installed and configured, let's move on to install GitLab. - -Download the packages using wget (replace the download link with the [latest packages from here][7]) : -``` -wget https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.9.4-omnibus.1-1_amd64.deb - -``` - -Then install the package: -``` -sudo dpkg -i gitlab_7.9.4-omnibus.1-1_amd64.deb - -``` - -Now it's time to configure and start GitLabs. -``` -sudo gitlab-ctl reconfigure - -``` - -You now need to configure the domain name in the configuration file so you can access GitLab. Open the file. -``` -nano /etc/gitlab/gitlab.rb - -``` - -In this file edit the 'external_url' and give the server domain. Save the file and then open the newly created GitLab site from a web browser. - -By default it creates 'root' as the system admin and uses '5iveL!fe' as the password. Log into the GitLab site and then change the password. - -Once the password is changed, log into the site and start managing your project. - -GitLab is overflowing with features and options. I will borrow popular lines from the movie, The Matrix: "Unfortunately, no one can be told what all GitLab can do. You have to try it for yourself." - --------------------------------------------------------------------------------- - -via: https://www.linux.com/learn/how-run-your-own-git-server - -作者:[Swapnil Bhartiya][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/arnieswap -[1]:https://github.com/git/git -[2]:https://www.linuxfoundation.org/blog/10-years-of-git-an-interview-with-git-creator-linus-torvalds/ -[3]:https://github.com/about/press -[4]:http://google-opensource.blogspot.com/2015/03/farewell-to-google-code.html -[5]:https://github.com/pricing -[6]:https://about.gitlab.com/ -[7]:https://about.gitlab.com/downloads/ diff --git a/sources/tech/20180531 You don-t know Bash- An introduction to Bash arrays.md b/sources/tech/20180531 You don-t know Bash- An introduction to Bash arrays.md deleted file mode 100644 index 10a1ecf526..0000000000 --- a/sources/tech/20180531 You don-t know Bash- An introduction to Bash arrays.md +++ /dev/null @@ -1,268 +0,0 @@ -You don't know Bash: An introduction to Bash arrays -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming-code-keyboard-laptop.png?itok=pGfEfu2S) - -Although software engineers regularly use the command line for many aspects of development, arrays are likely one of the more obscure features of the command line (although not as obscure as the regex operator `=~`). But obscurity and questionable syntax aside, [Bash][1] arrays can be very powerful. - -### Wait, but why? - -Writing about Bash is challenging because it's remarkably easy for an article to devolve into a manual that focuses on syntax oddities. Rest assured, however, the intent of this article is to avoid having you RTFM. - -#### A real (actually useful) example - -To that end, let's consider a real-world scenario and how Bash can help: You are leading a new effort at your company to evaluate and optimize the runtime of your internal data pipeline. As a first step, you want to do a parameter sweep to evaluate how well the pipeline makes use of threads. For the sake of simplicity, we'll treat the pipeline as a compiled C++ black box where the only parameter we can tweak is the number of threads reserved for data processing: `./pipeline --threads 4`. - -### The basics - -`--threads` parameter that we want to test: -``` -allThreads=(1 2 4 8 16 32 64 128) - -``` - -The first thing we'll do is define an array containing the values of theparameter that we want to test: - -In this example, all the elements are numbers, but it need not be the case—arrays in Bash can contain both numbers and strings, e.g., `myArray=(1 2 "three" 4 "five")` is a valid expression. And just as with any other Bash variable, make sure to leave no spaces around the equal sign. Otherwise, Bash will treat the variable name as a program to execute, and the `=` as its first parameter! - -Now that we've initialized the array, let's retrieve a few of its elements. You'll notice that simply doing `echo $allThreads` will output only the first element. - -To understand why that is, let's take a step back and revisit how we usually output variables in Bash. Consider the following scenario: -``` -type="article" - -echo "Found 42 $type" - -``` - -Say the variable `$type` is given to us as a singular noun and we want to add an `s` at the end of our sentence. We can't simply add an `s` to `$type` since that would turn it into a different variable, `$types`. And although we could utilize code contortions such as `echo "Found 42 "$type"s"`, the best way to solve this problem is to use curly braces: `echo "Found 42 ${type}s"`, which allows us to tell Bash where the name of a variable starts and ends (interestingly, this is the same syntax used in JavaScript/ES6 to inject variables and expressions in [template literals][2]). - -So as it turns out, although Bash variables don't generally require curly brackets, they are required for arrays. In turn, this allows us to specify the index to access, e.g., `echo ${allThreads[1]}` returns the second element of the array. Not including brackets, e.g.,`echo $allThreads[1]`, leads Bash to treat `[1]` as a string and output it as such. - -Yes, Bash arrays have odd syntax, but at least they are zero-indexed, unlike some other languages (I'm looking at you, `R`). - -### Looping through arrays - -Although in the examples above we used integer indices in our arrays, let's consider two occasions when that won't be the case: First, if we wanted the `$i`-th element of the array, where `$i` is a variable containing the index of interest, we can retrieve that element using: `echo ${allThreads[$i]}`. Second, to output all the elements of an array, we replace the numeric index with the `@` symbol (you can think of `@` as standing for `all`): `echo ${allThreads[@]}`. - -#### Looping through array elements - -With that in mind, let's loop through `$allThreads` and launch the pipeline for each value of `--threads`: -``` -for t in ${allThreads[@]}; do - -  ./pipeline --threads $t - -done - -``` - -#### Looping through array indices - -Next, let's consider a slightly different approach. Rather than looping over array elements, we can loop over array indices: -``` -for i in ${!allThreads[@]}; do - -  ./pipeline --threads ${allThreads[$i]} - -done - -``` - -Let's break that down: As we saw above, `${allThreads[@]}` represents all the elements in our array. Adding an exclamation mark to make it `${!allThreads[@]}` will return the list of all array indices (in our case 0 to 7). In other words, the `for` loop is looping through all indices `$i` and reading the `$i`-th element from `$allThreads` to set the value of the `--threads` parameter. - -This is much harsher on the eyes, so you may be wondering why I bother introducing it in the first place. That's because there are times where you need to know both the index and the value within a loop, e.g., if you want to ignore the first element of an array, using indices saves you from creating an additional variable that you then increment inside the loop. - -### Populating arrays - -So far, we've been able to launch the pipeline for each `--threads` of interest. Now, let's assume the output to our pipeline is the runtime in seconds. We would like to capture that output at each iteration and save it in another array so we can do various manipulations with it at the end. - -#### Some useful syntax - -But before diving into the code, we need to introduce some more syntax. First, we need to be able to retrieve the output of a Bash command. To do so, use the following syntax: `output=$( ./my_script.sh )`, which will store the output of our commands into the variable `$output`. - -The second bit of syntax we need is how to append the value we just retrieved to an array. The syntax to do that will look familiar: -``` -myArray+=( "newElement1" "newElement2" ) - -``` - -#### The parameter sweep - -Putting everything together, here is our script for launching our parameter sweep: -``` -allThreads=(1 2 4 8 16 32 64 128) - -allRuntimes=() - -for t in ${allThreads[@]}; do - -  runtime=$(./pipeline --threads $t) - -  allRuntimes+=( $runtime ) - -done - -``` - -And voilà! - -### What else you got? - -In this article, we covered the scenario of using arrays for parameter sweeps. But I promise there are more reasons to use Bash arrays—here are two more examples. - -#### Log alerting - -In this scenario, your app is divided into modules, each with its own log file. We can write a cron job script to email the right person when there are signs of trouble in certain modules:`` -``` -# List of logs and who should be notified of issues - -logPaths=("api.log" "auth.log" "jenkins.log" "data.log") - -logEmails=("jay@email" "emma@email" "jon@email" "sophia@email") - - - -# Look for signs of trouble in each log - -for i in ${!logPaths[@]}; - -do - -  log=${logPaths[$i]} - -  stakeholder=${logEmails[$i]} - -  numErrors=$( tail -n 100 "$log" | grep "ERROR" | wc -l ) - - - -  # Warn stakeholders if recently saw > 5 errors - -  if [[ "$numErrors" -gt 5 ]]; - -  then - -    emailRecipient="$stakeholder" - -    emailSubject="WARNING: ${log} showing unusual levels of errors" - -    emailBody="${numErrors} errors found in log ${log}" - -    echo "$emailBody" | mailx -s "$emailSubject" "$emailRecipient" - -  fi - -done - -``` - -#### API queries - -Say you want to generate some analytics about which users comment the most on your Medium posts. Since we don't have direct database access, SQL is out of the question, but we can use APIs! - -To avoid getting into a long discussion about API authentication and tokens, we'll instead use [JSONPlaceholder][3], a public-facing API testing service, as our endpoint. Once we query each post and retrieve the emails of everyone who commented, we can append those emails to our results array: -``` -endpoint="https://jsonplaceholder.typicode.com/comments" - -allEmails=() - - - -# Query first 10 posts - -for postId in {1..10}; - -do - -  # Make API call to fetch emails of this posts's commenters - -  response=$(curl "${endpoint}?postId=${postId}") - - - -  # Use jq to parse the JSON response into an array - -  allEmails+=( $( jq '.[].email' <<< "$response" ) ) - -done - -``` - -Note here that I'm using the [`jq` tool][4] to parse JSON from the command line. The syntax of `jq` is beyond the scope of this article, but I highly recommend you look into it. - -As you might imagine, there are countless other scenarios in which using Bash arrays can help, and I hope the examples outlined in this article have given you some food for thought. If you have other examples to share from your own work, please leave a comment below. - -### But wait, there's more! - -Since we covered quite a bit of array syntax in this article, here's a summary of what we covered, along with some more advanced tricks we did not cover: - -Syntax Result `arr=()` Create an empty array `arr=(1 2 3)` Initialize array `${arr[2]}` Retrieve third element `${arr[@]}` Retrieve all elements `${!arr[@]}` Retrieve array indices `${#arr[@]}` Calculate array size `arr[0]=3` Overwrite 1st element `arr+=(4)` Append value(s) `str=$(ls)` Save `ls` output as a string `arr=( $(ls) )` Save `ls` output as an array of files `${arr[@]:s:n}` Retrieve elements at indices `n` to `s+n` - -### One last thought - -As we've discovered, Bash arrays sure have strange syntax, but I hope this article convinced you that they are extremely powerful. Once you get the hang of the syntax, you'll find yourself using Bash arrays quite often. - -#### Bash or Python? - -Which begs the question: When should you use Bash arrays instead of other scripting languages such as Python? - -To me, it all boils down to dependencies—if you can solve the problem at hand using only calls to command-line tools, you might as well use Bash. But for times when your script is part of a larger Python project, you might as well use Python. - -For example, we could have turned to Python to implement the parameter sweep, but we would have ended up just writing a wrapper around Bash: -``` -import subprocess - - - -all_threads = [1, 2, 4, 8, 16, 32, 64, 128] - -all_runtimes = [] - - - -# Launch pipeline on each number of threads - -for t in all_threads: - -  cmd = './pipeline --threads {}'.format(t) - - - -  # Use the subprocess module to fetch the return output - -  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) - -  output = p.communicate()[0] - -  all_runtimes.append(output) - -``` - -Since there's no getting around the command line in this example, using Bash directly is preferable. - -#### Time for a shameless plug - -If you enjoyed this article, there's more where that came from! [Register here to attend OSCON][5], where I'll be presenting the live-coding workshop [You Don't Know Bash][6] on July 17, 2018. No slides, no clickers—just you and me typing away at the command line, exploring the wondrous world of Bash. - -This article originally appeared on [Medium][7] and is republished with permission. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays - -作者:[Robert Aboukhalil][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/robertaboukhalil -[1]:https://opensource.com/article/17/7/bash-prompt-tips-and-tricks -[2]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals -[3]:https://github.com/typicode/jsonplaceholder -[4]:https://stedolan.github.io/jq/ -[5]:https://conferences.oreilly.com/oscon/oscon-or -[6]:https://conferences.oreilly.com/oscon/oscon-or/public/schedule/detail/67166 -[7]:https://medium.com/@robaboukhalil/the-weird-wondrous-world-of-bash-arrays-a86e5adf2c69 diff --git a/sources/tech/20180604 4 cool new projects to try in COPR for June 2018.md b/sources/tech/20180604 4 cool new projects to try in COPR for June 2018.md deleted file mode 100644 index 8f030028b7..0000000000 --- a/sources/tech/20180604 4 cool new projects to try in COPR for June 2018.md +++ /dev/null @@ -1,80 +0,0 @@ -4 cool new projects to try in COPR for June 2018 -====== -COPR is a [collection][1] of personal repositories for software that isn’t carried in Fedora. Some software doesn’t conform to standards that allow easy packaging. Or it may not meet other Fedora standards, despite being free and open source. COPR can offer these projects outside the Fedora set of packages. Software in COPR isn’t supported by Fedora infrastructure or signed by the project. However, it can be a neat way to try new or experimental software. - -Here’s a set of new and interesting projects in COPR. - -### Ghostwriter - -[Ghostwriter][2] is a text editor for [Markdown][3] format with a minimal interface. It provides a preview of the document in HTML and syntax highlighting for Markdown. It offers the option to highlight only the paragraph or sentence currently being written. In addition, Ghostwriter can export documents to several formats, including PDF and HTML. Finally, it has the so-called “Hemingway” mode, in which erasing is disabled, forcing the user to write now and edit later.![][4] - -#### Installation instructions - -The repo currently provides Ghostwriter for Fedora 26, 27, 28, and Rawhide, and EPEL 7. To install Ghostwriter, use these commands: -``` -sudo dnf copr enable scx/ghostwriter -sudo dnf install ghostwriter - -``` - -### Lector - -[Lector][5] is a simple ebook reader application. Lector supports most common ebook formats, such as EPUB, MOBI, and AZW, as well as comic book archives CBZ and CBR. It’s easy to setup — just specify the directory containing your ebooks. You can browse books in Lector’s library using either a table or book covers. Among Lector’s features are bookmarks, user-defined tags, and a built-in dictionary.![][6] - -#### Installation instructions - -The repo currently provides Lector for Fedora 26, 27, 28, and Rawhide. To install Lector, use these commands: -``` -sudo dnf copr enable bugzy/lector -sudo dnf install lector - -``` - -### Ranger - -Ranerger is a text-based file manager with Vim key bindings. It displays the directory structure in three columns. The left one shows the parent directory, the middle the contents of the current directory, and the right a preview of the selected file or directory. In the case of text files, Ranger shows actual contents of the file as a preview.![][7] - -#### Installation instructions - -The repo currently provides Ranger for Fedora 27, 28, and Rawhide. To install Ranger, use these commands: -``` -sudo dnf copr enable fszymanski/ranger -sudo dnf install ranger - -``` - -### PrestoPalette - -PrestoPeralette is a tool that helps create balanced color palettes. A nice feature of PrestoPalette is the ability to use lighting to affect both lightness and saturation of the palette. You can export created palettes either as PNG or JSON. -![][8] - -#### Installation instructions - -The repo currently provides PrestoPalette for Fedora 26, 27, 28, and Rawhide, and EPEL 7. To install PrestoPalette, use these commands: -``` -sudo dnf copr enable dagostinelli/prestopalette -sudo dnf install prestopalette - -``` - - --------------------------------------------------------------------------------- - -via: https://fedoramagazine.org/4-try-copr-june-2018/ - -作者:[Dominik Turecek][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://fedoramagazine.org -[1]:https://copr.fedorainfracloud.org/ -[2]:http://wereturtle.github.io/ghostwriter/ -[3]:https://daringfireball.net/ -[4]:https://fedoramagazine.org/wp-content/uploads/2018/05/ghostwriter.png -[5]:https://github.com/BasioMeusPuga/Lector -[6]:https://fedoramagazine.org/wp-content/uploads/2018/05/lector.png -[7]:https://fedoramagazine.org/wp-content/uploads/2018/05/ranger.png -[8]:https://fedoramagazine.org/wp-content/uploads/2018/05/prestopalette.png diff --git a/sources/tech/20180606 Getting started with Buildah.md b/sources/tech/20180606 Getting started with Buildah.md deleted file mode 100644 index 8d72b92fed..0000000000 --- a/sources/tech/20180606 Getting started with Buildah.md +++ /dev/null @@ -1,343 +0,0 @@ -pinewall translating - -Getting started with Buildah -====== -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/blocks_building.png?itok=eMOT-ire) - -[Buildah][1] is a command-line tool for building [Open Container Initiative][2]-compatible (that means Docker- and Kubernetes-compatible, too) images quickly and easily. It can act as a drop-in replacement for the Docker daemon’s `docker build` command (i.e., building images with a traditional Dockerfile) but is flexible enough to allow you to build images with whatever tools you prefer to use. Buildah is easy to incorporate into scripts and build pipelines, and best of all, it doesn’t require a running container daemon to build its image. - -### A drop-in replacement for docker build - -You can get started with Buildah immediately, dropping it into place where images are currently built using a Dockerfile and `docker build`. Buildah’s `build-using-dockerfile`, or `bud` argument makes it behave just like `docker build` does, so it's easy to incorporate into existing scripts or build pipelines. - -As with [previous articles I’ve written about Buildah][3], I like to use the example of installing "GNU Hello" from source. Consider this Dockerfile: -``` -FROM fedora:28 - -LABEL maintainer Chris Collins - - - -RUN dnf install -y tar gzip gcc make \ - -        && dnf clean all - - - -ADD http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz /tmp/hello-2.10.tar.gz - - - -RUN tar xvzf /tmp/hello-2.10.tar.gz -C /opt - - - -WORKDIR /opt/hello-2.10 - - - -RUN ./configure - -RUN make - -RUN make install - -RUN hello -v - -ENTRYPOINT "/usr/local/bin/hello" - -``` - -Buildah can create an image from this Dockerfile as easily as `buildah bud -t hello .`, replacing `docker build -t hello .`: -``` -[chris@krang] $ sudo buildah bud -t hello . - -STEP 1: FROM fedora:28 - -Getting image source signatures - -Copying blob sha256:e06fd16225608e5b92ebe226185edb7422c3f581755deadf1312c6b14041fe73 - - 81.48 MiB / 81.48 MiB [====================================================] 8s - -Copying config sha256:30190780b56e33521971b0213810005a69051d720b73154c6e473c1a07ebd609 - - 2.29 KiB / 2.29 KiB [======================================================] 0s - -Writing manifest to image destination - -Storing signatures - -STEP 2: LABEL maintainer Chris Collins - -STEP 3: RUN dnf install -y tar gzip gcc make    && dnf clean all - - - - - -``` - -Once the build is complete, you can see the new image with the `buildah images` command: -``` -[chris@krang] $ sudo buildah images - -IMAGE ID        IMAGE NAME                              CREATED AT              SIZE - -30190780b56e    docker.io/library/fedora:28             Mar 7, 2018 16:53       247 MB - -6d54bef73e63    docker.io/library/hello:latest    May 3, 2018 15:24     391.8 MB - -``` - -The new image, tagged `hello:latest`, can be pushed to a remote image registry or run using [CRI-O][4] or other Kubernetes CRI-compatible runtimes, or pushed to a remote registry. If you’re testing it as a replacement for Docker build, you will probably want to copy the image to the docker daemon’s local image storage so it can be run by Docker. This is easily accomplished with the `buildah push` command: -``` -[chris@krang] $ sudo buildah push hello:latest docker-daemon:hello:latest - -Getting image source signatures - -Copying blob sha256:72fcdba8cff9f105a61370d930d7f184702eeea634ac986da0105d8422a17028 - - 247.02 MiB / 247.02 MiB [==================================================] 2s - -Copying blob sha256:e567905cf805891b514af250400cc75db3cb47d61219750e0db047c5308bd916 - - 144.75 MiB / 144.75 MiB [==================================================] 1s - -Copying config sha256:6d54bef73e638f2e2dd8b7bf1c4dfa26e7ed1188f1113ee787893e23151ff3ff - - 1.59 KiB / 1.59 KiB [======================================================] 0s - -Writing manifest to image destination - -Storing signatures - - - -[chris@krang] $ sudo docker images | head -n2 - -REPOSITORY              TAG             IMAGE ID        CREATED                 SIZE - -docker.io/hello      latest       6d54bef73e63  2 minutes ago   398 MB - - - -[chris@krang] $ sudo docker run -t hello:latest - -Hello, world! - -``` - -### A few differences - -Unlike Docker build, Buildah doesn’t commit changes to a layer automatically for every instruction in the Dockerfile—it builds everything from top to bottom, every time. On the positive side, this means non-cached builds (for example, those you would do with automation or build pipelines) end up being somewhat faster than their Docker build counterparts, especially if there are a lot of instructions. This is great for getting new changes into production quickly from an automated deployment or continuous delivery standpoint. - -Practically speaking, however, the lack of caching may not be quite as useful for image development, where caching layers can save significant time when doing builds over and over again. This applies only to the `build-using-dockerfile` command, however. When using Buildah native commands, as we’ll see below, you can choose when to commit your changes to disk, allowing for more flexible development. - -### Buildah native commands - -Where Buildah _really_ shines is in its native commands, which you can use to interact with container builds. Rather than using `build-using-dockerfile/bud` for each build, Buildah has commands to actually interact with the temporary container created during the build process. (Docker uses temporary, or _intermediate_ containers, too, but you don’t really interact with them while the image is being built.) - -Using the "GNU Hello" example again, consider this image build using Buildah commands: -``` -#!/usr/bin/env bash - - - -set -o errexit - - - -# Create a container - -container=$(buildah from fedora:28) - - - -# Labels are part of the "buildah config" command - -buildah config --label maintainer="Chris Collins " $container - - - -# Grab the source code outside of the container - -curl -sSL http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz -o hello-2.10.tar.gz - - - -buildah copy $container hello-2.10.tar.gz /tmp/hello-2.10.tar.gz - - - -buildah run $container dnf install -y tar gzip gcc make - -Buildah run $container dnf clean all - -buildah run $container tar xvzf /tmp/hello-2.10.tar.gz -C /opt - - - -# Workingdir is also a "buildah config" command - -buildah config --workingdir /opt/hello-2.10 $container - - - -buildah run $container ./configure - -buildah run $container make - -buildah run $container make install - -buildah run $container hello -v - - - -# Entrypoint, too, is a “buildah config” command - -buildah config --entrypoint /usr/local/bin/hello $container - - - -# Finally saves the running container to an image - -buildah commit --format docker $container hello:latest - -``` - -One thing that should be immediately obvious is the fact that this is a Bash script rather than a Dockerfile. Using Buildah’s native commands makes it easy to script, in whatever language or automation context you like to use. This could be a makefile, a Python script, or whatever tools you like to use. - -So what is going on here? The first Buildah command `container=$(buildah from fedora:28)`, creates a running container from the fedora:28 image, and stores the container name (the output of the command) as a variable for later use. All the rest of the Buildah commands use the `$container` variable to say what container to act upon. For the most part those commands are self-explanatory: `buildah copy` moves a file into the container, `buildah run` executes a command in the container. It is easy to match them to their Dockerfile equivalents. - -The final command, `buildah commit`, commits the container to an image on disk. When building images with Buildah commands rather than from a Dockerfile, you can use the `commit` command to decide when to save your changes. In the example above, all of the changes are committed at once, but intermediate commits could be included too, allowing you to choose cache points from which to start. (For example, it would be particularly useful to cache to disk after the `dnf install`, as that can take a long time, but is also reliably the same each time.) - -### Mountpoints, install directories, and chroots - -Another useful Buildah command opens the door to a lot of flexibility in building images. `buildah mount` mounts the root directory of a container to a mountpoint on your host. For example: -``` -[chris@krang] $ container=$(sudo buildah from fedora:28) - -[chris@krang] $ mountpoint=$(sudo buildah mount ${container}) - -[chris@krang] $ echo $mountpoint - -/var/lib/containers/storage/overlay2/463eda71ec74713d8cebbe41ee07da5f6df41c636f65139a7bd17b24a0e845e3/merged - -[chris@krang] $ cat ${mountpoint}/etc/redhat-release - -Fedora release 28 (Twenty Eight) - -[chris@krang] $ ls ${mountpoint} - -bin   dev  home  lib64          media  opt   root  sbin  sys  usr - -boot  etc  lib   lost+found  mnt        proc  run   srv   tmp  var - -``` - -This is great because now you can interact with the mountpoint to make changes to your container image. This allows you to use tools on your host to build and install software, rather than including those tools in the container image itself. For example, in the Bash script above, we needed to install the tar, Gzip, GCC, and make packages to compile "GNU Hello" inside the container. Using a mountpoint, we can build an image with the same software, but the downloaded tarball and tar, Gzip, etc., RPMs are all on the host machine rather than in the container and resulting image: -``` -#!/usr/bin/env bash - - - -set -o errexit - - - -# Create a container - -container=$(buildah from fedora:28) - -mountpoint=$(buildah mount $container) - - - -buildah config --label maintainer="Chris Collins " $container - - - -curl -sSL http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz \ - -     -o /tmp/hello-2.10.tar.gz - -tar xvzf src/hello-2.10.tar.gz -C ${mountpoint}/opt - - - -pushd ${mountpoint}/opt/hello-2.10 - -./configure - -make - -make install DESTDIR=${mountpoint} - -popd - - - -chroot $mountpoint bash -c "/usr/local/bin/hello -v" - - - -buildah config --entrypoint "/usr/local/bin/hello" $container - -buildah commit --format docker $container hello - -buildah unmount $container - -``` - -Take note of a few things in the script above: - - 1. The `curl` command downloads the tarball to the host, not the image - - 2. The `tar` command (running from the host itself) extracts the source code from the tarball into `/opt` inside the container. - - 3. `Configure`, `make`, and `make install` are all running from a directory inside the mountpoint, mounted to the host rather than running inside the container itself. - - 4. The `chroot` command here is used to change root into the mountpoint itself and test that "hello" is working, similar to the `buildah run` command used in the previous example. - - - - -This script is shorter, it uses tools most Linux folks are already familiar with, and the resulting image is smaller (no tarball, no extra packages, etc). You could even use the package manager for the host system to install software into the container. For example, let’s say you wanted to install [NGINX][5] into the container with GNU Hello (for whatever reason): -``` -[chris@krang] $ mountpoint=$(sudo buildah mount ${container}) - -[chris@krang] $ sudo dnf install nginx --installroot $mountpoint - -[chris@krang] $ sudo chroot $mountpoint nginx -v - -nginx version: nginx/1.12.1 - -``` - -In the example above, DNF is used with the `--installroot` flag to install NGINX into the container, which can be verified with chroot. - -### Try it out! - -Buildah is a lightweight and flexible way to create container images without running a full Docker daemon on your host. In addition to offering out-of-the-box support for building from Dockerfiles, Buildah is easy to use with scripts or build tools of your choice and can help build container images using existing tools on the build host. The result is leaner images that use less bandwidth to ship around, require less storage space, and have a smaller surface area for potential attackers. Give it a try! - -**[See our related story,[Creating small containers with Buildah][6]]** - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/6/getting-started-buildah - -作者:[Chris Collins][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/clcollins -[1]:https://github.com/projectatomic/buildah -[2]:https://www.opencontainers.org/ -[3]:http://chris.collins.is/2017/08/17/buildah-a-new-way-to-build-container-images/ -[4]:http://cri-o.io/ -[5]:https://www.nginx.com/ -[6]:https://opensource.com/article/18/5/containers-buildah diff --git a/sources/tech/20180607 GitLab-s Ultimate - Gold Plans Are Now Free For Open-Source Projects.md b/sources/tech/20180607 GitLab-s Ultimate - Gold Plans Are Now Free For Open-Source Projects.md deleted file mode 100644 index 1a7e3ca5e6..0000000000 --- a/sources/tech/20180607 GitLab-s Ultimate - Gold Plans Are Now Free For Open-Source Projects.md +++ /dev/null @@ -1,77 +0,0 @@ -GitLab’s Ultimate & Gold Plans Are Now Free For Open-Source Projects -====== -A lot has happened in the open-source community recently. First, [Microsoft acquired GitHub][1] and then people started to look for [GitHub alternatives][2] without even taking a second to think about it while Linus Torvalds released the [Linux Kernel 4.17][3]. Well, if you’ve been following us, I assume that you know all that. - -But, today, GitLab made a smart move by making some of its high-tier plans free for educational institutes and open-source projects. There couldn’t be a better time to offer something like this when a lot of developers are interested in migrating their open-source projects to GitLab. - -### GitLab’s premium plans are now free for open source projects and educational institutes - -![GitLab Logo][4] - -In a [blog post][5] today, GitLab announced that the **Ultimate** and Gold plans are now free for educational institutes and open-source projects. While we already know why GitLab made this move (a darn perfect timing!), they did explain their motive to make it free: - -> We make GitLab free for education because we want students to use our most advanced features. Many universities already run GitLab. If the students use the advanced features of GitLab Ultimate and Gold they will take their experiences with these advanced features to their workplaces. -> -> We would love to have more open source projects use GitLab. Public projects on GitLab.com already have all the features of GitLab Ultimate. And projects like [Gnome][6] and [Debian][7] already run their own server with the open source version of GitLab. With today’s announcement, open source projects that are comfortable running on proprietary software can use all the features GitLab has to offer while allowing us to have a sustainable business model by charging non-open-source organizations. - -### What are these ‘free’ plans offered by GitLab? - -![GitLab Pricing][8] - -GitLab has two categories of offerings. One is the software that you could host on your own cloud hosting service like [Digital Ocean][9]. The other is providing GitLab software as a service where the hosting is managed by GitLab itself and you get an account on GitLab.com. - -![GitLab Pricing for hosted service][10] - -Gold is the highest offering in the hosted category while Ultimate is the highest offering in the self-hosted category. - -You can get more details about their features on GitLab pricing page. Do note that the support is not included in this offer. You have to purchase it separately. - -### You have to match certain criteria to avail this offer - -GitLab also mentioned – to whom the offer will be valid for. Here’s what they wrote in their blog post: - -> 1. **Educational institutions:** any institution whose purposes directly relate to learning, teaching, and/or training by a qualified educational institution, faculty, or student. Educational purposes do not include commercial, professional, or any other for-profit purposes. -> -> 2. **Open source projects:** any project that uses a [standard open source license][11] and is non-commercial. It should not have paid support or paid contributors. -> -> - - -Although the free plan does not include support, you can still pay an additional fee of 4.95 USD per user per month – which is a very fair price, when you are in the dire need of an expert to help resolve an issue. - -GitLab also added a note for the students: - -> To reduce the administrative burden for GitLab, only educational institutions can apply on behalf of their students. If you’re a student and your educational institution does not apply, you can use public projects on GitLab.com with all functionality, use private projects with the free functionality, or pay yourself. - -### Wrapping Up - -Now that GitLab is stepping up its game, what do you think about it? - -Do you have a project hosted on [GitHub][12]? Will you be switching over? Or, luckily, you already happen to use GitLab from the start? - -Let us know your thoughts in the comments section below. - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/gitlab-free-open-source/ - -作者:[Ankush Das][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/ -[1]:https://itsfoss.com/microsoft-github/ -[2]:https://itsfoss.com/github-alternatives/ -[3]:https://itsfoss.com/linux-kernel-4-17/ -[4]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/GitLab-logo-800x450.png -[5]:https://about.gitlab.com/2018/06/05/gitlab-ultimate-and-gold-free-for-education-and-open-source/ -[6]:https://www.gnome.org/news/2018/05/gnome-moves-to-gitlab-2/ -[7]:https://salsa.debian.org/public -[8]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/gitlab-pricing.jpeg -[9]:https://m.do.co/c/d58840562553 -[10]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/gitlab-hosted-service-800x273.jpeg -[11]:https://itsfoss.com/open-source-licenses-explained/ -[12]:https://github.com/ diff --git a/sources/tech/20180607 Using MQTT to send and receive data for your next project.md b/sources/tech/20180607 Using MQTT to send and receive data for your next project.md deleted file mode 100644 index 7005aee93f..0000000000 --- a/sources/tech/20180607 Using MQTT to send and receive data for your next project.md +++ /dev/null @@ -1,311 +0,0 @@ -pinewall translating - -Using MQTT to send and receive data for your next project -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/toolbox-learn-draw-container-yearbook.png?itok=xDbwz1pP) - -Last November we bought an electric car, and it raised an interesting question: When should we charge it? I was concerned about having the lowest emissions for the electricity used to charge the car, so this is a specific question: What is the rate of CO2 emissions per kWh at any given time, and when during the day is it at its lowest? - -### Finding the data - -I live in New York State. About 80% of our electricity comes from in-state generation, mostly through natural gas, hydro dams (much of it from Niagara Falls), nuclear, and a bit of wind, solar, and other fossil fuels. The entire system is managed by the [New York Independent System Operator][1] (NYISO), a not-for-profit entity that was set up to balance the needs of power generators, consumers, and regulatory bodies to keep the lights on in New York. - -Although there is no official public API, as part of its mission, NYISO makes [a lot of open data][2] available for public consumption. This includes reporting on what fuels are being consumed to generate power, at five-minute intervals, throughout the state. These are published as CSV files on a public archive and updated throughout the day. If you know the number of megawatts coming from different kinds of fuels, you can make a reasonable approximation of how much CO2 is being emitted at any given time. - -We should always be kind when building tools to collect and process open data to avoid overloading those systems. Instead of sending everyone to their archive service to download the files all the time, we can do better. We can create a low-overhead event stream that people can subscribe to and get updates as they happen. We can do that with [MQTT][3]. The target for my project ([ny-power.org][4]) was inclusion in the [Home Assistant][5] project, an open source home automation platform that has hundreds of thousands of users. If all of these users were hitting this CSV server all the time, NYISO might need to restrict access to it. - -### What is MQTT? - -MQTT is a publish/subscribe (pubsub) wire protocol designed with small devices in mind. Pubsub systems work like a message bus. You send a message to a topic, and any software with a subscription for that topic gets a copy of your message. As a sender, you never really know who is listening; you just provide your information to a set of topics and listen for any other topics you might care about. It's like walking into a party and listening for interesting conversations to join. - -This can make for extremely efficient applications. Clients subscribe to a narrow selection of topics and only receive the information they are looking for. This saves both processing time and network bandwidth. - -As an open standard, MQTT has many open source implementations of both clients and servers. There are client libraries for every language you could imagine, even a library you can embed in Arduino for making sensor networks. There are many servers to choose from. My go-to is the [Mosquitto][6] server from Eclipse, as it's small, written in C, and can handle tens of thousands of subscribers without breaking a sweat. - -### Why I like MQTT - -Over the past two decades, we've come up with tried and true models for software applications to ask questions of services. Do I have more email? What is the current weather? Should I buy this thing now? This pattern of "ask/receive" works well much of the time; however, in a world awash with data, there are other patterns we need. The MQTT pubsub model is powerful where lots of data is published inbound to the system. Clients can subscribe to narrow slices of data and receive updates instantly when that data comes in. - -MQTT also has additional interesting features, such as "last-will-and-testament" messages, which make it possible to distinguish between silence because there is no relevant data and silence because your data collectors have crashed. MQTT also has retained messages, which provide the last message on a topic to clients when they first connect. This is extremely useful for topics that update slowly. - -In my work with the Home Assistant project, I've found this message bus model works extremely well for heterogeneous systems. If you dive into the Internet of Things space, you'll quickly run into MQTT everywhere. - -### Our first MQTT stream - -One of NYSO's CSV files is the real-time fuel mix. Every five minutes, it's updated with the fuel sources and power generated (in megawatts) during that time period. - -The CSV file looks something like this: - -| Time Stamp | Time Zone | Fuel Category | Gen MW | -| 05/09/2018 00:05:00 | EDT | Dual Fuel | 1400 | -| 05/09/2018 00:05:00 | EDT | Natural Gas | 2144 | -| 05/09/2018 00:05:00 | EDT | Nuclear | 4114 | -| 05/09/2018 00:05:00 | EDT | Other Fossil Fuels | 4 | -| 05/09/2018 00:05:00 | EDT | Other Renewables | 226 | -| 05/09/2018 00:05:00 | EDT | Wind | 1 | -| 05/09/2018 00:05:00 | EDT | Hydro | 3229 | -| 05/09/2018 00:10:00 | EDT | Dual Fuel | 1307 | -| 05/09/2018 00:10:00 | EDT | Natural Gas | 2092 | -| 05/09/2018 00:10:00 | EDT | Nuclear | 4115 | -| 05/09/2018 00:10:00 | EDT | Other Fossil Fuels | 4 | -| 05/09/2018 00:10:00 | EDT | Other Renewables | 224 | -| 05/09/2018 00:10:00 | EDT | Wind | 40 | -| 05/09/2018 00:10:00 | EDT | Hydro | 3166 | - -The only odd thing in the table is the dual-fuel category. Most natural gas plants in New York can also burn other fossil fuel to generate power. During cold snaps in the winter, the natural gas supply gets constrained, and its use for home heating is prioritized over power generation. This happens at a low enough frequency that we can consider dual fuel to be natural gas (for our calculations). - -The file is updated throughout the day. I created a simple data pump that polls for the file every minute and looks for updates. It publishes any new entries out to the MQTT server into a set of topics that largely mirror this CSV file. The payload is turned into a JSON object that is easy to parse from nearly any programming language. -``` -ny-power/upstream/fuel-mix/Hydro {"units": "MW", "value": 3229, "ts": "05/09/2018 00:05:00"} - -ny-power/upstream/fuel-mix/Dual Fuel {"units": "MW", "value": 1400, "ts": "05/09/2018 00:05:00"} - -ny-power/upstream/fuel-mix/Natural Gas {"units": "MW", "value": 2144, "ts": "05/09/2018 00:05:00"} - -ny-power/upstream/fuel-mix/Other Fossil Fuels {"units": "MW", "value": 4, "ts": "05/09/2018 00:05:00"} - -ny-power/upstream/fuel-mix/Wind {"units": "MW", "value": 41, "ts": "05/09/2018 00:05:00"} - -ny-power/upstream/fuel-mix/Other Renewables {"units": "MW", "value": 226, "ts": "05/09/2018 00:05:00"} - -ny-power/upstream/fuel-mix/Nuclear {"units": "MW", "value": 4114, "ts": "05/09/2018 00:05:00"} - -``` - -This direct reflection is a good first step in turning open data into open events. We'll be converting this into a CO2 intensity, but other applications might want these raw feeds to do other calculations with them. - -### MQTT topics - -Topics and topic structures are one of MQTT's major design points. Unlike more "enterprisey" message buses, in MQTT topics are not preregistered. A sender can create topics on the fly, the only limit being that they are less than 220 characters. The `/` character is special; it's used to create topic hierarchies. As we'll soon see, you can subscribe to slices of data in these hierarchies. - -Out of the box with Mosquitto, every client can publish to any topic. While it's great for prototyping, before going to production you'll want to add an access control list (ACL) to restrict writing to authorized applications. For example, my app's tree is accessible to everyone in read-only format, but only clients with specific credentials can publish to it. - -There is no automatic schema around topics nor a way to discover all the possible topics that clients will publish to. You'll have to encode that understanding directly into any application that consumes the MQTT bus. - -So how should you design your topics? The best practice is to start with an application-specific root name, in our case, `ny-power`. After that, build a hierarchy as deep as you need for efficient subscription. The `upstream` tree will contain data that comes directly from an upstream source without any processing. Our `fuel-mix` category is a specific type of data. We may add others later. - -### Subscribing to topics - -Subscriptions in MQTT are simple string matches. For processing efficiency, only two wildcards are allowed: - - * `#` matches everything recursively to the end - * `+` matches only until the next `/` character - - - -It's easiest to explain this with some examples: -``` -ny-power/#  - match everything published by the ny-power app - -ny-power/upstream/#  - match all raw data - -ny-power/upstream/fuel-mix/+  - match all fuel types - -ny-power/+/+/Hydro - match everything about Hydro power that's - -       nested 2 deep (even if it's not in the upstream tree) - -``` - -A wide subscription like `ny-power/#` is common for low-volume applications. Just get everything over the network and handle it in your own application. This works poorly for high-volume applications, as most of the network bandwidth will be wasted as you drop most of the messages on the floor. - -To stay performant at higher volumes, applications will do some clever topic slides like `ny-power/+/+/Hydro` to get exactly the cross-section of data they need. - -### Adding our next layer of data - -From this point forward, everything in the application will work off existing MQTT streams. The first additional layer of data is computing the power's CO2 intensity. - -Using the 2016 [U.S. Energy Information Administration][7] numbers for total emissions and total power by fuel type in New York, we can come up with an [average emissions rate][8] per megawatt hour of power. - -This is encapsulated in a dedicated microservice. This has a subscription on `ny-power/upstream/fuel-mix/+`, which matches all upstream fuel-mix entries from the data pump. It then performs the calculation and publishes out to a new topic tree: -``` -ny-power/computed/co2 {"units": "g / kWh", "value": 152.9486, "ts": "05/09/2018 00:05:00"} - -``` - -In turn, there is another process that subscribes to this topic tree and archives that data into an [InfluxDB][9] instance. It then publishes a 24-hour time series to `ny-power/archive/co2/24h`, which makes it easy to graph the recent changes. - -This layer model works well, as the logic for each of these programs can be distinct from each other. In a more complicated system, they may not even be in the same programming language. We don't care, because the interchange format is MQTT messages, with well-known topics and JSON payloads. - -### Consuming from the command line - -To get a feel for MQTT in action, it's useful to just attach it to a bus and see the messages flow. The `mosquitto_sub` program included in the `mosquitto-clients` package is a simple way to do that. - -After you've installed it, you need to provide a server hostname and the topic you'd like to listen to. The `-v` flag is important if you want to see the topics being posted to. Without that, you'll see only the payloads. -``` -mosquitto_sub -h mqtt.ny-power.org -t ny-power/# -v - -``` - -Whenever I'm writing or debugging an MQTT application, I always have a terminal with `mosquitto_sub` running. - -### Accessing MQTT directly from the web - -We now have an application providing an open event stream. We can connect to it with our microservices and, with some command-line tooling, it's on the internet for all to see. But the web is still king, so it's important to get it directly into a user's browser. - -The MQTT folks thought about this one. The protocol specification is designed to work over three transport protocols: [TCP][10], [UDP][11], and [WebSockets][12]. WebSockets are supported by all major browsers as a way to retain persistent connections for real-time applications. - -The Eclipse project has a JavaScript implementation of MQTT called [Paho][13], which can be included in your application. The pattern is to connect to the host, set up some subscriptions, and then react to messages as they are received. -``` -// ny-power web console application - -var client = new Paho.MQTT.Client(mqttHost, Number("80"), "client-" + Math.random()); - - - -// set callback handlers - -client.onMessageArrived = onMessageArrived; - - - -// connect the client - -client.reconnect = true; - -client.connect({onSuccess: onConnect}); - - - -// called when the client connects - -function onConnect() { - -    // Once a connection has been made, make a subscription and send a message. - -    console.log("onConnect"); - -    client.subscribe("ny-power/computed/co2"); - -    client.subscribe("ny-power/archive/co2/24h"); - -    client.subscribe("ny-power/upstream/fuel-mix/#"); - -} - - - -// called when a message arrives - -function onMessageArrived(message) { - -    console.log("onMessageArrived:"+message.destinationName + message.payloadString); - -    if (message.destinationName == "ny-power/computed/co2") { - -        var data = JSON.parse(message.payloadString); - -        $("#co2-per-kwh").html(Math.round(data.value)); - -        $("#co2-units").html(data.units); - -        $("#co2-updated").html(data.ts); - -    } - -    if (message.destinationName.startsWith("ny-power/upstream/fuel-mix")) { - -        fuel_mix_graph(message); - -    } - -    if (message.destinationName == "ny-power/archive/co2/24h") { - -        var data = JSON.parse(message.payloadString); - -        var plot = [ - -            { - -                x: data.ts, - -                y: data.values, - -                type: 'scatter' - -            } - -        ]; - -        var layout = { - -            yaxis: { - -                title: "g CO2 / kWh", - -            } - -        }; - -        Plotly.newPlot('co2_graph', plot, layout); - -    } - -``` - -This application subscribes to a number of topics because we're going to display a few different kinds of data. The `ny-power/computed/co2` topic provides us a topline number of current intensity. Whenever we receive that topic, we replace the related contents on the site. - - -![NY ISO Grid CO2 Intensity][15] - -NY ISO Grid CO2 Intensity graph from [ny-power.org][4]. - -The `ny-power/archive/co2/24h` topic provides a time series that can be loaded into a [Plotly][16] line graph. And `ny-power/upstream/fuel-mix` provides the data needed to provide a nice bar graph of the current fuel mix. - - -![Fuel mix on NYISO grid][18] - -Fuel mix on NYISO grid, [ny-power.org][4]. - -This is a dynamic website that is not polling the server. It is attached to the MQTT bus and listening on its open WebSocket. The webpage is a pub/sub client just like the data pump and the archiver. This one just happens to be executing in your browser instead of a microservice in the cloud. - -You can see the page in action at . That includes both the graphics and a real-time MQTT console to see the messages as they come in. - -### Diving deeper - -The entire ny-power.org application is [available as open source on GitHub][19]. You can also check out [this architecture overview][20] to see how it was built as a set of Kubernetes microservices deployed with [Helm][21]. You can see another interesting MQTT application example with [this code pattern][22] using MQTT and OpenWhisk to translate text messages in real time. - -MQTT is used extensively in the Internet of Things space, and many more examples of MQTT use can be found at the [Home Assistant][23] project. - -And if you want to dive deep into the protocol, [mqtt.org][3] has all the details for this open standard. - -To learn more, attend Sean Dague's talk, [Adding MQTT to your toolkit][24], at [OSCON][25], which will be held July 16-19 in Portland, Oregon. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/6/mqtt - -作者:[Sean Dague][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/sdague -[1]:http://www.nyiso.com/public/index.jsp -[2]:http://www.nyiso.com/public/markets_operations/market_data/reports_info/index.jsp -[3]:http://mqtt.org/ -[4]:http://ny-power.org/# -[5]:https://www.home-assistant.io -[6]:https://mosquitto.org/ -[7]:https://www.eia.gov/ -[8]:https://github.com/IBM/ny-power/blob/master/src/nypower/calc.py#L1-L60 -[9]:https://www.influxdata.com/ -[10]:https://en.wikipedia.org/wiki/Transmission_Control_Protocol -[11]:https://en.wikipedia.org/wiki/User_Datagram_Protocol -[12]:https://en.wikipedia.org/wiki/WebSocket -[13]:https://www.eclipse.org/paho/ -[14]:/file/400041 -[15]:https://opensource.com/sites/default/files/uploads/mqtt_nyiso-co2intensity.png (NY ISO Grid CO2 Intensity) -[16]:https://plot.ly/ -[17]:/file/400046 -[18]:https://opensource.com/sites/default/files/uploads/mqtt_nyiso_fuel-mix.png (Fuel mix on NYISO grid) -[19]:https://github.com/IBM/ny-power -[20]:https://developer.ibm.com/code/patterns/use-mqtt-stream-real-time-data/ -[21]:https://helm.sh/ -[22]:https://developer.ibm.com/code/patterns/deploy-serverless-multilingual-conference-room/ -[23]:https://www.home-assistant.io/ -[24]:https://conferences.oreilly.com/oscon/oscon-or/public/schedule/speaker/77317 -[25]:https://conferences.oreilly.com/oscon/oscon-or diff --git a/sources/tech/20180609 Anatomy of a Linux DNS Lookup – Part I.md b/sources/tech/20180609 Anatomy of a Linux DNS Lookup – Part I.md new file mode 100644 index 0000000000..d65bf40edc --- /dev/null +++ b/sources/tech/20180609 Anatomy of a Linux DNS Lookup – Part I.md @@ -0,0 +1,285 @@ +pinewall is translating + +Anatomy of a Linux DNS Lookup – Part I +============================================================ + +Since I [work][3] [a][4] [lot][5] [with][6] [clustered][7] [VMs][8], I’ve ended up spending a lot of time trying to figure out how [DNS lookups][9] work. I applied ‘fixes’ to my problems from StackOverflow without really understanding why they work (or don’t work) for some time. + +Eventually I got fed up with this and decided to figure out how it all hangs together. I couldn’t find a complete guide for this anywhere online, and talking to colleagues they didn’t know of any (or really what happens in detail) + +So I’m writing the guide myself. + + _If you’re looking for Part II, click [here][1]_ + +Turns out there’s quite a bit in the phrase ‘Linux does a DNS lookup’… + +* * * + +![linux-dns-0](https://zwischenzugs.files.wordpress.com/2018/06/linux-dns-0.png?w=121) + + _“How hard can it be?”_ + +* * * + +These posts are intended to break down how a program decides how it gets an IP address on a Linux host, and the components that can get involved. Without understanding how these pieces fit together, debugging and fixing problems with (for example) `dnsmasq`, `vagrant landrush`, or `resolvconf` can be utterly bewildering. + +It’s also a valuable illustration of how something so simple can get so very complex over time. I’ve looked at over a dozen different technologies and their archaeologies so far while trying to grok what’s going on. + +I even wrote some [automation code][10] to allow me to experiment in a VM. Contributions/corrections are welcome. + +Note that this is not a post on ‘how DNS works’. This is about everything up to the call to the actual DNS server that’s configured on a linux host (assuming it even calls a DNS server – as you’ll see, it need not), and how it might find out which one to go to, or how it gets the IP some other way. + +* * * + +### 1) There is no such thing as a ‘DNS Lookup’ call + +* * * + +![linux-dns-1](https://zwischenzugs.files.wordpress.com/2018/06/linux-dns-1.png?w=121) + + _This is NOT how it works_ + +* * * + +The first thing to grasp is that there is no single method of getting a DNS lookup done on Linux. It’s not a core system call with a clean interface. + +There is, however, a standard C library call called which many programs use: `[getaddrinfo][2]`. But not all applications use this! + +Let’s just take two simple standard programs: `ping` and `host`: + +``` +root@linuxdns1:~# ping -c1 bbc.co.uk | head -1 +PING bbc.co.uk (151.101.192.81) 56(84) bytes of data. +``` + +``` +root@linuxdns1:~# host bbc.co.uk | head -1 +bbc.co.uk has address 151.101.192.81 +``` + +They both get the same result, so they must be doing the same thing, right? + +Wrong. + +Here’s the files that `ping` looks at on my host that are relevant to DNS: + +``` +root@linuxdns1:~# strace -e trace=open -f ping -c1 google.com +open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 +open("/lib/x86_64-linux-gnu/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3 +open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 +open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4 +open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4 +open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 4 +open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4 +open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 4 +open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 4 +open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 4 +open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4 +open("/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4 +open("/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 4 +PING google.com (216.58.204.46) 56(84) bytes of data. +open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 4 +64 bytes from lhr25s12-in-f14.1e100.net (216.58.204.46): icmp_seq=1 ttl=63 time=13.0 ms +[...] +``` + +and the same for `host`: + +``` +$ strace -e trace=open -f host google.com +[...] +[pid  9869] open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory) +[pid  9869] open("/usr/share/locale/en/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory) +[pid  9869] open("/usr/share/locale/en/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory) +[pid  9869] open("/usr/lib/ssl/openssl.cnf", O_RDONLY) = 6 +[pid  9869] open("/usr/lib/x86_64-linux-gnu/openssl-1.0.0/engines/libgost.so", O_RDONLY|O_CLOEXEC) = 6[pid  9869] open("/etc/resolv.conf", O_RDONLY) = 6 +google.com has address 216.58.204.46 +[...] +``` + +You can see that while my `ping` looks at `nsswitch.conf`, `host` does not. And they both look at `/etc/resolv.conf`. + +We’re going to take these two `.conf` files in turn. + +* * * + +### 2) NSSwitch, and `/etc/nsswitch.conf` + +We’ve established that applications can do what they like when they decide which DNS server to go to. Many apps (like `ping`) above can refer (depending on the implementation (*)) to NSSwitch via its config file `/etc/nsswitch.conf`. + +###### (*) There’s a surprising degree of variation in +ping implementations. That’s a rabbit-hole I + _didn’t_  want to get lost in. + +NSSwitch is not just for DNS lookups. It’s also used for passwords and user lookup information (for example). + +NSSwitch was originally created as part of the Solaris OS to allow applications to not have to hard-code which file or service they look these things up on, but defer them to this other configurable centralised place they didn’t have to worry about. + +Here’s my `nsswitch.conf`: + +``` +passwd:         compat +group:          compat +shadow:         compat +gshadow:        files +hosts: files dns myhostname +networks:       files +protocols:      db files +services:       db files +ethers:         db files +rpc:            db files +netgroup:       nis +``` + +The ‘hosts’ line is the one we’re interested in. We’ve shown that `ping` cares about `nsswitch.conf` so let’s fiddle with it and see how we can mess with `ping`. + +* ### Set `nsswitch.conf` to only look at ‘files’ + +If you set the `hosts` line in `nsswitch.conf` to be ‘just’ `files`: + +`hosts: files` + +Then a `ping` to google.com will now fail: + +``` +$ ping -c1 google.com +ping: unknown host google.com +``` + +but `localhost` still works: + +``` +$ ping -c1 localhost +PING localhost (127.0.0.1) 56(84) bytes of data. +64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.039 ms +``` + +and using `host` still works fine: + +``` +$ host google.com +google.com has address 216.58.206.110 +``` + +since, as we saw, it doesn’t care about `nsswitch.conf` + +* ### Set `nsswitch.conf` to only look at ‘dns’ + +If you set the `hosts` line in `nsswitch.conf` to be ‘just’ dns: + +`hosts: dns` + +Then a `ping` to google.com will now succeed again: + +``` +$ ping -c1 google.com +PING google.com (216.58.198.174) 56(84) bytes of data. +64 bytes from lhr25s10-in-f174.1e100.net (216.58.198.174): icmp_seq=1 ttl=63 time=8.01 ms +``` + +But `localhost` is not found this time: + +``` +$ ping -c1 localhost +ping: unknown host localhost +``` + +Here’s a diagram of what’s going on with NSSwitch by default wrt `hosts` lookup: + +* * * + +![linux-dns-2 (1)](https://zwischenzugs.files.wordpress.com/2018/06/linux-dns-2-11.png?w=525) + + _My default ‘`hosts:`‘ configuration in `nsswitch.conf`_ + +* * * + +### 3) `/etc/resolv.conf` + +We’ve seen now that `host` and `ping` both look at this `/etc/resolv.conf` file. + +Here’s what my `/etc/resolv.conf` looks like: + +``` +# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) +#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN +nameserver 10.0.2.3 +``` + +Ignore the first two lines – we’ll come back to those (they are significant, but you’re not ready for that ball of wool yet). + +The `nameserver` lines specify the DNS servers to look up the host for. + +If you hash out that line: + +``` +#nameserver 10.0.2.3 +``` + +and run: + +``` +$ ping -c1 google.com +ping: unknown host google.com +``` + +it fails, because there’s no nameserver to go to (*). + +###### * Another rabbit hole: `host` appears to fall back to +127.0.0.1:53 if there’s no nameserver specified. + +This file takes other options too. For example, if you add this line to the `resolv.conf` file: + +``` +search com +``` + +and then `ping google` (sic) + +``` +$ ping google +PING google.com (216.58.204.14) 56(84) bytes of data. +``` + +it will try the `.com` domain automatically for you. + +### End of Part I + +That’s the end of Part I. The next part will start by looking at how that resolv.conf gets created and updated. + +Here’s what you covered above: + +* There’s no ‘DNS lookup’ call in the OS + +* Different programs figure out the IP of an address in different ways + * For example, `ping` uses `nsswitch`, which in turn uses (or can use) `/etc/hosts`, `/etc/resolv.conf` and its own hostname to get the result + +* `/etc/resolv.conf` helps decide: + * which addresses get called + + * which DNS server to look up + +If you thought that was complicated, buckle up… + +-------------------------------------------------------------------------------- + +via: https://zwischenzugs.com/2018/06/08/anatomy-of-a-linux-dns-lookup-part-i/ + +作者:[dmatech][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://twitter.com/dmatech2 +[1]:https://zwischenzugs.com/2018/06/18/anatomy-of-a-linux-dns-lookup-part-ii/ +[2]:http://man7.org/linux/man-pages/man3/getaddrinfo.3.html +[3]:https://zwischenzugs.com/2017/10/31/a-complete-chef-infrastructure-on-your-laptop/ +[4]:https://zwischenzugs.com/2017/03/04/a-complete-openshift-cluster-on-vagrant-step-by-step/ +[5]:https://zwischenzugs.com/2017/03/04/migrating-an-openshift-etcd-cluster/ +[6]:https://zwischenzugs.com/2017/03/04/1-minute-multi-node-vm-setup/ +[7]:https://zwischenzugs.com/2017/03/18/clustered-vm-testing-how-to/ +[8]:https://zwischenzugs.com/2017/10/27/ten-things-i-wish-id-known-before-using-vagrant/ +[9]:https://zwischenzugs.com/2017/10/21/openshift-3-6-dns-in-pictures/ +[10]:https://github.com/ianmiell/shutit-linux-dns/blob/master/linux_dns.py diff --git a/sources/tech/20180615 5 Commands for Checking Memory Usage in Linux.md b/sources/tech/20180615 5 Commands for Checking Memory Usage in Linux.md deleted file mode 100644 index 05c3da4f6c..0000000000 --- a/sources/tech/20180615 5 Commands for Checking Memory Usage in Linux.md +++ /dev/null @@ -1,195 +0,0 @@ -5 Commands for Checking Memory Usage in Linux -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/top-main.jpg?itok=WYAw6yJ1) -The Linux operating system includes a plethora of tools, all of which are ready to help you administer your systems. From simple file and directory tools to very complex security commands, there’s not much you can’t do on Linux. And, although regular desktop users may not need to become familiar with these tools at the command line, they’re mandatory for Linux admins. Why? First, you will have to work with a GUI-less Linux server at some point. Second, command-line tools often offer far more power and flexibility than their GUI alternative. - -Determining memory usage is a skill you might need should a particular app go rogue and commandeer system memory. When that happens, it’s handy to know you have a variety of tools available to help you troubleshoot. Or, maybe you need to gather information about a Linux swap partition or detailed information about your installed RAM? There are commands for that as well. Let’s dig into the various Linux command-line tools to help you check into system memory usage. These tools aren’t terribly hard to use, and in this article, I’ll show you five different ways to approach the problem. - -I’ll be demonstrating on the [Ubuntu Server 18.04 platform][1]. You should, however, find all of these commands available on your distribution of choice. Even better, you shouldn’t need to install a single thing (as most of these tools are included). - -With that said, let’s get to work. - -### top - -I want to start out with the most obvious tool. The top command provides a dynamic, real-time view of a running system. Included in that system summary is the ability to check memory usage on a per-process basis. That’s very important, as you could easily have multiple iterations of the same command consuming different amounts of memory. Although you won’t find this on a headless server, say you’ve opened Chrome and noticed your system slowing down. Issue the top command to see that Chrome has numerous processes running (one per tab - Figure 1). - -![top][3] - -Figure 1: Multiple instances of Chrome appearing in the top command. - -[Used with permission][4] - -Chrome isn’t the only app to show multiple processes. You see the Firefox entry in Figure 1? That’s the primary process for Firefox, whereas the Web Content processes are the open tabs. At the top of the output, you’ll see the system statistics. On my machine (a [System76 Leopard Extreme][5]), I have a total of 16GB of RAM available, of which just over 10GB is in use. You can then comb through the list and see what percentage of memory each process is using. - -One of the things top is very good for is discovering Process ID (PID) numbers of services that might have gotten out of hand. With those PIDs, you can then set about to troubleshoot (or kill) the offending tasks. - -If you want to make top a bit more memory-friendly, issue the command top -o %MEM, which will cause top to sort all processes by memory used (Figure 2). - -![top][7] - -Figure 2: Sorting process by memory used in top. - -[Used with permission][4] - -The top command also gives you a real-time update on how much of your swap space is being used. - -### free - -Sometimes, however, top can be a bit much for your needs. You may only need to see the amount of free and used memory on your system. For that, there is the free command. The free command displays: - - * Total amount of free and used physical memory - - * Total amount of swap memory in the system - - * Buffers and caches used by the kernel - - - - -From your terminal window, issue the command free. The output of this command is not in real time. Instead, what you’ll get is an instant snapshot of the free and used memory in that moment (Figure 3). - -![free][9] - -Figure 3: The output of the free command is simple and clear. - -[Used with permission][4] - -You can, of course, make free a bit more user-friendly by adding the -m option, like so: free -m. This will report the memory usage in MB (Figure 4). - -![free][11] - -Figure 4: The output of the free command in a more human-readable form. - -[Used with permission][4] - -Of course, if your system is even remotely modern, you’ll want to use the -g option (gigabytes), as in free -g. - -If you need memory totals, you can add the t option like so: free -mt. This will simply total the amount of memory in columns (Figure 5). - -![total][13] - -Figure 5: Having free total your memory columns for you. - -[Used with permission][4] - -### vmstat - -Another very handy tool to have at your disposal is vmstat. This particular command is a one-trick pony that reports virtual memory statistics. The vmstat command will report stats on: - - * Processes - - * Memory - - * Paging - - * Block IO - - * Traps - - * Disks - - * CPU - - - - -The best way to issue vmstat is by using the -s switch, like vmstat -s. This will report your stats in a single column (which is so much easier to read than the default report). The vmstat command will give you more information than you need (Figure 6), but more is always better (in such cases). - -![vmstat][15] - -Figure 6: Using the vmstat command to check memory usage. - -[Used with permission][4] - -### dmidecode - -What if you want to find out detailed information about your installed system RAM? For that, you could use the dmidecode command. This particular tool is the DMI table decoder, which dumps a system’s DMI table contents into a human-readable format. If you’re unsure as to what the DMI table is, it’s a means to describe what a system is made of (as well as possible evolutions for a system). - -To run the dmidecode command, you do need sudo privileges. So issue the command sudo dmidecode -t 17. The output of the command (Figure 7) can be lengthy, as it displays information for all memory-type devices. So if you don’t have the ability to scroll, you might want to send the output of that command to a file, like so: sudo dmidecode -t 17 > dmi_infoI, or pipe it to the less command, as in sudo dmidecode | less. - -![dmidecode][17] - -Figure 7: The output of the dmidecode command. - -[Used with permission][4] - -### /proc/meminfo - -You might be asking yourself, “Where do these commands get this information from?”. In some cases, they get it from the /proc/meminfo file. Guess what? You can read that file directly with the command less /proc/meminfo. By using the less command, you can scroll up and down through that lengthy output to find exactly what you need (Figure 8). - -![/proc/meminfo][19] - -Figure 8: The output of the less /proc/meminfo command. - -[Used with permission][4] - -One thing you should know about /proc/meminfo: This is not a real file. Instead /pro/meminfo is a virtual file that contains real-time, dynamic information about the system. In particular, you’ll want to check the values for: - - * MemTotal - - * MemFree - - * MemAvailable - - * Buffers - - * Cached - - * SwapCached - - * SwapTotal - - * SwapFree - - - - -If you want to get fancy with /proc/meminfo you can use it in conjunction with the egrep command like so: egrep --color 'Mem|Cache|Swap' /proc/meminfo. This will produce an easy to read listing of all entries that contain Mem, Cache, and Swap ... with a splash of color (Figure 9). - -![/proc/meminfo][21] - -Figure 9: Making /proc/meminfo easier to read. - -[Used with permission][4] - -### Keep learning - -One of the first things you should do is read the manual pages for each of these commands (so man top, man free, man vmstat, man dmidecode). Starting with the man pages for commands is always a great way to learn so much more about how a tool works on Linux. - -Learn more about Linux through the free ["Introduction to Linux" ][22]course from The Linux Foundation and edX. - --------------------------------------------------------------------------------- - -via: https://www.linux.com/learn/5-commands-checking-memory-usage-linux - -作者:[Jack Wallen][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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 -[1]:https://www.ubuntu.com/download/server -[2]:/files/images/memory1jpg -[3]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_1.jpg?itok=fhhhUL_l (top) -[4]:/licenses/category/used-permission -[5]:https://system76.com/desktops/leopard -[6]:/files/images/memory2jpg -[7]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_2.jpg?itok=zuVkQfvv (top) -[8]:/files/images/memory3jpg -[9]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_3.jpg?itok=rvuQp3t0 (free) -[10]:/files/images/memory4jpg -[11]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_4.jpg?itok=K_luLLPt (free) -[12]:/files/images/memory5jpg -[13]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_5.jpg?itok=q50atcsX (total) -[14]:/files/images/memory6jpg -[15]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_6.jpg?itok=bwFnUVmy (vmstat) -[16]:/files/images/memory7jpg -[17]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_7.jpg?itok=UNHIT_P6 (dmidecode) -[18]:/files/images/memory8jpg -[19]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_8.jpg?itok=t87jvmJJ (/proc/meminfo) -[20]:/files/images/memory9jpg -[21]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_9.jpg?itok=t-iSMEKq (/proc/meminfo) -[22]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180618 5 open source alternatives to Dropbox.md b/sources/tech/20180618 5 open source alternatives to Dropbox.md deleted file mode 100644 index d94b4537aa..0000000000 --- a/sources/tech/20180618 5 open source alternatives to Dropbox.md +++ /dev/null @@ -1,122 +0,0 @@ -5 open source alternatives to Dropbox -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/dropbox.jpg?itok=qFwcqboT) - -Dropbox is the 800-pound gorilla of filesharing applications. Even though it's a massively popular tool, you may choose to use an alternative. - -Maybe that's because you're dedicated to the [open source way][1] for all the good reasons, including security and freedom, or possibly you've been spooked by data breaches. Or perhaps the pricing plan doesn't work out in your favor for the amount of storage you actually need. - -Fortunately, there are a variety of open source filesharing applications out there that give you more storage, security, and control over your data at a far lower price than Dropbox charges. How much lower? Try free, if you're a bit tech savvy and have a Linux server to use. - -Here are five of the best open source alternatives to Dropbox, plus a few others that you might want to consider. - -### ownCloud - -![](https://opensource.com/sites/default/files/uploads/owncloud.png) - -[ownCloud][2], launched in 2010, is the oldest application on this list, but don't let that fool you: It's still very popular (with over 1.5 million users, according to the company) and actively maintained by a community of 1,100 contributors, with updates released regularly. - -Its primary features—file and folding sharing, document collaboration—are similar to Dropbox's. Its primary difference (aside from its [open source license][3]) is that your files are hosted on your private Linux server or cloud, giving users complete control over your data. (Self-hosting is a common thread among the apps on this list.) - -With ownCloud, you can sync and access files through clients for Linux, MacOS, or Windows computers or mobile apps for Android and iOS devices, and provide password-protected links to others for collaboration or file upload/download. Data transfers are secured by end-to-end encryption (E2EE) and SSL encryption. You can also expand its functionality with a wide variety of third-party apps available in its [marketplace][4], and there is also a paid, commercially licensed enterprise edition. - -ownCloud offers comprehensive [documentation][5], including an installation guide and manuals for users, admins, and developers, and you can access its [source code][6] in its GitHub repository. - -### NextCloud - -![](https://opensource.com/sites/default/files/uploads/nextcloud.png) - -[NextCloud][7] spun out of ownCloud in 2016 and shares much of the same functionality. Nextcloud [touts][8] its high security and regulatory compliance as a distinguishing feature. It has HIPAA (healthcare) and GDPR (privacy) compliance features and offers extensive data-policy enforcement, encryption, user management, and auditing capabilities. It also encrypts data during transfer and at rest and integrates with mobile device management and authentication mechanisms (including LDAP/AD, single-sign-on, two-factor authentication, etc.). - -Like the other solutions on this list, NextCloud is self-hosted, but if you don't want to roll your own NextCloud server on Linux, the company partners with several [providers][9] for setup and hosting and sells servers, appliances, and support. A [marketplace][10] offers numerous apps to extend its features. - -NextCloud's [documentation][11] page offers thorough information for users, admins, and developers as well as links to its forums, IRC channel, and social media pages for community-based support. If you'd like to contribute, access its source code, report a bug, check out its (AGPLv3) license, or just learn more, visit the project's [GitHub repository][12]. - -### Seafile - -![](https://opensource.com/sites/default/files/uploads/seafile.png) - -[Seafile][13] may not have the bells and whistles (or app ecosystem) of ownCloud or Nextcloud, but it gets the job done. Essentially, it acts as a virtual drive on your Linux server to extend your desktop storage and allow you to share files selectively with password protection and various levels of permission (i.e., read-only or read/write). - -Its collaboration features include per-folder access control, password-protected download links, and Git-like version control and retention. Files are secured with two-factor authentication, file encryption, and AD/LDAP integration, and they're accessible from Windows, MacOS, Linux, iOS, or Android devices. - -For more information, visit Seafile's [GitHub repository][14], [server manual][15], [wiki][16], and [forums][17]. Note that Seafile's community edition is licensed under [GPLv2][18], but its professional edition is not open source. - -### OnionShare - -![](https://opensource.com/sites/default/files/uploads/onionshare.png) - -[OnionShare][19] is a cool app that does one thing: It allows you to share individual files or folders securely and, if you want, anonymously. There's no server to set up or maintain—all you need to do is [download and install][20] the app on MacOS, Windows, or Linux. Files are always hosted on your own computer; when you share a file, OnionShare creates a web server, makes it accessible as a Tor Onion service, and generates an unguessable .onion URL that allows the recipient to access the file via [Tor browser][21]. - -You can set limits on your fileshare, such as limiting the number of times it can be downloaded or using an auto-stop timer, which sets a strict expiration date/time after which the file is inaccessible (even if it hasn't been accessed yet). - -OnionShare is licensed under [GPLv3][22]; for more information, check out its GitHub [repository][22], which also includes [documentation][23] that covers the features in this easy-to-use filesharing application. - -### Pydio Cells - -![](https://opensource.com/sites/default/files/uploads/pydiochat.png) - -[Pydio Cells][24], which achieved stability in May 2018, is a complete overhaul of the Pydio filesharing application's core server code. Due to limitations with Pydio's PHP-based backend, the developers decided to rewrite the backend in the Go server language with a microservices architecture. (The frontend is still based on PHP.) - -Pydio Cells includes the usual filesharing and version control features, as well as in-app messaging, mobile apps (Android and iOS), and a social network-style approach to collaboration. Security includes OpenID Connect-based authentication, encryption at rest, security policies, and more. Advanced features are included in the enterprise distribution, but there's plenty of power for most small and midsize businesses and home users in the community (or "Home") version. - -You can [download][25] Pydio Cells for Linux and MacOS. For more information, check out the [documentation FAQ][26], [source code][27] repository, and [AGPLv3 license][28]. - -### Others to consider - -If these choices don't meet your needs, you may want to consider these open source filesharing-type applications. - - * If your main goal is to sync files between devices, rather than to share files, check out [Syncthing][29]). - * If you're a Git fan and don't need a mobile app, you might appreciate [SparkleShare][30]. - * If you primarily want a place to aggregate all your personal data, take a look at [Cozy][31]. - * And, if you're looking for a lightweight or dedicated filesharing tool, peruse [Scott Nesbitt's review][32] of some lesser-known options. - - - -What is your favorite open source filesharing application? Let us know in the comments. - --------------------------------------------------------------------------------- - -via: https://opensource.com/alternatives/dropbox - -作者:[OPensource.com][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com -[1]:https://opensource.com/open-source-way -[2]:https://owncloud.org/ -[3]:https://www.gnu.org/licenses/agpl-3.0.html -[4]:https://marketplace.owncloud.com/ -[5]:https://doc.owncloud.com/ -[6]:https://github.com/owncloud -[7]:https://nextcloud.com/ -[8]:https://nextcloud.com/secure/ -[9]:https://nextcloud.com/providers/ -[10]:https://apps.nextcloud.com/ -[11]:https://nextcloud.com/support/ -[12]:https://github.com/nextcloud -[13]:https://www.seafile.com/en/home/ -[14]:https://github.com/haiwen/seafile -[15]:https://manual.seafile.com/ -[16]:https://seacloud.cc/group/3/wiki/ -[17]:https://forum.seafile.com/ -[18]:https://github.com/haiwen/seafile/blob/master/LICENSE.txt -[19]:https://onionshare.org/ -[20]:https://onionshare.org/#downloads -[21]:https://www.torproject.org/ -[22]:https://github.com/micahflee/onionshare/blob/develop/LICENSE -[23]:https://github.com/micahflee/onionshare/wiki -[24]:https://pydio.com/en -[25]:https://pydio.com/download/ -[26]:https://pydio.com/en/docs/faq -[27]:https://github.com/pydio/cells -[28]:https://github.com/pydio/pydio-core/blob/develop/LICENSE -[29]:https://syncthing.net/ -[30]:http://www.sparkleshare.org/ -[31]:https://cozy.io/en/ -[32]:https://opensource.com/article/17/3/file-sharing-tools diff --git a/sources/tech/20180619 Getting started with Open edX to host your course.md b/sources/tech/20180619 Getting started with Open edX to host your course.md deleted file mode 100644 index 835da91b4f..0000000000 --- a/sources/tech/20180619 Getting started with Open edX to host your course.md +++ /dev/null @@ -1,90 +0,0 @@ -Translating by qhwdw -Getting started with Open edX to host your course -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003588_01_rd3os.combacktoschoolseriesgen_rh_032x_0.png?itok=cApG9aB4) - -Now in its [seventh major release][1], the [Open edX platform][2] is a free and open source course management system that is used [all over the world][3] to host Massive Open Online Courses (MOOCs) as well as smaller classes and training modules. To date, Open edX software has powered more than 8,000 original courses and 50 million course enrollments. You can install the platform yourself with on-premise equipment or by leveraging any of the industry-leading cloud infrastructure services providers, but it is also increasingly being made available in a Software-as-a-Service (SaaS) model from several of the project’s growing list of [service providers][4]. - -The Open edX platform is used by many of the world’s premier educational institutions as well as private sector companies, public sector institutions, NGOs, non-profits, and educational technology startups, and the project’s global community of service providers continues to make the platform accessible to ever-smaller organizations. If you plan to create and offer educational content to a broad audience, you should consider using the Open edX platform. - -### Installation - -There are multiple ways to install the software, which might be an unwelcome surprise, at least initially. But you get the same application software with the same feature set regardless of how you go about [installing Open edX][5]. The default installation includes a fully functioning learning management system (LMS) for online learners plus a full-featured course management studio (CMS) that your instructor teams can use to author original course content. You can think of the CMS as a “[Wordpress][6]” of course content creation and management, and the LMS as a “[Magento][7]” of course marketing, distribution, and consumption. - -Open edX application software is device-agnostic and fully responsive, and with modest effort, you can also publish native iOS and Android apps that seamlessly integrate to your instance’s backend. The code repositories for the Open edX platform, the native mobile apps, and the installation scripts are all publicly available on [GitHub][8]. - -#### What to expect - -The Open edX platform [GitHub repository][9] contains performant, production-ready code that is suitable for organizations of all sizes. Thousands of programmers from hundreds of institutions regularly contribute to the edX repositories, and the platform is a veritable case study on how to build and manage a complex enterprise application the right way. So even though you’re certain to face a multitude of concerns about how to move the platform into production, you should not lose sleep about the general quality and robustness of the Open edX Platform codebase itself. - -With minimal training, your instructors will be able to create good online course content. But bear in mind that Open edX is extensible via its [XBlock][10] component architecture, so your instructors will have the potential to turn good course content into great course content with incremental effort on their parts and yours. - -The platform works well in a single-server environment, and it is highly modular, making it nearly infinitely horizontally scalable. It is theme-able, localizable, and completely open source, providing limitless possibilities to tailor the appearance and functionality of the platform to your needs. The platform runs reliably as an on-premise installation on your own equipment. - -#### Some assembly required - -Bear in mind that a handful of the edX software modules are not included in the default installation and that these modules are often on the requirements lists of organizations. Namely, the Analytics module, the e-commerce module, and the Notes/Annotations course feature are not part of the default platform installation, and each of these individually is a non-trivial installation. Additionally, you’re entirely on your own with regard to data backup-restore and system administration in general. Fortunately, there’s a growing body of community-sourced documentation and how-to articles, all searchable via Google and Bing, to help make your installation production-ready. - -Setting up [oAuth][11] and [SSL/TLS][12] as well as getting the platform’s [REST API][13] up and running can be challenging, depending on your skill level, even though these are all well-documented procedures. Additionally, some organizations require that MySQL and/or MongoDB databases be managed in an existing centralized environment, and if this is your situation, you’ll also need to work through the process of hiving these services out of the default platform installation. The edX design team has done everything possible to simplify this for you, but it’s still a non-trivial change that will likely take some time to implement. - -Not to be discouraged—if you’re facing resource and/or technical headwinds, Open edX community SaaS providers like [appsembler][14] and [eduNEXT][15] offer compelling alternatives to a do-it-yourself installation, particularly if you’re just window shopping. - -### Technology stack - -Poking around in an Open edX platform installation is a real thrill, and architecturally speaking, the project is a masterpiece. The application modules are [Django][16] apps that leverage a plethora of the open source community’s premier projects, including [Ubuntu][17], [MySQL][18], [MongoDB][19], [RabbitMQ][20], [Elasticsearch][21], [Hadoop][22], and others. - -![edx-architecture.png][24] - -The Open edX technology stack (CC BY, by edX) - -Getting all of these components installed and configured is a feat in and of itself, but packaging everything in such a way that organizations of arbitrary size and complexity can tailor installations to their needs without having to perform heart surgery on the codebase would seem impossible—that is, until you see how neatly and intuitively the major platform configuration parameters have been organized and named. Mind you, there’s a learning curve to the platform’s organizational structure, but the upshot is that everything you learn is worth knowing, not just for this project but large IT projects in general. - -One word of caution: The platform's UI is in flux, with the aim of eventually standardizing on [React][25] and [Bootstrap][26]. Meanwhile, you'll find multiple approaches to implementing styling for the base theme, and this can get confusing. - -### Adoption - -The edX project has enjoyed rapid international adoption, due in no small measure to how well the software works. Not surprisingly, the project’s success has attracted a large and growing list of talented participants who contribute to the project as programmers, project consultants, translators, technical writers, and bloggers. The annual [Open edX Conference][27], the [Official edX Google Group][28], and the [Open edX Service Providers List][4] are good starting points for learning more about this diverse and growing ecosystem. As a relative newcomer myself, I’ve found it comparatively easy to engage and to get directly involved with the project in multiple facets. - -Good luck with your journey, and feel free to reach out to me as a sounding board while you’re conceptualizing your project. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/6/getting-started-open-edx - -作者:[Lawrence Mc Daniel][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/mcdaniel0073 -[1]:https://openedx.atlassian.net/wiki/spaces/DOC/pages/11108700/Open+edX+Releases -[2]:https://open.edx.org/about-open-edx -[3]:https://www.edx.org/schools-partners -[4]:https://openedx.atlassian.net/wiki/spaces/COMM/pages/65667081/Open+edX+Service+Providers -[5]:https://openedx.atlassian.net/wiki/spaces/OpenOPS/pages/60227779/Open+edX+Installation+Options -[6]:https://wordpress.com/ -[7]:https://magento.com/ -[8]:https://github.com/edx -[9]:https://github.com/edx/edx-platform -[10]:https://open.edx.org/xblocks -[11]:https://oauth.net/ -[12]:https://en.wikipedia.org/wiki/Transport_Layer_Security -[13]:https://en.wikipedia.org/wiki/Representational_state_transfer -[14]:https://www.appsembler.com/ -[15]:https://www.edunext.co/ -[16]:https://www.djangoproject.com/ -[17]:https://www.ubuntu.com/ -[18]:https://www.mysql.com/ -[19]:https://www.mongodb.com/ -[20]:https://www.rabbitmq.com/ -[21]:https://www.elastic.co/ -[22]:http://hadoop.apache.org/ -[23]:/file/400696 -[24]:https://opensource.com/sites/default/files/uploads/edx-architecture_0.png (edx-architecture.png) -[25]:%E2%80%9Chttps://reactjs.org/%E2%80%9C -[26]:%E2%80%9Chttps://getbootstrap.com/%E2%80%9C -[27]:https://con.openedx.org/ -[28]:https://groups.google.com/forum/#!forum/openedx-ops diff --git a/sources/tech/20180619 How To Check Which Groups A User Belongs To On Linux.md b/sources/tech/20180619 How To Check Which Groups A User Belongs To On Linux.md deleted file mode 100644 index ba50a0dec2..0000000000 --- a/sources/tech/20180619 How To Check Which Groups A User Belongs To On Linux.md +++ /dev/null @@ -1,159 +0,0 @@ -How To Check Which Groups A User Belongs To On Linux -====== -Adding a user into existing group is one of the regular activity for Linux admin. This is daily activity for some of the administrator who’s working one big environments. - -Even i am performing such a activity on daily in my environment due to business requirement. It’s one of the important command which helps you to identify existing groups on your environment. - -Also these commands helps you to identify which groups a user belongs to. All the users are listed in `/etc/passwd` file and groups are listed in `/etc/group`. - -Whatever command we use, that will fetch the information from these files. Also, each command has their unique feature which helps user to get the required information alone. - -### What Is /etc/passwd? - -`/etc/passwd` is a text file that contains each user information, which is necessary to login Linux system. It maintain useful information about users such as username, password, user ID, group ID, user ID info, home directory and shell. The passwd file contain every user details as a single line with seven fields as described above. -``` -$ grep "daygeek" /etc/passwd -daygeek:x:1000:1000:daygeek,,,:/home/daygeek:/bin/bash - -``` - -### What Is /etc/group? - -`/etc/group` is a text file that defines which groups a user belongs to. We can add multiple users into single group. It allows user to access other users files and folders as Linux permissions are organized into three classes, user, group, and others. It maintain useful information about group such as Group name, Group password, Group ID (GID) and Member list. each on a separate line. The group file contain every group details as a single line with four fields as described above. - -This can be performed by using below methods. - - * `groups:`Show All Members of a Group. - * `id:`Print user and group information for the specified username. - * `lid:`It display user’s groups or group’s users. - * `getent:`get entries from Name Service Switch libraries. - * `grep`grep stands for “global regular expression print” which prints matching pattern. - - - -### What Is groups Command? - -groups command prints the names of the primary and any supplementary groups for each given username. -``` -$ groups daygeek -daygeek : daygeek adm cdrom sudo dip plugdev lpadmin sambashare - -``` - -If you would like to check list of groups associated with current user. Just run **“group”** command alone without any username. -``` -$ groups -daygeek adm cdrom sudo dip plugdev lpadmin sambashare - -``` - -### What Is id Command? - -id stands for identity. print real and effective user and group IDs. To print user and group information for the specified user, or for the current user. -``` -$ id daygeek -uid=1000(daygeek) gid=1000(daygeek) groups=1000(daygeek),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),118(lpadmin),128(sambashare) - -``` - -If you would like to check list of groups associated with current user. Just run **“id”** command alone without any username. -``` -$ id -uid=1000(daygeek) gid=1000(daygeek) groups=1000(daygeek),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),118(lpadmin),128(sambashare) - -``` - -### What Is lid Command? - -It display user’s groups or group’s users. Displays information about groups containing user name, or users contained in group name. This command required privileges to run. -``` -$ sudo lid daygeek - adm(gid=4) - cdrom(gid=24) - sudo(gid=27) - dip(gid=30) - plugdev(gid=46) - lpadmin(gid=108) - daygeek(gid=1000) - sambashare(gid=124) - -``` - -### What Is getent Command? - -The getent command displays entries from databases supported by the Name Service Switch libraries, which are configured in /etc/nsswitch.conf. -``` -$ getent group | grep daygeek -adm:x:4:syslog,daygeek -cdrom:x:24:daygeek -sudo:x:27:daygeek -dip:x:30:daygeek -plugdev:x:46:daygeek -lpadmin:x:118:daygeek -daygeek:x:1000: -sambashare:x:128:daygeek - -``` - -If you would like to print only associated groups name then include **“awk”** command along with above command. -``` -$ getent group | grep daygeek | awk -F: '{print $1}' -adm -cdrom -sudo -dip -plugdev -lpadmin -daygeek -sambashare - -``` - -Run the below command to print only primary group information. -``` -$ getent group daygeek -daygeek:x:1000: - -``` - -### What Is grep Command? - -grep stands for “global regular expression print” which prints matching pattern from the file. -``` -$ grep "daygeek" /etc/group -adm:x:4:syslog,daygeek -cdrom:x:24:daygeek -sudo:x:27:daygeek -dip:x:30:daygeek -plugdev:x:46:daygeek -lpadmin:x:118:daygeek -daygeek:x:1000: -sambashare:x:128:daygeek - -``` - -If you would like to print only associated groups name then include **“awk”** command along with above command. -``` -$ grep "daygeek" /etc/group | awk -F: '{print $1}' -adm -cdrom -sudo -dip -plugdev -lpadmin -daygeek -sambashare - -``` --------------------------------------------------------------------------------- - -via: https://www.2daygeek.com/how-to-check-which-groups-a-user-belongs-to-on-linux/ - -作者:[Prakash Subramanian][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/prakash/ diff --git a/sources/tech/20180619 How to reset, revert, and return to previous states in Git.md b/sources/tech/20180619 How to reset, revert, and return to previous states in Git.md index 3532681888..6e25a5faa1 100644 --- a/sources/tech/20180619 How to reset, revert, and return to previous states in Git.md +++ b/sources/tech/20180619 How to reset, revert, and return to previous states in Git.md @@ -1,3 +1,4 @@ +Translating by qhwdw How to reset, revert, and return to previous states in Git ====== diff --git a/sources/tech/20180621 Bitcoin is a Cult - Adam Caudill.md b/sources/tech/20180621 Bitcoin is a Cult - Adam Caudill.md index 44bc8fbc90..83f8a65a31 100644 --- a/sources/tech/20180621 Bitcoin is a Cult - Adam Caudill.md +++ b/sources/tech/20180621 Bitcoin is a Cult - Adam Caudill.md @@ -1,3 +1,4 @@ +Translating by qhwdw Bitcoin is a Cult — Adam Caudill ====== The Bitcoin community has changed greatly over the years; from technophiles that could explain a [Merkle tree][1] in their sleep, to speculators driven by the desire for a quick profit & blockchain startups seeking billion dollar valuations led by people who don’t even know what a Merkle tree is. As the years have gone on, a zealotry has been building around Bitcoin and other cryptocurrencies driven by people who see them as something far grander than they actually are; people who believe that normal (or fiat) currencies are becoming a thing of the past, and the cryptocurrencies will fundamentally change the world’s economy. diff --git a/sources/tech/20180622 How to Check Disk Space on Linux from the Command Line.md b/sources/tech/20180622 How to Check Disk Space on Linux from the Command Line.md deleted file mode 100644 index c69e6459fc..0000000000 --- a/sources/tech/20180622 How to Check Disk Space on Linux from the Command Line.md +++ /dev/null @@ -1,181 +0,0 @@ -How to Check Disk Space on Linux from the Command Line -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace-main.jpg?itok=t9Oxxc9X) - -Quick question: How much space do you have left on your drives? A little or a lot? Follow up question: Do you know how to find out? If you happen to use a GUI desktop (e.g., GNOME, KDE, Mate, Pantheon, etc.), the task is probably pretty simple. But what if you’re looking at a headless server, with no GUI? Do you need to install tools for the task? The answer is a resounding no. All the necessary bits are already in place to help you find out exactly how much space remains on your drives. In fact, you have two very easy-to-use options at the ready. - -In this article, I’ll demonstrate these tools. I’ll be using [Elementary OS][1], which also includes a GUI option, but we’re going to limit ourselves to the command line. The good news is these command-line tools are readily available for every Linux distribution. On my testing system, there are a number of attached drives (both internal and external). The commands used are agnostic to where a drive is plugged in; they only care that the drive is mounted and visible to the operating system. - -With that said, let’s take a look at the tools. - -### df - -The df command is the tool I first used to discover drive space on Linux, way back in the 1990s. It’s very simple in both usage and reporting. To this day, df is my go-to command for this task. This command has a few switches but, for basic reporting, you really only need one. That command is df -H. The -H switch is for human-readable format. The output of df -H will report how much space is used, available, percentage used, and the mount point of every disk attached to your system (Figure 1). - - -![df output][3] - -Figure 1: The output of df -H on my Elementary OS system. - -[Used with permission][4] - -What if your list of drives is exceedingly long and you just want to view the space used on a single drive? With df, that is possible. Let’s take a look at how much space has been used up on our primary drive, located at /dev/sda1. To do that, issue the command: -``` -df -H /dev/sda1 - -``` - -The output will be limited to that one drive (Figure 2). - - -![disk usage][6] - -Figure 2: How much space is on one particular drive? - -[Used with permission][4] - -You can also limit the reported fields shown in the df output. Available fields are: - - * source — the file system source - - * size — total number of blocks - - * used — spaced used on a drive - - * avail — space available on a drive - - * pcent — percent of used space, divided by total size - - * target — mount point of a drive - - - - -Let’s display the output of all our drives, showing only the size, used, and avail (or availability) fields. The command for this would be: -``` -df -H --output=size,used,avail - -``` - -The output of this command is quite easy to read (Figure 3). - - -![output][8] - -Figure 3: Specifying what output to display for our drives. - -[Used with permission][4] - -The only caveat here is that we don’t know the source of the output, so we’d want to include source like so: -``` -df -H --output=source,size,used,avail - -``` - -Now the output makes more sense (Figure 4). - -![source][10] - -Figure 4: We now know the source of our disk usage. - -[Used with permission][4] - -### du - -Our next command is du. As you might expect, that stands for disk usage. The du command is quite different to the df command, in that it reports on directories and not drives. Because of this, you’ll want to know the names of directories to be checked. Let’s say I have a directory containing virtual machine files on my machine. That directory is /media/jack/HALEY/VIRTUALBOX. If I want to find out how much space is used by that particular directory, I’d issue the command: -``` -du -h /media/jack/HALEY/VIRTUALBOX - -``` - -The output of the above command will display the size of every file in the directory (Figure 5). - -![du command][12] - -Figure 5: The output of the du command on a specific directory. - -[Used with permission][4] - -So far, this command isn’t all that helpful. What if we want to know the total usage of a particular directory? Fortunately, du can handle that task. On the same directory, the command would be: -``` -du -sh /media/jack/HALEY/VIRTUALBOX/ - -``` - -Now we know how much total space the files are using up in that directory (Figure 6). - -![space used][14] - -Figure 6: My virtual machine files are using 559GB of space. - -[Used with permission][4] - -You can also use this command to see how much space is being used on all child directories of a parent, like so: -``` -du -h /media/jack/HALEY - -``` - -The output of this command (Figure 7) is a good way to find out what subdirectories are hogging up space on a drive. - -![directories][16] - -Figure 7: How much space are my subdirectories using? - -[Used with permission][4] - -The du command is also a great tool to use in order to see a list of directories that are using the most disk space on your system. The way to do this is by piping the output of du to two other commands: sort and head. The command to find out the top 10 directories eating space on a drive would look something like this: -``` -du -a /media/jack | sort -n -r | head -n 10 - -``` - -The output would list out those directories, from largest to least offender (Figure 8). - -![top users][18] - -Figure 8: Our top ten directories using up space on a drive. - -[Used with permission][4] - -### Not as hard as you thought - -Finding out how much space is being used on your Linux-attached drives is quite simple. As long as your drives are mounted to the Linux system, both df and du will do an outstanding job of reporting the necessary information. With df you can quickly see an overview of how much space is used on a disk and with du you can discover how much space is being used by specific directories. These two tools in combination should be considered must-know for every Linux administrator. - -And, in case you missed it, I recently showed how to [determine your memory usage on Linux][19]. Together, these tips will go a long way toward helping you successfully manage your Linux servers. - -Learn more about Linux through the free ["Introduction to Linux"][20]course from The Linux Foundation and edX. - --------------------------------------------------------------------------------- - -via: https://www.linux.com/learn/intro-to-linux/2018/6how-check-disk-space-linux-command-line - -作者:[Jack Wallen][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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 -[1]:https://elementary.io/ -[2]:/files/images/diskspace1jpg -[3]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_1.jpg?itok=aJa8AZAM (df output) -[4]:https://www.linux.com/licenses/category/used-permission -[5]:/files/images/diskspace2jpg -[6]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_2.jpg?itok=_PAq3kxC (disk usage) -[7]:/files/images/diskspace3jpg -[8]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_3.jpg?itok=51m8I-Vu (output) -[9]:/files/images/diskspace4jpg -[10]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_4.jpg?itok=SuwgueN3 (source) -[11]:/files/images/diskspace5jpg -[12]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_5.jpg?itok=XfS4s7Zq (du command) -[13]:/files/images/diskspace6jpg -[14]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_6.jpg?itok=r71qICyG (space used) -[15]:/files/images/diskspace7jpg -[16]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_7.jpg?itok=PtDe4q5y (directories) -[17]:/files/images/diskspace8jpg -[18]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/diskspace_8.jpg?itok=v9E1SFcC (top users) -[19]:https://www.linux.com/learn/5-commands-checking-memory-usage-linux -[20]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180623 Intercepting and Emulating Linux System Calls with Ptrace - null program.md b/sources/tech/20180623 Intercepting and Emulating Linux System Calls with Ptrace - null program.md deleted file mode 100644 index 660e71642f..0000000000 --- a/sources/tech/20180623 Intercepting and Emulating Linux System Calls with Ptrace - null program.md +++ /dev/null @@ -1,294 +0,0 @@ -Translating by qhwdw -Intercepting and Emulating Linux System Calls with Ptrace « null program -====== - -The `ptrace(2)` (“process trace”) system call is usually associated with debugging. It’s the primary mechanism through which native debuggers monitor debuggees on unix-like systems. It’s also the usual approach for implementing [strace][1] — system call trace. With Ptrace, tracers can pause tracees, [inspect and set registers and memory][2], monitor system calls, or even intercept system calls. - -By intercept, I mean that the tracer can mutate system call arguments, mutate the system call return value, or even block certain system calls. Reading between the lines, this means a tracer can fully service system calls itself. This is particularly interesting because it also means **a tracer can emulate an entire foreign operating system**. This is done without any special help from the kernel beyond Ptrace. - -The catch is that a process can only have one tracer attached at a time, so it’s not possible emulate a foreign operating system while also debugging that process with, say, GDB. The other issue is that emulated systems calls will have higher overhead. - -For this article I’m going to focus on [Linux’s Ptrace][3] on x86-64, and I’ll be taking advantage of a few Linux-specific extensions. For the article I’ll also be omitting error checks, but the full source code listings will have them. - -You can find runnable code for the examples in this article here: - -**** - -### strace - -Before getting into the really interesting stuff, let’s start by reviewing a bare bones implementation of strace. It’s [no DTrace][4], but strace is still incredibly useful. - -Ptrace has never been standardized. Its interface is similar across different operating systems, especially in its core functionality, but it’s still subtly different from system to system. The `ptrace(2)` prototype generally looks something like this, though the specific types may be different. -``` -long ptrace(int request, pid_t pid, void *addr, void *data); - -``` - -The `pid` is the tracee’s process ID. While a tracee can have only one tracer attached at a time, a tracer can be attached to many tracees. - -The `request` field selects a specific Ptrace function, just like the `ioctl(2)` interface. For strace, only two are needed: - - * `PTRACE_TRACEME`: This process is to be traced by its parent. - * `PTRACE_SYSCALL`: Continue, but stop at the next system call entrance or exit. - * `PTRACE_GETREGS`: Get a copy of the tracee’s registers. - - - -The other two fields, `addr` and `data`, serve as generic arguments for the selected Ptrace function. One or both are often ignored, in which case I pass zero. - -The strace interface is essentially a prefix to another command. -``` -$ strace [strace options] program [arguments] - -``` - -My minimal strace doesn’t have any options, so the first thing to do — assuming it has at least one argument — is `fork(2)` and `exec(2)` the tracee process on the tail of `argv`. But before loading the target program, the new process will inform the kernel that it’s going to be traced by its parent. The tracee will be paused by this Ptrace system call. -``` -pid_t pid = fork(); -switch (pid) { - case -1: /* error */ - FATAL("%s", strerror(errno)); - case 0: /* child */ - ptrace(PTRACE_TRACEME, 0, 0, 0); - execvp(argv[1], argv + 1); - FATAL("%s", strerror(errno)); -} - -``` - -The parent waits for the child’s `PTRACE_TRACEME` using `wait(2)`. When `wait(2)` returns, the child will be paused. -``` -waitpid(pid, 0, 0); - -``` - -Before allowing the child to continue, we tell the operating system that the tracee should be terminated along with its parent. A real strace implementation may want to set other options, such as `PTRACE_O_TRACEFORK`. -``` -ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_EXITKILL); - -``` - -All that’s left is a simple, endless loop that catches on system calls one at a time. The body of the loop has four steps: - - 1. Wait for the process to enter the next system call. - 2. Print a representation of the system call. - 3. Allow the system call to execute and wait for the return. - 4. Print the system call return value. - - - -The `PTRACE_SYSCALL` request is used in both waiting for the next system call to begin, and waiting for that system call to exit. As before, a `wait(2)` is needed to wait for the tracee to enter the desired state. -``` -ptrace(PTRACE_SYSCALL, pid, 0, 0); -waitpid(pid, 0, 0); - -``` - -When `wait(2)` returns, the registers for the thread that made the system call are filled with the system call number and its arguments. However, the operating system has not yet serviced this system call. This detail will be important later. - -The next step is to gather the system call information. This is where it gets architecture specific. On x86-64, [the system call number is passed in `rax`][5], and the arguments (up to 6) are passed in `rdi`, `rsi`, `rdx`, `r10`, `r8`, and `r9`. Reading the registers is another Ptrace call, though there’s no need to `wait(2)` since the tracee isn’t changing state. -``` -struct user_regs_struct regs; -ptrace(PTRACE_GETREGS, pid, 0, ®s); -long syscall = regs.orig_rax; - -fprintf(stderr, "%ld(%ld, %ld, %ld, %ld, %ld, %ld)", - syscall, - (long)regs.rdi, (long)regs.rsi, (long)regs.rdx, - (long)regs.r10, (long)regs.r8, (long)regs.r9); - -``` - -There’s one caveat. For [internal kernel purposes][6], the system call number is stored in `orig_rax` rather than `rax`. All the other system call arguments are straightforward. - -Next it’s another `PTRACE_SYSCALL` and `wait(2)`, then another `PTRACE_GETREGS` to fetch the result. The result is stored in `rax`. -``` -ptrace(PTRACE_GETREGS, pid, 0, ®s); -fprintf(stderr, " = %ld\n", (long)regs.rax); - -``` - -The output from this simple program is very crude. There is no symbolic name for the system call and every argument is printed numerically, even if it’s a pointer to a buffer. A more complete strace would know which arguments are pointers and use `process_vm_readv(2)` to read those buffers from the tracee in order to print them appropriately. - -However, this does lay the groundwork for system call interception. - -### System call interception - -Suppose we want to use Ptrace to implement something like OpenBSD’s [`pledge(2)`][7], in which [a process pledges to use only a restricted set of system calls][8]. The idea is that many programs typically have an initialization phase where they need lots of system access (opening files, binding sockets, etc.). After initialization they enter a main loop in which they processing input and only a small set of system calls are needed. - -Before entering this main loop, a process can limit itself to the few operations that it needs. If [the program has a flaw][9] allowing it to be exploited by bad input, the pledge significantly limits what the exploit can accomplish. - -Using the same strace model, rather than print out all system calls, we could either block certain system calls or simply terminate the tracee when it misbehaves. Termination is easy: just call `exit(2)` in the tracer. Since it’s configured to also terminate the tracee. Blocking the system call and allowing the child to continue is a little trickier. - -The tricky part is that **there’s no way to abort a system call once it’s started**. When tracer returns from `wait(2)` on the entrance to the system call, the only way to stop a system call from happening is to terminate the tracee. - -However, not only can we mess with the system call arguments, we can change the system call number itself, converting it to a system call that doesn’t exist. On return we can report a “friendly” `EPERM` error in `errno` [via the normal in-band signaling][10]. -``` -for (;;) { - /* Enter next system call */ - ptrace(PTRACE_SYSCALL, pid, 0, 0); - waitpid(pid, 0, 0); - - struct user_regs_struct regs; - ptrace(PTRACE_GETREGS, pid, 0, ®s); - - /* Is this system call permitted? */ - int blocked = 0; - if (is_syscall_blocked(regs.orig_rax)) { - blocked = 1; - regs.orig_rax = -1; // set to invalid syscall - ptrace(PTRACE_SETREGS, pid, 0, ®s); - } - - /* Run system call and stop on exit */ - ptrace(PTRACE_SYSCALL, pid, 0, 0); - waitpid(pid, 0, 0); - - if (blocked) { - /* errno = EPERM */ - regs.rax = -EPERM; // Operation not permitted - ptrace(PTRACE_SETREGS, pid, 0, ®s); - } -} - -``` - -This simple example only checks against a whitelist or blacklist of system calls. And there’s no nuance, such as allowing files to be opened (`open(2)`) read-only but not as writable, allowing anonymous memory maps but not non-anonymous mappings, etc. There’s also no way to the tracee to dynamically drop privileges. - -How could the tracee communicate to the tracer? Use an artificial system call! - -### Creating an artificial system call - -For my new pledge-like system call — which I call `xpledge()` to distinguish it from the real thing — I picked system call number 10000, a nice high number that’s unlikely to ever be used for a real system call. -``` -#define SYS_xpledge 10000 - -``` - -Just for demonstration purposes, I put together a minuscule interface that’s not good for much in practice. It has little in common with OpenBSD’s `pledge(2)`, which uses a [string interface][11]. Actually designing robust and secure sets of privileges is really complicated, as the `pledge(2)` manpage shows. Here’s the entire interface and implementation of the system call for the tracee: -``` -#define _GNU_SOURCE -#include - -#define XPLEDGE_RDWR (1 << 0) -#define XPLEDGE_OPEN (1 << 1) - -#define xpledge(arg) syscall(SYS_xpledge, arg) - -``` - -If it passes zero for the argument, only a few basic system calls are allowed, including those used to allocate memory (e.g. `brk(2)`). The `PLEDGE_RDWR` bit allows [various][12] read and write system calls (`read(2)`, `readv(2)`, `pread(2)`, `preadv(2)`, etc.). The `PLEDGE_OPEN` bit allows `open(2)`. - -To prevent privileges from being escalated back, `pledge()` blocks itself — though this also prevents dropping more privileges later down the line. - -In the xpledge tracer, I just need to check for this system call: -``` -/* Handle entrance */ -switch (regs.orig_rax) { - case SYS_pledge: - register_pledge(regs.rdi); - break; -} - -``` - -The operating system will return `ENOSYS` (Function not implemented) since this isn’t a real system call. So on the way out I overwrite this with a success (0). -``` -/* Handle exit */ -switch (regs.orig_rax) { - case SYS_pledge: - ptrace(PTRACE_POKEUSER, pid, RAX * 8, 0); - break; -} - -``` - -I wrote a little test program that opens `/dev/urandom`, makes a read, tries to pledge, then tries to open `/dev/urandom` a second time, then confirms it can read from the original `/dev/urandom` file descriptor. Running without a pledge tracer, the output looks like this: -``` -$ ./example -fread("/dev/urandom")[1] = 0xcd2508c7 -XPledging... -XPledge failed: Function not implemented -fread("/dev/urandom")[2] = 0x0be4a986 -fread("/dev/urandom")[1] = 0x03147604 - -``` - -Making an invalid system call doesn’t crash an application. It just fails, which is a rather convenient fallback. When run under the tracer, it looks like this: -``` -$ ./xpledge ./example -fread("/dev/urandom")[1] = 0xb2ac39c4 -XPledging... -fopen("/dev/urandom")[2]: Operation not permitted -fread("/dev/urandom")[1] = 0x2e1bd1c4 - -``` - -The pledge succeeds but the second `fopen(3)` does not since the tracer blocked it with `EPERM`. - -This concept could be taken much further, to, say, change file paths or return fake results. A tracer could effectively chroot its tracee, prepending some chroot path to the root of any path passed through a system call. It could even lie to the process about what user it is, claiming that it’s running as root. In fact, this is exactly how the [Fakeroot NG][13] program works. - -### Foreign system emulation - -Suppose you don’t just want to intercept some system calls, but all system calls. You’ve got [a binary intended to run on another operating system][14], so none of the system calls it makes will ever work. - -You could manage all this using only what I’ve described so far. The tracer would always replace the system call number with a dummy, allow it to fail, then service the system call itself. But that’s really inefficient. That’s essentially three context switches for each system call: one to stop on the entrance, one to make the always-failing system call, and one to stop on the exit. - -The Linux version of PTrace has had a more efficient operation for this technique since 2005: `PTRACE_SYSEMU`. PTrace stops only once per a system call, and it’s up to the tracer to service that system call before allowing the tracee to continue. -``` -for (;;) { - ptrace(PTRACE_SYSEMU, pid, 0, 0); - waitpid(pid, 0, 0); - - struct user_regs_struct regs; - ptrace(PTRACE_GETREGS, pid, 0, ®s); - - switch (regs.orig_rax) { - case OS_read: - /* ... */ - - case OS_write: - /* ... */ - - case OS_open: - /* ... */ - - case OS_exit: - /* ... */ - - /* ... and so on ... */ - } -} - -``` - -To run binaries for the same architecture from any system with a stable (enough) system call ABI, you just need this `PTRACE_SYSEMU` tracer, a loader (to take the place of `exec(2)`), and whatever system libraries the binary needs (or only run static binaries). - -In fact, this sounds like a fun weekend project. - --------------------------------------------------------------------------------- - -via: http://nullprogram.com/blog/2018/06/23/ - -作者:[Chris Wellons][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://nullprogram.com -[1]:https://blog.plover.com/Unix/strace-groff.html -[2]:http://nullprogram.com/blog/2016/09/03/ -[3]:http://man7.org/linux/man-pages/man2/ptrace.2.html -[4]:http://nullprogram.com/blog/2018/01/17/ -[5]:http://nullprogram.com/blog/2015/05/15/ -[6]:https://stackoverflow.com/a/6469069 -[7]:https://man.openbsd.org/pledge.2 -[8]:http://www.openbsd.org/papers/hackfest2015-pledge/mgp00001.html -[9]:http://nullprogram.com/blog/2017/07/19/ -[10]:http://nullprogram.com/blog/2016/09/23/ -[11]:https://www.tedunangst.com/flak/post/string-interfaces -[12]:http://nullprogram.com/blog/2017/03/01/ -[13]:https://fakeroot-ng.lingnu.com/index.php/Home_Page -[14]:http://nullprogram.com/blog/2017/11/30/ diff --git a/sources/tech/20180625 How To Upgrade Everything Using A Single Command In Linux.md b/sources/tech/20180625 How To Upgrade Everything Using A Single Command In Linux.md deleted file mode 100644 index 741cd82f0d..0000000000 --- a/sources/tech/20180625 How To Upgrade Everything Using A Single Command In Linux.md +++ /dev/null @@ -1,123 +0,0 @@ -How To Upgrade Everything Using A Single Command In Linux -====== - -![](https://www.ostechnix.com/wp-content/uploads/2018/06/topgrade-720x340.png) - -As we all know already, keeping our Linux system up-to-date involves invoking more than one package manager. Say for instance, in Ubuntu you can’t upgrade everything using “sudo apt update && sudo apt upgrade” command. This command will only upgrade the applications which are installed using APT package manager. There are chances that you might have installed some other applications using **cargo** , [**pip**][1], **npm** , **snap** , **flatpak** or [**Linuxbrew**][2] package managers. You need to use the respective package manager in order to keep them all updated. Not anymore! Say hello to **“topgrade”** , an utility to upgrade all the things in your system in one go. - -You need not to run every package manager to update the packages. The topgrade tool resolves this problem by detecting the installed packages, tools, plugins and run their appropriate package manager to update everything in your Linux box with a single command. It is free, open source and written using **rust programming language**. It supports GNU/Linux and Mac OS X. - -### Upgrade Everything Using A Single Command In Linux - -The topgrade is available in AUR. So, you can install it using [**Yay**][3] helper program in any Arch-based systems. -``` -$ yay -S topgrade - -``` - -On other Linux distributions, you can install topgrade utility using **cargo** package manager. To install cargo package manager, refer the following link. - -And, then run the following command to install topgrade. -``` -$ cargo install topgrade - -``` - -Once installed, run the topgrade to upgrade all the things in your Linux system. -``` -$ topgrade - -``` - -Once topgrade is invoked, it will perform the following tasks one by one. You will be asked to enter root/sudo user password wherever necessary. - -1 Run your system’s package manager: - - * Arch: Run **yay** or fall back to [**pacman**][4] - * CentOS/RHEL: Run `yum upgrade` - * Fedora – Run `dnf upgrade` - * Debian/Ubuntu: Run `apt update && apt dist-upgrade` - * Linux/macOS: Run `brew update && brew upgrade` - - - -2\. Check if the following paths are tracked by Git. If so, pull them: - - * ~/.emacs.d (Should work whether you use **Spacemacs** or a custom configuration) - * ~/.zshrc - * ~/.oh-my-zsh - * ~/.tmux - * ~/.config/fish/config.fish - * Custom defined paths - - - -3\. Unix: Run **zplug** update - -4\. Unix: Upgrade **tmux** plugins with **TPM** - -5\. Run **Cargo install-update** - -6\. Upgrade **Emacs** packages - -7\. Upgrade Vim packages. Works with the following plugin frameworks: - - * NeoBundle - * [**Vundle**][5] - * Plug - - - -8\. Upgrade [**NPM**][6] globally installed packages - -9\. Upgrade **Atom** packages - -10\. Update [**Flatpak**][7] packages - -11\. Update [**snap**][8] packages - -12\. **Linux:** Run **fwupdmgr** to show firmware upgrade. (View only. No upgrades will actually be performed) - -13\. Run custom defined commands. - -Finally, topgrade utility will run **needrestart** to restart all services. In Mac OS X, it will upgrade App Store applications. - -Sample output from my Ubuntu 18.04 LTS test box: - -![][10] - -The good thing is if one task is failed, it will automatically run the next task and complete all other subsequent tasks. Finally, it will display the summary with details such as how many tasks did it run, how many succeeded and how many failed etc. - -![][11] - -**Suggested read:** - -Personally, I liked this idea of creating an utility like topgrade and upgrade everything installed with various package managers with a single command. I hope you find it useful too. More good stuffs to come. Stay tuned! - -Cheers! - - - --------------------------------------------------------------------------------- - -via: https://www.ostechnix.com/how-to-upgrade-everything-using-a-single-command-in-linux/ - -作者:[SK][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/ -[1]:https://www.ostechnix.com/manage-python-packages-using-pip/ -[2]:https://www.ostechnix.com/linuxbrew-common-package-manager-linux-mac-os-x/ -[3]:https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/ -[4]:https://www.ostechnix.com/getting-started-pacman/ -[5]:https://www.ostechnix.com/manage-vim-plugins-using-vundle-linux/ -[6]:https://www.ostechnix.com/manage-nodejs-packages-using-npm/ -[7]:https://www.ostechnix.com/flatpak-new-framework-desktop-applications-linux/ -[8]:https://www.ostechnix.com/install-snap-packages-arch-linux-fedora/ -[9]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 -[10]:http://www.ostechnix.com/wp-content/uploads/2018/06/topgrade-1.png -[11]:http://www.ostechnix.com/wp-content/uploads/2018/06/topgrade-2.png diff --git a/sources/tech/20180625 How to install Pipenv on Fedora.md b/sources/tech/20180625 How to install Pipenv on Fedora.md deleted file mode 100644 index e1099d5ded..0000000000 --- a/sources/tech/20180625 How to install Pipenv on Fedora.md +++ /dev/null @@ -1,95 +0,0 @@ -translating---geekpi - -How to install Pipenv on Fedora -====== - -![](https://fedoramagazine.org/wp-content/uploads/2018/06/pipenv-install-816x345.jpg) - -Pipenv aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. It tries to solve a couple of problems and also simplify the whole management process. - -Currently the management of Python application dependencies sometimes seems like a bit of a challenge. Developers usually create a [virtual environment][1] for each new project and install dependencies into it using [pip][2]. In addition they have to store the set of installed packages into the requirements.txt text file. We’ve seen many tools and wrappers that aim to automate this workflow. However, there was still necessity to combine multiple utilities and the requirements.txt format itself is not ideal for more complicated scenarios. - -### One tol to rule them all - -Pipenv manages complex inter-dependencies properly and it also provides manual documenting of installed packages. For example development, testing and production environments often require a different set of packages. It used to be necessary to maintain multiple requirements.txt per project. Pipenv introduces the new [Pipfile][3] format using [TOML][4] syntax. Thanks to this format, you can finally maintain multiple set of requirement for different environments in a single file. - -Pipenv has become the officially recommended tool for managing Python application dependencies only a year after the first lines of code were committed into the project. Now it is finally available as an package in Fedora repositories as well. - -### Installing Pipenv on Fedora - -On clean installation of Fedora 28 and later you can simply install Pipenv by running this command at the terminal: -``` -$ sudo dnf install pipenv - -``` - -Your system is now ready to start working on your new Python 3 application with help of Pipenv. - -The important point is that while this tool provides nice solution for the applications, it is not designed for dealing with library requirements. When writing a Python library, pinning dependencies is not desirable. You should rather specify install_requires in setup.py file. - -### Basic dependencies management - -Create a directory for your project first: -``` -$ mkdir new-project && cd new-project - -``` - -Another step is to create a virtual environment for this project: -``` -$ pipenv --three - -``` - -The –three option here sets the Python version of the virtual environment to Python 3. - -Install dependencies: -``` -$ pipenv install requests -Installing requests… -Adding requests to Pipfile's [packages]… -Pipfile.lock not found, creating… -Locking [dev-packages] dependencies… -Locking [packages] dependencies… - -``` - -Finally generate a lockfile: -``` -$ pipenv lock -Locking [dev-packages] dependencies… -Locking [packages] dependencies… -Updated Pipfile.lock (b14837) - -``` - -You can also check a dependency graph: -``` -$ pipenv graph - - certifi [required: >=2017.4.17, installed: 2018.4.16] -- chardet [required: <3.1.0,>=3.0.2, installed: 3.0.4] -- idna [required: <2.8,>=2.5, installed: 2.7] -- urllib3 [required: >=1.21.1,<1.24, installed: 1.23] - -``` - -More details on Pipenv and it commands are available in the [documentation][5]. - - --------------------------------------------------------------------------------- - -via: https://fedoramagazine.org/install-pipenv-fedora/ - -作者:[Michal Cyprian][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/mcyprian/ -[1]:https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments -[2]:https://developer.fedoraproject.org/tech/languages/python/pypi-installation.html -[3]:https://github.com/pypa/pipfile -[4]:https://github.com/toml-lang/toml -[5]:https://docs.pipenv.org/ diff --git a/sources/tech/20180626 TrueOS Doesnt Want to Be BSD for Desktop Anymore.md b/sources/tech/20180626 TrueOS Doesnt Want to Be BSD for Desktop Anymore.md deleted file mode 100644 index c9b6b117c5..0000000000 --- a/sources/tech/20180626 TrueOS Doesnt Want to Be BSD for Desktop Anymore.md +++ /dev/null @@ -1,79 +0,0 @@ -translating---geekpi - -TrueOS Doesn’t Want to Be ‘BSD for Desktop’ Anymore -============================================================ - - -There are some really big changes on the horizon for [TrueOS][9]. Today, we will take a look at what is going on in the world of desktop BSD. - -### The Announcement - -![TrueOS: Core Operating System BSD](https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/true-os-bsd-desktop.jpeg) - -The team behind [TrueOS][10] [announced][11] that they would be changing the focus of the project. Up until this point, TrueOS has made it easy to install BSD with a graphical user interface out of the box. However, it will now become “a cutting-edge operating system that keeps all of the stability that you know and love from ZFS ([OpenZFS][12]) and [FreeBSD][13], and adds additional features to create a fresh, innovative operating system. Our goal is to create a core-centric operating system that is modular, functional, and perfect for do-it-yourselfers and advanced users alike.” - -Essentially, TrueOs will become a downstream fork of FreeBSD. They will integrate newer software into the system, such as [OpenRC][14] and [LibreSSL][15]. They hope to stick to a 6-month release cycle. - -The goal is to make TrueOS so it can be used as the base for other projects to build on. The graphical part will be missing to make it more distro-agnostic. - -[Suggested readInterview with MidnightBSD Founder and Lead Dev Lucas Holt][16] - -### What about Desktop Users? - -If you read my [review of TrueOS][17] and are interested in trying a desktop BSD or already use TrueOS, never fear (which is good advice for life too). All of the desktop elements of TrueOS will be spun off into [Project Trident][18]. Currently, the Project Trident website is very light on details. It seems as though they are still figuring out the logistics of the spin-off. - -If you currently have TrueOS, you don’t have to worry about moving. The TrueOS team said that “there will be migration paths available for those that would like to move to other FreeBSD-based distributions like Project Trident or [GhostBSD][19].” - -[Suggested readInterview with FreeDOS Founder and Lead Dev Jim Hall][20] - -### Thoughts - -When I first read the announcement, I was frankly a little worried. Changing names can be a bad idea. Customers will be used to one name, but if the product name changes they could lose track of the project very easily. TrueOS already went through a name change. When the project was started in 2006 it was named PC-BSD, but in 2016 the name was changed to TrueOS. It kinds of reminds me of the [ArchMerge and Arcolinux saga][21]. - -That being said, I think this will be a good thing for desktop users of BSD. One of the common criticisms that I heard about PC-BSD and TrueOS is that it wasn’t very polished. Separating the two parts of the project will help sharpen the focus of the respective developers. The TrueOS team will be able to add newer features to the slow-moving FreeBSD base and the Project Trident team will be able to improve user’s desktop experience. - -I wish both teams well. Remember, people, when someone works on open source, we all benefit even if the work is done on something we don’t use. - -What are your thoughts about the future of TrueOS and Project Trident? Please let us know in the comments below. - - ------------------------------- - -关于作者: - -My name is John Paul Wohlscheid. I'm an aspiring mystery writer who loves to play with technology, especially Linux. You can catch up with me at [my personal website][23] - --------------------------------------------------------------------------------- - -via: https://itsfoss.com/trueos-plan-change/ - -作者:[John Paul Wohlscheid ][a] -译者:[译者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/ -[1]:https://itsfoss.com/author/john/ -[2]:https://itsfoss.com/trueos-plan-change/#comments -[3]:https://itsfoss.com/category/bsd/ -[4]:https://itsfoss.com/category/news/ -[5]:https://itsfoss.com/tag/bsd/ -[6]:https://itsfoss.com/tag/freebsd/ -[7]:https://itsfoss.com/tag/project-trident/ -[8]:https://itsfoss.com/tag/trueos/ -[9]:https://www.trueos.org/ -[10]:https://www.trueos.org/ -[11]:https://www.trueos.org/blog/trueosdownstream/ -[12]:http://open-zfs.org/wiki/Main_Page -[13]:https://www.freebsd.org/ -[14]:https://en.wikipedia.org/wiki/OpenRC -[15]:http://www.libressl.org/ -[16]:https://itsfoss.com/midnightbsd-founder-lucas-holt/ -[17]:https://itsfoss.com/trueos-bsd-review/ -[18]:http://www.project-trident.org/ -[19]:https://www.ghostbsd.org/ -[20]:https://itsfoss.com/interview-freedos-jim-hall/ -[21]:https://itsfoss.com/archlabs-vs-archmerge/ -[22]:http://reddit.com/r/linuxusersgroup -[23]:http://johnpaulwohlscheid.work/ diff --git a/sources/tech/20180628 Blockchain evolution- A quick guide and why open source is at the heart of it.md b/sources/tech/20180628 Blockchain evolution- A quick guide and why open source is at the heart of it.md deleted file mode 100644 index 01f9abb44a..0000000000 --- a/sources/tech/20180628 Blockchain evolution- A quick guide and why open source is at the heart of it.md +++ /dev/null @@ -1,98 +0,0 @@ -Translating by qhwdw -Blockchain evolution: A quick guide and why open source is at the heart of it -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/block-quilt-chain.png?itok=mECoDbrc) - -It isn't uncommon, when working on a new version of an open source project, to suffix it with "-ng", for "next generation." Fortunately, in their rapid evolution blockchains have so far avoided this naming pitfall. But in this evolutionary open source ecosystem, changes have been abundant, and good ideas have been picked up, remixed, and evolved between many different projects in a typical open source fashion. - -In this article, I will look at the different generations of blockchains and what ideas have emerged to address the problems the ecosystem has encountered. Of course, any attempt at classifying an ecosystem will have limits—and objectors—but it should provide a rough guide to the jungle of blockchain projects. - -### The beginning: Bitcoin - -The first generation of blockchains stems from the [Bitcoin][1] blockchain, the ledger underpinning the decentralized, peer-to-peer cryptocurrency that has gone from [Slashdot][2] miscellanea to a mainstream topic. - -This blockchain is a distributed ledger that keeps track of all users' transactions to prevent them from double-spending their coins (a task historically entrusted to third parties: banks). To prevent attackers from gaming the system, the ledger is replicated to every computer participating in the Bitcoin network and can be updated by only one computer in the network at a time. To decide which computer earns the right to update the ledger, the system organizes every 10 minutes a race between the computers, which costs them (a lot of) energy to enter. The winner wins the right to commit the last 10 minutes of transactions to the ledger (the "block" in blockchain) and some Bitcoin as a reward for their efforts. This setup is called a _proof of work_ consensus mechanism. - -The goal of using a blockchain is to raise the level of trust participants have in the network. - -This is where it gets interesting. Bitcoin was released as an [open source project][3] in January 2009. In 2010, realizing that quite a few of these elements can be tweaked, the community that had aggregated around Bitcoin, often on the [bitcointalk forums][4], started experimenting with them. - -First, seeing that the Bitcoin blockchain is a form of a distributed database, the [Namecoin][5] project emerged, suggesting to store arbitrary data in its transaction database. If the blockchain can record the transfer of money, it could also record the transfer of other assets, such as domain names. This is exactly Namecoin's main use case, which went live in April 2011, two years after Bitcoin's introduction. - -Where Namecoin tweaked the content of the blockchain, [Litecoin][6] tweaked two technical aspects: reducing the time between two blocks from 10 to 2.5 minutes and changing how the race is run (replacing the SHA-256 secure hashing algorithm with [scrypt][7]). This was possible because Bitcoin was released as open source software and Litecoin is essentially identical to Bitcoin in all other places. Litecoin was the first fork to modify the consensus mechanism, paving the way for many more. - -Along the way, many more variations of the Bitcoin codebase have appeared. Some started as proposed extensions to Bitcoin, such as the [Zerocash][8] protocol, which aimed to provide transaction anonymity and fungibility but was eventually spun off into its own currency, [Zcash][9]. - -While Zcash has brought its own innovations, using recent cryptographic advances known as zero-knowledge proofs, it maintains compatibility with the vast majority of the Bitcoin code base, meaning it too can benefit from upstream Bitcoin innovations. - -Another project, [CryptoNote][10], didn't use the same code base but sprouted from the same community, building on (and against) Bitcoin and again, on older ideas. Published in December 2012, it led to the creation of several cryptocurrencies, of which [Monero][11] (2014) is the best-known. Monero takes a different approach to Zcash but aims to solve the same issues: privacy and fungibility. - -As is often the case in the open source world, there is more than one tool for the job. - -### The next generations: "Blockchain-ng" - -So far, however, all these variations have only really been about refining cryptocurrencies or extending them to support another type of transaction. This brings us to the second generation of blockchains. - -Once the community started modifying what a blockchain could be used for and tweaking technical aspects, it didn't take long for some people to expand and rethink them further. A longtime follower of Bitcoin, [Vitalik Buterin][12] suggested in late 2013 that a blockchain's transactions could represent the change of states of a state machine, conceiving the blockchain as a distributed computer capable of running applications ("smart contracts"). The project, [Ethereum][13], went live in July 2015. It has seen fair success in running distributed apps, and the popularity of some of its better-known distributed apps ([CryptoKitties][14]) have even caused the Ethereum blockchain to slow down. - -This demonstrates one of the big limitations of current blockchains: speed and capacity. (Speed is often measured in transactions per second, or TPS.) Several approaches have been suggested to solve this, from sharding to sidechains and so-called "second-layer" solutions. The need for more innovation here is strong. - -With the words "smart contract" in the air and a proved—if still slow—technology to run them, another idea came to fruition: permissioned blockchains. So far, all the blockchain networks we've described have had two unsaid characteristics: They are public (anyone can see them function), and they are without permission (anyone can join them). These two aspects are both desirable and necessary to run a distributed, non-third-party-based currency. - -As blockchains were being considered more and more separately from cryptocurrencies, it started to make sense to consider them in some private, permissioned settings. A consortium-type group of actors that have business relationships but don't necessarily trust each other fully can benefit from these types of blockchains—for example, actors along a logistics chain, financial or insurance institutions that regularly do bilateral settlements or use a clearinghouse, idem for healthcare institutions. - -Once you change the setting from "anyone can join" to "invitation-only," further changes and tweaks to the blockchain building blocks become possible, yielding interesting results for some. - -For a start, proof of work, designed to protect the network from malicious and spammy actors, can be replaced by something simpler and less resource-hungry, such as a [Raft][15]-based consensus protocol. A tradeoff appears between a high level of security or faster speed, embodied by the option of simpler consensus algorithms. This is highly desirable to many groups, as they can trade some cryptography-based assurance for assurance based on other means—legal relationships, for instance—and avoid the energy-hungry arms race that proof of work often leads to. This is another area where innovation is ongoing, with [Proof of Stake][16] a notable contender for the public network consensus mechanism of choice. It would likely also find its way to permissioned networks too. - -Several projects make it simple to create permissioned blockchains, including [Quorum][17] (a fork of Ethereum) and [Hyperledger][18]'s [Fabric][19] and [Sawtooth][20], two open source projects based on new code. - -Permissioned blockchains can avoid certain complexities that public, non-permissioned ones can't, but they still have their own set of issues. Proper management of participants is one: Who can join? How do they identify? How can they be removed from the network? Does one entity on the network manage a central public key infrastructure (PKI)? - -The open nature of blockchains is seen as a form of governance. - -### Open nature of blockchains - -In all of the cases so far, one thing is clear: The goal of using a blockchain is to raise the level of trust participants have in the network and the data it produces—ideally, enough to be able to use it as is, without further work. - -Reaching this level of trust is possible only if the software that powers the network is free and open source. Even a correctly distributed proprietary blockchain is essentially a collection of independent agents running the same third party's code. By nature, it's necessary—but not sufficient—for a blockchain's source code to be open source. This has both been a minimum guarantee and the source of further innovation as the ecosystem keeps growing. - -Finally, it is worth mentioning that while the open nature of blockchains has been a source of innovation and variation, it has also been seen as a form of governance: governance by code, where users are expected to run whichever specific version of the code contains a function or approach they think the whole network should embrace. In this respect, one can say the open nature of some blockchains has also become a cop-out regarding governance. But this is being addressed. - -### Third and fourth generations: governance - -Next, I will look at what I am currently considering the third and fourth generations of blockchains: blockchains with built-in governance tools and projects to solve the tricky question of interconnecting the multitude of different blockchain projects to let them exchange information and value with each other. - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/6/blockchain-guide-next-generation - -作者:[Axel Simon][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/axel -[1]:https://bitcoin.org -[2]:https://slashdot.org/ -[3]:https://github.com/bitcoin/bitcoin -[4]:https://bitcointalk.org/ -[5]:https://www.namecoin.org/ -[6]:https://litecoin.org/ -[7]:https://en.wikipedia.org/wiki/Scrypt -[8]:http://zerocash-project.org/index -[9]:https://z.cash -[10]:https://cryptonote.org/ -[11]:https://en.wikipedia.org/wiki/Monero_(cryptocurrency) -[12]:https://en.wikipedia.org/wiki/Vitalik_Buterin -[13]:https://ethereum.org -[14]:http://cryptokitties.co/ -[15]:https://en.wikipedia.org/wiki/Raft_(computer_science) -[16]:https://www.investopedia.com/terms/p/proof-stake-pos.asp -[17]:https://www.jpmorgan.com/global/Quorum -[18]:https://hyperledger.org/ -[19]:https://www.hyperledger.org/projects/fabric -[20]:https://www.hyperledger.org/projects/sawtooth diff --git a/sources/tech/20180703 Why is Arch Linux So Challenging and What are Its Pros - Cons.md b/sources/tech/20180703 Why is Arch Linux So Challenging and What are Its Pros - Cons.md index 23ceb85dbe..ae870b85ec 100644 --- a/sources/tech/20180703 Why is Arch Linux So Challenging and What are Its Pros - Cons.md +++ b/sources/tech/20180703 Why is Arch Linux So Challenging and What are Its Pros - Cons.md @@ -1,3 +1,4 @@ +[Moelf](https://github.com/Moelf) Translating Why is Arch Linux So Challenging and What are Its Pros & Cons? ====== diff --git a/sources/tech/20180704 Install an NVIDIA GPU on almost any machine.md b/sources/tech/20180704 Install an NVIDIA GPU on almost any machine.md deleted file mode 100644 index aa0dc27fdb..0000000000 --- a/sources/tech/20180704 Install an NVIDIA GPU on almost any machine.md +++ /dev/null @@ -1,155 +0,0 @@ -Install an NVIDIA GPU on almost any machine -====== - -![](https://fedoramagazine.org/wp-content/uploads/2018/06/nvidia-816x345.jpg) - -Whether for research or recreation, installing a new GPU can bolster your computer’s performance and enable new functionality across the board. This installation guide uses Fedora 28’s brand-new third-party repositories to install NVIDIA drivers. It walks you through the installation of both software and hardware, and covers everything you need to get your NVIDIA card up and running. This process works for any UEFI-enabled computer, and any modern NVIDIA GPU. - -### Preparation - -This guide relies on the following materials: - - * A machine that is [UEFI][1] capable. If you’re uncertain whether your machine has this firmware, run sudo dmidecode -t 0. If “UEFI is supported” appears anywhere in the output, you are all set to continue. Otherwise, while it’s technically possible to update some computers to support UEFI, the process is often finicky and generally not recommended. - * A modern, UEFI-enabled NVIDIA card - * A power source that meets the wattage and wiring requirements for your NVIDIA card (see the Hardware & Modifications section for details) - * Internet connection - * Fedora 28 - - - -### Example setup - -This example installation uses: - - * An Optiplex 9010 (a fairly old machine) - * NVIDIA [GeForce GTX 1050 Ti XLR8 Gaming Overclocked Edition 4GB GDDR5 PCI Express 3.0][2] graphics card - * In order to meet the power requirements of the new GPU, the power supply was upgraded to an [EVGA – 80 PLUS 600W ATX 12V/EPS 12V][3]. This new PSU was 300W above the minimum recommendation, but simply meeting the minimum recommendation is sufficient in most cases. - * And, of course, Fedora 28. - - - -### Hardware and modifications - -#### PSU - -Open up your desktop case and check the maximum power output printed on your power supply. Next, check the documentation on your NVIDIA GPU and determine the minimum recommended power (in watts). Further, take a look at your GPU and see if it requires additional wiring, such as a 6-pin connector. Most entry-level GPUs only draw power directly from the motherboard, but some require extra juice. You’ll need to upgrade your PSU if: - - 1. Your power supply’s max power output is below the GPU’s suggested minimum power. **Note:** According to some NVIDIA card manufacturers, pre-built systems may require more or less power than recommended, depending on the system’s configuration. Use your discretion to determine your requirements if you’re using a particularly power-efficient or power-hungry setup. - 2. Your power supply does not provide the necessary wiring to power your card. - - - -PSUs are straightforward to replace, but make sure to take note of the wiring layout before detaching your current power supply. Additionally, make sure to select a PSU that fits your desktop case. - -#### CPU - -Although installing a high-quality NVIDIA GPU is possible in many old machines, a slow or damaged CPU can “bottleneck” the performance of the GPU. To calculate the impact of the bottlenecking effect for your machine, click [here][4]. It’s important to know your CPU’s performance to avoid pairing a high-powered GPU with a CPU that can’t keep up. Upgrading your CPU is a potential consideration. - -#### Motherboard - -Before proceeding, ensure your motherboard is compatible with your GPU of choice. Your graphics card should be inserted into the PCI-E x16 slot closest to the heat-sink. Ensure that your setup contains enough space for the GPU. In addition, note that most GPUs today employ PCI-E 3.0 technology. Though these GPUs will run best if mounted on a PCI-E 3.0 x16 slot, performance should not suffer significantly with an older version slot. - -### Installation -``` -sudo dnf update - -``` - -2\. Next, reboot with the simple command: -``` -reboot - -``` - -3\. After reboot, install the Fedora 28 workstation repositories: -``` -sudo dnf install fedora-workstation-repositories - -``` - -4\. Next, enable the NVIDIA driver repository: -``` -sudo dnf config-manager --set-enabled rpmfusion-nonfree-nvidia-driver - -``` - -5\. Then, reboot again. - -6\. After the reboot, verify the addition of the repository via the following command: -``` -sudo dnf repository-packages rpmfusion-nonfree-nvidia-driver info - -``` - -If several NVIDIA tools and their respective specs are loaded, then proceed to the next step. If not, you may have encountered an error when adding the new repository and you should give it another shot. - -7\. Login, connect to the internet, and open the software app. Click Add-ons> Hardware Drivers> NVIDIA Linux Graphics Driver> Install. - -Then, reboot once again. - -8\. After reboot, go to ‘Show Applications’ on the side bar, and open up the newly added NVIDIA X Server Settings application. A GUI should open up, and a dialog box will appear with the following message: - -![NVIDIA X Server Prompt][5] - -Take the application’s advice, but before doing so, ensure you have your NVIDIA GPU on-hand and are ready to install. **Please note** that running nvidia xconfig as root and powering off without installing your GPU immediately may cause drastic damage. Doing so may prevent your computer from booting, and force you to repair the system through the reboot screen. A fresh install of Fedora may fix these issues, but the effects can be much worse. - -If you’re ready to proceed, enter the command: -``` -sudo nvidia-xconfig - -``` - -If the system prompts you to perform any downloads, accept them and proceed. - -9\. Once this process is complete, close all applications and **shut down** the computer. Unplug the power supply to your machine. Then, press the power button once to drain any residual power to protect yourself from electric shock. If your PSU has a power switch, switch it off. - -10\. Finally, install the graphics card. Remove the old GPU and insert your new NVIDIA graphics card into the proper PCI-E x16 slot, with the fans facing down. If there is no space for the fans to ventilate in this position, place the graphics card face up instead, if possible. When you have successfully installed the new GPU, close your case, plug in the PSU, and turn the computer on. It should successfully boot up. - -**NOTE:** To disable the NVIDIA driver repository used in this installation, or to disable all fedora workstation repositories, consult [The Fedora Wiki Page][6]. - -### Verification - -1\. If your newly installed NVIDIA graphics card is connected to your monitor and displaying correctly, then your NVIDIA driver has successfully established a connection to the GPU. - -If you’d like to view your settings, or verify the driver is working (in the case that you have two GPUs installed on the motherboard), open up the NVIDIA X Server Settings app again. This time, you should not be prompted with an error message, and information on the X configuration file and your NVIDIA GPU should be available (see screenshot below). - -![NVIDIA X Server Settings][7] - -Through this app, you may alter your X configuration file should you please, and may monitor the GPU’s performance, clock speed, and thermal information. - -2\. To ensure the new card is working at capacity, a GPU performance test is needed. GL Mark 2, a benchmarking tool that provides information on buffering, building, lighting, texturing, etc, offers an excellent solution. GL Mark 2 records frame rates for a variety of different graphical tests, and outputs an overall performance score (called the glmark2 score). - -**Note:** glxgears will only test the performance of your screen or monitor, not the graphics card itself. Use GL Mark 2 instead. - -To run GLMark2: - - 1. Open up a terminal and close all other applications - 2. sudo dnf install glmark2 - 3. glmark2 - 4. Allow the test to run to completion for best results. Check to see if the frame rates match your expectation for your NVIDA card. If you’d like additional verification, consult the web to determine if a glmark2 benchmark has been previously conducted on your NVIDA card model and published to the web. Compare scores to assess your GPUs performance. - 5. If your framerates and/or glmark2 score are below expected, consider potential causes. CPU-induced bottlenecking? Other issues? - - - -Assuming the diagnostics look good, enjoy using your new GPU. - - --------------------------------------------------------------------------------- - -via: https://fedoramagazine.org/install-nvidia-gpu/ - -作者:[Justice del Castillo][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/justice/ -[1]:https://whatis.techtarget.com/definition/Unified-Extensible-Firmware-Interface-UEFI -[2]:https://www.cnet.com/products/pny-geforce-gtx-xlr8-gaming-1050-ti-overclocked-edition-graphics-card-gf-gtx-1050-ti-4-gb/specs/ -[3]:https://www.evga.com/products/product.aspx?pn=100-B1-0600-KR -[4]:http://thebottlenecker.com (Home: The Bottle Necker) -[5]:https://bytebucket.org/kenneym/fedora-28-nvidia-gpu-installation/raw/7bee7dc6effe191f1f54b0589fa818960a8fa18b/nvidia_xserver_error.jpg?token=c6a7effe35f1c592a155a4a46a068a19fd060a91 (NVIDIA X Sever Prompt) -[6]:https://fedoraproject.org/wiki/Workstation/Third_Party_Software_Repositories -[7]:https://bytebucket.org/kenneym/fedora-28-nvidia-gpu-installation/raw/7bee7dc6effe191f1f54b0589fa818960a8fa18b/NVIDIA_XCONFIG.png?token=64e1a7be21e5e9ba157f029b65e24e4eef54d88f (NVIDIA X Server Settings) diff --git a/sources/tech/20180705 5 Reasons Open Source Certification Matters More Than Ever.md b/sources/tech/20180705 5 Reasons Open Source Certification Matters More Than Ever.md new file mode 100644 index 0000000000..dace150f39 --- /dev/null +++ b/sources/tech/20180705 5 Reasons Open Source Certification Matters More Than Ever.md @@ -0,0 +1,49 @@ +5 Reasons Open Source Certification Matters More Than Ever +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/open-source-training_0.jpg?itok=lqkiM56e) +In today’s technology landscape, open source is the new normal, with open source components and platforms driving mission-critical processes and everyday tasks at organizations of all sizes. As open source has become more pervasive, it has also profoundly impacted the job market. Across industries [the skills gap is widening][1], making it ever more difficult to hire people with much needed job skills. In response, the [demand for training and certification is growing][2]. + +In a recent webinar, Clyde Seepersad, General Manager of Training and Certification at The Linux Foundation, discussed the growing need for certification and some of the benefits of obtaining open source credentials. “As open source has become the new normal in everything from startups to Fortune 2000 companies, it is important to start thinking about the career road map, the paths that you can take and how Linux and open source in general can help you reach your career goals,” Seepersad said. + +With all this in mind, this is the first article in a weekly series that will cover: why it is important to obtain certification; what to expect from training options that lead to certification; and how to prepare for exams and understand what your options are if you don’t initially pass them. + +Seepersad pointed to these five reasons for pursuing certification: + + * **Demand for Linux and open source talent.** “Year after year, we do the Linux jobs report, and year after year we see the same story, which is that the demand for Linux professionals exceeds the supply. This is true for the open source market in general,” Seepersad said. For example, certifications such as the [LFCE, LFCS,][3] and [OpenStack administrator exam][4] have made a difference for many people. + + * **Getting the interview.** “One of the challenges that recruiters always reference, especially in the age of open source, is that it can be hard to decide who you want to have come in to the interview,” Seepersad said. “Not everybody has the time to do reference checks. One of the beautiful things about certification is that it independently verifies your skillset.” + + * **Confirming your skills.** “Certification programs allow you to step back, look across what we call the domains and topics, and find those areas where you might be a little bit rusty,” Seepersad said. “Going through that process and then being able to demonstrate skills on the exam shows that you have a very broad skillset, not just a deep skillset in certain areas.” + + * **Confidence.** This is the beauty of performance-based exams,” Seepersad said. “You're working on our live system. You're being monitored and recorded. Your timer is counting down. This really puts you on the spot to demonstrate that you can troubleshoot.” The inevitable result of successfully navigating the process is confidence. + + * **Making hiring decisions.** “As you become more senior in your career, you're going to find the tables turned and you are in the role of making a hiring decision,” Seepersad said. “You're going to want to have candidates who are certified, because you recognize what that means in terms of the skillsets.” + + + + +Although Linux has been around for more than 25 years, “it's really only in the past few years that certification has become a more prominent feature,” Seepersad noted. As a matter of fact, 87 percent of hiring managers surveyed for the [2018 Open Source Jobs Report][5] cite difficulty in finding the right open source skills and expertise. The Jobs Report also found that hiring open source talent is a priority for 83 percent of hiring managers, and half are looking for candidates holding certifications. + +With certification playing a more important role in securing a rewarding long-term career, are you interested in learning about options for gaining credentials? If so, stay tuned for more information in this series. + +[Learn more about Linux training and certification.][6] + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/sysadmin-cert/2018/7/5-reasons-open-source-certification-matters-more-ever + +作者:[Sam Dean][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/sam-dean +[1]:https://www.linuxfoundation.org/blog/open-source-skills-soar-in-demand-according-to-2018-jobs-report/ +[2]:https://www.linux.com/blog/os-jobs-report/2018/7/certification-plays-big-role-open-source-hiring +[3]:https://www.linux.com/learn/certification/2018/5/linux-foundation-lfcs-lfce-maja-kraljic +[4]:https://training.linuxfoundation.org/linux-courses/system-administration-training/openstack-administration-fundamentals +[5]:https://www.linuxfoundation.org/publications/open-source-jobs-report-2018/ +[6]:https://training.linuxfoundation.org/certification diff --git a/sources/tech/20180705 How to use dd in Linux without destroying your disk.md b/sources/tech/20180705 How to use dd in Linux without destroying your disk.md deleted file mode 100644 index ddcce8e34f..0000000000 --- a/sources/tech/20180705 How to use dd in Linux without destroying your disk.md +++ /dev/null @@ -1,96 +0,0 @@ -How to use dd in Linux without destroying your disk -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_happy_sad_developer_programming.png?itok=72nkfSQ_) - -This article is excerpted from chapter 4 of [Linux in Action][1], published by Manning. - -Whether you're trying to rescue data from a dying storage drive, backing up archives to remote storage, or making a perfect copy of an active partition somewhere else, you'll need to know how to safely and reliably copy drives and filesystems. Fortunately, `dd` is a simple and powerful image-copying tool that's been around, well, pretty much forever. And in all that time, nothing's come along that does the job better. - -### Making perfect copies of drives and partitions - -`dd` if you research hard enough, but where it shines is in the ways it lets you play with partitions. You can, of course, use `tar` or even `scp` to replicate entire filesystems by copying the files from one computer and then pasting them as-is on top of a fresh Linux install on another computer. But, because those filesystem archives aren't complete images, they'll require a running host OS at both ends to serve as a base. - -There's all kinds of stuff you can do withif you research hard enough, but where it shines is in the ways it lets you play with partitions. You can, of course, useor evento replicate entire filesystems by copying the files from one computer and then pasting them as-is on top of a fresh Linux install on another computer. But, because those filesystem archives aren't complete images, they'll require a running host OS at both ends to serve as a base. - -Using `dd`, on the other hand, can make perfect byte-for-byte images of, well, just about anything digital. But before you start flinging partitions from one end of the earth to the other, I should mention that there's some truth to that old Unix admin joke: "dd stands for disk destroyer." If you type even one wrong character in a `dd` command, you can instantly and permanently wipe out an entire drive of valuable data. And yes, spelling counts. - -**Remember:** Before pressing that Enter key to invoke `dd`, pause and think very carefully! - -### Basic dd operations - -Now that you've been suitably warned, we'll start with something straightforward. Suppose you want to create an exact image of an entire disk of data that's been designated as `/dev/``sda`. You've plugged in an empty drive (ideally having the same capacity as your `/dev/``sda` system). The syntax is simple: `if=` defines the source drive and `of=` defines the file or location where you want your data saved: -``` -# dd if=/dev/sda of=/dev/sdb - -``` - -The next example will create an .img archive of the `/dev/``sda` drive and save it to the home directory of your user account: -``` -# dd if=/dev/sda of=/home/username/sdadisk.img - -``` - -Those commands created images of entire drives. You could also focus on a single partition from a drive. The next example does that and also uses `bs` to set the number of bytes to copy at a single time (4,096, in this case). Playing with the `bs` value can have an impact on the overall speed of a `dd` operation, although the ideal setting will depend on your hardware profile and other considerations. -``` -# dd if=/dev/sda2 of=/home/username/partition2.img bs=4096 - -``` - -Restoring is simple: Effectively, you reverse the values of `if` and `of`. In this case, `if=` takes the image you want to restore, and `of=` takes the target drive to which you want to write the image: -``` -# dd if=sdadisk.img of=/dev/sdb - -``` - -You can also perform both the create and copy operations in one command. This example, for instance, will create a compressed image of a remote drive using SSH and save the resulting archive to your local machine: -``` -# ssh username@54.98.132.10 "dd if=/dev/sda | gzip -1 -" | dd of=backup.gz - -``` - -You should always test your archives to confirm they're working. If it's a boot drive you've created, stick it into a computer and see if it launches as expected. If it's a normal data partition, mount it to make sure the files both exist and are appropriately accessible. - -### Wiping disks with dd - -Years ago, I had a friend who was responsible for security at his government's overseas embassies. He once told me that each embassy under his watch was provided with an official government-issue hammer. Why? In case the facility was ever at risk of being overrun by unfriendlies, the hammer was to be used to destroy all their hard drives. - -What's that? Why not just delete the data? You're kidding, right? Everyone knows that deleting files containing sensitive data from storage devices doesn't actually remove the data. Given enough time and motivation, nearly anything can be retrieved from virtually any digital media, with the possible exception of the ones that have been well and properly hammered. - -You can, however, use `dd` to make it a whole lot more difficult for the bad guys to get at your old data. This command will spend some time writing millions and millions of zeros over every nook and cranny of the `/dev/sda1` partition: -``` -# dd if=/dev/zero of=/dev/sda1 - -``` - -But it gets better. Using `/dev/``urandom` file as your source, you can write over a disk with random characters: -``` -# dd if=/dev/urandom of=/dev/sda1 - -``` - -### Monitoring dd operations - -Since disk or partition archiving can take a very long time, you might want to add a progress monitor to your command. Install Pipe Viewer (`sudo apt install pv` on Ubuntu) and insert it into `dd`. With `pv`, that last command might look something like this: -``` -# dd if=/dev/urandom | pv | dd of=/dev/sda1 - -4,14MB 0:00:05 [ 98kB/s] [      <=>                  ] - -``` - -Putting off backups and disk management? With dd, you aren't left with too many excuses. It's really not difficult, but be careful. Good luck! - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/7/how-use-dd-linux - -作者:[David Clinton][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[译者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/remyd -[1]:https://www.manning.com/books/linux-in-action?a_aid=bootstrap-it&a_bid=4ca15fc9&chan=opensource diff --git a/sources/tech/20180705 Testing Node.js in 2018.md b/sources/tech/20180705 Testing Node.js in 2018.md new file mode 100644 index 0000000000..37ec5c120d --- /dev/null +++ b/sources/tech/20180705 Testing Node.js in 2018.md @@ -0,0 +1,322 @@ +BriFuture is translating + + +Testing Node.js in 2018 +============================================================ + +![](https://cdn-images-1.medium.com/max/1600/1*J3lGUOAGK-XdZMXwiHcI6w.png) + +[Stream][4] powers feeds for over 300+ million end users. With all of those users relying on our infrastructure, we’re very good about testing everything that gets pushed into production. Our primary codebase is written in Go, with some remaining bits of Python. + +Our recent showcase application, [Winds 2.0][5], is built with Node.js and we quickly learned that our usual testing methods in Go and Python didn’t quite fit. Furthermore, creating a proper test suite requires a bit of upfront work in Node.js as the frameworks we are using don’t offer any type of built-in test functionality. + +Setting up a good test framework can be tricky regardless of what language you’re using. In this post, we’ll uncover the hard parts of testing with Node.js, the various tooling we decided to utilize in Winds 2.0, and point you in the right direction for when it comes time for you to write your next set of tests. + +### Why Testing is so Important + +We’ve all pushed a bad commit to production and faced the consequences. It’s not a fun thing to have happen. Writing a solid test suite is not only a good sanity check, but it allows you to completely refactor code and feel confident that your codebase is still functional. This is especially important if you’ve just launched. + +If you’re working with a team, it’s extremely important that you have test coverage. Without it, it’s nearly impossible for other developers on the team to know if their contributions will result in a breaking change (ouch). + +Writing tests also encourage you and your teammates to split up code into smaller pieces. This makes it much easier to understand your code, and fix bugs along the way. The productivity gains are even bigger, due to the fact that you catch bugs early on. + +Finally, without tests, your codebase might as well be a house of cards. There is simply zero certainty that your code is stable. + +### The Hard Parts + +In my opinion, most of the testing problems we ran into with Winds were specific to Node.js. The ecosystem is always growing. For example, if you are on macOS and run “brew upgrade” (with homebrew installed), your chances of seeing a new version of Node.js are quite high. With Node.js moving quickly and libraries following close behind, keeping up to date with the latest libraries is difficult. + +Below are a few pain points that immediately come to mind: + +1. Testing in Node.js is very opinionated and un-opinionated at the same time. Many people have different views on how a test infrastructure should be built and measured for success. The sad part is that there is no golden standard (yet) for how you should approach testing. + +2. There are a large number of frameworks available to use in your application. However, they are generally minimal with no well-defined configuration or boot process. This leads to side effects that are very common, and yet hard to diagnose; so, you’ll likely end up writing your own test runner from scratch. + +3. It’s almost guaranteed that you will be  _required_  to write your own test runner (we’ll get to this in a minute). + +The situations listed above are not ideal and it’s something that the Node.js community needs to address sooner rather than later. If other languages have figured it out, I think it’s time for Node.js, a widely adopted language, to figure it out as well. + +### Writing Your Own Test Runner + +So… you’re probably wondering what a test runner  _is_ . To be honest, it’s not that complicated. A test runner is the highest component in the test suite. It allows for you to specify global configurations and environments, as well as import fixtures. One would assume this would be simple and easy to do… Right? Not so fast… + +What we learned is that, although there is a solid number of test frameworks out there, not a single one for Node.js provides a unified way to construct your test runner. Sadly, it’s up to the developer to do so. Here’s a quick breakdown of the requirements for a test runner: + +* Ability to load different configurations (e.g. local, test, development) and ensure that you  _NEVER_  load a production configuration — you can guess what goes wrong when that happens. + +* Lift and seed a database with dummy data for testing. This must work for various databases, whether it be MySQL, PostgreSQL, MongoDB, or any other, for that matter. + +* Ability to load fixtures (files with seed data for testing in a development environment). + +With Winds, we chose to use Mocha as our test runner. Mocha provides an easy and programmatic way to run tests on an ES6 codebase via command-line tools (integrated with Babel). + +To kick off the tests, we register the Babel module loader ourselves. This provides us with finer grain greater control over which modules are imported before Babel overrides Node.js module loading process, giving us the opportunity to mock modules before any tests are run. + +Additionally, we also use Mocha’s test runner feature to pre-assign HTTP handlers to specific requests. We do this because the normal initialization code is not run during tests (server interactions are mocked by the Chai HTTP plugin) and run some safety check to ensure we are not connecting to production databases. + +While this isn’t part of the test runner, having a fixture loader is an important part of our test suite. We examined existing solutions; however, we settled on writing our own helper so that it was tailored to our requirements. With our solution, we can load fixtures with complex data-dependencies by following an easy ad-hoc convention when generating or writing fixtures by hand. + +### Tooling for Winds + +Although the process was cumbersome, we were able to find the right balance of tools and frameworks to make proper testing become a reality for our backend API. Here’s what we chose to go with: + +### Mocha ☕ + +[Mocha][6], described as a “feature-rich JavaScript test framework running on Node.js”, was our immediate choice of tooling for the job. With well over 15k stars, many backers, sponsors, and contributors, we knew it was the right framework for the job. + +### Chai 🥃 + +Next up was our assertion library. We chose to go with the traditional approach, which is what works best with Mocha — [Chai][7]. Chai is a BDD and TDD assertion library for Node.js. With a simple API, Chai was easy to integrate into our application and allowed for us to easily assert what we should  _expect_ tobe returned from the Winds API. Best of all, writing tests feel natural with Chai. Here’s a short example: + +``` +describe('retrieve user', () => { + let user; + + before(async () => { + await loadFixture('user'); + user = await User.findOne({email: authUser.email}); + expect(user).to.not.be.null; + }); + + after(async () => { + await User.remove().exec(); + }); + + describe('valid request', () => { + it('should return 200 and the user resource, including the email field, when retrieving the authenticated user', async () => { + const response = await withLogin(request(api).get(`/users/${user._id}`), authUser); + + expect(response).to.have.status(200); + expect(response.body._id).to.equal(user._id.toString()); + }); + + it('should return 200 and the user resource, excluding the email field, when retrieving another user', async () => { + const anotherUser = await User.findOne({email: 'another_user@email.com'}); + + const response = await withLogin(request(api).get(`/users/${anotherUser.id}`), authUser); + + expect(response).to.have.status(200); + expect(response.body._id).to.equal(anotherUser._id.toString()); + expect(response.body).to.not.have.an('email'); + }); + + }); + + describe('invalid requests', () => { + + it('should return 404 if requested user does not exist', async () => { + const nonExistingId = '5b10e1c601e9b8702ccfb974'; + expect(await User.findOne({_id: nonExistingId})).to.be.null; + + const response = await withLogin(request(api).get(`/users/${nonExistingId}`), authUser); + expect(response).to.have.status(404); + }); + }); + +}); +``` + +### Sinon 🧙‍ + +With the ability to work with any unit testing framework, [Sinon][8] was our first choice for a mocking library. Again, a super clean integration with minimal setup, Sinon turns mocking requests into a simple and easy process. Their website has an extremely friendly user experience and offers up easy steps to integrate Sinon with your test suite. + +### Nock 🔮 + +For all external HTTP requests, we use [nock][9], a robust HTTP mocking library that really comes in handy when you have to communicate with a third party API (such as [Stream’s REST API][10]). There’s not much to say about this little library aside from the fact that it is awesome at what it does, and that’s why we like it. Here’s a quick example of us calling our [personalization][11] engine for Stream: + +``` +nock(config.stream.baseUrl) + .get(/winds_article_recommendations/) + .reply(200, { results: [{foreign_id:`article:${article.id}`}] }); +``` + +### Mock-require 🎩 + +The library [mock-require][12] allows dependencies on external code. In a single line of code, you can replace a module and mock-require will step in when some code attempts to import that module. It’s a small and minimalistic, but robust library, and we’re big fans. + +### Istanbul 🔭 + +[Istanbul][13] is a JavaScript code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Although we have similar functionality with CodeCov (see next section), this is a nice tool to have when running tests locally. + +### The End Result — Working Tests + + _With all of the libraries, including the test runner mentioned above, let’s have a look at what a full test looks like (you can have a look at our entire test suite _ [_here_][14] _):_ + +``` +import nock from 'nock'; +import { expect, request } from 'chai'; + +import api from '../../src/server'; +import Article from '../../src/models/article'; +import config from '../../src/config'; +import { dropDBs, loadFixture, withLogin } from '../utils.js'; + +describe('Article controller', () => { + let article; + + before(async () => { + await dropDBs(); + await loadFixture('initial-data', 'articles'); + article = await Article.findOne({}); + expect(article).to.not.be.null; + expect(article.rss).to.not.be.null; + }); + + describe('get', () => { + it('should return the right article via /articles/:articleId', async () => { + let response = await withLogin(request(api).get(`/articles/${article.id}`)); + expect(response).to.have.status(200); + }); + }); + + describe('get parsed article', () => { + it('should return the parsed version of the article', async () => { + const response = await withLogin( + request(api).get(`/articles/${article.id}`).query({ type: 'parsed' }) + ); + expect(response).to.have.status(200); + }); + }); + + describe('list', () => { + it('should return the list of articles', async () => { + let response = await withLogin(request(api).get('/articles')); + expect(response).to.have.status(200); + }); + }); + + describe('list from personalization', () => { + after(function () { + nock.cleanAll(); + }); + + it('should return the list of articles', async () => { + nock(config.stream.baseUrl) + .get(/winds_article_recommendations/) + .reply(200, { results: [{foreign_id:`article:${article.id}`}] }); + + const response = await withLogin( + request(api).get('/articles').query({ + type: 'recommended', + }) + ); + expect(response).to.have.status(200); + expect(response.body.length).to.be.at.least(1); + expect(response.body[0].url).to.eq(article.url); + }); + }); +}); +``` + +### Continuous Integration + +There are a lot of continuous integration services available, but we like to use [Travis CI][15] because they love the open-source environment just as much as we do. Given that Winds is open-source, it made for a perfect fit. + +Our integration is rather simple — we have a [.travis.yml][16] file that sets up the environment and kicks off our tests via a simple [npm][17] command. The coverage reports back to GitHub, where we have a clear picture of whether or not our latest codebase or PR passes our tests. The GitHub integration is great, as it is visible without us having to go to Travis CI to look at the results. Below is a screenshot of GitHub when viewing the PR (after tests): + +![](https://cdn-images-1.medium.com/max/1600/1*DWfI0No5wZn7BBoWtJsLoA.png) + +In addition to Travis CI, we use a tool called [CodeCov][18]. CodeCov is similar to [Istanbul][19], however, it’s a visualization tool that allows us to easily see code coverage, files changed, lines modified, and all sorts of other goodies. Though visualizing this data is possible without CodeCov, it’s nice to have everything in one spot. + +### What We Learned + +![](https://cdn-images-1.medium.com/max/1600/1*c9uadS4Rk4oQHxf9Gl6Q3g.png) + +We learned a lot throughout the process of developing our test suite. With no “correct” way of doing things, we decided to set out and create our own test flow by sorting through the available libraries to find ones that were promising enough to add to our toolbox. + +What we ultimately learned is that testing in Node.js is not as easy as it may sound. Hopefully, as Node.js continues to grow, the community will come together and build a rock solid library that handles everything test related in a “correct” manner. + +Until then, we’ll continue to use our test suite, which is open-source on the [Winds GitHub repository][20]. + +### Limitations + +#### No Easy Way to Create Fixtures + +Frameworks and languages, such as Python’s Django, have easy ways to create fixtures. With Django, for example, you can use the following commands to automate the creation of fixtures by dumping data into a file: + +The Following command will dump the whole database into a db.json file: +./manage.py dumpdata > db.json + +The Following command will dump only the content in django admin.logentry table: +./manage.py dumpdata admin.logentry > logentry.json + +The Following command will dump the content in django auth.user table: ./manage.py dumpdata auth.user > user.json + +There’s no easy way to create a fixture in Node.js. What we ended up doing is using MongoDB Compass and exporting JSON from there. This resulted in a nice fixture, as shown below (however, it was a tedious process and prone to error): + + +![](https://cdn-images-1.medium.com/max/1600/1*HvXXS57rAIfBTOQ9h1HCew.png) + +#### Unintuitive Module Loading When Using Babel, Mocked Modules, and Mocha Test-Runner + +To support a broader variety of node versions and have access to latest additions to Javascript standard, we are using Babel to transpile our ES6 codebase to ES5\. Node.js module system is based on the CommonJS standard whereas the ES6 module system has different semantics. + +Babel emulates ES6 module semantics on top of the Node.js module system, but because we are interfering with module loading by using mock-require, we are embarking on a journey through weird module loading corner cases, which seem unintuitive and can lead to multiple independent versions of the module imported and initialized and used throughout the codebase. This complicates mocking and global state management during testing. + +#### Inability to Mock Functions Used Within the Module They Are Declared in When Using ES6 Modules + +When a module exports multiple functions where one calls the other, it’s impossible to mock the function being used inside the module. The reason is that when you require an ES6 module you are presented with a separate set of references from the one used inside the module. Any attempt to rebind the references to point to new values does not really affect the code inside the module, which will continue to use the original function. + +### Final Thoughts + +Testing Node.js applications is a complicated process because the ecosystem is always evolving. It’s important to stay on top of the latest and greatest tools so you don’t fall behind. + +There are so many outlets for JavaScript related news these days that it’s hard to keep up to date with all of them. Following email newsletters such as [JavaScript Weekly][21] and [Node Weekly][22] is a good start. Beyond that, joining a subreddit such as [/r/node][23] is a great idea. If you like to stay on top of the latest trends, [State of JS][24] does a great job at helping developers visualize trends in the testing world. + +Lastly, here are a couple of my favorite blogs where articles often popup: + +* [Hacker Noon][1] + +* [Free Code Camp][2] + +* [Bits and Pieces][3] + +Think I missed something important? Let me know in the comments, or on Twitter – [@NickParsons][25]. + +Also, if you’d like to check out Stream, we have a great 5 minute tutorial on our website. Give it a shot [here][26]. + +-------------------------------------------------------------------------------- + +作者简介: + +Nick Parsons + +Dreamer. Doer. Engineer. Developer Evangelist https://getstream.io. + +-------------------------------------------------------------------------------- + +via: https://hackernoon.com/testing-node-js-in-2018-10a04dd77391 + +作者:[Nick Parsons][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://hackernoon.com/@nparsons08?source=post_header_lockup +[1]:https://hackernoon.com/ +[2]:https://medium.freecodecamp.org/ +[3]:https://blog.bitsrc.io/ +[4]:https://getstream.io/ +[5]:https://getstream.io/winds +[6]:https://github.com/mochajs/mocha +[7]:http://www.chaijs.com/ +[8]:http://sinonjs.org/ +[9]:https://github.com/node-nock/nock +[10]:https://getstream.io/docs_rest/ +[11]:https://getstream.io/personalization +[12]:https://github.com/boblauer/mock-require +[13]:https://github.com/gotwarlost/istanbul +[14]:https://github.com/GetStream/Winds/tree/master/api/test +[15]:https://travis-ci.org/ +[16]:https://github.com/GetStream/Winds/blob/master/.travis.yml +[17]:https://www.npmjs.com/ +[18]:https://codecov.io/#features +[19]:https://github.com/gotwarlost/istanbul +[20]:https://github.com/GetStream/Winds/tree/master/api/test +[21]:https://javascriptweekly.com/ +[22]:https://nodeweekly.com/ +[23]:https://www.reddit.com/r/node/ +[24]:https://stateofjs.com/2017/testing/results/ +[25]:https://twitter.com/@nickparsons +[26]:https://getstream.io/try-the-api diff --git a/sources/tech/20180706 Revisiting wallabag, an open source alternative to Instapaper.md b/sources/tech/20180706 Revisiting wallabag, an open source alternative to Instapaper.md new file mode 100644 index 0000000000..8bca52e1af --- /dev/null +++ b/sources/tech/20180706 Revisiting wallabag, an open source alternative to Instapaper.md @@ -0,0 +1,72 @@ +translating---geekpi + +Revisiting wallabag, an open source alternative to Instapaper +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/email_paper_envelope_document.png?itok=uPj_kouJ) + +Back in 2014, I [wrote about wallabag][1], an open source alternative to read-it-later applications like Instapaper and Pocket. Go take a look at that article if you want to. Don't worry, I'll wait for you. + +Done? Great! + +In the four years since I wrote that article, a lot about [wallabag][2] has changed. It's time to take a peek to see how wallabag has matured. + +### What's new + +The biggest change took place behind the scenes. Wallabag's developer Nicolas Lœuillet and the project's contributors did a lot of tinkering with the code, which improved the application. You see and feel the changes wrought by wallabag's newer codebase every time you use it. + +So what are some of those changes? There are [quite a few][3]. Here are the ones I found most interesting and useful. + +Besides making wallabag a bit snappier and more stable, the application's ability to import and export content has improved. You can import articles from Pocket and Instapaper, as well as articles marked as "To read" in bookmarking service [Pinboard][4]. You can also import Firefox and Chrome bookmarks. + +You can also export your articles in several formats including EPUB, MOBI, PDF, and plaintext. You can do that for individual articles, all your unread articles, or every article—read and unread. The version of wallabag that I used four years ago could export to EPUB and PDF, but that export was balky at times. Now, those exports are quick and smooth. + +Annotations and highlighting in the web interface now work much better and more consistently. Admittedly, I don't use them often—but they don't randomly disappear like they sometimes did with version 1 of wallabag. + +![](https://opensource.com/sites/default/files/uploads/wallabag-annotation.png) + +The look and feel of wallabag have improved, too. That's thanks to a new theme inspired by [Material Design][5]. That might not seem like a big deal, but that theme makes wallabag a bit more visually attractive and makes articles easier to scan and read. Yes, kids, good UX can make a difference. + +![](https://opensource.com/sites/default/files/uploads/wallabag-theme.png) + +One of the biggest changes was the introduction of [a hosted version][6] of wallabag. More than a few people (yours truly included) don't have a server to run web apps and aren't entirely comfortable doing that. When it comes to anything technical, I have 10 thumbs. I don't mind paying € 9 (just over US$ 10 at the time I wrote this) a year to get a fully working version of the application that I don't need to watch over. + +### What hasn't changed + +Overall, wallabag's core functions are the same. The updated codebase, as I mentioned above, makes those functions run quite a bit smoother and quicker. + +Wallabag's [browser extensions][7] do the same job in the same way. I've found that the extensions work a bit better than they did when I first tried them and when the application was at version 1. + +### What's disappointing + +The mobile app is good, but it's not great. It does a good job of rendering articles and has a few configuration options. But you can't highlight or annotate articles. That said, you can use the app to dip into your stock of archived articles. + +![](https://opensource.com/sites/default/files/uploads/wallabag-android.png) + +While wallabag does a great job collecting articles, there are sites whose content you can't save to it. I haven't run into many such sites, but there have been enough for the situation to be annoying. I'm not sure how much that has to do with wallabag. Rather, I suspect it has something to do with the way the sites are coded—I ran into the same problem while looking at a couple of proprietary read-it-later tools. + +Wallabag might not be a feature-for-feature replacement for Pocket or Instapaper, but it does a great job. It has improved noticeably in the four years since I first wrote about it. There's still room for improvement, but does what it says on the tin. + +### Final thoughts + +Since 2014, wallabag has evolved. It's gotten better, bit by bit and step by step. While it might not be a feature-for-feature replacement for the likes of Instapaper and Pocket, wallabag is a worthy open source alternative to proprietary read-it-later tools. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/wallabag + +作者:[Scott Nesbitt][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/scottnesbitt +[1]:https://opensource.com/life/14/4/open-source-read-it-later-app-wallabag +[2]:https://wallabag.org/en +[3]:https://www.wallabag.org/en/news/wallabag-v2 +[4]:https://pinboard.in +[5]:https://en.wikipedia.org/wiki/Material_Design +[6]:https://www.wallabag.it +[7]:https://github.com/wallabag/wallabagger diff --git a/sources/tech/20180706 Robolinux Lets You Easily Run Linux and Windows Without Dual Booting.md b/sources/tech/20180706 Robolinux Lets You Easily Run Linux and Windows Without Dual Booting.md new file mode 100644 index 0000000000..783aa0bd4e --- /dev/null +++ b/sources/tech/20180706 Robolinux Lets You Easily Run Linux and Windows Without Dual Booting.md @@ -0,0 +1,141 @@ +Robolinux Lets You Easily Run Linux and Windows Without Dual Booting +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/robolinux-main.jpg?itok=zsMPdGsP) + +The number of Linux distributions available just keeps getting bigger. In fact, in the time it took me to write this sentence, another one may have appeared on the market. Many Linux flavors have trouble standing out in this crowd, and some are just a different combination of puzzle pieces joined to form something new: An Ubuntu base with a KDE desktop environment. A Debian base with an Xfce desktop. The combinations go on and on. + +[Robolinux][1], however, does something unique. It’s the only distro, to my knowledge, that makes working with Windows alongside Linux a little easier for the typical user. With just a few clicks, it lets you create a Windows virtual machine (by way of VirtualBox) that can run side by side with Linux. No more dual booting. With this process, you can have Windows XP, Windows 7, or Windows 10 up and running with ease. + +And, you get all this on top of an operating system that’s pretty fantastic on its own. Robolinux not only makes short work of having Windows along for the ride, it simplifies using Linux itself. Installation is easy, and the installed collection of software means anyone can be productive right away. + +Let’s install Robolinux and see what there is to see. + +### Installation + +As I mentioned earlier, installing Robolinux is easy. Obviously, you must first [download an ISO][2] image of the operating system. You have the choice of installing a Cinnamon, Mate, LXDE, or xfce desktop (I opted to go the Mate route). I will warn you, the developers do make a pretty heavy-handed plea for donations. I don’t fault them for this. Developing an operating system takes a great deal of time. So if you have the means, do make a donation. +Once you’ve downloaded the file, burn it to a CD/DVD or flash drive. Boot your system with the media and then, once the desktop loads, click the Install icon on the desktop. As soon as the installer opens (Figure 1), you should be immediately familiar with the layout of the tool. + +![Robolinux installer][4] + +Figure 1: The Robolinux installer is quite user-friendly. + +[Used with permission][5] + +Once you’ve walked through the installer, reboot, remove the installation media, and login when prompted. I will say that I installed Robolinux as a VirtualBox VM and it installed to perfection. This however, isn’t a method you should use, if you’re going to take advantage of the Stealth VM option. After logging in, the first thing I did was install the Guest Additions and everything was working smoothly. + +### Default applications + +The collection of default applications is impressive, but not overwhelming. You’ll find all the standard tools to get your work done, including: + + * LibreOffice + + * Atril Document Viewer + + * Backups + + * GNOME Disks + + * Medit text editor + + * Seahorse + + * GIMP + + * Shotwell + + * Simple Scan + + * Firefox + + * Pidgen + + * Thunderbird + + * Transmission + + * Brasero + + * Cheese + + * Kazam + + * Rhythmbox + + * VLC + + * VirtualBox + + * And more + + + + +With that list of software, you shouldn’t want for much. However, should you find a app not installed, click on the desktop menu button and then click Package Manager, which will open Synaptic Package Manager, where you can install any of the Linux software you need. + +If that’s not enough, it’s time to take a look at the Windows side of things. + +### Installing Windows + +This is what sets Robolinux apart from other Linux distributions. If you click on the desktop menu button, you see a Stealth VM entry. Within that sub-menu, a listing of the different Windows VMs that can be installed appears (Figure 2). + +![Windows VMs][7] + +Figure 2: The available Windows VMs that can be installed alongside of Robolinux. + +[Used with permission][5] + +Before you can install one of the VMs, you must first download the Stealth VM file. To do that, double-click on the desktop icon that includes an image of the developer’s face (labeled Robo’s FREE Stealth VM). You must save that file to the ~/Downloads directory. Don’t save it anywhere else, don’t extract it, and don’t rename it. With that file in place, click the start menu and then click Stealth VM. From the listing, click the top entry, Robolinx Stealth VM Installer. When prompted, type your sudo password. You will then be prompted that the Stealth VM is ready to be used. Go back to the start menu and click Stealth VM and select the version of Windows you want to install. A new window will appear (Figure 3). Click Yes and the installation will continue. + +![Installing Windows][9] + +Figure 3: Installing Windows in the Stealth VM. + +[Used with permission][5] + +Next you will be prompted to type your sudo password again (so your user can be added to the vboxusers group). Once you’ve taken care of that, you’ll be prompted to configure the RAM you want to dedicate to the VM. After that, a browser window will appear (once again asking for a donation). At this point everything is (almost) done. Close the browser and the terminal window. + +You’re not finished. + +Next you must insert the Windows installer media that matches the type of Windows VM you installed. You then must start VirtualBox by click start menu > System Tools > Oracle VM VirtualBox. When VirtualBox opens, an entry will already be created for your Windows VM (Figure 4). + +![Windows VM][11] + +Figure 4: Your Windows VM is ready to go. + +[Used with permission][5] + +You can now click the Start button (in VirtualBox) to finish up the installation. When the Windows installation completes, you’re ready to work with Linux and Windows side-by-side. + +### Making VMs a bit more user-friendly + +You may be thinking to yourself, “Creating a virtual machine for Windows is actually easier than that!”. Although you are correct with that sentiment, not everyone knows how to create a new VM with VirtualBox. In the time it took me to figure out how to work with the Robolinux Stealth VM, I could have had numerous VMs created in VirtualBox. Additionally, this approach doesn’t happen free of charge. You do still have to have a licensed copy of Windows (as well as the installation media). But anything developers can do to make using Linux easier is a plus. That’s how I see this—a Linux distribution doing something just slightly different that could remove a possible barrier to entry for the open source platform. From my perspective, that’s a win-win. And, you’re getting a pretty solid Linux distribution to boot. + +If you already know the ins and outs of VirtualBox, Robolinux might not be your cuppa. But, if you don’t like technology getting in the way of getting your work done and you want to have a Linux distribution that includes all the necessary tools to help make you productive, Robolinux is definitely worth a look. + +Learn more about Linux through the free ["Introduction to Linux" ][12] course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/7/robolinux-lets-you-easily-run-linux-and-windows-without-dual-booting + +作者:[Jack Wallen][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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 +[1]:https://www.robolinux.org +[2]:https://www.robolinux.org/downloads/ +[3]:/files/images/robolinux1jpg +[4]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/robolinux_1.jpg?itok=MA0MD6KY (Robolinux installer) +[5]:/licenses/category/used-permission +[6]:/files/images/robolinux2jpg +[7]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/robolinux_2.jpg?itok=bHktIhhK (Windows VMs) +[8]:/files/images/robolinux3jpg +[9]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/robolinux_3.jpg?itok=B7ar6hZf (Installing Windows) +[10]:/files/images/robolinux4jpg +[11]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/robolinux_4.jpg?itok=nEOt5Vnc (Windows VM) +[12]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180706 Using Ansible to set up a workstation.md b/sources/tech/20180706 Using Ansible to set up a workstation.md new file mode 100644 index 0000000000..cc9e63b2d8 --- /dev/null +++ b/sources/tech/20180706 Using Ansible to set up a workstation.md @@ -0,0 +1,168 @@ +Using Ansible to set up a workstation +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/07/ansible-workstation-816x345.png) + +Ansible is an extremely popular [open-source configuration management and software automation project][1]. While IT professionals almost certainly use Ansible on a daily basis, its influence outside the IT industry is not as wide. Ansible is a powerful and flexible tool. It is easily applied to a task common to nearly every desktop computer user: the post-installation “checklist”. + +Most users like to apply one “tweak” after a new installation. Ansible’s idempotent, declarative syntax lends itself perfectly to describing how a system should be configured. + +### Ansible in a nutshell + +The _ansible_ program itself performs a **single task** against a set of hosts. This is roughly conceptualized as: +``` +for HOST in $HOSTS; do + ssh $HOST /usr/bin/echo "Hello World" +done + +``` + +To perform more than one task, Ansible defines the concept of a “playbook”. A playbook is a YAML file describing the _state_ of the targeted machine. When run, Ansible inspects each host and performs only the tasks necessary to enforce the state defined in the playbook. +``` +- hosts: all + tasks: + - name: Echo "Hello World" + command: echo "Hello World" + +``` + +Run the playbook using the _ansible-playbook_ command: +``` +$ ansible-playbook ~/playbook.yml + +``` + +### Configuring a workstation + +Start by installing ansible: +``` +dnf install ansible + +``` + +Next, create a file to store the playbook: +``` +touch ~/post_install.yml + +``` + +Start by defining the host on which to run this playbook. In this case, “localhost”: +``` +- hosts: localhost + +``` + +Each task consists of a _name_ field and a module field. Ansible has **a lot** of [modules][2]. Be sure to browse the module index to become familiar with all Ansible has to offer. + +#### The package module + +Most users install additional packages after a fresh install, and many like to remove some shipped software they don’t use. The _[package][3]_ module provides a generic wrapper around the system package manager (in Fedora’s case, _dnf_ ). +``` +- hosts: localhost + tasks: + - name: Install Builder + become: yes + package: + name: gnome-builder + state: present + - name: Remove Rhythmbox + become: yes + package: + name: rhythmbox + state: absent + - name: Install GNOME Music + become: yes + package: + name: gnome-music + state: present + - name: Remove Shotwell + become: yes + package: + name: shotwell + state: absent +``` + +This playbook results in the following outcomes: + + * GNOME Builder and GNOME Music are installed + * Rhythmbox is removed + * On Fedora 28 or greater, nothing happens with Shotwell (it is not in the default list of packages) + * On Fedora 27 or older, Shotwell is removed + + + +This playbook also introduces the **become: yes** directive. This specifies the task must be run by a privileged user (in most cases, _root_ ). + +#### The DConf Module + +Ansible can do a lot more than install software. For example, GNOME includes a great color-shifting feature called Night Light. It ships disabled by default, however the Ansible _[dconf][4]_ module can very easily enable it. +``` +- hosts: localhost + tasks: + - name: Enable Night Light + dconf: + key: /org/gnome/settings-daemon/plugins/color/night-light-enabled + value: true + - name: Set Night Light Temperature + dconf: + key: /org/gnome/settings-daemon/plugins/color/night-light-temperature + value: uint32 5500 +``` + +Ansible can also create files at specified locations with the _[copy][5]_ module. In this example, a local file is copied to the destination path. +``` +- hosts: localhost + tasks: + - name: Enable "AUTH_ADMIN_KEEP" for pkexec + become: yes + copy: + src: files/51-pkexec-auth-admin-keep.rules + dest: /etc/polkit-1/rules.d/51-pkexec-auth-admin-keep.rules + +``` + +#### The Command Module + +Ansible can still run commands even if no specialized module exists (via the aptly named _[command][6]_ module). This playbook enables the [Flathub][7] repository and installs a few Flatpaks. The commands are crafted in such a way that they are effectively idempotent. This is an important behavior to consider; a playbook should succeed each time it is run on a machine. +``` +- hosts: localhost + tasks: + - name: Enable Flathub repository + become: yes + command: flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + - name: Install Fractal + become: yes + command: flatpak install --assumeyes flathub org.gnome.Fractal + - name: Install Spotify + become: yes + command: flatpak install --assumeyes flathub com.spotify.Client +``` + +Combine all these tasks together into a single playbook and, in one command, ** Ansible will customize a freshly installed workstation. Not only that, but 6 months later, after making changes to the playbook, run it again to bring a “seasoned” install back to a known state. +``` +$ ansible-playbook -K ~/post_install.yml + +``` + +This article only touched the surface of what’s possible with Ansible. A follow-up article will go into more advanced Ansible concepts such as _roles,_ configuring multiple hosts with a divided set of responsibilities. + + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/using-ansible-setup-workstation/ + +作者:[Link Dupont][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/linkdupont/ +[1]:https://ansible.com +[2]:https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html +[3]:https://docs.ansible.com/ansible/latest/modules/package_module.html#package-module +[4]:https://docs.ansible.com/ansible/latest/modules/dconf_module.html#dconf-module +[5]:https://docs.ansible.com/ansible/latest/modules/copy_module.html#copy-module +[6]:https://docs.ansible.com/ansible/latest/modules/command_module.html#command-module +[7]:https://flathub.org diff --git a/sources/tech/20180708 simple and elegant free podcast player.md b/sources/tech/20180708 simple and elegant free podcast player.md new file mode 100644 index 0000000000..72e35c7029 --- /dev/null +++ b/sources/tech/20180708 simple and elegant free podcast player.md @@ -0,0 +1,119 @@ +simple and elegant free podcast player +====== + +![](https://i0.wp.com/www.linuxlinks.com/wp-content/uploads/2018/07/CPod-Subscriptions.jpg?resize=750%2C393&ssl=1) + +CPod (formerly known as Cumulonimbus) is a cross-platform, open source podcast player for the desktop. The application is built with web technologies – it’s written in the JavaScript programming language and uses the Electron framework. Electron is often (rightly?) criticized for being a memory hog and dog slow. But is that mainly because of poor programming, rather than an inherent flaw in the technology? + +CPod is available for Linux, Mac OS, and Windows. Installation was a breeze on my Ubuntu 18.04 distribution as the author conveniently provides a 64-bit deb package. If you don’t run a Debian/Ubuntu based distro, there’s an AppImage which effortlessly installs the software on all major Linux distributions. There’s also a snap package from the snapcraft website, but bizarrely (and incorrectly) flags the software as proprietary software. As CPod is released under an open source license, there’s the full source code available too. + +The deb package installs the software to /opt/CPod, although the binary is still called cumulonimbus. A bit of tidying up needed there. For Mac OS users, there’s an Apple Disk Image file. + +### Home + +![CPod Playlist][2] +First off, you cannot fail to notice the gorgeous attractive interface. Presentation is first class. + +First off, you cannot fail to notice the gorgeous attractive interface. Presentation is first class. + +The home section shows your subscribed podcasts. There are helpful filters at the top. They let you select podcasts of specified duration (handy if time is limited), you can filter by date, filter for podcasts that you’ve downloaded an offline copy, as well as podcasts that have not been listened to, you’ve started listening to, and podcasts you’ve heard to the end. + +Below the filters, there’s the option to select multiple podcasts, download local copies, add podcasts to your queue, as well as actually playing a podcast. The interface is remarkably intuitive. + +One quirk is that offline episodes are downloaded to the directory ~/.config/cumulonimbus/offline_episodes/. The downloaded podcasts are therefore not visible in the Files file manager by default (this is because the standard installation of Files does not display ‘hidden files’). It’s easy to enable hidden files in the file manager. Good news, the developer plans to add a configurable default download directory. + +There’s lots of nice touches which enhance the user experience, such as the progress bars when downloading episodes. + +### Playing a podcast + +![CPod][3] + +Here’s one of my favourite podcasts, Ubuntu Podcast, in playback. There’s visualization effects enabled; they only show when the window has focus. The visualizations don’t always display properly. There’s also the option of changing the playback speed (0.5x – 4x speed). I’m not sure why I’d want to change the playback speed though. Maybe someone could enlighten me? + +More functional is the slider that lets you skip to a specific point of the podcast although this is a tad buggy. The software is in an early stage of development. In any case, I prefer using the keyboard shortcuts to move forwards and backwards, and they work fine. Some podcasts offer links that let you skip to a particular segment; they are displayed in the large pane. + +There’s also the ability to watch video podcasts in both fullscreen and window mode. I spend most of my time listening to audio podcasts, but having full screen video podcasts is a pretty cool feature. Video playback is powered by ffmpeg. + +### Queue + +![CPod Queue][4] +There’s not much to say about the queue functionality, but it’s worth noting you can change the order of episodes simply by dragging and dropping them in the interface. It’s well implemented and really simple to use. Another tick for CPod. + +### Subscriptions + +There’s not much to say about the queue functionality, but it’s worth noting you can change the order of episodes simply by dragging and dropping them in the interface. It’s well implemented and really simple to use. Another tick for CPod. + +![CPod Subscriptions][5] + +The interface makes it really easy to subscribe and unsubscribe to podcasts. Clicking the image of a subscribed podcast lets you find an episode, as well as a list of recent episodes, again with the ability to play, queue, and download. It’s all very clean and easy to use. + +### Explore + +In explore you can search for podcasts. Just type some keywords into the Explore dialog box, and you’re presented with a list of podcasts you can listen and subscribe. + +If you’re a fan of YouTube, you’re in luck. There’s the ability to preview and subscribe to YouTube channels by pasting a channel’s URL into the Explore box. That’s great if you have YouTube channel hyperlinks handy, but some sort of YouTube channel finder would be a great addition. + +Here’s a YouTube video in action. + +![CPod YTube][6] + +### Settings + +![CPod Settings][7] + +There’s a lot you can configure in Settings. There’s functionality to: + + * Internationalization support – the ability to select the language displayed. Currently, there’s fairly limited support in this respect. Besides English, there’s Chinese, French, German, Korean, Portuguese, Portuguese (Brazilian), and Spanish available. Contributing translations is probably the easiest way for non-programmers to contribute to an open source project. + * Option to group episodes in Home by day or month. + * Keyboard shortcuts that let you skip backward, skip forward, and play/pause playback. I love my keyboard shortcuts. + * Configure different lengths of forward/backward skip. + * Enable waveform visualization – you can see examples of the visualization in our images (Playlist and Subscription sections). + * Basic gpodder.net integration (currently only subscriptions and device sync are supported; other functionality such as episodes actions and queue are planned). + * Allow pre-releases when auto-updating. + * Export subscriptions to OPML – Outline Processor Markup Language is an XML format commonly used to exchange lists of web feeds between web feed aggregators. + * Import subscriptions from OPML. + * Update podcast cover art. + * View offline episodes directory. + + + +The software has a bag of neat touches. For example, if I change the language setting, the software presents a pop up saying CPod needs to be restarted for the change to take effect. All very user-friendly. + +The Media Player Remote Interfacing Specification (MPRIS) is a standard D-Bus interface which aims to provide a common programmatic API for controlling media players. CPod offers basic MPRIS integration. + +### Summary + +CPod is another good example of what’s possible with modern web technologies. Sure, it’s got a few quirks, it’s in an early stage of development (read ‘expect to find lots of bugs’), and there’s some useful functionality waiting to be implemented. But I’m using the software on a daily basis, and will definitely keep up-to-date with developments. + +Linux already has some high quality open source podcast players. But CPod is definitely worth a download if you’re passionate about podcasts. + +**Website:** [**github.com/z————-/CPod**][8] +**Support:** +**Developer:** Zack Guard +**License:** Apache License 2.0 + +Zack Guard, CPod’s developer, is a student who lives in Hong Kong. You can buy him a coffee at ****. Unfortunately, I’m an impoverished student too. + +### Related + + +-------------------------------------------------------------------------------- + +via: https://www.linuxlinks.com/cpod-simple-elegant-free-podcast-player/ + +作者:[Luke Baker][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxlinks.com/author/luke-baker/ +[1]:https://www.linuxlinks.com/wp-content/plugins/jetpack/modules/lazy-images/images/1x1.trans.gif +[2]:https://i2.wp.com/www.linuxlinks.com/wp-content/uploads/2018/07/CPod-Playlist.jpg?resize=750%2C368&ssl=1 +[3]:https://i0.wp.com/www.linuxlinks.com/wp-content/uploads/2018/07/CPod-Main.jpg?resize=750%2C368&ssl=1 +[4]:https://i0.wp.com/www.linuxlinks.com/wp-content/uploads/2018/07/CPod-Queue.jpg?resize=750%2C368&ssl=1 +[5]:https://i0.wp.com/www.linuxlinks.com/wp-content/uploads/2018/07/CPod-Subscriptions.jpg?resize=750%2C368&ssl=1 +[6]:https://i1.wp.com/www.linuxlinks.com/wp-content/uploads/2018/07/CPod-YouTube.jpg?resize=750%2C368&ssl=1 +[7]:https://i1.wp.com/www.linuxlinks.com/wp-content/uploads/2018/07/CPod-Settings.jpg?resize=750%2C368&ssl=1 +[8]:https://github.com/z-------------/CPod diff --git a/sources/tech/20180709 5 Firefox extensions to protect your privacy.md b/sources/tech/20180709 5 Firefox extensions to protect your privacy.md new file mode 100644 index 0000000000..848856fe07 --- /dev/null +++ b/sources/tech/20180709 5 Firefox extensions to protect your privacy.md @@ -0,0 +1,54 @@ +5 Firefox extensions to protect your privacy +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/biz_cinderblock_cloud_yellowhat.jpg?itok=sJdlsYTF) + +In the wake of the Cambridge Analytica story, I took a hard look at how far I had let Facebook penetrate my online presence. As I'm generally concerned about single points of failure (or compromise), I am not one to use social logins. I use a password manager and create unique logins for every site (and you should, too). + +What I was most perturbed about was the pervasive intrusion Facebook was having on my digital life. I uninstalled the Facebook mobile app almost immediately after diving into the Cambridge Analytica story. I also [disconnected all apps, games, and websites][1] from Facebook. Yes, this will change your experience on Facebook, but it will also protect your privacy. As a veteran with friends spread out across the globe, maintaining the social connectivity of Facebook is important to me. + +I went about the task of scrutinizing other services as well. I checked Google, Twitter, GitHub, and more for any unused connected applications. But I know that's not enough. I need my browser to be proactive in preventing behavior that violates my privacy. I began the task of figuring out how best to do that. Sure, I can lock down a browser, but I need to make the sites and tools I use work while trying to keep them from leaking data. + +Following are five tools that will protect your privacy while using your browser. The first three extensions are available for Firefox and Chrome, while the latter two are only available for Firefox. + +### Privacy Badger + +[Privacy Badger][2] has been my go-to extension for quite some time. Do other content or ad blockers do a better job? Maybe. The problem with a lot of content blockers is that they are "pay for play." Meaning they have "partners" that get whitelisted for a fee. That is the antithesis of why content blockers exist. Privacy Badger is made by the Electronic Frontier Foundation (EFF), a nonprofit entity with a donation-based business model. Privacy Badger promises to learn from your browsing habits and requires minimal tuning. For example, I have only had to whitelist a handful of sites. Privacy Badger also allows granular controls of exactly which trackers are enabled on what sites. It's my #1, must-install extension, no matter the browser. + +### DuckDuckGo Privacy Essentials + +The search engine DuckDuckGo has typically been privacy-conscious. [DuckDuckGo Privacy Essentials][3] works across major mobile devices and browsers. It's unique in the sense that it grades sites based on the settings you give them. For example, Facebook gets a D, even with Privacy Protection enabled. Meanwhile, [chrisshort.net][4] gets a B with Privacy Protection enabled and a C with it disabled. If you're not keen on EFF or Privacy Badger for whatever reason, I would recommend DuckDuckGo Privacy Essentials (choose one, not both, as they essentially do the same thing). + +### HTTPS Everywhere + +[HTTPS Everywhere][5] is another extension from the EFF. According to HTTPS Everywhere, "Many sites on the web offer some limited support for encryption over HTTPS, but make it difficult to use. For instance, they may default to unencrypted HTTP or fill encrypted pages with links that go back to the unencrypted site. The HTTPS Everywhere extension fixes these problems by using clever technology to rewrite requests to these sites to HTTPS." While a lot of sites and browsers are getting better about implementing HTTPS, there are a lot of sites that still need help. HTTPS Everywhere will try its best to make sure your traffic is encrypted. + +### NoScript Security Suite + +[NoScript Security Suite][6] is not for the faint of heart. While the Firefox-only extension "allows JavaScript, Java, Flash, and other plugins to be executed only by trusted websites of your choice," it doesn't do a great job at figuring out what your choices are. But, make no mistake, a surefire way to prevent leaking data is not executing code that could leak it. NoScript enables that via its "whitelist-based preemptive script blocking." This means you will need to build the whitelist as you go for sites not already on it. Note that NoScript is only available for Firefox. + +### Facebook Container + +[Facebook Container][7] makes Firefox the only browser where I will use Facebook. "Facebook Container works by isolating your Facebook identity into a separate container that makes it harder for Facebook to track your visits to other websites with third-party cookies." This means Facebook cannot snoop on activity happening elsewhere in your browser. Suddenly those creepy ads will stop appearing so frequently (assuming you uninstalled the Facebook app from your mobile devices). Using Facebook in an isolated space will prevent any additional collection of data. Remember, you've given Facebook data already, and Facebook Container can't prevent that data from being shared. + +These are my go-to extensions for browser privacy. What are yours? Please share them in the comments. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/firefox-extensions-protect-privacy + +作者:[Chris Short][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/chrisshort +[1]:https://www.facebook.com/help/211829542181913 +[2]:https://www.eff.org/privacybadger +[3]:https://duckduckgo.com/app +[4]:https://chrisshort.net +[5]:https://www.eff.org/https-everywhere +[6]:https://noscript.net/ +[7]:https://addons.mozilla.org/en-US/firefox/addon/facebook-container/ diff --git a/sources/tech/20180709 Anbox- How To Install Google Play Store And Enable ARM (libhoudini) Support, The Easy Way.md b/sources/tech/20180709 Anbox- How To Install Google Play Store And Enable ARM (libhoudini) Support, The Easy Way.md new file mode 100644 index 0000000000..f390109123 --- /dev/null +++ b/sources/tech/20180709 Anbox- How To Install Google Play Store And Enable ARM (libhoudini) Support, The Easy Way.md @@ -0,0 +1,101 @@ +Anbox: How To Install Google Play Store And Enable ARM (libhoudini) Support, The Easy Way +====== +**[Anbox][1], or Android in a Box, is a free and open source tool that allows running Android applications on Linux.** It works by running the Android runtime environment in an LXC container, recreating the directory structure of Android as a mountable loop image, while using the native Linux kernel to execute applications. + +Its key features are security, performance, integration and convergence (scales across different form factors), according to its website. + +**Using Anbox, each Android application or game is launched in a separate window, just like system applications** , and they behave more or less like regular windows, showing up in the launcher, can be tiled, etc. + +By default, Anbox doesn't ship with the Google Play Store or support for ARM applications. To install applications you must download each app APK and install it manually using adb. Also, installing ARM applications or games doesn't work by default with Anbox - trying to install ARM apps results in the following error being displayed: +``` +Failed to install PACKAGE.NAME.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113] + +``` + +You can set up both Google Play Store and support for ARM applications (through libhoudini) manually for Android in a Box, but it's a quite complicated process. **To make it easier to install Google Play Store and Google Play Services on Anbox, and get it to support ARM applications and games (using libhoudini), the folks at[geeks-r-us.de][2] (linked article is in German) have created a [script][3] that automates these tasks.** + +Before using this, I'd like to make it clear that not all Android applications and games work in Anbox, even after integrating libhoudini for ARM support. Some Android applications and games may not show up in the Google Play Store at all, while others may be available for installation but will not work. Also, some features may not be available in some applications. + +### Install Google Play Store and enable ARM applications / games support on Anbox (Android in a Box) + +These instructions will obviously not work if Anbox is not already installed on your Linux desktop. If you haven't already, install Anbox by following the installation instructions found + +`anbox.appmgr` + +at least once after installing Anbox and before using this script, to avoid running into issues. + +1\. Install the required dependencies (`wget` , `lzip` , `unzip` and `squashfs-tools`). + +In Debian, Ubuntu or Linux Mint, use this command to install the required dependencies: +``` +sudo apt install wget lzip unzip squashfs-tools + +``` + +2\. Download and run the script that automatically downloads and installs Google Play Store (and Google Play Services) and libhoudini (for ARM apps / games support) on your Android in a Box installation. + +**Warning: never run a script you didn't write without knowing what it does. Before running this script, check out its [code][4]. ** + +To download the script, make it executable and run it on your Linux desktop, use these commands in a terminal: +``` +wget https://raw.githubusercontent.com/geeks-r-us/anbox-playstore-installer/master/install-playstore.sh +chmod +x install-playstore.sh +sudo ./install-playstore.sh + +``` + +3\. To get Google Play Store to work in Anbox, you need to enable all the permissions for both Google Play Store and Google Play Services + +To do this, run Anbox: +``` +anbox.appmgr + +``` + +Then go to `Settings > Apps > Google Play Services > Permissions` and enable all available permissions. Do the same for Google Play Store! + +You should now be able to login using a Google account into Google Play Store. + +Without enabling all permissions for Google Play Store and Google Play Services, you may encounter an issue when trying to login to your Google account, with the following error message: " _Couldn't sign in. There was a problem communicating with Google servers. Try again later_ ", as you can see in this screenshot: + +After logging in, you can disable some of the Google Play Store / Google Play Services permissions. + +**If you're encountering some connectivity issues when logging in to your Google account on Anbox,** make sure the `anbox-bride.sh` is running: + + * to start it: + + +``` +sudo /snap/anbox/current/bin/anbox-bridge.sh start + +``` + + * to restart it: + + +``` +sudo /snap/anbox/current/bin/anbox-bridge.sh restart + +``` + +You may also need to install the dnsmasq package if you continue to have connectivity issues with Anbox, according to + + +-------------------------------------------------------------------------------- + +via: https://www.linuxuprising.com/2018/07/anbox-how-to-install-google-play-store.html + +作者:[Logix][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://plus.google.com/118280394805678839070 +[1]:https://anbox.io/ +[2]:https://geeks-r-us.de/2017/08/26/android-apps-auf-dem-linux-desktop/ +[3]:https://github.com/geeks-r-us/anbox-playstore-installer/ +[4]:https://github.com/geeks-r-us/anbox-playstore-installer/blob/master/install-playstore.sh +[5]:https://docs.anbox.io/userguide/install.html +[6]:https://github.com/anbox/anbox/issues/118#issuecomment-295270113 diff --git a/sources/tech/20180709 How To Configure SSH Key-based Authentication In Linux.md b/sources/tech/20180709 How To Configure SSH Key-based Authentication In Linux.md new file mode 100644 index 0000000000..06ca1b9178 --- /dev/null +++ b/sources/tech/20180709 How To Configure SSH Key-based Authentication In Linux.md @@ -0,0 +1,225 @@ +How To Configure SSH Key-based Authentication In Linux +====== + +![](https://www.ostechnix.com/wp-content/uploads/2017/01/Configure-SSH-Key-based-Authentication-In-Linux-720x340.png) + +### What is SSH Key-based authentication? + +As we all know, **Secure Shell** , shortly **SSH** , is the cryptographic network protocol that allows you to securely communicate/access a remote system over unsecured network, for example Internet. Whenever you send a data over an unsecured network using SSH, the data will be automatically encrypted in the source system, and decrypted in the destination side. SSH provides four authentication methods namely **password-based authentication** , **key-based authentication** , **Host-based authentication** , and **Keyboard authentication**. The most commonly used authentication methods are password-based and key-based authentication. + +In password-based authentication, all you need is the password of the remote system’s user. If you know the password of remote user, you can access the respective system using **“ssh[[email protected]][1]”**. On the other hand, in key-based authentication, you need to generate SSH key pairs and upload the SSH public key to the remote system in order to communicate it via SSH. Each SSH key pair consists of a private key and public key. The private key should be kept within the client system, and the public key should uploaded to the remote systems. You shouldn’t disclose the private key to anyone. Hope you got the basic idea about SSH and its authentication methods. + +In this tutorial, we will be discussing how to configure SSH key-based authentication in Linux. + +### Configure SSH Key-based Authentication In Linux + +For the purpose of this guide, I will be using Arch Linux system as local system and Ubuntu 18.04 LTS as remote system. + +Local system details: + + * **OS** : Arch Linux Desktop + * **IP address** : 192.168.225.37 /24 + + + +Remote system details: + + * **OS** : Ubuntu 18.04 LTS Server + * **IP address** : 192.168.225.22/24 + + + +### Local system configuration + +Like I said already, in SSH key-based authentication method, the public key should be uploaded to the remote system that you want to access via SSH. The public keys will usually be stored in a file called **~/.ssh/authorized_keys** in the remote SSH systems. + +**Important note:** Do not generate key pairs as **root** , as only root would be able to use those keys. Create key pairs as normal user. + +Now, let us create the SSH key pair in the local system. To do so, run the following command in your client system. +``` +$ ssh-keygen + +``` + +The above command will create 2048 bit RSA key pair. Enter the passphrase twice. More importantly, Remember your passphrase. You’ll need it later. + +**Sample output:** +``` +Generating public/private rsa key pair. +Enter file in which to save the key (/home/sk/.ssh/id_rsa): +Enter passphrase (empty for no passphrase): +Enter same passphrase again: +Your identification has been saved in /home/sk/.ssh/id_rsa. +Your public key has been saved in /home/sk/.ssh/id_rsa.pub. +The key fingerprint is: +SHA256:wYOgvdkBgMFydTMCUI3qZaUxvjs+p2287Tn4uaZ5KyE [email protected] +The key's randomart image is: ++---[RSA 2048]----+ +|+=+*= + | +|o.o=.* = | +|.oo * o + | +|. = + . o | +|. o + . S | +| . E . | +| + o | +| +.*o+o | +| .o*=OO+ | ++----[SHA256]-----+ + +``` + +In case you have already created the key pair, you will see the following message. Just type “y” to create overwrite the existing key . +``` +/home/username/.ssh/id_rsa already exists. +Overwrite (y/n)? + +``` + +Please note that **passphrase is optional**. If you give one, you’ll be asked to enter the password every time when you try to SSH a remote system unless you are using any SSH agent to store the password. If you don’t want passphrase(not safe though), simply press ENTER key twice when you’ll be asked to enter the passphrase. However, we recommend you to use passphrase. Using a password-less ssh key is generally not a good idea from a security point of view. They should be limited to very specific cases such as services having to access a remote system without the user intervention (e.g. remote backups with rsync, …). + +If you already have a ssh key without a passphrase in private file **~/.ssh/id_rsa** and wanted to update key with passphrase, use the following command: +``` +$ ssh-keygen -p -f ~/.ssh/id_rsa + +``` + +Sample output: +``` +Enter new passphrase (empty for no passphrase): +Enter same passphrase again: +Your identification has been saved with the new passphrase. + +``` + +Now, we have created the key pair in the local system. Now, copy the SSH public key to your remote SSH server using command: + +Here, I will be copying the local (Arch Linux) system’s public key to the remote system (Ubuntu 18.04 LTS in my case). Technically speaking, the above command will copy the contents of local system’s **~/.ssh/id_rsa.pub key** into remote system’s **~/.ssh/authorized_keys** file. Clear? Good. + +Type **yes** to continue connecting to your remote SSH server. And, then Enter the root user’s password of the remote system. +``` +/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed +/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys +[email protected]2.168.225.22's password: + +Number of key(s) added: 1 + +Now try logging into the machine, with: "ssh '[email protected]'" +and check to make sure that only the key(s) you wanted were added. + +``` + +If you have already copied the key, but want to update the key with new passphrase, use **-f** option to overwrite the existing key like below. + +We have now successfully added the local system’s SSH public key to the remote system. Now, let us disable the password-based authentication completely in the remote system. Because, we have configured key-based authentication, so we don’t need password-base authentication anymore. + +### Disable SSH Password-based authentication in remote system + +You need to perform the following commands as root or sudo user. + +To disable password-based authentication, go to your remote system’s console and edit **/etc/ssh/sshd_config** configuration file using any editor: +``` +$ sudo vi /etc/ssh/sshd_config + +``` + +Find the following line. Uncomment it and set it’s value as **no**. +``` +PasswordAuthentication no + +``` + +Restart ssh service to take effect the changes. +``` +$ sudo systemctl restart sshd + +``` + +### Access Remote system from local system + +Go to your local system and SSH into your remote server using command: + +Enter the passphrase. + +**Sample output:** +``` +Enter passphrase for key '/home/sk/.ssh/id_rsa': +Last login: Mon Jul 9 09:59:51 2018 from 192.168.225.37 +[email protected]:~$ + +``` + +Now, you’ll be able to SSH into your remote system. As you noticed, we have logged-in to the remote system’s account using passphrase which we created earlier using **ssh-keygen** command, not using the actual account’s password. + +If you try to ssh from another client system, you will get this error message. Say for example, I am tried to SSH into my Ubuntu system from my CentOS using command: + +**Sample output:** +``` +The authenticity of host '192.168.225.22 (192.168.225.22)' can't be established. +ECDSA key fingerprint is 67:fc:69:b7:d4:4d:fd:6e:38:44:a8:2f:08:ed:f4:21. +Are you sure you want to continue connecting (yes/no)? yes +Warning: Permanently added '192.168.225.22' (ECDSA) to the list of known hosts. +Permission denied (publickey). + +``` + +As you see in the above output, I can’t SSH into my remote Ubuntu 18.04 systems from any other systems, except the CentOS system. + +### Adding more Client system’s keys to SSH server + +This is very important. Like I said already, you can’t access the remote system via SSH, except the one you configured (In our case, it’s Ubuntu). I want to give permissions to more clients to access the remote SSH server. What should I do? Simple. You need to generate the SSH key pair in all your client systems and copy the ssh public key manually to the remote server that you want to access via SSH. + +To create SSH key pair on your client system’s, run: +``` +$ ssh-keygen + +``` + +Enter the passphrase twice. Now, the ssh key pair is generated. You need to copy the public ssh key (not private key) to your remote server manually. + +Display the pub key using command: +``` +$ cat ~/.ssh/id_rsa.pub + +``` + +You should an output something like below. + +Copy the entire contents (via USB drive or any medium) and go to your remote server’s console. Create a directory called **ssh** in the home directory as shown below. You need to execute the following commands as root user. +``` +$ mkdir -p ~/.ssh + +``` + +Now, append the your client system’s pub key which you generated in the previous step in a file called +``` +echo {Your_public_key_contents_here} >> ~/.ssh/authorized_keys + +``` + +Restart ssh service on the remote system. Now, you’ll be able to SSH to your server from the new client. + +If manually adding ssh pubkey seems difficult, enable password-based authentication temporarily in the remote system and copy the key using “ssh-copy-id” command from your local system and finally disable the password-based authentication. + +**Suggested read:** + +And, that’s all for now. SSH Key-based authentication provides an extra layer protection from brute-force attacks. As you can see, configuring key-based authentication is not that difficult either. It is one of the recommended method to keep your Linux servers safe and secure. + +I will be here soon with another useful article. Until then, stay tuned with OSTechNix. + +Cheers! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/configure-ssh-key-based-authentication-linux/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/ +[1]:https://www.ostechnix.com/cdn-cgi/l/email-protection diff --git a/sources/tech/20180710 4 Essential and Practical Usage of Cut Command in Linux.md b/sources/tech/20180710 4 Essential and Practical Usage of Cut Command in Linux.md new file mode 100644 index 0000000000..e4bbab6e27 --- /dev/null +++ b/sources/tech/20180710 4 Essential and Practical Usage of Cut Command in Linux.md @@ -0,0 +1,543 @@ +FSSlc is translating + +4 Essential and Practical Usage of Cut Command in Linux +============================================================ + +The cut command is the canonical tool to remove “columns” from a text file. In this context, a “column” can be defined as a range of characters or bytes identified by their physical position on the line, or a range of fields delimited by a separator. + +I have written about [using AWK commands][13] earlier. In this detailed guide, I’ll explain four essential and practical examples of cut command in Linux that will help you big time. + +![Cut Linux command examples](https://i1.wp.com/linuxhandbook.com/wp-content/uploads/2018/07/cut-command-linux.jpeg?resize=702%2C395&ssl=1) + +### 4 Practical examples of Cut command in Linux + +If you prefer, you can watch this video explaining the same practical examples of cut command that I have listed in the article. + + +Table of Contents: + +* [Working with character ranges][8] + * [What’s a range?][1] + +* [Working with byte ranges][9] + * [Working with multibyte characters][2] + +* [Working with fields][10] + * [Handling lines not containing the delimiter][3] + + * [Changing the output delimiter][4] + +* [Non-POSIX GNU extensions][11] + +### 1\. Working with character ranges + +When invoked with the `-c` command line option, the cut command will remove characterranges. + +Like any other filter, the cut command does not change the input file in place but it will copy the modified data to its standard output. It is your responsibility to redirect the command output to a file to save the result or to use a pipe to send it as input to another command. + +If you’ve downloaded the [sample test files][26] used in the video above, you can see the `BALANCE.txt` data file, coming straight out of an accounting software my wife is using at her work: + +``` +sh$ head BALANCE.txt +ACCDOC ACCDOCDATE ACCOUNTNUM ACCOUNTLIB ACCDOCLIB DEBIT CREDIT +4 1012017 623477 TIDE SCHEDULE ALNEENRE-4701-LOC 00000001615,00 +4 1012017 445452 VAT BS/ENC ALNEENRE-4701-LOC 00000000323,00 +4 1012017 4356 PAYABLES ALNEENRE-4701-LOC 00000001938,00 +5 1012017 623372 ACCOMODATION GUIDE ALNEENRE-4771-LOC 00000001333,00 +5 1012017 445452 VAT BS/ENC ALNEENRE-4771-LOC 00000000266,60 +5 1012017 4356 PAYABLES ALNEENRE-4771-LOC 00000001599,60 +6 1012017 4356 PAYABLES FACT FA00006253 - BIT QUIROBEN 00000001837,20 +6 1012017 445452 VAT BS/ENC FACT FA00006253 - BIT QUIROBEN 00000000306,20 +6 1012017 623795 TOURIST GUIDE BOOK FACT FA00006253 - BIT QUIROBEN 00000001531,00 +``` + +This is a fixed-width text file since the data fields are padded with a variable number of spaces to ensure they are displayed as a nicely aligned table. + +As a corollary, a data column always starts and ends at the same character position on each line. There is a little pitfall though: despite its name, the `cut` command actually requires you to specify the range of data you want to  _keep_ , not the range you want to  _remove_ . So, if I need  _only_  the `ACCOUNTNUM` and `ACCOUNTLIB` columns in the data file above, I would write that: + +``` +sh$ cut -c 25-59 BALANCE.txt | head +ACCOUNTNUM ACCOUNTLIB +623477 TIDE SCHEDULE +445452 VAT BS/ENC +4356 /accountPAYABLES +623372 ACCOMODATION GUIDE +445452 VAT BS/ENC +4356 PAYABLES +4356 PAYABLES +445452 VAT BS/ENC +623795 TOURIST GUIDE BOOK +``` + +#### What’s a range? + +As we have just seen it, the cut command requires we specify the  _range_  of data we want to keep. So, let’s introduce more formally what is a range: for the `cut` command, a range is defined by a starting and ending position separated by a hyphen. Ranges are 1-based, that is the first item of the line is the item number 1, not 0\. Ranges are inclusive: the start and end will be preserved in the output, as well as all characters between them. It is an error to specify a range whose ending position is before (“lower”) than its starting position. As a shortcut, you can omit the start  _or_  end value as described in the table below: + + +||| +|--|--| +| `a-b` | the range between a and b (inclusive) | +|`a` | equivalent to the range `a-a` | +| `-b` | equivalent to `1-a` | +| `b-` | equivalent to `b-∞` | + +The cut commands allow you to specify several ranges by separating them with a comma. Here are a couple of examples: + +``` +# Keep characters from 1 to 24 (inclusive) +cut -c -24 BALANCE.txt + +# Keep characters from 1 to 24 and 36 to 59 (inclusive) +cut -c -24,36-59 BALANCE.txt + +# Keep characters from 1 to 24, 36 to 59 and 93 to the end of the line (inclusive) +cut -c -24,36-59,93- BALANCE.txt +``` + +One limitation (or feature, depending on the way you see it) of the `cut` command is it will  _never reorder the data_ . So the following command will produce exactly the same result as the previous one, despite the ranges being specified in a different order: + +``` +cut -c 93-,-24,36-59 BALANCE.txt +``` + +You can check that easily using the `diff` command: + +``` +diff -s <(cut -c -24,36-59,93- BALANCE.txt) \ + <(cut -c 93-,-24,36-59 BALANCE.txt) +Files /dev/fd/63 and /dev/fd/62 are identical +``` + +Similarly, the `cut` command  _never duplicates data_ : + +``` +# One might expect that could be a way to repeat +# the first column three times, but no... +cut -c -10,-10,-10 BALANCE.txt | head -5 +ACCDOC +4 +4 +4 +5 +``` + +Worth mentioning there was a proposal for a `-o` option to lift those two last limitations, allowing the `cut` utility to reorder or duplicate data. But this was [rejected by the POSIX committee][14] _“because this type of enhancement is outside the scope of the IEEE P1003.2b draft standard.”_ + +As of myself, I don’t know any cut version implementing that proposal as an extension. But if you do, please, share that with us using the comment section! + +### 2\. Working with byte ranges + +When invoked with the `-b` command line option, the cut command will remove byte ranges. + +At first sight, there is no obvious difference between  _character_  and  _byte_  ranges: + +``` +sh$ diff -s <(cut -b -24,36-59,93- BALANCE.txt) \ + <(cut -c -24,36-59,93- BALANCE.txt) +Files /dev/fd/63 and /dev/fd/62 are identical +``` + +That’s because my sample data file is using the [US-ASCII character encoding][27] (“charset”) as the `file -i` command can correctly guess it: + +``` +sh$ file -i BALANCE.txt +BALANCE.txt: text/plain; charset=us-ascii +``` + +In that character encoding, there is a one-to-one mapping between characters and bytes. Using only one byte, you can theoretically encode up to 256 different characters (digits, letters, punctuations, symbols, … ) In practice, that number is much lower since character encodings make provision for some special values (like the 32 or 65 [control characters][28]generally found). Anyway, even if we could use the full byte range, that would be far from enough to store the variety of human writing. So, today, the one-to-one mapping between characters and byte is more the exception than the norm and is almost always replaced by the ubiquitous UTF-8 multibyte encoding. Let’s see now how the cut command could handle that. + +#### Working with multibyte characters + +As I said previously, the sample data files used as examples for that article are coming from an accounting software used by my wife. It appends she updated that software recently and, after that, the exported text files were subtlely different. I let you try spotting the difference by yourself: + +``` +sh$ head BALANCE-V2.txt +ACCDOC ACCDOCDATE ACCOUNTNUM ACCOUNTLIB ACCDOCLIB DEBIT CREDIT +4 1012017 623477 TIDE SCHEDULE ALNÉENRE-4701-LOC 00000001615,00 +4 1012017 445452 VAT BS/ENC ALNÉENRE-4701-LOC 00000000323,00 +4 1012017 4356 PAYABLES ALNÉENRE-4701-LOC 00000001938,00 +5 1012017 623372 ACCOMODATION GUIDE ALNÉENRE-4771-LOC 00000001333,00 +5 1012017 445452 VAT BS/ENC ALNÉENRE-4771-LOC 00000000266,60 +5 1012017 4356 PAYABLES ALNÉENRE-4771-LOC 00000001599,60 +6 1012017 4356 PAYABLES FACT FA00006253 - BIT QUIROBEN 00000001837,20 +6 1012017 445452 VAT BS/ENC FACT FA00006253 - BIT QUIROBEN 00000000306,20 +6 1012017 623795 TOURIST GUIDE BOOK FACT FA00006253 - BIT QUIROBEN 00000001531,00 +``` + +The title of this section might help you in finding what has changed. But, found or not, let see now the consequences of that change: + +``` +sh$ cut -c 93-,-24,36-59 BALANCE-V2.txt +ACCDOC ACCDOCDATE ACCOUNTLIB DEBIT CREDIT +4 1012017 TIDE SCHEDULE 00000001615,00 +4 1012017 VAT BS/ENC 00000000323,00 +4 1012017 PAYABLES 00000001938,00 +5 1012017 ACCOMODATION GUIDE 00000001333,00 +5 1012017 VAT BS/ENC 00000000266,60 +5 1012017 PAYABLES 00000001599,60 +6 1012017 PAYABLES 00000001837,20 +6 1012017 VAT BS/ENC 00000000306,20 +6 1012017 TOURIST GUIDE BOOK 00000001531,00 +19 1012017 SEMINAR FEES 00000000080,00 +19 1012017 PAYABLES 00000000080,00 +28 1012017 MAINTENANCE 00000000746,58 +28 1012017 VAT BS/ENC 00000000149,32 +28 1012017 PAYABLES 00000000895,90 +31 1012017 PAYABLES 00000000240,00 +31 1012017 VAT BS/DEBIT 00000000040,00 +31 1012017 ADVERTISEMENTS 00000000200,00 +32 1012017 WATER 00000000202,20 +32 1012017 VAT BS/DEBIT 00000000020,22 +32 1012017 WATER 00000000170,24 +32 1012017 VAT BS/DEBIT 00000000009,37 +32 1012017 PAYABLES 00000000402,03 +34 1012017 RENTAL COSTS 00000000018,00 +34 1012017 PAYABLES 00000000018,00 +35 1012017 MISCELLANEOUS CHARGES 00000000015,00 +35 1012017 VAT BS/DEBIT 00000000003,00 +35 1012017 PAYABLES 00000000018,00 +36 1012017 LANDLINE TELEPHONE 00000000069,14 +36 1012017 VAT BS/ENC 00000000013,83 +``` + +I have copied above the command output  _in-extenso_  so it should be obvious something has gone wrong with the column alignment. + +The explanation is the original data file contained only US-ASCII characters (symbol, punctuations, numbers and Latin letters without any diacritical marks) + +But if you look closely at the file produced after the software update, you can see that new export data file now preserves accented letters. For example, the company named “ALNÉENRE” is now properly spelled whereas it was previously exported as “ALNEENRE” (no accent) + +The `file -i` utility did not miss that change since it reports now the file as being [UTF-8 encoded][15]: + +``` +sh$ file -i BALANCE-V2.txt +BALANCE-V2.txt: text/plain; charset=utf-8 +``` + +To see how are encoded accented letters in an UTF-8 file, we can use the `[hexdump][12]` utility that allows us to look directly at the bytes in a file: + +``` +# To reduce clutter, let's focus only on the second line of the file +sh$ sed '2!d' BALANCE-V2.txt +4 1012017 623477 TIDE SCHEDULE ALNÉENRE-4701-LOC 00000001615,00 +sh$ sed '2!d' BALANCE-V2.txt | hexdump -C +00000000 34 20 20 20 20 20 20 20 20 20 31 30 31 32 30 31 |4 101201| +00000010 37 20 20 20 20 20 20 20 36 32 33 34 37 37 20 20 |7 623477 | +00000020 20 20 20 54 49 44 45 20 53 43 48 45 44 55 4c 45 | TIDE SCHEDULE| +00000030 20 20 20 20 20 20 20 20 20 20 20 41 4c 4e c3 89 | ALN..| +00000040 45 4e 52 45 2d 34 37 30 31 2d 4c 4f 43 20 20 20 |ENRE-4701-LOC | +00000050 20 20 20 20 20 20 20 20 20 20 20 20 20 30 30 30 | 000| +00000060 30 30 30 30 31 36 31 35 2c 30 30 20 20 20 20 20 |00001615,00 | +00000070 20 20 20 20 20 20 20 20 20 20 20 0a | .| +0000007c +``` + +On the line 00000030 of the `hexdump` output, after a bunch of spaces (byte `20`), you can see: + +* the letter `A` is encoded as the byte `41`, + +* the letter `L` is encoded a the byte `4c`, + +* and the letter `N` is encoded as the byte `4e`. + +But, the uppercase [LATIN CAPITAL LETTER E WITH ACUTE][16] (as it is the official name of the letter  _É_  in the Unicode standard) is encoded using the  _two_  bytes `c3 89` + +And here is the problem: using the `cut` command with ranges expressed as byte positions works well for fixed length encodings, but not for variable length ones like UTF-8 or [Shift JIS][17]. This is clearly explained in the following [non-normative extract of the POSIX standard][18]: + +> Earlier versions of the cut utility worked in an environment where bytes and characters were considered equivalent (modulo and processing in some implementations). In the extended world of multi-byte characters, the new -b option has been added. + +Hey, wait a minute! I wasn’t using the `-b` option in the “faulty” example above, but the `-c`option. So,  _shouldn’t_  that have worked?!? + +Yes, it  _should_ : it is unfortunate, but we are in 2018 and despite that, as of GNU Coreutils 8.30, the GNU implementation of the cut utility still does not handle multi-byte characters properly. To quote the [GNU documentation][19], the `-c` option is  _“The same as -b for now, but internationalization will change that[… ]”_  — a mention that is present since more than 10 years now! + +On the other hand, the [OpenBSD][20] implementation of the cut utility is POSIX compliant, and will honor the current locale settings to handle multi-byte characters properly: + +``` +# Ensure subseauent commands will know we are using UTF-8 encoded +# text files +openbsd-6.3$ export LC_CTYPE=en_US.UTF-8 + +# With the `-c` option, cut works properly with multi-byte characters +openbsd-6.3$ cut -c -24,36-59,93- BALANCE-V2.txt +ACCDOC ACCDOCDATE ACCOUNTLIB DEBIT CREDIT +4 1012017 TIDE SCHEDULE 00000001615,00 +4 1012017 VAT BS/ENC 00000000323,00 +4 1012017 PAYABLES 00000001938,00 +5 1012017 ACCOMODATION GUIDE 00000001333,00 +5 1012017 VAT BS/ENC 00000000266,60 +5 1012017 PAYABLES 00000001599,60 +6 1012017 PAYABLES 00000001837,20 +6 1012017 VAT BS/ENC 00000000306,20 +6 1012017 TOURIST GUIDE BOOK 00000001531,00 +19 1012017 SEMINAR FEES 00000000080,00 +19 1012017 PAYABLES 00000000080,00 +28 1012017 MAINTENANCE 00000000746,58 +28 1012017 VAT BS/ENC 00000000149,32 +28 1012017 PAYABLES 00000000895,90 +31 1012017 PAYABLES 00000000240,00 +31 1012017 VAT BS/DEBIT 00000000040,00 +31 1012017 ADVERTISEMENTS 00000000200,00 +32 1012017 WATER 00000000202,20 +32 1012017 VAT BS/DEBIT 00000000020,22 +32 1012017 WATER 00000000170,24 +32 1012017 VAT BS/DEBIT 00000000009,37 +32 1012017 PAYABLES 00000000402,03 +34 1012017 RENTAL COSTS 00000000018,00 +34 1012017 PAYABLES 00000000018,00 +35 1012017 MISCELLANEOUS CHARGES 00000000015,00 +35 1012017 VAT BS/DEBIT 00000000003,00 +35 1012017 PAYABLES 00000000018,00 +36 1012017 LANDLINE TELEPHONE 00000000069,14 +36 1012017 VAT BS/ENC 00000000013,83 +``` + +As expected, when using the `-b` byte mode instead of the `-c` character mode, the OpenBSD cut implementation behave like the legacy `cut`: + +``` +openbsd-6.3$ cut -b -24,36-59,93- BALANCE-V2.txt +ACCDOC ACCDOCDATE ACCOUNTLIB DEBIT CREDIT +4 1012017 TIDE SCHEDULE 00000001615,00 +4 1012017 VAT BS/ENC 00000000323,00 +4 1012017 PAYABLES 00000001938,00 +5 1012017 ACCOMODATION GUIDE 00000001333,00 +5 1012017 VAT BS/ENC 00000000266,60 +5 1012017 PAYABLES 00000001599,60 +6 1012017 PAYABLES 00000001837,20 +6 1012017 VAT BS/ENC 00000000306,20 +6 1012017 TOURIST GUIDE BOOK 00000001531,00 +19 1012017 SEMINAR FEES 00000000080,00 +19 1012017 PAYABLES 00000000080,00 +28 1012017 MAINTENANCE 00000000746,58 +28 1012017 VAT BS/ENC 00000000149,32 +28 1012017 PAYABLES 00000000895,90 +31 1012017 PAYABLES 00000000240,00 +31 1012017 VAT BS/DEBIT 00000000040,00 +31 1012017 ADVERTISEMENTS 00000000200,00 +32 1012017 WATER 00000000202,20 +32 1012017 VAT BS/DEBIT 00000000020,22 +32 1012017 WATER 00000000170,24 +32 1012017 VAT BS/DEBIT 00000000009,37 +32 1012017 PAYABLES 00000000402,03 +34 1012017 RENTAL COSTS 00000000018,00 +34 1012017 PAYABLES 00000000018,00 +35 1012017 MISCELLANEOUS CHARGES 00000000015,00 +35 1012017 VAT BS/DEBIT 00000000003,00 +35 1012017 PAYABLES 00000000018,00 +36 1012017 LANDLINE TELEPHONE 00000000069,14 +36 1012017 VAT BS/ENC 00000000013,83 +``` + +### 3\. Working with fields + +In some sense, working with fields in a delimited text file is easier for the `cut` utility, since it will only have to locate the (one byte) field delimiters on each row, copying then verbatim the field content to the output without bothering with any encoding issues. + +Here is a sample delimited text file: + +``` +sh$ head BALANCE.csv +ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;ACCDOCLIB;DEBIT;CREDIT +4;1012017;623477;TIDE SCHEDULE;ALNEENRE-4701-LOC;00000001615,00; +4;1012017;445452;VAT BS/ENC;ALNEENRE-4701-LOC;00000000323,00; +4;1012017;4356;PAYABLES;ALNEENRE-4701-LOC;;00000001938,00 +5;1012017;623372;ACCOMODATION GUIDE;ALNEENRE-4771-LOC;00000001333,00; +5;1012017;445452;VAT BS/ENC;ALNEENRE-4771-LOC;00000000266,60; +5;1012017;4356;PAYABLES;ALNEENRE-4771-LOC;;00000001599,60 +6;1012017;4356;PAYABLES;FACT FA00006253 - BIT QUIROBEN;;00000001837,20 +6;1012017;445452;VAT BS/ENC;FACT FA00006253 - BIT QUIROBEN;00000000306,20; +6;1012017;623795;TOURIST GUIDE BOOK;FACT FA00006253 - BIT QUIROBEN;00000001531,00; +``` + +You may know that file format as [CSV][29] (for Comma-separated Value), even if the field separator is not always a comma. For example, the semi-colon (`;`) is frequently encountered as a field separator, and it is often the default choice when exporting data as “CSV” in countries already using the comma as the [decimal separator][30] (like we do in France — hence the choice of that character in my sample file). Another popular variant uses a [tab character][31] as the field separator, producing what is sometimes called a [tab-separated values][32] file. Finally, in the Unix and Linux world, the colon (`:`) is yet another relatively common field separator you may find, for example, in the standard `/etc/passwd` and `/etc/group` files. + +When using a delimited text file format, you provide to the cut command the range of fields to keep using the `-f` option, and you have to specify the delimiter using the `-d` option (without the `-d` option, the cut utility defaults to a tab character for the separator): + +``` +sh$ cut -f 5- -d';' BALANCE.csv | head +ACCDOCLIB;DEBIT;CREDIT +ALNEENRE-4701-LOC;00000001615,00; +ALNEENRE-4701-LOC;00000000323,00; +ALNEENRE-4701-LOC;;00000001938,00 +ALNEENRE-4771-LOC;00000001333,00; +ALNEENRE-4771-LOC;00000000266,60; +ALNEENRE-4771-LOC;;00000001599,60 +FACT FA00006253 - BIT QUIROBEN;;00000001837,20 +FACT FA00006253 - BIT QUIROBEN;00000000306,20; +FACT FA00006253 - BIT QUIROBEN;00000001531,00; +``` + +#### Handling lines not containing the delimiter + +But what if some line in the input file does not contain the delimiter? It is tempting to imagine that as a row containing only the first field. But this is  _not_  what the cut utility does. + +By default, when using the `-f` option, the cut utility will always output verbatim a line that does not contain the delimiter (probably assuming this is a non-data row like a header or comment of some sort): + +``` +sh$ (echo "# 2018-03 BALANCE"; cat BALANCE.csv) > BALANCE-WITH-HEADER.csv + +sh$ cut -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5 +# 2018-03 BALANCE +DEBIT;CREDIT +00000001615,00; +00000000323,00; +;00000001938,00 +``` + +Using the `-s` option, you can reverse that behavior, so `cut` will always ignore such line: + +``` +sh$ cut -s -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5 +DEBIT;CREDIT +00000001615,00; +00000000323,00; +;00000001938,00 +00000001333,00; +``` + +If you are in a hackish mood, you can exploit that feature as a relatively obscure way to keep only lines containing a given character: + +``` +# Keep lines containing a `e` +sh$ printf "%s\n" {mighty,bold,great}-{condor,monkey,bear} | cut -s -f 1- -d'e' +``` + +#### Changing the output delimiter + +As an extension, the GNU implementation of cut allows to use a different field separator for the output using the `--output-delimiter` option: + +``` +sh$ cut -f 5,6- -d';' --output-delimiter="*" BALANCE.csv | head +ACCDOCLIB*DEBIT*CREDIT +ALNEENRE-4701-LOC*00000001615,00* +ALNEENRE-4701-LOC*00000000323,00* +ALNEENRE-4701-LOC**00000001938,00 +ALNEENRE-4771-LOC*00000001333,00* +ALNEENRE-4771-LOC*00000000266,60* +ALNEENRE-4771-LOC**00000001599,60 +FACT FA00006253 - BIT QUIROBEN**00000001837,20 +FACT FA00006253 - BIT QUIROBEN*00000000306,20* +FACT FA00006253 - BIT QUIROBEN*00000001531,00* +``` + +Notice, in that case, all occurrences of the field separator are replaced, and not only those at the boundary of the ranges specified on the command line arguments. + +### 4\. Non-POSIX GNU extensions + +Speaking of non-POSIX GNU extension, a couple of them that can be particularly useful. Worth mentioning the following extensions work equally well with the byte, character (for what that means in the current GNU implementation) or field ranges: + +Think of that option like the exclamation mark in a sed address (`!`); instead of keeping the data matching the given range, `cut` will keep data NOT matching the range + +``` +# Keep only field 5 +sh$ cut -f 5 -d';' BALANCE.csv |head -3 +ACCDOCLIB +ALNEENRE-4701-LOC +ALNEENRE-4701-LOC + +# Keep all but field 5 +sh$ cut --complement -f 5 -d';' BALANCE.csv |head -3 +ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;DEBIT;CREDIT +4;1012017;623477;TIDE SCHEDULE;00000001615,00; +4;1012017;445452;VAT BS/ENC;00000000323,00; +``` + +use the [NUL character][6] as the line terminator instead of the [newline character][7]. The `-z`option is particularly useful when your data may contain embedded newline characters, like when working with filenames (since newline is a valid character in a filename, but NUL isn’t). + + +To show you how the `-z` option works, let’s make a little experiment. First, we will create a file whose name contains embedded new lines: + +``` +bash$ touch $'EMPTY\nFILE\nWITH FUNKY\nNAME'.txt +bash$ ls -1 *.txt +BALANCE.txt +BALANCE-V2.txt +EMPTY?FILE?WITH FUNKY?NAME.txt +``` + +Let’s now assume I want to display the first 5 characters of each `*.txt` file name. A naive solution will miserably fail here: + +``` +sh$ ls -1 *.txt | cut -c 1-5 +BALAN +BALAN +EMPTY +FILE +WITH +NAME. +``` + +You may have already read `[ls][21]` was designed for [human consumption][33], and using it in a command pipeline is an anti-pattern (it is indeed). So let’s use the `[find][22]` command instead: + +``` +sh$ find . -name '*.txt' -printf "%f\n" | cut -c 1-5 +BALAN +EMPTY +FILE +WITH +NAME. +BALAN +``` + +and … that produced basically the same erroneous result as before (although in a different order because `ls` implicitly sorts the filenames, something the `find` command does not do) + +The problem is in both cases, the `cut` command can’t make the distinction between a newline character being part of a data field (the filename), and a newline character used as an end of record marker. But, using the NUL byte (`\0`) as the line terminator clears the confusion so we can finally obtain the expected result: + +``` +# I was told (?) some old versions of tr require using \000 instead of \0 +# to denote the NUL character (let me know if you needed that change!) +sh$ find . -name '*.txt' -printf "%f\0" | cut -z -c 1-5| tr '\0' '\n' +BALAN +EMPTY +BALAN +``` + +With that latest example, we are moving away from the core of this article that was the `cut`command. So, I will let you try to figure by yourself the meaning of the funky `"%f\0"` after the `-printf` argument of the `find` command or why I used the `[tr][23]` command at the end of the pipeline. + +### A lot more can be done with Cut command + +I just showed the most common and in my opinion the most essential usage of Cut command. You can apply the command in even more practical ways. It depends on your logical reasoning and imagination. + +Don’t hesitate to use the comment section below to post your findings. And, as always, if you like this article, don’t forget to share it on your favorite websites and social media! + +-------------------------------------------------------------------------------- + +via: https://linuxhandbook.com/cut-command/ + +作者:[Sylvain Leroux ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://linuxhandbook.com/author/sylvain/ +[1]:https://linuxhandbook.com/cut-command/#_what_s_a_range +[2]:https://linuxhandbook.com/cut-command/#_working_with_multibyte_characters +[3]:https://linuxhandbook.com/cut-command/#_handling_lines_not_containing_the_delimiter +[4]:https://linuxhandbook.com/cut-command/#_changing_the_output_delimiter +[5]:http://click.linksynergy.com/deeplink?id=IRL8ozn3lq8&type=10&mid=39197&murl=https%3A%2F%2Fwww.udemy.com%2Fyes-i-know-the-bash-linux-command-line-tools%2F +[6]:https://en.wikipedia.org/wiki/Null_character +[7]:https://en.wikipedia.org/wiki/Newline +[8]:https://linuxhandbook.com/cut-command/#_working_with_character_ranges +[9]:https://linuxhandbook.com/cut-command/#_working_with_byte_ranges +[10]:https://linuxhandbook.com/cut-command/#_working_with_fields +[11]:https://linuxhandbook.com/cut-command/#_non_posix_gnu_extensions +[12]:https://linux.die.net/man/1/hexdump +[13]:https://linuxhandbook.com/awk-command-tutorial/ +[14]:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_18 +[15]:https://en.wikipedia.org/wiki/UTF-8#Codepage_layout +[16]:https://www.fileformat.info/info/unicode/char/00c9/index.htm +[17]:https://en.wikipedia.org/wiki/Shift_JIS#Shift_JIS_byte_map +[18]:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_16 +[19]:https://www.gnu.org/software/coreutils/manual/html_node/cut-invocation.html#cut-invocation +[20]:https://www.openbsd.org/ +[21]:https://linux.die.net/man/1/ls +[22]:https://linux.die.net/man/1/find +[23]:https://linux.die.net/man/1/tr +[24]:https://linuxhandbook.com/author/sylvain/ +[25]:https://linuxhandbook.com/cut-command/#comments +[26]:https://static.yesik.it/EP22/Yes_I_Know_IT-EP22.tar.gz +[27]:https://en.wikipedia.org/wiki/ASCII#Character_set +[28]:https://en.wikipedia.org/wiki/Control_character +[29]:https://en.wikipedia.org/wiki/Comma-separated_values +[30]:https://en.wikipedia.org/wiki/Decimal_separator +[31]:https://en.wikipedia.org/wiki/Tab_key#Tab_characters +[32]:https://en.wikipedia.org/wiki/Tab-separated_values +[33]:http://lists.gnu.org/archive/html/coreutils/2014-02/msg00005.html diff --git a/sources/tech/20180710 How To View Detailed Information About A Package In Linux.md b/sources/tech/20180710 How To View Detailed Information About A Package In Linux.md new file mode 100644 index 0000000000..86ba067463 --- /dev/null +++ b/sources/tech/20180710 How To View Detailed Information About A Package In Linux.md @@ -0,0 +1,408 @@ +Translating by DavidChenLiang + + + +How To View Detailed Information About A Package In Linux +====== +This is know topic and we can write so many articles because most of the time we would stick with package managers for many reasons. + +Each distribution clones has their own package manager, each has comes with their unique features that allow users to perform many actions such as installing new software packages, removing unnecessary software packages, updating the existing software packages, searching for specific software packages, and updating the system to latest available version, etc. + +Whoever is sticking with command-line most of the time they would preferring the CLI based package managers. The major CLI package managers for Linux are Yum, Dnf, Rpm,Apt, Apt-Get, Deb, pacman and zypper. + +**Suggested Read :** +**(#)** [List of Command line Package Managers For Linux & Usage][1] +**(#)** [A Graphical frontend tool for Linux Package Manager][2] +**(#)** [How To Search If A Package Is Available On Your Linux Distribution Or Not][3] +**(#)** [How To Add, Enable And Disable A Repository By Using The DNF/YUM Config Manager Command On Linux][4] + +As a system administrator you should aware of from where packages are coming, which repository, version of the package, size of the package, release, package source url, license info, etc,. + +This will help you to understand the package usage in simple way since it’s coming with package summary & Description. Run the below commands based on your distribution to get detailed information about given package. + +### [YUM Command][5] : View Package Information On RHEL & CentOS Systems + +YUM stands for Yellowdog Updater, Modified is an open-source command-line front-end package-management utility for RPM based systems such as Red Hat Enterprise Linux (RHEL) and CentOS. + +Yum is the primary tool for getting, installing, deleting, querying, and managing RPM packages from distribution repositories, as well as other third-party repositories. +``` +# yum info python +Loaded plugins: fastestmirror, security +Loading mirror speeds from cached hostfile + * epel: epel.mirror.constant.com +Installed Packages +Name : python +Arch : x86_64 +Version : 2.6.6 +Release : 66.el6_8 +Size : 78 k +Repo : installed +From repo : updates +Summary : An interpreted, interactive, object-oriented programming language +URL : http://www.python.org/ +License : Python +Description : Python is an interpreted, interactive, object-oriented programming + : language often compared to Tcl, Perl, Scheme or Java. Python includes + : modules, classes, exceptions, very high level dynamic data types and + : dynamic typing. Python supports interfaces to many system calls and + : libraries, as well as to various windowing systems (X11, Motif, Tk, + : Mac and MFC). + : + : Programmers can write new built-in modules for Python in C or C++. + : Python can be used as an extension language for applications that need + : a programmable interface. + : + : Note that documentation for Python is provided in the python-docs + : package. + : + : This package provides the "python" executable; most of the actual + : implementation is within the "python-libs" package. + +``` + +### YUMDB Command : View Package Information On RHEL & CentOS Systems + +Yumdb info provides information similar to yum info but additionally it provides package checksum data, type, user info (who installed the package). Since yum 3.2.26 yum has started storing additional information outside of the rpmdatabase (where user indicates it was installed by the user, and dep means it was brought in as a dependency). +``` +# yumdb info python +Loaded plugins: fastestmirror +python-2.6.6-66.el6_8.x86_64 + changed_by = 4294967295 + checksum_data = 53c75a1756e5b4f6564c5229a37948c9b4561e0bf58076bd7dab7aff85a417f2 + checksum_type = sha256 + command_line = update -y + from_repo = updates + from_repo_revision = 1488370672 + from_repo_timestamp = 1488371100 + installed_by = 4294967295 + reason = dep + releasever = 6 + + +``` + +### [RPM Command][6] : View Package Information On RHEL/CentOS/Fedora Systems + +RPM stands for Red Hat Package Manager is a powerful, command line Package Management utility for Red Hat based system such as (RHEL, CentOS, Fedora, openSUSE & Mageia) distributions. The utility allow you to install, upgrade, remove, query & verify the software on your Linux system/server. RPM files comes with .rpm extension. RPM package built with required libraries and dependency which will not conflicts other packages were installed on your system. +``` +# rpm -qi nano +Name : nano Relocations: (not relocatable) +Version : 2.0.9 Vendor: CentOS +Release : 7.el6 Build Date: Fri 12 Nov 2010 02:18:36 AM EST +Install Date: Fri 03 Mar 2017 08:57:47 AM EST Build Host: c5b2.bsys.dev.centos.org +Group : Applications/Editors Source RPM: nano-2.0.9-7.el6.src.rpm +Size : 1588347 License: GPLv3+ +Signature : RSA/8, Sun 03 Jul 2011 12:46:50 AM EDT, Key ID 0946fca2c105b9de +Packager : CentOS BuildSystem +URL : http://www.nano-editor.org +Summary : A small text editor +Description : +GNU nano is a small and friendly text editor. + +``` + +### [DNF Command][7] : View Package Information On Fedora System + +DNF stands for Dandified yum. We can tell DNF, the next generation of yum package manager (Fork of Yum) using hawkey/libsolv library for backend. Aleš Kozumplík started working on DNF since Fedora 18 and its implemented/launched in Fedora 22 finally. Dnf command is used to install, update, search & remove packages on Fedora 22 and later system. It automatically resolve dependencies and make it smooth package installation without any trouble. +``` +$ dnf info tilix +Last metadata expiration check: 27 days, 10:00:23 ago on Wed 04 Oct 2017 06:43:27 AM IST. +Installed Packages +Name : tilix +Version : 1.6.4 +Release : 1.fc26 +Arch : x86_64 +Size : 3.6 M +Source : tilix-1.6.4-1.fc26.src.rpm +Repo : @System +From repo : @commandline +Summary : Tiling terminal emulator +URL : https://github.com/gnunn1/tilix +License : MPLv2.0 and GPLv3+ and CC-BY-SA +Description : Tilix is a tiling terminal emulator with the following features: + : + : - Layout terminals in any fashion by splitting them horizontally or vertically + : - Terminals can be re-arranged using drag and drop both within and between + : windows + : - Terminals can be detached into a new window via drag and drop + : - Input can be synchronized between terminals so commands typed in one + : terminal are replicated to the others + : - The grouping of terminals can be saved and loaded from disk + : - Terminals support custom titles + : - Color schemes are stored in files and custom color schemes can be created by + : simply creating a new file + : - Transparent background + : - Supports notifications when processes are completed out of view + : + : The application was written using GTK 3 and an effort was made to conform to + : GNOME Human Interface Guidelines (HIG). + +``` + +### [Zypper Command][8] : View Package Information On openSUSE System + +Zypper is a command line package manager which makes use of libzypp. Zypper provides functions like repository access, dependency solving, package installation, etc. +``` +$ zypper info nano + +Loading repository data... +Reading installed packages... + + +Information for package nano: +----------------------------- +Repository : Main Repository (OSS) +Name : nano +Version : 2.4.2-5.3 +Arch : x86_64 +Vendor : openSUSE +Installed Size : 1017.8 KiB +Installed : No +Status : not installed +Source package : nano-2.4.2-5.3.src +Summary : Pico editor clone with enhancements +Description : + GNU nano is a small and friendly text editor. It aims to emulate + the Pico text editor while also offering a few enhancements. + +``` + +### [pacman Command][9] : View Package Information On Arch Linux & Manjaro Systems + +Pacman stands for package manager utility. pacman is a simple command-line utility to install, build, remove and manage Arch Linux packages. Pacman uses libalpm (Arch Linux Package Management (ALPM) library) as a back-end to perform all the actions. +``` +$ pacman -Qi bash +Name : bash +Version : 4.4.012-2 +Description : The GNU Bourne Again shell +Architecture : x86_64 +URL : http://www.gnu.org/software/bash/bash.html +Licenses : GPL +Groups : base +Provides : sh +Depends On : readline>=7.0 glibc ncurses +Optional Deps : bash-completion: for tab completion +Required By : autoconf automake bison bzip2 ca-certificates-utils db + dhcpcd diffutils e2fsprogs fakeroot figlet findutils + flex freetype2 gawk gdbm gettext gmp grub gzip icu + iptables keyutils libgpg-error libksba libpcap libpng + libtool lvm2 m4 man-db mkinitcpio nano neofetch nspr + nss openresolv os-prober pacman pcre pcre2 shadow + systemd texinfo vte-common which xdg-user-dirs xdg-utils + xfsprogs xorg-mkfontdir xorg-xpr xz +Optional For : None +Conflicts With : None +Replaces : None +Installed Size : 7.13 MiB +Packager : Jan Alexander Steffens (heftig) +Build Date : Tue 14 Feb 2017 01:16:51 PM UTC +Install Date : Thu 24 Aug 2017 06:08:12 AM UTC +Install Reason : Explicitly installed +Install Script : No +Validated By : Signature + +``` + +### [Apt-Cache Command][10] : View Package Information On Debian/Ubuntu/Mint Systems + +The apt-cache command can display much of the information stored in APT’s internal database. This information is a sort of cache since it is gathered from the different sources listed in the sources.list file. This happens during the apt update operation. +``` +$ sudo apt-cache show apache2 +Package: apache2 +Priority: optional +Section: web +Installed-Size: 473 +Maintainer: Ubuntu Developers +Original-Maintainer: Debian Apache Maintainers +Architecture: amd64 +Version: 2.4.12-2ubuntu2 +Replaces: apache2.2-common +Provides: httpd, httpd-cgi +Depends: lsb-base, procps, perl, mime-support, apache2-bin (= 2.4.12-2ubuntu2), apache2-utils (>= 2.4), apache2-data (= 2.4.12-2ubuntu2) +Pre-Depends: dpkg (>= 1.17.14) +Recommends: ssl-cert +Suggests: www-browser, apache2-doc, apache2-suexec-pristine | apache2-suexec-custom, ufw +Conflicts: apache2.2-common (<< 2.3~) +Filename: pool/main/a/apache2/apache2_2.4.12-2ubuntu2_amd64.deb +Size: 91348 +MD5sum: ab0ee0b0d1c6b3d19bd87aa2a9537125 +SHA1: 350c9a1a954906088ed032aebb77de3d5bb24004 +SHA256: 03f515f7ebc3b67b050b06e82ebca34b5e83e34a528868498fce020bf1dbbe34 +Description-en: Apache HTTP Server + The Apache HTTP Server Project's goal is to build a secure, efficient and + extensible HTTP server as standards-compliant open source software. The + result has long been the number one web server on the Internet. + . + Installing this package results in a full installation, including the + configuration files, init scripts and support scripts. +Description-md5: d02426bc360345e5acd45367716dc35c +Homepage: http://httpd.apache.org/ +Bugs: https://bugs.launchpad.net/ubuntu/+filebug +Origin: Ubuntu +Supported: 9m +Task: lamp-server, mythbuntu-frontend, mythbuntu-desktop, mythbuntu-backend-slave, mythbuntu-backend-master, mythbuntu-backend-master + +``` + +### [APT Command][11] : View Package Information On Debian/Ubuntu/Mint Systems + +APT stands for Advanced Packaging Tool (APT) which is replacement for apt-get, like how DNF came to picture instead of YUM. It’s feature rich command-line tools with included all the futures in one command (APT) such as apt-cache, apt-search, dpkg, apt-cdrom, apt-config, apt-key, etc..,. and several other unique features. For example we can easily install .dpkg packages through APT but we can’t do through Apt-Get similar more features are included into APT command. APT-GET replaced by APT Due to lock of futures missing in apt-get which was not solved. +``` +$ apt show nano +Package: nano +Version: 2.8.6-3 +Priority: standard +Section: editors +Origin: Ubuntu +Maintainer: Ubuntu Developers +Original-Maintainer: Jordi Mallach +Bugs: https://bugs.launchpad.net/ubuntu/+filebug +Installed-Size: 766 kB +Depends: libc6 (>= 2.14), libncursesw5 (>= 6), libtinfo5 (>= 6) +Suggests: spell +Conflicts: pico +Breaks: nano-tiny (<< 2.8.6-2) +Replaces: nano-tiny (<< 2.8.6-2), pico +Homepage: https://www.nano-editor.org/ +Task: standard, ubuntu-touch-core, ubuntu-touch +Supported: 9m +Download-Size: 222 kB +APT-Manual-Installed: yes +APT-Sources: http://in.archive.ubuntu.com/ubuntu artful/main amd64 Packages +Description: small, friendly text editor inspired by Pico + GNU nano is an easy-to-use text editor originally designed as a replacement + for Pico, the ncurses-based editor from the non-free mailer package Pine + (itself now available under the Apache License as Alpine). + . + However, GNU nano also implements many features missing in pico, including: + - undo/redo + - line numbering + - syntax coloring + - soft-wrapping of overlong lines + - selecting text by holding Shift + - interactive search and replace (with regular expression support) + - a go-to line (and column) command + - support for multiple file buffers + - auto-indentation + - tab completion of filenames and search terms + - toggling features while running + - and full internationalization support + +``` + +### [dpkg Command][12] : View Package Information On Debian/Ubuntu/Mint Systems + +dpkg stands for Debian package manager (dpkg). dpkg is a command-line tool to install, build, remove and manage Debian packages. dpkg uses Aptitude (primary and more user-friendly) as a front-end to perform all the actions. Other utility such as dpkg-deb and dpkg-query uses dpkg as a front-end to perform some action. Now a days most of the administrator using Apt, Apt-Get & Aptitude to manage packages easily without headache and its robust management too. Even though still we need to use dpkg to perform some software installation where it’s necessary. +``` +$ dpkg -s python +Package: python +Status: install ok installed +Priority: optional +Section: python +Installed-Size: 626 +Maintainer: Ubuntu Developers +Architecture: amd64 +Multi-Arch: allowed +Source: python-defaults +Version: 2.7.14-2ubuntu1 +Replaces: python-dev (<< 2.6.5-2) +Provides: python-ctypes, python-email, python-importlib, python-profiler, python-wsgiref +Depends: python2.7 (>= 2.7.14-1~), libpython-stdlib (= 2.7.14-2ubuntu1) +Pre-Depends: python-minimal (= 2.7.14-2ubuntu1) +Suggests: python-doc (= 2.7.14-2ubuntu1), python-tk (>= 2.7.14-1~) +Breaks: update-manager-core (<< 0.200.5-2) +Conflicts: python-central (<< 0.5.5) +Description: interactive high-level object-oriented language (default version) + Python, the high-level, interactive object oriented language, + includes an extensive class library with lots of goodies for + network programming, system administration, sounds and graphics. + . + This package is a dependency package, which depends on Debian's default + Python version (currently v2.7). +Homepage: http://www.python.org/ +Original-Maintainer: Matthias Klose + +``` + +Alternatively we can use `-p` option with dpkg that provides information similar to `dpkg -s` info but additionally it provides package checksum data and type. +``` +$ dpkg -p python3 +Package: python3 +Priority: important +Section: python +Installed-Size: 67 +Origin: Ubuntu +Maintainer: Ubuntu Developers +Bugs: https://bugs.launchpad.net/ubuntu/+filebug +Architecture: amd64 +Multi-Arch: allowed +Source: python3-defaults +Version: 3.6.3-0ubuntu2 +Replaces: python3-minimal (<< 3.1.2-2) +Provides: python3-profiler +Depends: python3.6 (>= 3.6.3-1~), libpython3-stdlib (= 3.6.3-0ubuntu2), dh-python +Pre-Depends: python3-minimal (= 3.6.3-0ubuntu2) +Suggests: python3-doc (>= 3.6.3-0ubuntu2), python3-tk (>= 3.6.3-1~), python3-venv (>= 3.6.3-0ubuntu2) +Filename: pool/main/p/python3-defaults/python3_3.6.3-0ubuntu2_amd64.deb +Size: 8712 +MD5sum: a8bae494c6e5d1896287675faf40d373 +Description: interactive high-level object-oriented language (default python3 version) +Original-Maintainer: Matthias Klose +SHA1: 2daec885cea7d4dc83c284301c3bebf42b23e095 +SHA256: 865e509c91d2504a16c4b573dbe27e260c36fceec2add3fa43a30c1751d7e9bb +Homepage: http://www.python.org/ +Task: minimal, ubuntu-core, ubuntu-core +Description-md5: 950ebd8122c0a7340f0a740c295b9eab +Supported: 9m + +``` + +### Aptitude Command : View Package Information On Debian/Ubuntu/Mint Systems + +aptitude is a text-based interface to the Debian GNU/Linux package system. It allows the user to view the list of packages and to perform package management tasks such as installing, upgrading, and removing packages. Actions may be performed from a visual interface or from the command-line. +``` +$ aptitude show htop +Package: htop +Version: 2.0.2-1 +State: installed +Automatically installed: no +Priority: optional +Section: universe/utils +Maintainer: Ubuntu Developers +Architecture: amd64 +Uncompressed Size: 216 k +Depends: libc6 (>= 2.15), libncursesw5 (>= 6), libtinfo5 (>= 6) +Suggests: lsof, strace +Conflicts: htop:i386 +Description: interactive processes viewer + Htop is an ncursed-based process viewer similar to top, but it allows one to scroll the list vertically and horizontally to see all processes and their full command lines. + + Tasks related to processes (killing, renicing) can be done without entering their PIDs. +Homepage: http://hisham.hm/htop/ + +``` + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/how-to-view-detailed-information-about-a-package-in-linux/ + +作者:[Prakash Subramanian][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/prakash/ +[1]:https://www.2daygeek.com/list-of-command-line-package-manager-for-linux/ +[2]:https://www.2daygeek.com/list-of-graphical-frontend-tool-for-linux-package-manager/ +[3]:https://www.2daygeek.com/how-to-search-if-a-package-is-available-on-your-linux-distribution-or-not/ +[4]:https://www.2daygeek.com/how-to-add-enable-disable-a-repository-dnf-yum-config-manager-on-linux/ +[5]:https://www.2daygeek.com/yum-command-examples-manage-packages-rhel-centos-systems/ +[6]:https://www.2daygeek.com/rpm-command-examples/ +[7]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/ +[8]:https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/ +[9]:https://www.2daygeek.com/pacman-command-examples-manage-packages-arch-linux-system/ +[10]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/ +[11]:https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/ +[12]:https://www.2daygeek.com/dpkg-command-to-manage-packages-on-debian-ubuntu-linux-mint-systems/ diff --git a/sources/tech/20180710 The aftermath of the Gentoo GitHub hack.md b/sources/tech/20180710 The aftermath of the Gentoo GitHub hack.md new file mode 100644 index 0000000000..fc9ff4b4e5 --- /dev/null +++ b/sources/tech/20180710 The aftermath of the Gentoo GitHub hack.md @@ -0,0 +1,72 @@ +The aftermath of the Gentoo GitHub hack +====== + +![](https://images.idgesg.net/images/article/2018/07/gentoo_penguins-100763422-large.jpg) + +### Gentoo GitHub hack: What happened? + +Late last month (June 28), the Gentoo GitHub repository was attacked after someone gained control of an admin account. All access to the repositories was soon removed from Gentoo developers. Repository and page content were altered. But within 10 minutes of the attacker gaining access, someone noticed something was going on, 7 minutes later a report was sent, and within 70 minutes the attack was over. Legitimate Gentoo developers were shut out for 5 days while the dust settled and repairs and analysis were completed. + +The attackers also attempted to add "rm -rf" commands to some repositories to cause user data to be recursively removed. As it turns out, this code was unlikely to be run because of technical precautions that were in place, but this wouldn't have been obvious to the attacker. + +One of the things that constrained how big a disaster this break in might have turned out to be was that the attack was "loud." The removal of developers resulted in them being emailed, and developers quickly discovered they'd been shut out. A stealthier attack might have led to a significant delay in anyone responding to the problem and a significantly bigger problem. + +A detailed timeline showing the details of what happened is available at the [Gentoo Linux site][1]. + +### How the Gentoo GitHub attack happened + +Much of the focus in the aftermath of this very significant attack has been on how the attacker was able to gain admin access and what might have been done differently to keep the site safe. The most obvious take-home was that the admin's password was guessed because it too closely related to one that had been captured on another system. This might be like your using "Spring2018" on one system and "Summer2018" on another. + +Another problem was that it was unclear how end users might have been able to tell whether or not they had a clean copy of the code, and there was no confirmation as to whether the malicious commits (accessible for a while) would execute. + +### Lessons learned from the hack + +The lessons learned should come as no surprise. We should all be careful not to use the same password on multiple systems and not to use passwords that relate to each other so strongly that knowing one in a set suggests another. + +We also have to admit that two-factor authentication would have prevented this break-in. While something of a burden on users (i.e., they may have to carry a token generator or confirm their login through some secondary service), it very strongly limits who can get access to an account. + +Of course the lessons learned should also not overlook what this incident showed us was going right. The fact that the break-in was noticed so quickly and that communications lines were functional meant the break-in could be quickly addressed. The breach was also made public, the repository was only a secondary copy of the main Gentoo source code, and changes in the main repository were signed and could be verified. + +#### The best news + +The really good news is that it appears that no one was affected by the break in other than the fact that developers were locked out for a while. The hackers weren't able to penetrate Gentoo's master repository (the default location for automatic updates). They also weren't able to get their hands on Gentoo's digital signing key. This means that default updates would have rejected their files as fakes. + +The harm that could have been made to Gentoo's reputation was avoided by the precautions in place and their professional handling of the incident. What could have cost them a lot ended up as a confirmation of what they're doing right and added to their determination to make some changes to strengthen their security. They faced up to some cyberbullies and came out stronger and more confident. + +### Fixing the potholes + +Gentoo is already addressing the weaknesses that contributed to the break-in. They are making frequent backups of their GitHub Organization (i.e., their content), starting to use two-factor authentication by default, working on an incident response plan with a focus on sharing information about a security incident with their users, and tightening procedures around credential revocation. They are also reducing the number of users with elevated privileges, auditing logins, and publishing password policies that mandate the use of password managers. + +### Gentoo and GitHub + +For readers unfamiliar with Gentoo, it's important to understand that Gentoo is different than most Linux distributions. Users download and then compile the source to build the OS they will then be using. It's as close to the Linux mantra of “know how to do it yourself” as you can get. + +Git is a code management system not unlike CVS, and GitHub provides repositories for the code. + +### Gentoo strengths + +Gentoo users tend to be more knowledgeable about the low-level aspects of the OS (e.g., kernel configuration and hardware support) than most Linux users — probably due to their interest in working with the source code. The OS is also highly scalable and flexible with a "build what you need" focus. The name derives from that of the "Gentoo penguin" — a penguin breed that lives on many sub-Antarctic islands. More information and downloads are available at [www.gentoo.org][2]. + +### More on the Gentoo GitHub break-in + +More information on the break in is available on [Naked Security][3] and (as noted above) the [Gentoo site][1]. + +Join the Network World communities on [Facebook][4] and [LinkedIn][5] to comment on topics that are top of mind. + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3287973/linux/the-aftermath-of-the-gentoo-github-hack.html + +作者:[Sandra Henry-Stocker][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/ +[1]:https://wiki.gentoo.org/wiki/Project:Infrastructure/Incident_Reports/2018-06-28_Github +[2]:https://www.gentoo.org/ +[3]:https://nakedsecurity.sophos.com/2018/06/29/linux-distro-hacked-on-github-all-code-considered-compromised/ +[4]:https://www.facebook.com/NetworkWorld/ +[5]:https://www.linkedin.com/company/network-world diff --git a/sources/tech/20180710 Users, Groups, and Other Linux Beasts.md b/sources/tech/20180710 Users, Groups, and Other Linux Beasts.md new file mode 100644 index 0000000000..6083111a32 --- /dev/null +++ b/sources/tech/20180710 Users, Groups, and Other Linux Beasts.md @@ -0,0 +1,153 @@ +Users, Groups, and Other Linux Beasts +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/flamingo-2458782_1920.jpg?itok=_gkzGGx5) + +Having reached this stage, [after seeing how to manipulate folders/directories][1], but before flinging ourselves headlong into fiddling with files, we have to brush up on the matter of _permissions_ , _users_ and _groups_. Luckily, [there is already an excellent and comprehensive tutorial on this site that covers permissions][2], so you should go and read that right now. In a nutshell: you use permissions to establish who can do stuff to files and directories and what they can do with each file and directory -- read from it, write to it, move it, erase it, etc. + +To try everything this tutorial covers, you'll need to create a new user on your system. Let's be practical and make a user for anybody who needs to borrow your computer, that is, what we call a _guest account_. + +**WARNING:** _Creating and especially deleting users, along with home directories, can seriously damage your system if, for example, you remove your own user and files by mistake. You may want to practice on another machine which is not your main work machine or on a virtual machine. Regardless of whether you want to play it safe, or not, it is always a good idea to back up your stuff frequently, check the backups have worked correctly, and save yourself a lot of gnashing of teeth later on._ + +### A New User + +You can create a new user with the `useradd` command. Run `useradd` with superuser/root privileges, that is using `sudo` or `su`, depending on your system, you can do: +``` +sudo useradd -m guest + +``` + +... and input your password. Or do: +``` +su -c "useradd -m guest" + +``` + +... and input the password of root/the superuser. + +( _For the sake of brevity, we'll assume from now on that you get superuser/root privileges by using`sudo`_ ). + +By including the `-m` argument, `useradd` will create a home directory for the new user. You can see its contents by listing _/home/guest_. + +Next you can set up a password for the new user with +``` +sudo passwd guest + +``` + +Or you could also use `adduser`, which is interactive and asks you a bunch of questions, including what shell you want to assign the user (yes, there are more than one), where you want their home directory to be, what groups you want them to belong to (more about that in a second) and so on. At the end of running `adduser`, you get to set the password. Note that `adduser` is not installed by default on many distributions, while `useradd` is. + +Incidentally, you can get rid of a user with `userdel`: +``` +sudo userdel -r guest + +``` + +With the `-r` option, `userdel` not only removes the _guest_ user, but also deletes their home directory and removes their entry in the mailing spool, if they had one. + +### Skeletons at Home + +Talking of users' home directories, depending on what distro you're on, you may have noticed that when you use the `-m` option, `useradd` populates a user's directory with subdirectories for music, documents, and whatnot as well as an assortment of hidden files. To see everything in you guest's home directory run `sudo ls -la /home/guest`. + +What goes into a new user's directory is determined by a skeleton directory which is usually _/etc/skel_. Sometimes it may be a different directory, though. To check which directory is being used, run: +``` +useradd -D +GROUP=100 +HOME=/home +INACTIVE=-1 +EXPIRE= +SHELL=/bin/bash +SKEL=/etc/skel +CREATE_MAIL_SPOOL=no + +``` + +This gives you some extra interesting information, but what you're interested in right now is the `SKEL=/etc/skel` line. In this case, and as is customary, it is pointing to _/etc/skel/_. + +As everything is customizable in Linux, you can, of course, change what gets put into a newly created user directory. Try this: Create a new directory in _/etc/skel/_ : +``` +sudo mkdir /etc/skel/Documents + +``` + +And create a file containing a welcome text and copy it over: +``` +sudo cp welcome.txt /etc/skel/Documents + +``` + +Now delete the guest account: +``` +sudo userdel -r guest + +``` + +And create it again: +``` +sudo useradd -m guest + +``` + +Hey presto! Your _Documents/_ directory and _welcome.txt_ file magically appear in the guest's home directory. + +You can also modify other things when you create a user by editing _/etc/default/useradd_. Mine looks like this: +``` +GROUP=users +HOME=/home +INACTIVE=-1 +EXPIRE= +SHELL=/bin/bash +SKEL=/etc/skel +CREATE_MAIL_SPOOL=no + +``` + +Most of these options are self-explanatory, but let's take a closer look at the `GROUP` option. + +### Herd Mentality + +Instead of assigning permissions and privileges to users one by one, Linux and other Unix-like operating systems rely on _groups_. A group is a what you imagine it to be: a bunch of users that are related in some way. On your system you may have a group of users that are allowed to use the printer. They would belong to the _lp_ (for " _line printer_ ") group. The members of the _wheel_ group were traditionally the only ones who could become superuser/root by using _su_. The _network_ group of users can bring up and power down the network. And so on and so forth. + +Different distributions have different groups and groups with the same or similar names have different privileges also depending on the distribution you are using. So don't be surprised if what you read in the prior paragraph doesn't match what is going on in your system. + +Either way, to see which groups are on your system you can use: +``` +getent group + +``` + +The `getent` command lists the contents of some of the system's databases. + +To find out which groups your current user belongs to, try: +``` +groups + +``` + +When you create a new user with `useradd`, unless you specify otherwise, the user will only belong to one group: their own. A _guest_ user will belong to a _guest_ group and the group gives the user the power to administer their own stuff and that is about it. + +You can create new groups and then add users to them at will with the `groupadd` command: +``` +sudo groupadd photos + +``` + +will create the _photos_ group, for example. Next time, we’ll use this to build a shared directory all members of the group can read from and write to, and we'll learn even more about permissions and privileges. Stay tuned! + +Learn more about Linux through the free ["Introduction to Linux" ][3]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/7/users-groups-and-other-linux-beasts + +作者:[Paul Brown][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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 +[1]:https://www.linux.com/blog/learn/2018/5/manipulating-directories-linux +[2]:https://www.linux.com/learn/understanding-linux-file-permissions +[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180711 5 open source racing and flying games for Linux.md b/sources/tech/20180711 5 open source racing and flying games for Linux.md new file mode 100644 index 0000000000..c2b540f498 --- /dev/null +++ b/sources/tech/20180711 5 open source racing and flying games for Linux.md @@ -0,0 +1,102 @@ +5 open source racing and flying games for Linux +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/car-penguin-drive-linux-yellow.png?itok=twWGlYAc) + +Gaming has traditionally been one of Linux's weak points. That has changed somewhat in recent years thanks to Steam, GOG, and other efforts to bring commercial games to multiple operating systems, but those games often are not open source. Sure, the games can be played on an open source operating system, but that is not good enough for an open source purist. + +So, can someone who uses only free and open source software find games that are polished enough to present a solid gaming experience without compromising their open source ideals? Absolutely. While open source games are unlikely to ever rival some of the AAA commercial games developed with massive budgets, there are plenty of open source games, in many genres, that are fun to play and can be installed from the repositories of most major Linux distributions. Even if a particular game is not packaged for a particular distribution, it is usually easy to download the game from the project's website to install and play it. + +This article looks at racing and flying games. I have already written about [arcade-style games][1], [board and card games][2], and [puzzle games][3]. In future articles, I plan to cover role-playing games and strategy & simulation games. + +### Extreme Tux Racer + +![](https://opensource.com/sites/default/files/uploads/extreme_tux_racer.png) + +Race down snow and ice-covered mountains as Tux or other characters in [Extreme Tux Racer][4]. In this racing game, the goal is to collect herrings and earn the best time. There are many different tracks to choose from, and tracks can be customized by altering the time of day, wind, and weather conditions. While the game has a few rough edges compared to modern, commercial racing games, it is still an enjoyable game to play. The controls and gameplay are straightforward and simple to learn, making this a great choice for kids. + +To install Extreme Tux Racer, run the following command: + + * On Fedora: `dnf install extremetuxracer` + * On Debian/Ubuntu: `apt install extremetuxracer` + + + +### FlightGear + +![](https://opensource.com/sites/default/files/uploads/flightgear.png) + +[FlightGear][5] is a full-fledged, open source flight simulator. Multiple aircraft types are available, and 20,000 airports are included in the full world scenery set. That means the player can fly to most parts of the world and have realistic airports and scenery. The full world scenery data is large enough to fill three DVDs. Even the developers are jokingly not sure if that counts as "a feature or a problem," so be aware that a complete installation of FlightGear and all its scenery data is huge. While certainly not the right game for everyone, FlightGear provides a very complete and complex flight simulator experience for players looking to explore the skies on their own computer. + +To install FlightGear, run the following command: + + * On Fedora: `dnf install FlightGear` + * On Debian/Ubuntu: `apt install flightgear` + + + +### SuperTuxKart + +![](https://opensource.com/sites/default/files/uploads/supertuxkart.png) + +[SuperTuxKart][6] takes the basic formula used by Nintendo in the Mario Kart series and applies it to open source mascots. Players race around a variety of tracks in go-karts driven by the mascots for a plethora of open source projects. Character choices include the mascots for open source operating systems and applications of varying familiarity, with options ranging from Tux and Beastie to Gavroche, the mascot for [GNU MediaGoblin][7]. There are several gameplay modes to choose from, including multi-player modes, but many of the tracks are unavailable until they are unlocked by playing the game's single-player story mode. SuperTuxKart's graphics settings can be tweaked to run on everything from older computers with built-in graphics to modern hardware with high-end graphics cards. There is also a version of [SuperTuxKart for Android][8] available. SuperTuxKart is a very good game and great for players of all ages. + +To install SuperTuxKart, run the following command: + + * On Fedora: `dnf install supertuxkart` + * On Debian/Ubuntu: `apt install supertuxkart` + + + +### Torcs + +![](https://opensource.com/sites/default/files/uploads/torcs.png) + +[Torcs][9] is a fairly standard racing game with some extra features for the tech-savvy. Torcs can be played as just a standard racing game, where the player drives around a track trying to get the best time, but an alternative usage is as a platform to develop an artificial intelligence driver that can drive itself through Torcs' tracks. The cars and tracks included with the game vary in style, ranging from stock car racing to rally racing, but the gameplay is pretty typical for a racing game. Keyboard, mouse, joystick, and steering wheel input are all supported, but keyboard and mouse input modes are a little hard to get used to. Single-player races range from practice runs to championships, and there is a [split-screen multi-player mode][10] for up to four players. + +To install Torcs, run the following command: + + * On Fedora: `dnf install torcs` + * On Debian/Ubuntu: `apt install torcs` + + + +### Trigger Rally + +![](https://opensource.com/sites/default/files/uploads/trigger_rally.png) + +[Trigger Rally][11] is an off-road, single-player rally racing game. The player needs to make it to each checkpoint in time to complete the race, which is standard racing game fare, but still enjoyable. The gameplay is more arcade-like than a strict racing simulator like Torcs but more realistic than cartoonish racing games like SuperTuxKart. The tracks are interesting and the controls are responsive, but a little too sensitive when playing with a keyboard. Joystick controls are available by changing an option in a configuration file. Unfortunately, development on the game is slow going, with the latest release in 2016, but the gameplay that is already there is fun. + +To install Trigger Rally, run the following command: + + * On Debian/Ubuntu: `apt install trigger-rally` + + + +Unfortunately, Trigger Rally is not packaged for Fedora. + +Did I miss one of your favorite open source racing or flying games? Share it in the comments below. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/racing-flying-games-linux + +作者:[About The Author;Joshua Allen Holm;Mlis;Med;Is One Of Opensource.Com'S Community Moderators. Joshua'S Main Interests Are Digital Humanities;Open Access;Open Educational Resources. He Can Reached At][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/holmja +[1]:https://opensource.com/article/18/1/arcade-games-linux +[2]:https://opensource.com/article/18/3/card-board-games-linux +[3]:https://opensource.com/article/18/6/puzzle-games-linux +[4]:https://extremetuxracer.sourceforge.io/ +[5]:http://home.flightgear.org/ +[6]:https://supertuxkart.net/Main_Page +[7]:https://mediagoblin.org +[8]:https://play.google.com/store/apps/details?id=org.supertuxkart.stk +[9]:http://torcs.sourceforge.net/index.php +[10]:http://torcs.sourceforge.net/?name=Sections&op=viewarticle&artid=30#c4_4_4 +[11]:http://trigger-rally.sf.net/ diff --git a/sources/tech/20180711 Open hardware meets open science in a multi-microphone hearing aid project.md b/sources/tech/20180711 Open hardware meets open science in a multi-microphone hearing aid project.md new file mode 100644 index 0000000000..f6a348980d --- /dev/null +++ b/sources/tech/20180711 Open hardware meets open science in a multi-microphone hearing aid project.md @@ -0,0 +1,69 @@ +Open hardware meets open science in a multi-microphone hearing aid project +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BIZ_OpenInnovation.png?itok=l29msbql) + +Since [Opensource.com][1] first published the story of the [GNU/Linux hearing aid][2] research platform in 2010, there has been an explosion in the availability of miniature system boards, including the original BeagleBone in 2011 and the Raspberry Pi in 2012. These ARM processor devices built from cellphone chips differ from the embedded system reference boards of the past—not only by being far less expensive and more widely available—but also because they are powerful enough to run familiar GNU/Linux distributions and desktop applications. + +What took a laptop to accomplish in 2010 can now be achieved with a pocket-sized board costing a fraction as much. Because a hearing aid does not need a screen and a small ARM board's power consumption is far less than a typical laptop's, field trials can potentially run all day. Additionally, the system's lower weight is easier for the end user to wear. + +The [openMHA project][3]—from the [Carl von Ossietzky Universität Oldenburg][4] in Germany, [BatAndCat Sound Labs][5] in Palo Alto, California, and [HörTech gGmbH][6]—is an open source platform for improving hearing aids using real-time audio signal processing. For the next iteration of the research platform, openMHA is using the US$ 55 [BeagleBone Black][7] board with its 1GHz Cortex A8 CPU. + +The BeagleBone family of boards enjoys guaranteed long-term availability, thanks to its open hardware design that can be produced by anyone with the requisite knowledge. For example, BeagleBone hardware variations are available from community members including [SeeedStudio][8] and [SanCloud][9]. + +![BeagleBone Black][11] + +The BeagleBone Black is open hardware finding its way into research labs. + +Spatial filtering techniques, including [beamforming][12] and [directional microphone arrays][13], can suppress distracting noise, focusing audio amplification on the point in space where the hearing aid wearer is looking, rather than off to the side where a truck might be thundering past. These neat tricks can use two or three microphones per ear, yet typical sound cards for embedded devices support only one or two input channels in total. + +Fortunately, the [McASP][14] communication peripheral in Texas Instruments chips offers multiple channels and support for the [I2S protocol][15], originally devised by Philips for short digital audio interconnects inside CD players. This means an add-on "cape" board can hook directly into the BeagleBone's audio system without using USB or other external interfaces. The direct approach helps reduce the signal processing delay into the range where it is undetectable by the hearing aid wearer. + +The openMHA project uses an audio cape developed by the [Hearing4all][16] project, which combines three stereo codecs to provide up to six input channels. Like the BeagleBone, the Cape4all is open hardware with design files available on [GitHub][17]. + +The Cape4all, [presented recently][18] at the Linux Audio Conference in Berlin, Germany, runs at a sample rate from 24kHz to 96Khz with as few as 12 samples per period, leading to internal latencies in the sub-millisecond range. With hearing enhancement algorithms running, the complete round-trip latency from a microphone to an earpiece has been measured at 3.6 milliseconds (at 48KHz sample rate with 16 samples per period). Using the speed of sound for comparison, this latency is similar to listening to someone just over four feet away without a hearing aid. + +![Cape4all ][20] + +The Cape4all might be the first multi-microphone hearing aid on an open hardware platform. + +The next step for the openMHA project is to develop a [Bluetooth Low Energy][21] module that will enable remote control of the research device from a smartphone and perhaps route phone calls and media playback to the hearing aid. Consumer hearing aids support Bluetooth, so the openMHA research platform must do so, too. + +Also, instructions for running a [stereo hearing aid on the Raspberry Pi][22] were released by an openMHA user-project. + +As evidenced by the openMHA project, open source innovation has transformed digital hearing aid research from an esoteric branch of audiology into an accessible open science. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/open-hearing-aid-platform + +作者:[Daniel James,Christopher Obbard][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/daniel-james +[1]:http://Opensource.com +[2]:https://opensource.com/life/10/9/open-source-designing-next-generation-digital-hearing-aids +[3]:http://www.openmha.org/ +[4]:https://www.uni-oldenburg.de/ +[5]:http://batandcat.com/ +[6]:http://www.hoertech.de/ +[7]:https://beagleboard.org/black +[8]:https://www.seeedstudio.com/ +[9]:http://www.sancloud.co.uk +[10]:/file/403046 +[11]:https://opensource.com/sites/default/files/uploads/1-beagleboneblack-600.jpg (BeagleBone Black) +[12]:https://en.wikipedia.org/wiki/Beamforming +[13]:https://en.wikipedia.org/wiki/Microphone_array +[14]:https://en.wikipedia.org/wiki/McASP +[15]:https://en.wikipedia.org/wiki/I%C2%B2S +[16]:http://hearing4all.eu/EN/ +[17]:https://github.com/HoerTech-gGmbH/Cape4all +[18]:https://lac.linuxaudio.org/2018/pages/event/35/ +[19]:/file/403051 +[20]:https://opensource.com/sites/default/files/uploads/2-beaglebone-wireless-with-cape4all-labelled-600.jpg (Cape4all ) +[21]:https://en.wikipedia.org/wiki/Bluetooth_Low_Energy +[22]:http://www.openmha.org/userproject/2017/12/21/openMHA-on-raspberry-pi.html diff --git a/sources/tech/20180712 A sysadmin-s guide to SELinux- 42 answers to the big questions.md b/sources/tech/20180712 A sysadmin-s guide to SELinux- 42 answers to the big questions.md new file mode 100644 index 0000000000..4a7212c061 --- /dev/null +++ b/sources/tech/20180712 A sysadmin-s guide to SELinux- 42 answers to the big questions.md @@ -0,0 +1,272 @@ +Translating by qhwdw +A sysadmin's guide to SELinux: 42 answers to the big questions +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security-lock-password.jpg?itok=KJMdkKum) + +> "It is an important and popular fact that things are not always what they seem…" +> ―Douglas Adams, The Hitchhiker's Guide to the Galaxy + +Security. Hardening. Compliance. Policy. The Four Horsemen of the SysAdmin Apocalypse. In addition to our daily tasks—monitoring, backup, implementation, tuning, updating, and so forth—we are also in charge of securing our systems. Even those systems where the third-party provider tells us to disable the enhanced security. It seems like a job for Mission Impossible's [Ethan Hunt][1]. + +Faced with this dilemma, some sysadmins decide to [take the blue pill][2] because they think they will never know the answer to the big question of life, the universe, and everything else. And, as we all know, that answer is **[42][3]**. + +In the spirit of The Hitchhiker's Guide to the Galaxy, here are the 42 answers to the big questions about managing and using [SELinux][4] with your systems. + + 1. SELinux is a LABELING system, which means every process has a LABEL. Every file, directory, and system object has a LABEL. Policy rules control access between labeled processes and labeled objects. The kernel enforces these rules. + + + 2. The two most important concepts are: Labeling (files, process, ports, etc.) and Type enforcement (which isolates processes from each other based on types). + + + 3. The correct Label format is `user:role:type:level` (optional). + + + 4. The purpose of Multi-Level Security (MLS) enforcement is to control processes (domains) based on the security level of the data they will be using. For example, a secret process cannot read top-secret data. + + + 5. Multi-Category Security (MCS) enforcement protects similar processes from each other (like virtual machines, OpenShift gears, SELinux sandboxes, containers, etc.). + + + 6. Kernel parameters for changing SELinux modes at boot: + * `autorelabel=1` → forces the system to relabel + * `selinux=0` → kernel doesn't load any part of the SELinux infrastructure + * `enforcing=0` → boot in permissive mode + + + 7. If you need to relabel the entire system: +`# touch /.autorelabel #reboot` +If the system labeling contains a large amount of errors, you might need to boot in permissive mode in order for the autorelabel to succeed. + + + 8. To check if SELinux is enabled: `# getenforce` + + + 9. To temporarily enable/disable SELinux: `# setenforce [1|0]` + + + 10. SELinux status tool: `# sestatus` + + + 11. Configuration file: `/etc/selinux/config` + + + 12. How does SELinux work? Here's an example of labeling for an Apache Web Server: + * Binary: `/usr/sbin/httpd`→`httpd_exec_t` + * Configuration directory: `/etc/httpd`→`httpd_config_t` + * Logfile directory: `/var/log/httpd` → `httpd_log_t` + * Content directory: `/var/www/html` → `httpd_sys_content_t` + * Startup script: `/usr/lib/systemd/system/httpd.service` → `httpd_unit_file_d` + * Process: `/usr/sbin/httpd -DFOREGROUND` → `httpd_t` + * Ports: `80/tcp, 443/tcp` → `httpd_t, http_port_t` + + + +A process running in the `httpd_t` context can interact with an object with the `httpd_something_t` label. + + 13. Many commands accept the argument `-Z` to view, create, and modify context: + * `ls -Z` + * `id -Z` + * `ps -Z` + * `netstat -Z` + * `cp -Z` + * `mkdir -Z` + + + +Contexts are set when files are created based on their parent directory's context (with a few exceptions). RPMs can set contexts as part of installation. + + 14. There are four key causes of SELinux errors, which are further explained in items 15-21 below: + * Labeling problems + * Something SELinux needs to know + * A bug in an SELinux policy/app + * Your information may be compromised + + + 15. Labeling problem: If your files in `/srv/myweb` are not labeled correctly, access might be denied. Here are some ways to fix this: + * If you know the label: +`# semanage fcontext -a -t httpd_sys_content_t '/srv/myweb(/.*)?'` + * If you know the file with the equivalent labeling: +`# semanage fcontext -a -e /srv/myweb /var/www` + * Restore the context (for both cases): +`# restorecon -vR /srv/myweb` + + + 16. Labeling problem: If you move a file instead of copying it, the file keeps its original context. To fix these issues: + * Change the context command with the label: +`# chcon -t httpd_system_content_t /var/www/html/index.html` + * Change the context command with the reference label: +`# chcon --reference /var/www/html/ /var/www/html/index.html` + * Restore the context (for both cases): `# restorecon -vR /var/www/html/` + + + 17. If SELinux needs to know HTTPD listens on port 8585, tell SELinux: +`# semanage port -a -t http_port_t -p tcp 8585` + + + 18. SELinux needs to know booleans allow parts of SELinux policy to be changed at runtime without any knowledge of SELinux policy writing. For example, if you want httpd to send email, enter: `# setsebool -P httpd_can_sendmail 1` + + + 19. SELinux needs to know booleans are just off/on settings for SELinux: + * To see all booleans: `# getsebool -a` + * To see the description of each one: `# semanage boolean -l` + * To set a boolean execute: `# setsebool [_boolean_] [1|0]` + * To configure it permanently, add `-P`. For example: +`# setsebool httpd_enable_ftp_server 1 -P` + + + 20. SELinux policies/apps can have bugs, including: + * Unusual code paths + * Configurations + * Redirection of `stdout` + * Leaked file descriptors + * Executable memory + * Badly built libraries Open a ticket (do not file a Bugzilla report; there are no SLAs with Bugzilla). + + + 21. Your information may be compromised if you have confined domains trying to: + * Load kernel modules + * Turn off the enforcing mode of SELinux + * Write to `etc_t/shadow_t` + * Modify iptables rules + + + 22. SELinux tools for the development of policy modules: +`# yum -y install setroubleshoot setroubleshoot-server` +Reboot or restart `auditd` after you install. + + + 23. Use `journalctl` for listing all logs related to `setroubleshoot`: +`# journalctl -t setroubleshoot --since=14:20` + + + 24. Use `journalctl` for listing all logs related to a particular SELinux label. For example: +`# journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0` + + + 25. Use `setroubleshoot` log when an SELinux error occurs and suggest some possible solutions. For example, from `journalctl`: +[code] Jun 14 19:41:07 web1 setroubleshoot: SELinux is preventing httpd from getattr access on the file /var/www/html/index.html. For complete message run: sealert -l 12fd8b04-0119-4077-a710-2d0e0ee5755e + + + + # sealert -l 12fd8b04-0119-4077-a710-2d0e0ee5755e + + SELinux is preventing httpd from getattr access on the file /var/www/html/index.html. + + + + ***** Plugin restorecon (99.5 confidence) suggests ************************ + + + + If you want to fix the label, + + /var/www/html/index.html default label should be httpd_syscontent_t. + + Then you can restorecon. + + Do + + # /sbin/restorecon -v /var/www/html/index.html + +``` + + + + 26. Logging: SELinux records information all over the place: + * `/var/log/messages` + * `/var/log/audit/audit.log` + * `/var/lib/setroubleshoot/setroubleshoot_database.xml` + + + 27. Logging: Looking for SELinux errors in the audit log: +`# ausearch -m AVC,USER_AVC,SELINUX_ERR -ts today` + + + 28. To search for SELinux Access Vector Cache (AVC) messages for a particular service: +`# ausearch -m avc -c httpd` + + + 29. The `audit2allow` utility gathers information from logs of denied operations and then generates SELinux policy-allow rules. For example: + * To produce a human-readable description of why the access was denied: `# audit2allow -w -a` + * To view the type enforcement rule that allows the denied access: `# audit2allow -a` + * To create a custom module: `# audit2allow -a -M mypolicy` +The `-M` option creates a type enforcement file (.te) with the name specified and compiles the rule into a policy package (.pp): `mypolicy.pp mypolicy.te` + * To install the custom module: `# semodule -i mypolicy.pp` + + + 30. To configure a single process (domain) to run permissive: `# semanage permissive -a httpd_t` + + + 31. If you no longer want a domain to be permissive: `# semanage permissive -d httpd_t` + + + 32. To disable all permissive domains: `# semodule -d permissivedomains` + + + 33. Enabling SELinux MLS policy: `# yum install selinux-policy-mls` +In `/etc/selinux/config:` +`SELINUX=permissive` +`SELINUXTYPE=mls` +Make sure SELinux is running in permissive mode: `# setenforce 0` +Use the `fixfiles` script to ensure that files are relabeled upon the next reboot: +`# fixfiles -F onboot # reboot` + + + 34. Create a user with a specific MLS range: `# useradd -Z staff_u john` +Using the `useradd` command, map the new user to an existing SELinux user (in this case, `staff_u`). + + + 35. To view the mapping between SELinux and Linux users: `# semanage login -l` + + + 36. Define a specific range for a user: `# semanage login --modify --range s2:c100 john` + + + 37. To correct the label on the user's home directory (if needed): `# chcon -R -l s2:c100 /home/john` + + + 38. To list the current categories: `# chcat -L` + + + 39. To modify the categories or to start creating your own, modify the file as follows: +`/etc/selinux/__/setrans.conf` + + + 40. To run a command or script in a specific file, role, and user context: +`# runcon -t initrc_t -r system_r -u user_u yourcommandhere` + * `-t` is the file context + * `-r` is the role context + * `-u` is the user context + + + 41. Containers running with SELinux disabled: + * With Podman: `# podman run --security-opt label=disable` … + * With Docker: `# docker run --security-opt label=disable` … + + + 42. If you need to give a container full access to the system: + * With Podman: `# podman run --privileged` … + * With Docker: `# docker run --privileged` … + + + +And with this, you already know the answer. So please: **Don't panic, and turn on SELinux**. + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/sysadmin-guide-selinux + +作者:[Alex Callejas][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/darkaxl +[1]:https://en.wikipedia.org/wiki/Ethan_Hunt +[2]:https://en.wikipedia.org/wiki/Red_pill_and_blue_pill +[3]:https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life,_the_Universe,_and_Everything_%2842%29 +[4]:https://en.wikipedia.org/wiki/Security-Enhanced_Linux diff --git a/sources/tech/20180720 4 cool new projects to try in COPR for July 2018.md b/sources/tech/20180720 4 cool new projects to try in COPR for July 2018.md new file mode 100644 index 0000000000..70b6130e37 --- /dev/null +++ b/sources/tech/20180720 4 cool new projects to try in COPR for July 2018.md @@ -0,0 +1,90 @@ +translating---geekpi + +4 cool new projects to try in COPR for July 2018 +====== + +![](https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg) + +COPR is a [collection][1] of personal repositories for software that isn’t carried in Fedora. Some software doesn’t conform to standards that allow easy packaging. Or it may not meet other Fedora standards, despite being free and open source. COPR can offer these projects outside the Fedora set of packages. Software in COPR isn’t supported by Fedora infrastructure or signed by the project. However, it can be a neat way to try new or experimental software. + +Here’s a set of new and interesting projects in COPR. + +### Hledger + +[Hledger][2] is a command-line program for tracking money or other commodities. It uses a simple, plain-text formatted journal for storing data and double-entry accounting. In addition to the command-line interface, hledger offers a terminal interface and a web client that can show graphs of balance on the accounts. +![][3] + +#### Installation instructions + +The repo currently provides hledger for Fedora 27, 28, and Rawhide. To install hledger, use these commands: +``` +sudo dnf copr enable kefah/HLedger +sudo dnf install hledger + +``` + +### Neofetch + +[Neofetch][4] is a command-line tool that displays information about the operating system, software, and hardware. Its main purpose is to show the data in a compact way to take screenshots. You can configure Neofetch to display exactly the way you want, by using both command-line flags and a configuration file. +![][5] + +#### Installation instructions + +The repo currently provides Neofetch for Fedora 28. To install Neofetch, use these commands: +``` +sudo dnf copr enable sysek/neofetch +sudo dnf install neofetch + +``` + +### Remarkable + +[Remarkable][6] is a Markdown text editor that uses the GitHub-like flavor of Markdown. It offers a preview of the document, as well as the option to export to PDF and HTML. There are several styles available for the Markdown, including an option to create your own styles using CSS. In addition, Remarkable supports LaTeX syntax for writing equations and syntax highlighting for source code. +![][7] + +#### Installation instructions + +The repo currently provides Remarkable for Fedora 28 and Rawhide. To install Remarkable, use these commands: +``` +sudo dnf copr enable neteler/remarkable +sudo dnf install remarkable + +``` + +### Aha + +[Aha][8] (or ANSI HTML Adapter) is a command-line tool that converts terminal escape sequences to HTML code. This allows you to share, for example, output of git diff or htop as a static HTML page. +![][9] + +#### Installation instructions + +The [repo][10] currently provides aha for Fedora 26, 27, 28, and Rawhide, EPEL 6 and 7, and other distributions. To install aha, use these commands: +``` +sudo dnf copr enable scx/aha +sudo dnf install aha + +``` + + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/4-try-copr-july-2018/ + +作者:[Dominik Turecek][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://fedoramagazine.org +[1]:https://copr.fedorainfracloud.org/ +[2]:http://hledger.org/ +[3]:https://fedoramagazine.org/wp-content/uploads/2018/07/hledger.png +[4]:https://github.com/dylanaraps/neofetch +[5]:https://fedoramagazine.org/wp-content/uploads/2018/07/neofetch.png +[6]:https://remarkableapp.github.io/linux.html +[7]:https://fedoramagazine.org/wp-content/uploads/2018/07/remarkable.png +[8]:https://github.com/theZiz/aha +[9]:https://fedoramagazine.org/wp-content/uploads/2018/07/aha.png +[10]:https://copr.fedorainfracloud.org/coprs/scx/aha/ diff --git a/sources/tech/20180720 A brief history of text-based games and open source.md b/sources/tech/20180720 A brief history of text-based games and open source.md new file mode 100644 index 0000000000..2b8728fb39 --- /dev/null +++ b/sources/tech/20180720 A brief history of text-based games and open source.md @@ -0,0 +1,142 @@ +A brief history of text-based games and open source +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/compass_map_explore_adventure.jpg?itok=ecCoVTrZ) + +The [Interactive Fiction Technology Foundation][1] (IFTF) is a non-profit organization dedicated to the preservation and improvement of technologies enabling the digital art form we call interactive fiction. When a Community Moderator for Opensource.com suggested an article about IFTF, the technologies and services it supports, and how it all intersects with open source, I found it a novel angle to the decades-long story I’ve so often told. The history of IF is longer than—but quite enmeshed with—the modern FOSS movement. I hope you’ll enjoy my sharing it here. + +### Definitions and history + +To me, the term interactive fiction includes any video game or digital artwork whose audience interacts with it primarily through text. The term originated in the 1980s when parser-driven text adventure games—epitomized in the United States by [Zork][2], [The Hitchhiker’s Guide to the Galaxy][3], and the rest of [Infocom][4]’s canon—defined home-computer entertainment. Its mainstream commercial viability had guttered by the 1990s, but online hobbyist communities carried on the tradition, releasing both games and game-creation tools. + +After a quarter century, interactive fiction now comprises a broad and sparkling variety of work, from puzzle-laden text adventures to sprawling and introspective hypertexts. Regular online competitions and festivals provide a great place to peruse and play new work: The English-language IF world enjoys annual events including [Spring Thing][5] and [IFComp][6], the latter a centerpiece of modern IF since 1995—which also makes it the longest-lived continually running game showcase event of its kind in any genre. [IFComp’s crop of judged-and-ranked entries from 2017][7] shows the amazing diversity in form, style, and subject matter that text-based games boast today. + +(I specify "English-language" above because IF communities tend to self-segregate by language, perhaps due to the technology's focus on writing. There are also annual IF events in [French][8] and [Italian][9], for example, and I've heard of at least one Chinese IF festival. Happily, these borders are porous; during the four years I managed IFComp, it has welcomed English-translated work from all international communities.) + +![counterfeit monkey game screenshot][11] + +Starting a new game of Emily Short's "Counterfeit Monkey," running on the interpreter Lectrote (both open source software). + +Also due to its focus on text, IF presents some of the most accessible platforms for both play and authorship. Almost anyone who can read digital text—including users of assistive technology such as text-to-speech software—can play most IF works. Likewise, IF creation is open to all writers willing to learn and work with its tools and techniques. + +This brings us to IF’s long relationship with open source, which has helped enable the art form’s availability since its commercial heyday. I'll provide an overview of contemporary open-source IF creation tools, and then discuss the ancient and sometimes curious tradition of IF works that share their source code. + +### The world of open source IF tools + +A number of development platforms, most of which are open source, are available to create traditional parser-driven IF in which the user types commands—for example, `go north,` `get lamp`, `pet the cat`, or `ask Zoe about quantum mechanics`—to interact with the game’s world. The early 1990s saw the emergence of several hacker-friendly parser-game development kits; those still in use today include [TADS][12], [Alan][13], and [Quest][14]—all open, with the latter two bearing FOSS licenses. + +But by far the most prominent of these is [Inform][15], first released by Graham Nelson in 1993 and now maintained by a team Nelson still leads. Inform source is semi-open, in an unusual fashion: Inform 6, the previous major version, [makes its source available through the Artistic License][16]. This has more immediate relevance than may be obvious, since the otherwise proprietary Inform 7 holds Inform 6 at its core, translating its [remarkable natural-language syntax][17] into its predecessor’s more C-like code before letting it compile the work down into machine code. + +![inform 7 IDE screenshot][19] + +The Inform 7 IDE, loaded up with documentation and a sample project. + +Inform games run on a virtual machine, a relic of the Infocom era when that publisher targeted a VM so that it could write a single game that would run on Apple II, Commodore 64, Atari 800, and other flavors of the "[home computer][20]." Fewer popular operating systems exist today, but Inform’s virtual machines—the relatively modern [Glulx][21] or the charmingly antique [Z-machine][22], a reverse-engineered clone of Infocom’s historical VM—let Inform-created work run on any computer with an Inform interpreter. Currently, popular cross-platform interpreters include desktop programs like [Lectrote][23] and [Gargoyle][24] or browser-based ones like [Quixe][25] and [Parchment][26]. All are open source. + +If the pace of Inform’s development has slowed in its maturity, it remains vital through an active and transparent ecosystem—just like any other popular open source project. In Inform’s case, this includes the aforementioned interpreters, [a collection of language extensions][27] (usually written in a mix of Inform 6 and 7), and of course, all the work created with it and shared with the world, sometimes with source included (I’ll return to that topic later in this article). + +IF creation tools invented in the 21st century tend to explore player interactions outside of the traditional parser, generating hypertext-driven work that any modern web browser can load. Chief among these is [Twine][28], originally developed by Chris Klimas in 2009 and under active development by many contributors today as [a GNU-licensed open source project][29]. (In fact, [Twine][30] can trace its OSS lineage back to [TiddlyWiki][31], the project from which Klimas initially derived it.) + +Twine represents a sort of maximally [open and accessible approach][30] to IF development: Beyond its own FOSS nature, it renders its output as self-contained websites, relying not on machine code requiring further specialized interpretation but the open and well-exercised standards of HTML, CSS, and JavaScript. As a creative tool, Twine can match its own exposed complexity to the creator’s skill level. Users with little or no programming knowledge can create simple but playable IF work, while those with more coding and design skills—including those developing these skills by making Twine games—can develop more sophisticated projects. Little wonder that Twine’s visibility and popularity in educational contexts has grown quite a bit in recent years. + +Other noteworthy open source IF development projects include the MIT-licensed [Undum][32] by Ian Millington, and [ChoiceScript][33] by Dan Fabulich and the [Choice of Games][34] team—both of which also target the web browser as the gameplay platform. Looking beyond strict development systems like these, web-based IF gives us a rich and ever-churning ecosystem of open source work, such as furkle’s [collection of Twine-extending tools][35] and Liza Daly’s [Windrift][36], a JavaScript framework purpose-built for her own IF games. + +### Programs, games, and game-programs + +Twine benefits from [a standing IFTF program dedicated to its support][37], allowing the public to help fund its maintenance and development. IFTF also directly supports two long-time public services, IFComp and the IF Archive, both of which depend upon and contribute back into open software and technologies. + +![Harmonia opening screen shot][39] + +The opening of Liza Daly's "Harmonia," created with the Windrift open source IF-creation framework. + +The Perl- and JavaScript-based application that runs the IFComp’s website has been [a shared-source project][40] since 2014, and it reflects [the stew of FOSS licenses used by its IF-specific sub-components][41], including the various code libraries that allow parser-driven competition entries to run in a web browser. [The IF Archive][42]—online since 1992 and [an IFTF project since 2017][43]—is a set of mirrored repositories based entirely on ancient and stable internet standards, with [a little open source Python script][44] to handle indexing. + +### At last, the fun part: Let's talk about open source text games + +The bulk of the archive [comprises games][45], of course—years and years of games, reflecting decades of evolving game-design trends and IF tool development. + +Lots of IF work shares its source code, and the community’s quick-start solution for finding it is simple: [Search the IFDB for the tag "source available"][46]. (The IFDB is yet another long-running IF community service, run privately by TADS creator Mike Roberts.) Users who are comfortable with a more bare-bones interface may also wish to browse [the `/games/source` directory][47] of the IF Archive, which groups content by development platform and written language (there's also a lot of work either too miscellaneous or too ancient to categorize floating at the top). + +A little bit of random sampling of these code-sharing games reveals an interesting dilemma: Unlike the wider world of open source software, the IF community lacks a generally agreed-upon way of licensing all the code that it generates. Unlike a software tool—including all the tools we use to build IF—an interactive fiction game is a work of art in the most literal sense, meaning that an open source license intended for software would fit it no better than it would any other work of prose or poetry. But then again, an IF game is also a piece of software, and it exhibits source-code patterns and techniques that its creator may legitimately wish to share with the world. What is an open source-aware IF creator to do? + +Some games address this by passing their code into the public domain, either through explicit license or—as in the case of [the original 42-year-old Adventure by Crowther and Woods][48]—through community fiat. Some try to split the difference, rolling their own license that allows for free re-use of a game’s exposed business logic but prohibits the creation of work derived specifically from its prose. This is the tack I took when I opened up the source of my own game, [The Warbler’s Nest][49]. Lord knows how well that’d stand up in court, but I didn’t have any better ideas at the time. + +Naturally, you can find work that simply puts everything under a single common license and never mind the naysayers. A prominent example is [Emily Short’s epic Counterfeit Monkey][50], released in its entirety under a Creative Commons 4.0 license. [CC frowns at its application to code][51], but you could argue that [the strangely prose-like nature of Inform 7 source][52] makes it at least a little more compatible with a CC license than a more traditional software project would be. + +### What now, adventurer? + +If you are eager to start exploring the world of interactive fiction, here are a few links to check out: + + ++ As mentioned above, IFDB and the IF Archive both present browsable interfaces to more than 40 years worth of collected interactive fiction work. Much of this is playable in a web browser, but some require additional interpreter programs. IFDB can help you find and install these. + + IFComp’s annual results pages provide another view into the best of this free and archive-available work. + ++ The Interactive Fiction Technology Foundation is a charitable non-profit organization that helps support Twine, IFComp, and the IF Archive, as well as improve the accessibility of IF, explore IF’s use in education, and more. Join its mailing list to receive IFTF’s monthly newsletter, peruse its blog, and browse some thematic merchandise. + ++ John Paul Wohlscheid wrote this article about open-source IF tools earlier this year. It covers some platforms not mentioned here, so if you’re still hungry for more, have a look. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/interactive-fiction-tools + +作者:[Jason Mclntosh][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/jmac +[1]:http://iftechfoundation.org/ +[2]:https://en.wikipedia.org/wiki/Zork +[3]:https://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy_(video_game) +[4]:https://en.wikipedia.org/wiki/Infocom +[5]:http://www.springthing.net/ +[6]:http://ifcomp.org/ +[7]:https://ifcomp.org/comp/2017 +[8]:http://www.fiction-interactive.fr/ +[9]:http://www.oldgamesitalia.net/content/marmellata-davventura-2018 +[10]:/file/403396 +[11]:https://opensource.com/sites/default/files/uploads/monkey.png (counterfeit monkey game screenshot) +[12]:http://tads.org/ +[13]:https://www.alanif.se/ +[14]:http://textadventures.co.uk/quest/ +[15]:http://inform7.com/ +[16]:https://github.com/DavidKinder/Inform6 +[17]:http://inform7.com/learn/man/RB_4_1.html#e307 +[18]:/file/403386 +[19]:https://opensource.com/sites/default/files/uploads/inform.png (inform 7 IDE screenshot) +[20]:https://www.youtube.com/watch?v=bu55q_3YtOY +[21]:http://ifwiki.org/index.php/Glulx +[22]:http://ifwiki.org/index.php/Z-machine +[23]:https://github.com/erkyrath/lectrote +[24]:https://github.com/garglk/garglk/ +[25]:http://eblong.com/zarf/glulx/quixe/ +[26]:https://github.com/curiousdannii/parchment +[27]:https://github.com/i7/extensions +[28]:http://twinery.org/ +[29]:https://github.com/klembot/twinejs +[30]:/article/18/7/twine-vs-renpy-interactive-fiction +[31]:https://tiddlywiki.com/ +[32]:https://github.com/idmillington/undum +[33]:https://github.com/dfabulich/choicescript +[34]:https://www.choiceofgames.com/ +[35]:https://github.com/furkle +[36]:https://github.com/lizadaly/windrift +[37]:http://iftechfoundation.org/committees/twine/ +[38]:/file/403391 +[39]:https://opensource.com/sites/default/files/uploads/harmonia.png (Harmonia opening screen shot) +[40]:https://github.com/iftechfoundation/ifcomp +[41]:https://github.com/iftechfoundation/ifcomp/blob/master/LICENSE.md +[42]:https://www.ifarchive.org/ +[43]:http://blog.iftechfoundation.org/2017-06-30-iftf-is-adopting-the-if-archive.html +[44]:https://github.com/iftechfoundation/ifarchive-ifmap-py +[45]:https://www.ifarchive.org/indexes/if-archiveXgames +[46]:http://ifdb.tads.org/search?sortby=ratu&searchfor=%22source+available%22 +[47]:https://www.ifarchive.org/indexes/if-archiveXgamesXsource.html +[48]:http://ifdb.tads.org/viewgame?id=fft6pu91j85y4acv +[49]:https://github.com/jmacdotorg/warblers-nest/ +[50]:https://github.com/i7/counterfeit-monkey +[51]:https://creativecommons.org/faq/#can-i-apply-a-creative-commons-license-to-software +[52]:https://github.com/i7/counterfeit-monkey/blob/master/Counterfeit%20Monkey.materials/Extensions/Counterfeit%20Monkey/Liquids.i7x diff --git a/sources/tech/20180720 An Introduction to Using Git.md b/sources/tech/20180720 An Introduction to Using Git.md new file mode 100644 index 0000000000..2a91406721 --- /dev/null +++ b/sources/tech/20180720 An Introduction to Using Git.md @@ -0,0 +1,193 @@ +translating by distant1219 + +An Introduction to Using Git +====== +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/developer-3461405_1920.png?itok=6H3sYe80) +If you’re a developer, then you know your way around development tools. You’ve spent years studying one or more programming languages and have perfected your skills. You can develop with GUI tools or from the command line. On your own, nothing can stop you. You code as if your mind and your fingers are one to create elegant, perfectly commented, source for an app you know will take the world by storm. + +But what happens when you’re tasked with collaborating on a project? Or what about when that app you’ve developed becomes bigger than just you? What’s the next step? If you want to successfully collaborate with other developers, you’ll want to make use of a distributed version control system. With such a system, collaborating on a project becomes incredibly efficient and reliable. One such system is [Git][1]. Along with Git comes a handy repository called [GitHub][2], where you can house your projects, such that a team can check out and check in code. + +I will walk you through the very basics of getting Git up and running and using it with GitHub, so the development on your game-changing app can be taken to the next level. I’ll be demonstrating on Ubuntu 18.04, so if your distribution of choice is different, you’ll only need to modify the Git install commands to suit your distribution’s package manager. + +### Git and GitHub + +The first thing to do is create a free GitHub account. Head over to the [GitHub signup page][3] and fill out the necessary information. Once you’ve done that, you’re ready to move on to installing Git (you can actually do these two steps in any order). + +Installing Git is simple. Open up a terminal window and issue the command: +``` +sudo apt install git-all + +``` + +This will include a rather large number of dependencies, but you’ll wind up with everything you need to work with Git and GitHub. + +On a side note: I use Git quite a bit to download source for application installation. There are times when a piece of software isn’t available via the built-in package manager. Instead of downloading the source files from a third-party location, I’ll often go the project’s Git page and clone the package like so: +``` +git clone ADDRESS + +``` + +Where ADDRESS is the URL given on the software’s Git page. +Doing this most always ensures I am installing the latest release of a package. + +Create a local repository and add a file + +The next step is to create a local repository on your system (we’ll call it newproject and house it in ~/). Open up a terminal window and issue the commands: +``` +cd ~/ + +mkdir newproject + +cd newproject + +``` + +Now we must initialize the repository. In the ~/newproject folder, issue the command git init. When the command completes, you should see that the empty Git repository has been created (Figure 1). + +![new repository][5] + +Figure 1: Our new repository has been initialized. + +[Used with permission][6] + +Next we need to add a file to the project. From within the root folder (~/newproject) issue the command: +``` +touch readme.txt + +``` + +You will now have an empty file in your repository. Issue the command git status to verify that Git is aware of the new file (Figure 2). + +![readme][8] + +Figure 2: Git knows about our readme.txt file. + +[Used with permission][6] + +Even though Git is aware of the file, it hasn’t actually been added to the project. To do that, issue the command: +``` +git add readme.txt + +``` + +Once you’ve done that, issue the git status command again to see that readme.txt is now considered a new file in the project (Figure 3). + +![file added][10] + +Figure 3: Our file now has now been added to the staging environment. + +[Used with permission][6] + +### Your first commit + +With the new file in the staging environment, you are now ready to create your first commit. What is a commit? Easy: A commit is a record of the files you’ve changed within the project. Creating the commit is actually quite simple. It is important, however, that you include a descriptive message for the commit. By doing this, you are adding notes about what the commit contains (such as what changes you’ve made to the file). Before we do this, however, we have to inform Git who we are. To do this, issue the command: +``` +git config --global user.email EMAIL + +git config --global user.name “FULL NAME” + +``` + +Where EMAIL is your email address and FULL NAME is your name. + +Now we can create the commit by issuing the command: +``` +git commit -m “Descriptive Message” + +``` + +Where Descriptive Message is your message about the changes within the commit. For example, since this is the first commit for the readme.txt file, the commit could be: +``` +git commit -m “First draft of readme.txt file” + +``` + +You should see output indicating that 1 file has changed and a new mode was created for readme.txt (Figure 4). + +![success][12] + +Figure 4: Our commit was successful. + +[Used with permission][6] + +### Create a branch and push it to GitHub + +Branches are important, as they allow you to move between project states. Let’s say you want to create a new feature for your game-changing app. To do that, create a new branch. Once you’ve completed work on the feature you can merge this feature from the branch to the master branch. To create the new branch, issue the command: + +git checkout -b BRANCH + +where BRANCH is the name of the new branch. Once the command completes, issue the command git branch to see that it has been created (Figure 5). + +![featureX][14] + +Figure 5: Our new branch, called featureX. + +[Used with permission][6] + +Next we need to create a repository on GitHub. If you log into your GitHub account, click the New Repository button from your account main page. Fill out the necessary information and click Create repository (Figure 6). + +![new repository][16] + +Figure 6: Creating the new repository on GitHub. + +[Used with permission][6] + +After creating the repository, you will be presented with a URL to use for pushing our local repository. To do this, go back to the terminal window (still within ~/newproject) and issue the commands: +``` +git remote add origin URL + +git push -u origin master + +``` + +Where URL is the url for our new GitHub repository. + +You will be prompted for your GitHub username and password. Once you successfully authenticate, the project will be pushed to your GitHub repository and you’re ready to go. + +### Pulling the project + +Say your collaborators make changes to the code on the GitHub project and have merged those changes. You will then need to pull the project files to your local machine, so the files you have on your system match those on the remote account. To do this, issue the command (from within ~/newproject): +``` +git pull origin master + +``` + +The above command will pull down any new or changed files to your local repository. + +### The very basics + +And that is the very basics of using Git from the command line to work with a project stored on GitHub. There is quite a bit more to learn, so I highly recommend you issue the commands man git, man git-push, and man git-pull to get a more in-depth understanding of what the git command can do. + +Happy developing! + +Learn more about Linux through the free ["Introduction to Linux" ][17]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/7/introduction-using-git + +作者:[Jack Wallen][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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 +[1]:https://git-scm.com/ +[2]:https://github.com/ +[3]:https://github.com/join?source=header-home +[4]:/files/images/git1jpg +[5]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/git_1.jpg?itok=FKkr5Mrk (new repository) +[6]:https://www.linux.com/licenses/category/used-permission +[7]:/files/images/git2jpg +[8]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/git_2.jpg?itok=54G9KBHS (readme) +[9]:/files/images/git3jpg +[10]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/git_3.jpg?itok=KAJwRJIB (file added) +[11]:/files/images/git4jpg +[12]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/git_4.jpg?itok=qR0ighDz (success) +[13]:/files/images/git5jpg +[14]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/git_5.jpg?itok=6m9RTWg6 (featureX) +[15]:/files/images/git6jpg +[16]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/git_6.jpg?itok=d2toRrUq (new repository) +[17]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180720 How to build a URL shortener with Apache.md b/sources/tech/20180720 How to build a URL shortener with Apache.md new file mode 100644 index 0000000000..ede90814af --- /dev/null +++ b/sources/tech/20180720 How to build a URL shortener with Apache.md @@ -0,0 +1,82 @@ +How to build a URL shortener with Apache +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openweb-osdc-lead.png?itok=yjU4KliG) + +Long ago, folks started sharing links on Twitter. The 140-character limit meant that URLs might consume most (or all) of a tweet, so people turned to URL shorteners. Eventually, Twitter added a built-in URL shortener ([t.co][1]). + +Character count isn't as important now, but there are still other reasons to shorten links. For one, the shortening service may provide analytics—you can see how popular the links are that you share. It also simplifies making easy-to-remember URLs. For example, [bit.ly/INtravel][2] is much easier to remember than . And URL shorteners can come in handy if you want to pre-share a link but don't know the final destination yet. + +Like any technology, URL shorteners aren't all positive. By masking the ultimate destination, shortened links can be used to direct people to malicious or offensive content. But if you surf carefully, URL shorteners are a useful tool. + +We [covered shorteners previously][3] on this site, but maybe you want to run something simple that's powered by a text file. In this article, we'll show how to use the Apache HTTP server's mod_rewrite feature to set up your own URL shortener. If you're not familiar with the Apache HTTP server, check out David Both's article on [installing and configuring][4] it. + +### Create a VirtualHost + +In this tutorial, I'm assuming you bought a cool domain that you'll use exclusively for the URL shortener. For example, my website is [funnelfiasco.com][5] , so I bought [funnelfias.co][6] to use for my URL shortener (okay, it's not exactly short, but it feeds my vanity). If you won't run the shortener as a separate domain, skip to the next section. + +The first step is to set up the VirtualHost that will be used for the URL shortener. For more information on VirtualHosts, see [David Both's article][7]. This setup requires just a few basic lines: +``` +    + +        ServerName funnelfias.co + +    + +``` + +### Create the rewrites + +This service uses HTTPD's rewrite engine to rewrite the URLs. If you created a VirtualHost in the section above, the configuration below goes into your VirtualHost section. Otherwise, it goes in the VirtualHost or main HTTPD configuration for your server. +``` +    RewriteEngine on + +    RewriteMap shortlinks txt:/data/web/shortlink/links.txt + +    RewriteRule ^/(.+)$ ${shortlinks:$1} [R=temp,L] + +``` + +The first line simply enables the rewrite engine. The second line builds a map of the short links from a text file. The path above is only an example; you will need to use a valid path on your system (make sure it's readable by the user account that runs HTTPD). The last line rewrites the URL. In this example, it takes any characters and looks them up in the rewrite map. You may want to have your rewrites use a particular string at the beginning. For example, if you wanted all your shortened links to be of the form "slX" (where X is a number), you would replace `(.+)` above with `(sl\d+)`. + +I used a temporary (HTTP 302) redirect here. This allows me to update the destination URL later. If you want the short link to always point to the same target, you can use a permanent (HTTP 301) redirect instead. Replace `temp` on line three with `permanent`. + +### Build your map + +Edit the file you specified on the `RewriteMap` line of the configuration. The format is a space-separated key-value store. Put one link on each line: +``` +    osdc https://opensource.com/users/bcotton + +    twitter https://twitter.com/funnelfiasco + +    swody1 https://www.spc.noaa.gov/products/outlook/day1otlk.html + +``` + +### Restart HTTPD + +The last step is to restart the HTTPD process. This is done with `systemctl restart httpd` or similar (the command and daemon name may differ by distribution). Your link shortener is now up and running. When you're ready to edit your map, you don't need to restart the web server. All you have to do is save the file, and the web server will pick up the differences. + +### Future work + +This example gives you a basic URL shortener. It can serve as a good starting point if you want to develop your own management interface as a learning project. Or you can just use it to share memorable links to forgettable URLs. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/apache-url-shortener + +作者:[Ben Cotton][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/bcotton +[1]:http://t.co +[2]:http://bit.ly/INtravel +[3]:https://opensource.com/article/17/3/url-link-shortener +[4]:https://opensource.com/article/18/2/how-configure-apache-web-server +[5]:http://funnelfiasco.com +[6]:http://funnelfias.co +[7]:https://opensource.com/article/18/3/configuring-multiple-web-sites-apache diff --git a/sources/tech/20180723 4 open source media conversion tools for the Linux desktop.md b/sources/tech/20180723 4 open source media conversion tools for the Linux desktop.md new file mode 100644 index 0000000000..48d7d83362 --- /dev/null +++ b/sources/tech/20180723 4 open source media conversion tools for the Linux desktop.md @@ -0,0 +1,71 @@ +4 open source media conversion tools for the Linux desktop +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_newmedia.png?itok=imgehG2v) + +Ah, so many file formats—especially audio and video ones—can make for fun times if you get a file with an extension you don't recognize, if your media player doesn't play a file in that format, or if you want to use an open format. + +So, what can a Linux user do? Turn to one of the many open source media conversion tools for the Linux desktop, of course. Let's take a look at four of them. + +### Gnac + +![](https://opensource.com/sites/default/files/uploads/gnac.png) + +[Gnac][1] is one of my favorite audio converters and has been for years. It's easy to use, it's powerful, and it does one thing well—as any top-notch utility should. + +How easy? You click a toolbar button to add one or more files to convert, choose a format to convert to, and then click **Convert**. The conversions are quick, and they're clean. + +How powerful? Gnac can handle all the audio formats that the [GStreamer][2] multimedia framework supports. Out of the box, you can convert between Ogg, FLAC, AAC, MP3, WAV, and SPX. You can also change the conversion options for each format or add new ones. + +### SoundConverter + +![](https://opensource.com/sites/default/files/uploads/soundconverter.png) + +If simplicity with a few extra features is your thing, then give [SoundConverter][3] a look. As its name states, SoundConverter works its magic only on audio files. Like Gnac, it can read the formats that GStreamer supports, and it can spit out Ogg Vorbis, MP3, FLAC, WAV, AAC, and Opus files. + +Load individual files or an entire folder by either clicking **Add File** or dragging and dropping it into the SoundConverter window. Click **Convert** , and the software powers through the conversion. It's fast, too—I've converted a folder containing a couple dozen files in about a minute. + +SoundConverter has options for setting the quality of your converted files. You can change the way files are named (for example, include a track number or album name in the title) and create subfolders for the converted files. + +### WinFF + +![](https://opensource.com/sites/default/files/uploads/winff.png) + +[WinFF][4], on its own, isn't a converter. It's a graphical frontend to FFmpeg, which [Tim Nugent looked at][5] for Opensource.com. While WinFF doesn't have all the flexibility of FFmpeg, it makes FFmpeg easier to use and gets the job done quickly and fairly easily. + +Although it's not the prettiest application out there, WinFF doesn't need to be. It's more than usable. You can choose what formats to convert to from a dropdown list and select several presets. On top of that, you can specify options like bitrates and frame rates, the number of audio channels to use, and even the size at which to crop videos. + +The conversions, especially video, take a bit of time, but the results are generally quite good. Once in a while, the conversion gets a bit mangled—but not often enough to be a concern. And, as I said earlier, using WinFF can save me a bit of time. + +### Miro Video Converter + +![](https://opensource.com/sites/default/files/uploads/miro-main-window.png) + +Not all video files are created equally. Some are in proprietary formats. Others look great on a monitor or TV screen but aren't optimized for a mobile device. That's where [Miro Video Converter][6] comes to the rescue. + +Miro Video Converter has a heavy emphasis on mobile. It can convert video that you can play on Android phones, Apple devices, the PlayStation Portable, and the Kindle Fire. It will convert most common video formats to MP4, [WebM][7] , and [Ogg Theora][8] . You can find a full list of supported devices and formats [on Miro's website][6] + +To use it, either drag and drop a file into the window or select the file that you want to convert. Then, click the Format menu to choose the format for the conversion. You can also click the Apple, Android, or Other menus to choose a device for which you want to convert the file. Miro Video Converter resizes the video for the device's screen resolution. + +Do you have a favorite Linux media conversion application? Feel free to share it by leaving a comment. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/media-conversion-tools-linux + +作者:[Scott Nesbitt][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/scottnesbitt +[1]:http://gnac.sourceforge.net +[2]:http://www.gstreamer.net/ +[3]:http://soundconverter.org/ +[4]:https://www.biggmatt.com/winff/ +[5]:https://opensource.com/article/17/6/ffmpeg-convert-media-file-formats +[6]:http://www.mirovideoconverter.com/ +[7]:https://en.wikipedia.org/wiki/WebM +[8]:https://en.wikipedia.org/wiki/Ogg_theora diff --git a/sources/tech/20180723 Setting Up a Timer with systemd in Linux.md b/sources/tech/20180723 Setting Up a Timer with systemd in Linux.md new file mode 100644 index 0000000000..27841dec61 --- /dev/null +++ b/sources/tech/20180723 Setting Up a Timer with systemd in Linux.md @@ -0,0 +1,165 @@ +Setting Up a Timer with systemd in Linux +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/clock-650753_1920.jpg?itok=RiRyCbAP) + +Previously, we saw how to enable and disable systemd services [by hand][1], [at boot time and on power down][2], [when a certain device is activated][3], and [when something changes in the filesystem][4]. + +Timers add yet another way of starting services, based on... well, time. Although similar to cron jobs, systemd timers are slightly more flexible. Let's see how they work. + +### "Run when" + +Let's expand the [Minetest][5] [service you set up][1] in [the first two articles of this series][2] as our first example on how to use timer units. If you haven't read those articles yet, you may want to go and give them a look now. + +So you will "improve" your Minetest set up by creating a timer that will run the game's server 1 minute after boot up has finished instead of right away. The reason for this could be that, as you want your service to do other stuff, like send emails to the players telling them the game is available, you will want to make sure other services (like the network) are fully up and running before doing anything fancy. + +Jumping in at the deep end, your _minetest.timer_ unit will look like this: +``` +# minetest.timer +[Unit] +Description=Runs the minetest.service 1 minute after boot up + +[Timer] +OnBootSec=1 m +Unit=minetest.service + +[Install] +WantedBy=basic.target + +``` + +Not hard at all. + +As usual, you have a `[Unit]` section with a description of what the unit does. Nothing new there. The `[Timer]` section is new, but it is pretty self-explanatory: it contains information on when the service will be triggered and the service to trigger. In this case, the `OnBootSec` is the directive you need to tell systemd to run the service after boot has finished. + +Other directives you could use are: + + * `OnActiveSec=`, which tells systemd how long to wait after the timer itself is activated before starting the service. + * `OnStartupSec=`, on the other hand, tells systemd how long to wait after systemd was started before starting the service. + * `OnUnitActiveSec=` tells systemd how long to wait after the service the timer is activating was last activated. + * `OnUnitInactiveSec=` tells systemd how long to wait after the service the timer is activating was last deactivated. + + + +Continuing down the _minetest.timer_ unit, the `basic.target` is usually used as a synchronization point for late boot services. This means it makes _minetest.timer_ wait until local mount points and swap devices are mounted, sockets, timers, path units and other basic initialization processes are running before letting _minetest.timer_ start. As we explained in [the second article on systemd units][2], _targets_ are like the old run levels and can be used to put your machine into one state or another, or, like here, to tell your service to wait until a certain state has been reached. + +The _minetest.service_ you developed in the first two articles [ended up][2] looking like this: +``` +# minetest.service +[Unit] +Description= Minetest server +Documentation= https://wiki.minetest.net/Main_Page + +[Service] +Type= simple +User= + +ExecStart= /usr/games/minetest --server +ExecStartPost= /home//bin/mtsendmail.sh "Ready to rumble?" "Minetest Starting up" + +TimeoutStopSec= 180 +ExecStop= /home//bin/mtsendmail.sh "Off to bed. Nightie night!" "Minetest Stopping in 2 minutes" +ExecStop= /bin/sleep 120 +ExecStop= /bin/kill -2 $MAINPID + +[Install] +WantedBy= multi-user.target + +``` + +There’s nothing you need to change here. But you do have to change _mtsendmail.sh_ (your email sending script) from this: +``` +#!/bin/bash +# mtsendmail +sleep 20 +echo $1 | mutt -F /home//.muttrc -s "$2" my_minetest@mailing_list.com +sleep 10 + +``` + +to this: +``` +#!/bin/bash +# mtsendmail.sh +echo $1 | mutt -F /home/paul/.muttrc -s "$2" pbrown@mykolab.com + +``` + +What you are doing is stripping out those hacky pauses in the Bash script. Systemd does the waiting now. + +### Making it work + +To make sure things work, disable _minetest.service_ : +``` +sudo systemctl disable minetest + +``` + +so it doesn't get started when the system starts; and, instead, enable _minetest.timer_ : +``` +sudo systemctl enable minetest.timer + +``` + +Now you can reboot you server machine and, when you run `sudo journalctl -u minetest.*` you will see how, first the _minetest.timer_ unit gets executed and then the _minetest.service_ starts up after a minute... more or less. + +![minetest timer][7] + +Figure 1: The minetest.service gets started one minute after the minetest.timer... more or less. + +[Used with permission][8] + +### A Matter of Time + +A couple of clarifications about why the _minetest.timer_ entry in the systemd's Journal shows its start time as 09:08:33, while the _minetest.service_ starts at 09:09:18, that is less than a minute later: First, remember we said that the `OnBootSec=` directive calculates when to start a service from when boot is complete. By the time _minetest.timer_ comes along, boot has finished a few seconds ago. + +The other thing is that systemd gives itself a margin of error (by default, 1 minute) to run stuff. This helps distribute the load when several resource-intensive processes are running at the same time: by giving itself a minute, systemd can wait for some processes to power down. This also means that _minetest.service_ will start somewhere between the 1 minute and 2 minute mark after boot is completed, but when exactly within that range is anybody's guess. + +For the record, [you can change the margin of error with `AccuracySec=` directive][9]. + +Another thing you can do is check when all the timers on your system are scheduled to run or the last time the ran: +``` +systemctl list-timers --all + +``` + +![check timer][11] + +Figure 2: Check when your timers are scheduled to fire or when they fired last. + +[Used with permission][8] + +The final thing to take into consideration is the format you should use to express the periods of time. Systemd is very flexible in that respect: `2 h`, `2 hours` or `2hr` will all work to express a 2 hour delay. For seconds, you can use `seconds`, `second`, `sec`, and `s`, the same way as for minutes you can use `minutes`, `minute`, `min`, and `m`. You can see a full list of time units systemd understands by checking `man systemd.time`. + +### Next Time + +You'll see how to use calendar dates and times to run services at regular intervals and how to combine timers and device units to run services at defined point in time after you plug in some hardware. + +See you then! + +Learn more about Linux through the free ["Introduction to Linux" ][12]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/intro-to-linux/2018/7/setting-timer-systemd-linux + +作者:[Paul Brown][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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 +[1]:https://www.linux.com/blog/learn/intro-to-linux/2018/5/writing-systemd-services-fun-and-profit +[2]:https://www.linux.com/blog/learn/2018/5/systemd-services-beyond-starting-and-stopping +[3]:https://www.linux.com/blog/intro-to-linux/2018/6/systemd-services-reacting-change +[4]:https://www.linux.com/blog/learn/intro-to-linux/2018/6/systemd-services-monitoring-files-and-directories +[5]:https://www.minetest.net/ +[6]:/files/images/minetest-timer-1png +[7]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/minetest-timer-1.png?itok=TG0xJvYM (minetest timer) +[8]:/licenses/category/used-permission +[9]:https://www.freedesktop.org/software/systemd/man/systemd.timer.html#AccuracySec= +[10]:/files/images/minetest-timer-2png +[11]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/minetest-timer-2.png?itok=pYxyVx8- (check timer) +[12]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180724 Building a network attached storage device with a Raspberry Pi.md b/sources/tech/20180724 Building a network attached storage device with a Raspberry Pi.md new file mode 100644 index 0000000000..4083023ca4 --- /dev/null +++ b/sources/tech/20180724 Building a network attached storage device with a Raspberry Pi.md @@ -0,0 +1,285 @@ +translating by wyxplus +Building a network attached storage device with a Raspberry Pi +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus-storage.png?itok=95-zvHYl) + +In this three-part series, I'll explain how to set up a simple, useful NAS (network attached storage) system. I use this kind of setup to store my files on a central system, creating incremental backups automatically every night. To mount the disk on devices that are located in the same network, NFS is installed. To access files offline and share them with friends, I use [Nextcloud][1]. + +This article will cover the basic setup of software and hardware to mount the data disk on a remote device. In the second article, I will discuss a backup strategy and set up a cron job to create daily backups. In the third and last article, we will install Nextcloud, a tool for easy file access to devices synced offline as well as online using a web interface. It supports multiple users and public file-sharing so you can share pictures with friends, for example, by sending a password-protected link. + +The target architecture of our system looks like this: +![](https://opensource.com/sites/default/files/uploads/nas_part1.png) + +### Hardware + +Let's get started with the hardware you need. You might come up with a different shopping list, so consider this one an example. + +The computing power is delivered by a [Raspberry Pi 3][2], which comes with a quad-core CPU, a gigabyte of RAM, and (somewhat) fast ethernet. Data will be stored on two USB hard drives (I use 1-TB disks); one is used for the everyday traffic, the other is used to store backups. Be sure to use either active USB hard drives or a USB hub with an additional power supply, as the Raspberry Pi will not be able to power two USB drives. + +### Software + +The operating system with the highest visibility in the community is [Raspbian][3] , which is excellent for custom projects. There are plenty of [guides][4] that explain how to install Raspbian on a Raspberry Pi, so I won't go into details here. The latest official supported version at the time of this writing is [Raspbian Stretch][5] , which worked fine for me. + +At this point, I will assume you have configured your basic Raspbian and are able to connect to the Raspberry Pi by `ssh`. + +### Prepare the USB drives + +To achieve good performance reading from and writing to the USB hard drives, I recommend formatting them with ext4. To do so, you must first find out which disks are attached to the Raspberry Pi. You can find the disk devices in `/dev/sd/`. Using the command `fdisk -l`, you can find out which two USB drives you just attached. Please note that all data on the USB drives will be lost as soon as you follow these steps. +``` +pi@raspberrypi:~ $ sudo fdisk -l + + + +<...> + + + +Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors + +Units: sectors of 1 * 512 = 512 bytes + +Sector size (logical/physical): 512 bytes / 512 bytes + +I/O size (minimum/optimal): 512 bytes / 512 bytes + +Disklabel type: dos + +Disk identifier: 0xe8900690 + + + +Device     Boot Start        End    Sectors   Size Id Type + +/dev/sda1        2048 1953525167 1953523120 931.5G 83 Linux + + + + + +Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors + +Units: sectors of 1 * 512 = 512 bytes + +Sector size (logical/physical): 512 bytes / 512 bytes + +I/O size (minimum/optimal): 512 bytes / 512 bytes + +Disklabel type: dos + +Disk identifier: 0x6aa4f598 + + + +Device     Boot Start        End    Sectors   Size Id Type + +/dev/sdb1  *     2048 1953521663 1953519616 931.5G  83 Linux + +``` + +As those devices are the only 1TB disks attached to the Raspberry Pi, we can easily see that `/dev/sda` and `/dev/sdb` are the two USB drives. The partition table at the end of each disk shows how it should look after the following steps, which create the partition table and format the disks. To do this, repeat the following steps for each of the two devices by replacing `sda` with `sdb` the second time (assuming your devices are also listed as `/dev/sda` and `/dev/sdb` in `fdisk`). + +First, delete the partition table of the disk and create a new one containing only one partition. In `fdisk`, you can use interactive one-letter commands to tell the program what to do. Simply insert them after the prompt `Command (m for help):` as follows (you can also use the `m` command anytime to get more information): +``` +pi@raspberrypi:~ $ sudo fdisk /dev/sda + + + +Welcome to fdisk (util-linux 2.29.2). + +Changes will remain in memory only, until you decide to write them. + +Be careful before using the write command. + + + + + +Command (m for help): o + +Created a new DOS disklabel with disk identifier 0x9c310964. + + + +Command (m for help): n + +Partition type + +   p   primary (0 primary, 0 extended, 4 free) + +   e   extended (container for logical partitions) + +Select (default p): p + +Partition number (1-4, default 1): + +First sector (2048-1953525167, default 2048): + +Last sector, +sectors or +size{K,M,G,T,P} (2048-1953525167, default 1953525167): + + + +Created a new partition 1 of type 'Linux' and of size 931.5 GiB. + + + +Command (m for help): p + + + +Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors + +Units: sectors of 1 * 512 = 512 bytes + +Sector size (logical/physical): 512 bytes / 512 bytes + +I/O size (minimum/optimal): 512 bytes / 512 bytes + +Disklabel type: dos + +Disk identifier: 0x9c310964 + + + +Device     Boot Start        End    Sectors   Size Id Type + +/dev/sda1        2048 1953525167 1953523120 931.5G 83 Linux + + + +Command (m for help): w + +The partition table has been altered. + +Syncing disks. + +``` + +Now we will format the newly created partition `/dev/sda1` using the ext4 filesystem: +``` +pi@raspberrypi:~ $ sudo mkfs.ext4 /dev/sda1 + +mke2fs 1.43.4 (31-Jan-2017) + +Discarding device blocks: done + + + +<...> + + + +Allocating group tables: done + +Writing inode tables: done + +Creating journal (1024 blocks): done + +Writing superblocks and filesystem accounting information: done + +``` + +After repeating the above steps, let's label the new partitions according to their usage in your system: +``` +pi@raspberrypi:~ $ sudo e2label /dev/sda1 data + +pi@raspberrypi:~ $ sudo e2label /dev/sdb1 backup + +``` + +Now let's get those disks mounted to store some data. My experience, based on running this setup for over a year now, is that USB drives are not always available to get mounted when the Raspberry Pi boots up (for example, after a power outage), so I recommend using autofs to mount them when needed. + +First install autofs and create the mount point for the storage: +``` +pi@raspberrypi:~ $ sudo apt install autofs + +pi@raspberrypi:~ $ sudo mkdir /nas + +``` + +Then mount the devices by adding the following line to `/etc/auto.master`: +``` +/nas    /etc/auto.usb + +``` + +Create the file `/etc/auto.usb` if not existing with the following content, and restart the autofs service: +``` +data -fstype=ext4,rw :/dev/disk/by-label/data + +backup -fstype=ext4,rw :/dev/disk/by-label/backup + +pi@raspberrypi3:~ $ sudo service autofs restart + +``` + +Now you should be able to access the disks at `/nas/data` and `/nas/backup`, respectively. Clearly, the content will not be too thrilling, as you just erased all the data from the disks. Nevertheless, you should be able to verify the devices are mounted by executing the following commands: +``` +pi@raspberrypi3:~ $ cd /nas/data + +pi@raspberrypi3:/nas/data $ cd /nas/backup + +pi@raspberrypi3:/nas/backup $ mount + +<...> + +/etc/auto.usb on /nas type autofs (rw,relatime,fd=6,pgrp=463,timeout=300,minproto=5,maxproto=5,indirect) + +<...> + +/dev/sda1 on /nas/data type ext4 (rw,relatime,data=ordered) + +/dev/sdb1 on /nas/backup type ext4 (rw,relatime,data=ordered) + +``` + +First move into the directories to make sure autofs mounts the devices. Autofs tracks access to the filesystems and mounts the needed devices on the go. Then the `mount` command shows that the two devices are actually mounted where we wanted them. + +Setting up autofs is a bit fault-prone, so do not get frustrated if mounting doesn't work on the first try. Give it another chance, search for more detailed resources (there is plenty of documentation online), or leave a comment. + +### Mount network storage + +Now that you have set up the basic network storage, we want it to be mounted on a remote Linux machine. We will use the network file system (NFS) for this. First, install the NFS server on the Raspberry Pi: +``` +pi@raspberrypi:~ $ sudo apt install nfs-kernel-server + +``` + +Next we need to tell the NFS server to expose the `/nas/data` directory, which will be the only device accessible from outside the Raspberry Pi (the other one will be used for backups only). To export the directory, edit the file `/etc/exports` and add the following line to allow all devices with access to the NAS to mount your storage: +``` +/nas/data *(rw,sync,no_subtree_check) + +``` + +For more information about restricting the mount to single devices and so on, refer to `man exports`. In the configuration above, anyone will be able to mount your data as long as they have access to the ports needed by NFS: `111` and `2049`. I use the configuration above and allow access to my home network only for ports 22 and 443 using the routers firewall. That way, only devices in the home network can reach the NFS server. + +To mount the storage on a Linux computer, run the commands: +``` +you@desktop:~ $ sudo mkdir /nas/data + +you@desktop:~ $ sudo mount -t nfs :/nas/data /nas/data + +``` + +Again, I recommend using autofs to mount this network device. For extra help, check out [How to use autofs to mount NFS shares][6]. + +Now you are able to access files stored on your own RaspberryPi-powered NAS from remote devices using the NFS mount. In the next part of this series, I will cover how to automatically back up your data to the second hard drive using `rsync`. To save space on the device while still doing daily backups, you will learn how to create incremental backups with `rsync`. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/network-attached-storage-Raspberry-Pi + +作者:[Manuel Dewald][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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 +[1]:https://nextcloud.com/ +[2]:https://www.raspberrypi.org/products/raspberry-pi-3-model-b/ +[3]:https://www.raspbian.org/ +[4]:https://www.raspberrypi.org/documentation/installation/installing-images/ +[5]:https://www.raspberrypi.org/blog/raspbian-stretch/ +[6]:https://opensource.com/article/18/6/using-autofs-mount-nfs-shares diff --git a/sources/tech/20180724 How To Mount Google Drive Locally As Virtual File System In Linux.md b/sources/tech/20180724 How To Mount Google Drive Locally As Virtual File System In Linux.md new file mode 100644 index 0000000000..3f804ffe9e --- /dev/null +++ b/sources/tech/20180724 How To Mount Google Drive Locally As Virtual File System In Linux.md @@ -0,0 +1,265 @@ +How To Mount Google Drive Locally As Virtual File System In Linux +====== + +![](https://www.ostechnix.com/wp-content/uploads/2018/07/Google-Drive-720x340.png) + +[**Google Drive**][1] is the one of the popular cloud storage provider on the planet. As of 2017, over 800 million users are actively using this service worldwide. Even though the number of users have dramatically increased, Google haven’t released a Google drive client for Linux yet. But it didn’t stop the Linux community. Every now and then, some developers had brought few google drive clients for Linux operating system. In this guide, we will see three unofficial google drive clients for Linux. Using these clients, you can mount Google drive locally as a virtual file system and access your drive files in your Linux box. Read on. + +### 1. Google-drive-ocamlfuse + +The **google-drive-ocamlfuse** is a FUSE filesystem for Google Drive, written in OCaml. For those wondering, FUSE, stands for **F** ilesystem in **Use** rspace, is a project that allows the users to create virtual file systems in user level. **google-drive-ocamlfuse** allows you to mount your Google Drive on Linux system. It features read/write access to ordinary files and folders, read-only access to Google docks, sheets, and slides, support for multiple google drive accounts, duplicate file handling, access to your drive trash directory, and more. + +#### Installing google-drive-ocamlfuse + +google-drive-ocamlfuse is available in the [**AUR**][2], so you can install it using any AUR helper programs, for example [**Yay**][3]. +``` +$ yay -S google-drive-ocamlfuse + +``` + +On Ubuntu: +``` +$ sudo add-apt-repository ppa:alessandro-strada/ppa +$ sudo apt-get update +$ sudo apt-get install google-drive-ocamlfuse + +``` + +To install latest beta version, do: +``` +$ sudo add-apt-repository ppa:alessandro-strada/google-drive-ocamlfuse-beta +$ sudo apt-get update +$ sudo apt-get install google-drive-ocamlfuse + +``` + +#### Usage + +Once installed, run the following command to launch **google-drive-ocamlfuse** utility from your Terminal: +``` +$ google-drive-ocamlfuse + +``` + +When you run this first time, the utility will open your web browser and ask your permission to authorize your google drive files. Once you gave authorization, all necessary config files and folders it needs to mount your google drive will be automatically created. + +![][5] + +After successful authentication, you will see the following message in your Terminal. +``` +Access token retrieved correctly. + +``` + +You’re good to go now. Close the web browser and then create a mount point to mount your google drive files. +``` +$ mkdir ~/mygoogledrive + +``` + +Finally, mount your google drive using command: +``` +$ google-drive-ocamlfuse ~/mygoogledrive + +``` + +Congratulations! You can access access your files either from Terminal or file manager. + +From **Terminal** : +``` +$ ls ~/mygoogledrive + +``` + +From **File manager** : + +![][6] + +If you have more than one account, use **label** option to distinguish different accounts like below. +``` +$ google-drive-ocamlfuse -label label [mountpoint] + +``` + +Once you’re done, unmount the FUSE flesystem using command: +``` +$ fusermount -u ~/mygoogledrive + +``` + +For more details, refer man pages. +``` +$ google-drive-ocamlfuse --help + +``` + +Also, do check the [**official wiki**][7] and the [**project GitHub repository**][8] for more details. + +### 2. GCSF + +**GCSF** is a FUSE filesystem based on Google Drive, written using **Rust** programming language. The name GCSF has come from the Romanian word “ **G** oogle **C** onduce **S** istem de **F** ișiere”, which means “Google Drive Filesystem” in English. Using GCSF, you can mount your Google drive as a local virtual file system and access the contents from the Terminal or file manager. You might wonder how it differ from other Google Drive FUSE projects, for example **google-drive-ocamlfuse**. The developer of GCSF replied to a similar [comment on Reddit][9] “GCSF tends to be faster in several cases (listing files recursively, reading large files from Drive). The caching strategy it uses also leads to very fast reads (x4-7 improvement compared to google-drive-ocamlfuse) for files that have been cached, at the cost of using more RAM“. + +#### Installing GCSF + +GCSF is available in the [**AUR**][10], so the Arch Linux users can install it using any AUR helper, for example [**Yay**][3]. +``` +$ yay -S gcsf-git + +``` + +For other distributions, do the following. + +Make sure you have installed Rust on your system. + +Make sure **pkg-config** and the **fuse** packages are installed. They are available in the default repositories of most Linux distributions. For example, on Ubuntu and derivatives, you can install them using command: +``` +$ sudo apt-get install -y libfuse-dev pkg-config + +``` + +Once all dependencies installed, run the following command to install GCSF: +``` +$ cargo install gcsf + +``` + +#### Usage + +First, we need to authorize our google drive. To do so, simply run: +``` +$ gcsf login ostechnix + +``` + +You must specify a session name. Replace **ostechnix** with your own session name. You will see an output something like below with an URL to authorize your google drive account. + +![][11] + +Just copy and navigate to the above URL from your browser and click **allow** to give permission to access your google drive contents. Once you gave the authentication you will see an output like below. +``` +Successfully logged in. Credentials saved to "/home/sk/.config/gcsf/ostechnix". + +``` + +GCSF will create a configuration file in **$XDG_CONFIG_HOME/gcsf/gcsf.toml** , which is usually defined as **$HOME/.config/gcsf/gcsf.toml**. Credentials are stored in the same directory. + +Next, create a directory to mount your google drive contents. +``` +$ mkdir ~/mygoogledrive + +``` + +Then, edit **/etc/fuse.conf** file: +``` +$ sudo vi /etc/fuse.conf + +``` + +Uncomment the following line to allow non-root users to specify the allow_other or allow_root mount options. +``` +user_allow_other + +``` + +Save and close the file. + +Finally, mount your google drive using command: +``` +$ gcsf mount ~/mygoogledrive -s ostechnix + +``` + +Sample output: +``` +INFO gcsf > Creating and populating file system... +INFO gcsf > File sytem created. +INFO gcsf > Mounting to /home/sk/mygoogledrive +INFO gcsf > Mounted to /home/sk/mygoogledrive +INFO gcsf::gcsf::file_manager > Checking for changes and possibly applying them. +INFO gcsf::gcsf::file_manager > Checking for changes and possibly applying them. + +``` + +Again, replace **ostechnix** with your session name. You can view the existing sessions using command: +``` +$ gcsf list +Sessions: +- ostechnix + +``` + +You can now access your google drive contents either from the Terminal or from File manager. + +From **Terminal** : +``` +$ ls ~/mygoogledrive + +``` + +From **File manager** : + +![][12] + +If you don’t know where your Google drive is mounted, use **df** or **mount** command as shown below. +``` +$ df -h +Filesystem Size Used Avail Use% Mounted on +udev 968M 0 968M 0% /dev +tmpfs 200M 1.6M 198M 1% /run +/dev/sda1 20G 7.5G 12G 41% / +tmpfs 997M 0 997M 0% /dev/shm +tmpfs 5.0M 4.0K 5.0M 1% /run/lock +tmpfs 997M 0 997M 0% /sys/fs/cgroup +tmpfs 200M 40K 200M 1% /run/user/1000 +GCSF 15G 857M 15G 6% /home/sk/mygoogledrive + +$ mount | grep GCSF +GCSF on /home/sk/mygoogledrive type fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000,allow_other) + +``` + +Once done, unmount the google drive using command: +``` +$ fusermount -u ~/mygoogledrive + +``` + +Check the [**GCSF GitHub repository**][13] for more details. + +### 3. Tuxdrive + +**Tuxdrive** is yet another unofficial google drive client for Linux. We have written a detailed guide about Tuxdrive a while ago. Please check the following link. + +Of course, there were few other unofficial google drive clients available in the past, such as Grive2, Syncdrive. But it seems that they are discontinued now. I will keep updating this list when I come across any active google drive clients. + +And, that’s all for now, folks. Hope this was useful. More good stuffs to come. Stay tuned! + +Cheers! + + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/how-to-mount-google-drive-locally-as-virtual-file-system-in-linux/ + +作者:[SK][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/ +[1]:https://www.google.com/drive/ +[2]:https://aur.archlinux.org/packages/google-drive-ocamlfuse/ +[3]:https://www.ostechnix.com/yay-found-yet-another-reliable-aur-helper/ +[4]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[5]:http://www.ostechnix.com/wp-content/uploads/2018/07/google-drive.png +[6]:http://www.ostechnix.com/wp-content/uploads/2018/07/google-drive-2.png +[7]:https://github.com/astrada/google-drive-ocamlfuse/wiki/Configuration +[8]:https://github.com/astrada/google-drive-ocamlfuse +[9]:https://www.reddit.com/r/DataHoarder/comments/8vlb2v/google_drive_as_a_file_system/e1oh9q9/ +[10]:https://aur.archlinux.org/packages/gcsf-git/ +[11]:http://www.ostechnix.com/wp-content/uploads/2018/07/google-drive-3.png +[12]:http://www.ostechnix.com/wp-content/uploads/2018/07/google-drive-4.png +[13]:https://github.com/harababurel/gcsf diff --git a/sources/tech/20180724 Textricator- Data extraction made simple.md b/sources/tech/20180724 Textricator- Data extraction made simple.md new file mode 100644 index 0000000000..6712fd2a3d --- /dev/null +++ b/sources/tech/20180724 Textricator- Data extraction made simple.md @@ -0,0 +1,42 @@ +translating---geekpi + +Textricator: Data extraction made simple +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/document_free_access_cut_security.png?itok=ocvCv8G2) + +You probably know the feeling: You ask for data and get a positive response, only to open the email and find a whole bunch of PDFs attached. Data, interrupted. + +We understand your frustration, and we’ve done something about it: Introducing [Textricator][1], our first open source product. + +We’re Measures for Justice, a criminal justice research and transparency organization. Our mission is to provide data transparency for the entire justice system, from arrest to post-conviction. We do this by producing a series of up to 32 performance measures covering the entire criminal justice system, county by county. We get our data in many ways—all legal, of course—and while many state and county agencies are data-savvy, giving us quality, formatted data in CSVs, the data is often bundled inside software with no simple way to get it out. PDF reports are the best they can offer. + +Developers Joe Hale and Stephen Byrne have spent the past two years developing Textricator to extract tens of thousands of pages of data for our internal use. Textricator can process just about any text-based PDF format—not just tables, but complex reports with wrapping text and detail sections generated from tools like Crystal Reports. Simply tell Textricator the attributes of the fields you want to collect, and it chomps through the document, collecting and writing out your records. + +Not a software engineer? Textricator doesn’t require programming skills; rather, the user describes the structure of the PDF and Textricator handles the rest. Most users run it via the command line; however, a browser-based GUI is available. + +We evaluated other great open source solutions like [Tabula][2], but they just couldn’t handle the structure of some of the PDFs we needed to scrape. “Textricator is both flexible and powerful and has cut the time we spend to process large datasets from days to hours,” says Andrew Branch, director of technology. + +At MFJ, we’re committed to transparency and knowledge-sharing, which includes making our software available to anyone, especially those trying to free and share data publicly. Textricator is available on [GitHub][3] and released under [GNU Affero General Public License Version 3][4]. + +You can see the results of our work, including data processed via Textricator, on our free [online data portal][5]. Textricator is an essential part of our process and we hope civic tech and government organizations alike can unlock more data with this new tool. + +If you use Textricator, let us know how it helped solve your data problem. Want to improve it? Submit a pull request. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/textricator + +作者:[Stephen Byrne][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: +[1]:https://textricator.mfj.io/ +[2]:https://tabula.technology/ +[3]:https://github.com/measuresforjustice/textricator +[4]:https://www.gnu.org/licenses/agpl-3.0.en.html +[5]:https://www.measuresforjustice.org/portal/ diff --git a/sources/tech/20180725 Best Online Linux Terminals and Online Bash Editors.md b/sources/tech/20180725 Best Online Linux Terminals and Online Bash Editors.md new file mode 100644 index 0000000000..7f430c3d59 --- /dev/null +++ b/sources/tech/20180725 Best Online Linux Terminals and Online Bash Editors.md @@ -0,0 +1,212 @@ +Best Online Linux Terminals and Online Bash Editors +====== +No matter whether you want to practice Linux commands or just analyze/test your shell scripts online, there’s always a couple of online Linux terminals and online bash compilers available. + +This is particularly helpful when you are using the Windows operating system. Though you can [install Linux inside Windows using Windows Subsystem for Linux][1], using online Linux terminals are often more convenient for a quick test. + +![Websites that allow to use Linux Terminal online][2] + +But where can you find free Linux console? Which online Linux shell should you use? + +Fret not, to save you the hassle, here, we have compiled a list of the best online Linux terminals and a separate list of best online bash compilers for you to look at. + +**Note:** All of the online terminals support several browsers that include Google Chrome, Mozilla Firefox, Opera and Microsoft Edge. + +### Best Online Linux Terminals To Practice Linux Commands + +In the first part, I’ll list the online Linux terminals. These websites allow you to run the regular Linux commands in a web browser so that you can practice or test them. Some websites may require you to register and login to save your sessions. + +#### 1. JSLinux + +![online linux terminal - jslinux][3] + +JSLinux is more like a complete Linux emulator instead of just offering you the terminal. As the name suggests, it has been entirely written in JavaScript. You get to choose a console-based system or a GUI-based online Linux system. However, in this case, you would want to launch the console-based system to practice Linux commands. To be able to connect your account, you need to sign up first. + +JSLinux also lets you upload files to the virtual machine. At its core, it utilizes [Buildroot][4] (a tool that helps you to build a complete Linux system for an embedded system). + +[Try JSLinux Terminal][5] + +#### 2. Copy.sh + +![copysh online linux terminal][6] + +Copy.sh offers one of the best online Linux terminals which is fast and reliable to test and run Linux commands. + +Copy.sh is also on [GitHub][7] – and it is being actively maintained, which is a good thing. It also supports other Operating Systems, which includes: + + * Windows 98 + * KolibriOS + * FreeDOS + * Windows 1.01 + * Archlinux + + + +[Try Copy.sh Terminal][8] + +#### 3. Webminal + +![webminal online linux terminal][9] + +Webminal is an impressive online Linux terminal – and my personal favorite when it comes to a recommendation for beginners to practice Linux commands online. + +The website offers several lessons to learn from while you type in the commands in the same window. So, you do not need to refer to another site for the lessons and then switch back or split the screen in order to practice commands. It’s all right there – in a single tab on the browser. + +[Try Webminal Terminal][10] + +#### 4. Tutorialspoint Unix Terminal + +![tutorialspoint linux terminal][11] + +You might be aware of Tutorialspoint – which happens to be one of the most popular websites with high quality (yet free) online tutorials for just about any programming language (and more). + +So, for obvious reasons, they provide a free online Linux console for you to practice commands while referring to their site as a resource at the same time. You also get the ability to upload files. It is quite simple but an effective online terminal. Also, it doesn’t stop there, it offers a lot of different online terminals as well in its [Coding Ground][12] page. + +[Try Unix Terminal Online][13] + +#### 5. JS/UIX + +![js uix online linux terminal][14] + +JS/UIX is yet another online Linux terminal which is written entirely in JavaScript without any plug-ins. It contains an online Linux virtual machine, virtual file-system, shell, and so on. + +You can go through its manual page for the list of commands implemented. + +[Try JS/UX Terminal][15] + +#### 6. CB.VU + +![online linux terminal][16] + +If you are in for a treat with FreeBSD 7.1 stable version, cb.vu is a quite simple solution for that. + +Nothing fancy, just try out the Linux commands you want and get the output. Unfortunately, you do not get the ability to upload files here. + +[Try CB.VU Terminal][17] + +#### 7. Linux Containers + +![online linux terminal][18] + +Linux Containers lets you run a demo server with a 30-minute countdown on which acts as one of the best online Linux terminals. In fact, it’s a project sponsored by Canonical. + +[Try Linux LXD][19] + +#### 8. Codeanywhere + +![online linux terminal][20] + +Codeanywhere is a service which offers cross-platform cloud IDEs. However, in order to run a free Linux virtual machine, you just need to sign up and choose the free plan. And, then, proceed to create a new connection while setting up a container with an OS of your choice. Finally, you will have a free Linux console at your disposal. + +[Try Codeanywhere Editor][21] + +### Best Online Bash Editors + +Wait a sec! Are the online Linux terminals not good enough for Bash scripting? They are. But creating bash scripts in terminal editors and then executing them is not as convinient as using an online Bash editor. + +These bash editors allow you to easily write shell scripts online and you can run them to check if it works or not. + +Let’s see here can you run shell scripts online. + +#### Tutorialspoint Bash Compiler + +![online bash compiler][22] + +As mentioned above, Tutorialspoint also offers an online Bash compiler. It is a very simple bash compiler to execute bash shell online. + +[Try Tutorialspoint Bash Compiler][23] + +#### JDOODLE + +![online bash compiler][24] + +Yet another useful online bash editor to test Bash scripts is JDOODLE. It also offers other IDEs, but we’ll focus on bash script execution here. You get to set the command line arguments and the stdin inputs, and would normally get the result of your code. + +[Try JDOODLE Bash Script Online Tester][25] + +#### Paizo.io + +![paizo online bash editor][26] + +Paizo.io is a good bash online editor that you can try for free. To utilize some of its advanced features like task scheduling, you need to first sign up. It also supports real-time collaboration, but that’s still in the experimental phase. + +[Try Paizo.io Bash Editor][27] + +#### ShellCheck + +![shell check bash check][28] + +An interesting Bash editor which lets you find bugs in your shell script. It is available on [GitHub][29] as well. In addition, you can install ShellCheck locally on [supported platforms][30]. + +[Try ShellCheck][31] + +#### Rextester + +![rextester bash editor][32] + +If you only want a dead simple online bash compiler, Rextester should be your choice. It also supports other programming languages. + +[Try Rextester][33] + +#### Learn Shell + +![online bash shell editor][34] + +Just like [Webminal][35], Learnshell provides you with the content (or resource) to learn shell programming and you could also run/try your code at the same time. It covers the basics and a few advanced topics as well. + +[Try Learn Shell Programming][36] + +### Wrapping Up + +Now that you know of the most reliable and fast online Linux terminals & online bash editors, learn, experiment, and play with the code! + +We might have missed any of your favorite online Linux terminals or maybe the best online bash compiler which you happen to use? Let us know your thoughts in the comments below. + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/online-linux-terminals/ + +作者:[Ankush Das][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/ +[1]:https://itsfoss.com/install-bash-on-windows/ +[2]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/online-linux-terminals.jpeg +[3]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/jslinux-online-linux-terminal.jpg +[4]:https://buildroot.org/ +[5]:https://bellard.org/jslinux/ +[6]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/copy-sh-online-linux-terminal.jpg +[7]:https://github.com/copy/v86 +[8]:https://copy.sh/v86/?profile=linux26 +[9]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/webminal.jpg +[10]:http://www.webminal.org/terminal/ +[11]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/coding-ground-tutorialspoint-online-linux-terminal.jpg +[12]:https://www.tutorialspoint.com/codingground.htm +[13]:https://www.tutorialspoint.com/unix_terminal_online.php +[14]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/JS-UIX-online-linux-terminal.jpg +[15]:http://www.masswerk.at/jsuix/index.html +[16]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/cb-vu-online-linux-terminal.jpg +[17]:http://cb.vu/ +[18]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/linux-containers-terminal.jpg +[19]:https://linuxcontainers.org/lxd/try-it/ +[20]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/codeanywhere-terminal.jpg +[21]:https://codeanywhere.com/editor/ +[22]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/tutorialspoint-bash-compiler.jpg +[23]:https://www.tutorialspoint.com/execute_bash_online.php +[24]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/jdoodle-online-bash-editor.jpg +[25]:https://www.jdoodle.com/test-bash-shell-script-online +[26]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/paizo-io-bash-editor.jpg +[27]:https://paiza.io/en/projects/new?language=bash +[28]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/shell-check-bash-analyzer.jpg +[29]:https://github.com/koalaman/shellcheck +[30]:https://github.com/koalaman/shellcheck#user-content-installing +[31]:https://www.shellcheck.net/# +[32]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/rextester-bash-editor.jpg +[33]:http://rextester.com/l/bash_online_compiler +[34]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/learnshell-online-bash-shell.jpg +[35]:http://www.webminal.org/ +[36]:http://www.learnshell.org/ diff --git a/sources/tech/20180725 Build an interactive CLI with Node.js.md b/sources/tech/20180725 Build an interactive CLI with Node.js.md new file mode 100644 index 0000000000..6ec13f1cfc --- /dev/null +++ b/sources/tech/20180725 Build an interactive CLI with Node.js.md @@ -0,0 +1,531 @@ +Build an interactive CLI with Node.js +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/programming_keyboard_coding.png?itok=E0Vvam7A) + +Node.js can be very useful when it comes to building command-line interfaces (CLIs). In this post, I'll teach you how to use [Node.js][1] to build a CLI that asks some questions and creates a file based on the answers. + +### Get started + +Let's start by creating a brand new [npm][2] package. (Npm is the JavaScript package manager.) +``` +mkdir my-script + +cd my-script + +npm init + +``` + +Npm will ask some questions. After that, we need to install some packages. +``` +npm install --save chalk figlet inquirer shelljs + +``` + +Here's what these packages do: + + * **Chalk:** Terminal string styling done right + * **Figlet:** A program for making large letters out of ordinary text + * **Inquirer:** A collection of common interactive command-line user interfaces + * **ShellJS:** Portable Unix shell commands for Node.js + + + +### Make an index.js file + +Now we'll create an `index.js` file with the following content: +``` +#!/usr/bin/env node + + + +const inquirer = require("inquirer"); + +const chalk = require("chalk"); + +const figlet = require("figlet"); + +const shell = require("shelljs"); + +``` + +### Plan the CLI + +It's always good to plan what a CLI needs to do before writing any code. This CLI will do just one thing: **create a file**. + +The CLI will ask two questions—what is the filename and what is the extension?—then create the file, and show a success message with the created file path. +``` +// index.js + + + +const run = async () => { + +  // show script introduction + +  // ask questions + +  // create the file + +  // show success message + +}; + + + +run(); + +``` + +The first function is the script introduction. Let's use `chalk` and `figlet` to get the job done. +``` +const init = () => { + +  console.log( + +    chalk.green( + +      figlet.textSync("Node JS CLI", { + +        font: "Ghost", + +        horizontalLayout: "default", + +        verticalLayout: "default" + +      }) + +    ) + +  ); + +} + + + +const run = async () => { + +  // show script introduction + +  init(); + + + +  // ask questions + +  // create the file + +  // show success message + +}; + + + +run(); + +``` + +Second, we'll write a function that asks the questions. +``` +const askQuestions = () => { + +  const questions = [ + +    { + +      name: "FILENAME", + +      type: "input", + +      message: "What is the name of the file without extension?" + +    }, + +    { + +      type: "list", + +      name: "EXTENSION", + +      message: "What is the file extension?", + +      choices: [".rb", ".js", ".php", ".css"], + +      filter: function(val) { + +        return val.split(".")[1]; + +      } + +    } + +  ]; + +  return inquirer.prompt(questions); + +}; + + + +// ... + + + +const run = async () => { + +  // show script introduction + +  init(); + + + +  // ask questions + +  const answers = await askQuestions(); + +  const { FILENAME, EXTENSION } = answers; + + + +  // create the file + +  // show success message + +}; + +``` + +Notice the constants FILENAME and EXTENSIONS that came from `inquirer`. + +The next step will create the file. +``` +const createFile = (filename, extension) => { + +  const filePath = `${process.cwd()}/${filename}.${extension}` + +  shell.touch(filePath); + +  return filePath; + +}; + + + +// ... + + + +const run = async () => { + +  // show script introduction + +  init(); + + + +  // ask questions + +  const answers = await askQuestions(); + +  const { FILENAME, EXTENSION } = answers; + + + +  // create the file + +  const filePath = createFile(FILENAME, EXTENSION); + + + +  // show success message + +}; + +``` + +And last but not least, we'll show the success message along with the file path. +``` +const success = (filepath) => { + +  console.log( + +    chalk.white.bgGreen.bold(`Done! File created at ${filepath}`) + +  ); + +}; + + + +// ... + + + +const run = async () => { + +  // show script introduction + +  init(); + + + +  // ask questions + +  const answers = await askQuestions(); + +  const { FILENAME, EXTENSION } = answers; + + + +  // create the file + +  const filePath = createFile(FILENAME, EXTENSION); + + + +  // show success message + +  success(filePath); + +}; + +``` + +Let's test the script by running `node index.js`. Here's what we get: + +### The full code + +Here is the final code: +``` +#!/usr/bin/env node + + + +const inquirer = require("inquirer"); + +const chalk = require("chalk"); + +const figlet = require("figlet"); + +const shell = require("shelljs"); + + + +const init = () => { + +  console.log( + +    chalk.green( + +      figlet.textSync("Node JS CLI", { + +        font: "Ghost", + +        horizontalLayout: "default", + +        verticalLayout: "default" + +      }) + +    ) + +  ); + +}; + + + +const askQuestions = () => { + +  const questions = [ + +    { + +      name: "FILENAME", + +      type: "input", + +      message: "What is the name of the file without extension?" + +    }, + +    { + +      type: "list", + +      name: "EXTENSION", + +      message: "What is the file extension?", + +      choices: [".rb", ".js", ".php", ".css"], + +      filter: function(val) { + +        return val.split(".")[1]; + +      } + +    } + +  ]; + +  return inquirer.prompt(questions); + +}; + + + +const createFile = (filename, extension) => { + +  const filePath = `${process.cwd()}/${filename}.${extension}` + +  shell.touch(filePath); + +  return filePath; + +}; + + + +const success = filepath => { + +  console.log( + +    chalk.white.bgGreen.bold(`Done! File created at ${filepath}`) + +  ); + +}; + + + +const run = async () => { + +  // show script introduction + +  init(); + + + +  // ask questions + +  const answers = await askQuestions(); + +  const { FILENAME, EXTENSION } = answers; + + + +  // create the file + +  const filePath = createFile(FILENAME, EXTENSION); + + + +  // show success message + +  success(filePath); + +}; + + + +run(); + +``` + +### Use the script anywhere + +To execute this script anywhere, add a `bin` section in your `package.json` file and run `npm link`. +``` +{ + +  "name": "creator", + +  "version": "1.0.0", + +  "description": "", + +  "main": "index.js", + +  "scripts": { + +    "test": "echo \"Error: no test specified\" && exit 1", + +    "start": "node index.js" + +  }, + +  "author": "", + +  "license": "ISC", + +  "dependencies": { + +    "chalk": "^2.4.1", + +    "figlet": "^1.2.0", + +    "inquirer": "^6.0.0", + +    "shelljs": "^0.8.2" + +  }, + +  "bin": { + +    "creator": "./index.js" + +  } + +} + +``` + +Running `npm link` makes this script available anywhere. + +That's what happens when you run this command: +``` +/usr/bin/creator -> /usr/lib/node_modules/creator/index.js + +/usr/lib/node_modules/creator -> /home/hugo/code/creator + +``` + +It links the `index.js` file as an executable. This is only possible because of the first line of the CLI script: `#!/usr/bin/env node`. + +Now we can run this script by calling: +``` +$ creator + +``` + +### Wrapping up + +As you can see, Node.js makes it very easy to build nice command-line tools! If you want to go even further, check this other packages: + + * [meow][3] – a simple command-line helper + * [yargs][4] – a command-line opt-string parser + * [pkg][5] – package your Node.js project into an executable + + + +Tell us about your experience building a CLI in the comments. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/node-js-interactive-cli + +作者:[Hugo Dias][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/hugodias +[1]:https://nodejs.org/en/ +[2]:https://www.npmjs.com/ +[3]:https://github.com/sindresorhus/meow +[4]:https://github.com/yargs/yargs +[5]:https://github.com/zeit/pkg diff --git a/sources/tech/20180725 How do private keys work in PKI and cryptography.md b/sources/tech/20180725 How do private keys work in PKI and cryptography.md new file mode 100644 index 0000000000..bc73101560 --- /dev/null +++ b/sources/tech/20180725 How do private keys work in PKI and cryptography.md @@ -0,0 +1,101 @@ +How do private keys work in PKI and cryptography? +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/security_privacy_lock.png?itok=ZWjrpFzx) + +In [a previous article][1], I gave an overview of cryptography and discussed the core concepts of confidentiality (keeping data secret), integrity (protecting data from tampering), and authentication (knowing the identity of the data's source). Since authentication relates so closely to all the messiness of identity in the real world, a complex technological ecosystem has evolved around establishing that someone is who they claim to be. In this article, I'll describe in broad strokes how these systems work. + +### A quick review of public key cryptography and digital signatures + +Authentication in the online world relies on public key cryptography where a key has two parts: a private key kept secret by the owner and a public key shared with the world. After the public key encrypts data, only the private key can decrypt it. This feature is useful if a whistleblower wanted to establish contact with a [journalist][2], for example. More importantly for this article, a private key can be combined with a message to create a digital signature that provides integrity and authentication. + +In practice, what is signed is not the actual message, but a digest of a message attained by sending the message through a cryptographic hash function. Instead of signing an entire zip file of source code, the sender signs the 256-bit [SHA-256][3] digest of that zip file and sends the zip file in the clear. Recipients independently calculate the SHA-256 digest of the file they received. They input their digest, the signature they received, and the sender's public key into a signature verification algorithm. The verification process varies depending on the encryption algorithm, and there are enough subtleties that signature verification [vulnerabilities][4] still [pop up][5] . If the verification succeeds, the file has not been modified in transit and must have originated from the sender since only the sender has the private key that created the signature. + +### The missing piece of the puzzle + +There's one major detail missing from this scenario. Where do we get the sender's public key? The sender could send the public key along with a message, but then we have no proof of their identity beyond their own assertion. Imagine being a bank teller and a customer walks up and says, "Hello, I'm Jane Doe, and I'd like to make a withdrawal." When you ask for identification, she points to a name tag sticker on her shirt that says "Jane Doe." Personally, I would politely turn "Jane" away. + +If you already know the sender, you could meet in person and exchange public keys. If you don't, you could meet in person, examine their passport, and once you are satisfied it is authentic, accept their public key. To make the process more efficient, you could throw a [party][6], invite a bunch of people, examine all their passports, and accept all their public keys. Building off that, if you know Jane Doe and trust her (despite her unusual banking practices), Jane could go to the party, get the public keys, and give them to you. In fact, Jane could just sign the other public keys using her own private key, and then you could use [an online repository][7] of public keys, trusting the ones signed by Jane. If a person's public key is signed by multiple people you trust, then you might decide to trust that person as well (even though you don't know them). In this fashion, you can build a [web of trust][8]. + +But now things have gotten complicated: We need to decide on a standard way to encode a key and the identity associated with that key into a digital bundle we can sign. More properly, these digital bundles are called certificates. We'll also need tooling that can create, use, and manage these certificates. The way we solve these and other requirements is what constitutes a public key infrastructure (PKI). + +### Beyond the web of trust + +You can think of the web of trust as a network of people. A network with many interconnections between the people makes it easy to find a short path of trust: a social circle, for example. [GPG][9]-encrypted email relies on a web of trust, and it functions ([in theory][10]) since most of us communicate primarily with a relatively small group of friends, family, and co-workers. + +In practice, the web of trust has some [significant problems][11], many of them around scaling. When the network starts to get larger and there are few connections between people, the web of trust starts to break down. If the path of trust is attenuated across a long chain of people, you face a higher chance of encountering someone who carelessly or maliciously signed a key. And if there is no path at all, you have to create one by contacting the other party and verifying their key to your satisfaction. Imagine going to an online store that you and your friends have never used. Before you establish a secure communications channel to place an order, you'd need to verify the site's public key belongs to the company and not an impostor. That vetting would entail going to a physical store, making telephone calls, or some other laborious process. Online shopping would be a lot less convenient (or a lot less secure since many people would cut corners and accept the key without verifying it). + +What if the world had some exceptionally trustworthy people constantly verifying and signing keys for websites? You could just trust them, and browsing the internet would be much smoother. At a high level, that's how things work today. These "exceptionally trustworthy people" are companies called certificate authorities (CAs). When a website wants to get its public key signed, it submits a certificate signing request (CSR) to the CA. + +CSRs are like stub certificates that contain a public key and an identity (in this case, the hostname of the server), but are not signed by a CA. Before signing, the CA performs some verification steps. In some cases, the CA merely verifies that the requester controls the domain for the hostname listed in the CSR (via a challenge-and-response email exchange with the address in the WHOIS entry, for example). [In other cases][12], the CA inspects legal documents, like business licenses. Once the CA is satisfied (and usually after the requester has paid a fee), it takes the data from the CSR and signs it with its own private key to create a certificate. The CA then sends the certificate to the requester. The requester installs the certificate on their site's web server, and the certificate is delivered to users when they connect over HTTPS (or any other protocol secured with [TLS][13]). + +When users connect to the site, their browser looks at the certificate, checks that the hostname in the certificate is the same as the hostname it is connected to (more on this in a moment), and verifies the CA's signature. If any of these steps fail, the browser will show a warning and break off the connection. Otherwise, the browser uses the public key in the certificate to verify some signed information sent from the server to ensure that the server possesses the certificate's private key. These messages also serve as steps in one of several algorithms used to establish a shared secret key that will encrypt subsequent messages. Key exchange algorithms are beyond the scope of this article, but there's a good discussion of one of them in [this video][14]. + +### Creating trust + +You're probably wondering, "If the CA's private key signs a certificate, that means to verify a certificate we need the CA's public key. Where does it come from and who signs it?" The answer is the CA signs for itself! A certificate can be signed using the private key associated with the same certificate's public key. These certificates are said to be self-signed; they are the PKI equivalent of saying, "Trust me." (People often say, as a form of shorthand, that a certificate has signed something even though it's the private key—which isn't in the certificate at all—doing the actual signing.) + +By adhering to policies established by [web browser][15] and [operating system][16] vendors, CAs demonstrate they are trustworthy enough to be placed into a group of self-signed certificates built into the browser or operating system. These certificates are called trust anchors or root CA certificates, and they are placed in a root certificate store where they are trusted implicitly. + +A CA can also issue a certificate endowed with the ability to act as a CA itself. In this way, they can create a chain of certificates. To verify the chain, a program starts at the trust anchor and verifies (among other things) the signature on the next certificate using the public key of the current certificate. It continues down the chain, verifying each link until it reaches the end. If there are no problems along the way, a chain of trust is established. When a website pays a CA to sign a certificate for it, they are paying for the privilege of being placed at the end of that chain. CAs mark certificates sold to websites as not being allowed to sign subsequent certificates; this is so they can terminate the chain of trust at the appropriate place. + +Why would a chain ever be more than two links long? After all, a site just needs its certificate signed by a CA's root certificate. In practice, CAs create intermediate CA certificates for convenience (among other reasons). The private keys for a CA's root certificates are so valuable that they reside in a specialized device, a [hardware security module][17] (HSM), that requires multiple people to unlock it, is completely offline, and is kept inside a [vault][18] wired with alarms and cameras. + +CAB Forum, the association that governs CAs, [requires][19] any interaction with a CA's root certificate to be performed directly by a human. Issuing certificates for dozens of websites a day would be tedious if every certificate request required an employee to place the request on secure media, enter a vault, unlock the HSM with a coworker, sign the certificate, exit the vault, and then copy the signed certificate off the media. Instead, CAs create internal, intermediate CAs used to sign certificates automatically. + +You can see this chain in Firefox by clicking the lock icon in the URL bar, opening up the page information, and clicking the "View Certificate" button on the "Security" tab. As of this writing, [opensource.com][20] had the following chain: +``` +DigiCert High Assurance EV Root CA + +    DigiCert SHA2 High Assurance Server CA + +        opensource.com + +``` + +### The man in the middle + +I mentioned earlier that a browser needs to check that the hostname in the certificate is the same as the hostname it connected to. Why? The answer has to do with what's called a [man-in-the-middle (MITM) attack][21]. These are [network attacks][22] that allow an attacker to insert itself between a client and a server, masquerading as the server to the client and vice versa. If the traffic is over HTTPS, it's encrypted and eavesdropping is fruitless. Instead, the attacker can create a proxy that will accept HTTPS connections from the victim, decrypt the information, and then form an HTTPS connection with the original destination. To create the phony HTTPS connection, the proxy must return a certificate that our attacker has the private key for. Our attacker could generate self-signed certificates, but the victim's browser won't trust anything not signed by a CA's root certificate in the browser's root certificate store. What if instead, the attacker uses a certificate signed by a trusted CA for a domain it owns? + +Imagine we're back to our job in the bank. A man walks in and asks to withdraw money from Jane Doe's account. When asked for identification, the man hands us a valid driver's license for Joe Smith. We would be rightfully fired if we allowed the transaction to continue. If a browser detects a mismatch between the certificate hostname and the connection hostname, it will show a warning that says something like "Your connection is not secure" and an option to show additional details. In Firefox, this error is called SSL_ERROR_BAD_CERT_DOMAIN. + +If there's one lesson I want you to remember from this article, it's: If you see these warnings, **do not disregard them**! They signal that the site is either configured so erroneously that you shouldn't use it or that you're the potential victim of a MITM attack. + +### Final thoughts + +I've only scratched the surface of the PKI world in this article, but I hope that I've given you a map that you can use to guide your further explorations. Cryptography and PKI are fractal-like in their beauty and complexity. The further you dive in, the more there is to discover. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/private-keys + +作者:[Alex Wood][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/awood +[1]:https://opensource.com/article/18/5/cryptography-pki +[2]:https://theintercept.com/2014/10/28/smuggling-snowden-secrets/ +[3]:https://en.wikipedia.org/wiki/SHA-2 +[4]:https://www.ietf.org/mail-archive/web/openpgp/current/msg00999.html +[5]:https://www.imperialviolet.org/2014/09/26/pkcs1.html +[6]:https://en.wikipedia.org/wiki/Key_signing_party +[7]:https://en.wikipedia.org/wiki/Key_server_(cryptographic) +[8]:https://en.wikipedia.org/wiki/Web_of_trust +[9]:https://www.gnupg.org/gph/en/manual/x547.html +[10]:https://blog.cryptographyengineering.com/2014/08/13/whats-matter-with-pgp/ +[11]:https://lists.torproject.org/pipermail/tor-talk/2013-September/030235.html +[12]:https://en.wikipedia.org/wiki/Extended_Validation_Certificate +[13]:https://en.wikipedia.org/wiki/Transport_Layer_Security +[14]:https://www.youtube.com/watch?v=YEBfamv-_do +[15]:https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/policy/ +[16]:https://technet.microsoft.com/en-us/library/cc751157.aspx +[17]:https://en.wikipedia.org/wiki/Hardware_security_module +[18]:https://arstechnica.com/information-technology/2012/11/inside-symantecs-ssl-certificate-vault/ +[19]:https://cabforum.org/baseline-requirements-documents/ +[20]:http://opensource.com +[21]:https://en.wikipedia.org/wiki/Man-in-the-middle_attack +[22]:http://www.shortestpathfirst.net/2010/11/18/man-in-the-middle-mitm-attacks-explained-arp-poisoining/ diff --git a/sources/tech/20180726 4 cool apps for your terminal.md b/sources/tech/20180726 4 cool apps for your terminal.md new file mode 100644 index 0000000000..b86d47be79 --- /dev/null +++ b/sources/tech/20180726 4 cool apps for your terminal.md @@ -0,0 +1,123 @@ +translating---geekpi + +4 cool apps for your terminal +====== + +![](https://fedoramagazine.org/wp-content/uploads/2018/07/terminal4cool-816x345.jpg) + +Many Linux users think that working in a terminal is either too complex or boring, and try to escape it. Here is a fix, though — four great open source apps for your terminal. They’re fun and easy to use, and may even brighten up your life when you need to spend a time in the command line. + +### No More Secrets + +This is a simple command line tool that recreates the famous data decryption effect seen in the 1992 movie [Sneakers][1]. The project lets you compile the nms command, which works with piped data and prints the output in the form of messed characters. Once it does so, you can press any key, and see the live “deciphering” of the output with a cool Hollywood-style effect. + +![][2] + +#### Installation instructions + +A fresh Fedora Workstation system already includes everything you need to build No More Secrets from source. Just enter the following command in your terminal: +``` +git clone https://github.com/bartobri/no-more-secrets.git +cd ./no-more-secrets +make nms +make sneakers ## Optional +sudo make install + +``` + +The sneakers command is a little bonus for those who remember the original movie, but the main hero is nms. Use a pipe to redirect any Linux command to nms, like this: +``` +systemctl list-units --type=target | nms + +``` + +Once the text stops flickering, hit any key to “decrypt” it. The systemctl command above is only an example — you can replace it with virtually anything! + +### Lolcat + +Here’s a command that colorizes the terminal output with rainbows. Nothing can be more useless, but boy, it looks awesome! + +![][3] + +#### Installation instructions + +Lolcat is a Ruby package available from the official Ruby Gems hosting. So, you’ll need the gem client first: +``` +sudo dnf install -y rubygems + +``` + +And then install Lolcat itself: +``` +gem install lolcat + +``` + +Again, use the lolcat command in for piping any other command and enjoy rainbows (and unicorns!) right in your Fedora terminal. + +### Chafa + +![][4] + +Chafa is a [command line image converter and viewer][5]. It helps you enjoy your images without leaving your lovely terminal. The syntax is very straightforward: +``` +chafa /path/to/your/image + +``` + +You can throw almost any sort of image to Chafa, including JPG, PNG, TIFF, BMP or virtually anything that ImageMagick supports — this is the engine that Chafa uses for parsing input files. The coolest part is that Chafa can also show very smooth and fluid GIF animations right inside your terminal! + +#### Installation instructions + +Chafa isn’t packaged for Fedora yet, but it’s quite easy to build it from source. First, get the necessary build dependencies: +``` +sudo dnf install -y autoconf automake libtool gtk-doc glib2-devel ImageMagick-devel + +``` + +Next, clone the code or download a snapshot from the project’s Github page and cd to the Chafa directory. After that, you’re ready to go: +``` +git clone https://github.com/hpjansson/chafa +./autogen.sh +make +sudo make install + +``` + +Large images can take a while to process at the first run, but Chafa caches everything you load with it. Next runs will be nearly instantaneous. + +### Browsh + +Browsh is a fully-fledged web browser for the terminal. It’s more powerful than Lynx and certainly more eye-catching. Browsh launches the Firefox web browser in a headless mode (so that you can’t see it) and connects it with your terminal with the help of special web extension. Therefore, Browsh renders all rich media content just like Firefox, only in a bit pixelated style. + +![][6] + +#### Installation instructions + +The project provides packages for various Linux distributions, including Fedora. Install it this way: +``` +sudo dnf install -y https://github.com/browsh-org/browsh/releases/download/v1.4.6/browsh_1.4.6_linux_amd64.rpm + +``` + +After that, launch the browsh command and give it a couple of seconds to load up. Press Ctrl+L to switch focus to the address bar and start browsing the Web like you never did before! Use Ctrl+Q to get back to your terminal. + + +-------------------------------------------------------------------------------- + +via: https://fedoramagazine.org/4-cool-apps-for-your-terminal/ + +作者:[atolstoy][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/atolstoy/ +[1]:https://www.imdb.com/title/tt0105435/ +[2]:https://fedoramagazine.org/wp-content/uploads/2018/07/nms.gif +[3]:https://fedoramagazine.org/wp-content/uploads/2018/07/lolcat.png +[4]:https://fedoramagazine.org/wp-content/uploads/2018/07/sir.gif +[5]:https://hpjansson.org/chafa/ +[6]:https://fedoramagazine.org/wp-content/uploads/2018/07/browsh.png diff --git a/sources/tech/20180726 The evolution of package managers.md b/sources/tech/20180726 The evolution of package managers.md new file mode 100644 index 0000000000..a95eefc770 --- /dev/null +++ b/sources/tech/20180726 The evolution of package managers.md @@ -0,0 +1,599 @@ +The evolution of package managers +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/suitcase_container_bag.png?itok=q40lKCBY) + +Every computerized device uses some form of software to perform its intended tasks. In the early days of software, products were stringently tested for bugs and other defects. For the last decade or so, software has been released via the internet with the intent that any bugs would be fixed by applying new versions of the software. In some cases, each individual application has its own updater. In others, it is left up to the user to figure out how to obtain and upgrade software. + +Linux adopted early the practice of maintaining a centralized location where users could find and install software. In this article, I'll discuss the history of software installation on Linux and how modern operating systems are kept up to date against the never-ending torrent of [CVEs][1]. + +### How was software on Linux installed before package managers? + +Historically, software was provided either via FTP or mailing lists (eventually this distribution would grow to include basic websites). Only a few small files contained the instructions to create a binary (normally in a tarfile). You would untar the files, read the readme, and as long as you had GCC or some other form of C compiler, you would then typically run a `./configure` script with some list of attributes, such as pathing to library files, location to create new binaries, etc. In addition, the `configure` process would check your system for application dependencies. If any major requirements were missing, the configure script would exit and you could not proceed with the installation until all the dependencies were met. If the configure script completed successfully, a `Makefile` would be created. + +Once a `Makefile` existed, you would then proceed to run the `make` command (this command is provided by whichever compiler you were using). The `make` command has a number of options called make flags, which help optimize the resulting binaries for your system. In the earlier days of computing, this was very important because hardware struggled to keep up with modern software demands. Today, compilation options can be much more generic as most hardware is more than adequate for modern software. + +Finally, after the `make` process had been completed, you would need to run `make install` (or `sudo make install`) in order to actually install the software. As you can imagine, doing this for every single piece of software was time-consuming and tedious—not to mention the fact that updating software was a complicated and potentially very involved process. + +### What is a package? + +Packages were invented to combat this complexity. Packages collect multiple data files together into a single archive file for easier portability and storage, or simply compress files to reduce storage space. The binaries included in a package are precompiled with according to the sane defaults the developer chosen. Packages also contain metadata, such as the software's name, a description of its purpose, a version number, and a list of dependencies necessary for the software to run properly. + +Several flavors of Linux have created their own package formats. Some of the most commonly used package formats include: + + * .deb: This package format is used by Debian, Ubuntu, Linux Mint, and several other derivatives. It was the first package type to be created. + * .rpm: This package format was originally called Red Hat Package Manager. It is used by Red Hat, Fedora, SUSE, and several other smaller distributions. + * .tar.xz: While it is just a compressed tarball, this is the format that Arch Linux uses. + + + +While packages themselves don't manage dependencies directly, they represented a huge step forward in Linux software management. + +### What is a software repository? + +A few years ago, before the proliferation of smartphones, the idea of a software repository was difficult for many users to grasp if they were not involved in the Linux ecosystem. To this day, most Windows users still seem to be hardwired to open a web browser to search for and install new software. However, those with smartphones have gotten used to the idea of a software "store." The way smartphone users obtain software and the way package managers work are not dissimilar. While there have been several attempts at making an attractive UI for software repositories, the vast majority of Linux users still use the command line to install packages. Software repositories are a centralized listing of all of the available software for any repository the system has been configured to use. Below are some examples of searching a repository for a specifc package (note that these have been truncated for brevity): + +Arch Linux with aurman +``` +user@arch ~ $  aurman -Ss kate + +extra/kate 18.04.2-2 (kde-applications kdebase) +    Advanced Text Editor +aur/kate-root 18.04.0-1 (11, 1.139399) +    Advanced Text Editor, patched to be able to run as root +aur/kate-git r15288.15d26a7-1 (1, 1e-06) +    An advanced editor component which is used in numerous KDE applications requiring a text editing component +``` + +CentOS 7 using YUM +``` +[user@centos ~]$ yum search kate + +kate-devel.x86_64 : Development files for kate +kate-libs.x86_64 : Runtime files for kate +kate-part.x86_64 : Kate kpart plugin +``` + +Ubuntu using APT +``` +user@ubuntu ~ $ apt search kate +Sorting... Done +Full Text Search... Done + +kate/xenial 4:15.12.3-0ubuntu2 amd64 +  powerful text editor + +kate-data/xenial,xenial 4:4.14.3-0ubuntu4 all +  shared data files for Kate text editor + +kate-dbg/xenial 4:15.12.3-0ubuntu2 amd64 +  debugging symbols for Kate + +kate5-data/xenial,xenial 4:15.12.3-0ubuntu2 all +  shared data files for Kate text editor +``` + +### What are the most prominent package managers? + +As suggested in the above output, package managers are used to interact with software repositories. The following is a brief overview of some of the most prominent package managers. + +#### RPM-based package managers + +Updating RPM-based systems, particularly those based on Red Hat technologies, has a very interesting and detailed history. In fact, the current versions of [yum][2] (for enterprise distributions) and [DNF][3] (for community) combine several open source projects to provide their current functionality. + +Initially, Red Hat used a package manager called [RPM][4] (Red Hat Package Manager), which is still in use today. However, its primary use is to install RPMs, which you have locally, not to search software repositories. The package manager named `up2date` was created to inform users of updates to packages and enable them to search remote repositories and easily install dependencies. While it served its purpose, some community members felt that `up2date` had some significant shortcomings. + +The current incantation of yum came from several different community efforts. Yellowdog Updater (YUP) was developed in 1999-2001 by folks at Terra Soft Solutions as a back-end engine for a graphical installer of [Yellow Dog Linux][5]. Duke University liked the idea of YUP and decided to improve upon it. They created [Yellowdog Updater, Modified (yum)][6] which was eventually adapted to help manage the university's Red Hat Linux systems. Yum grew in popularity, and by 2005 it was estimated to be used by more than half of the Linux market. Today, almost every distribution of Linux that uses RPMs uses yum for package management (with a few notable exceptions). + +#### Working with yum + +In order for yum to download and install packages out of an internet repository, files must be located in `/etc/yum.repos.d/` and they must have the extension `.repo`. Here is an example repo file: +``` +[local_base] +name=Base CentOS  (local) +baseurl=http://7-repo.apps.home.local/yum-repo/7/ +enabled=1 +gpgcheck=0 +``` + +This is for one of my local repositories, which explains why the GPG check is off. If this check was on, each package would need to be signed with a cryptographic key and a corresponding key would need to be imported into the system receiving the updates. Because I maintain this repository myself, I trust the packages and do not bother signing them. + +Once a repository file is in place, you can start installing packages from the remote repository. The most basic command is `yum update`, which will update every package currently installed. This does not require a specific step to refresh the information about repositories; this is done automatically. A sample of the command is shown below: +``` +[user@centos ~]$ sudo yum update +Loaded plugins: fastestmirror, product-id, search-disabled-repos, subscription-manager +local_base                             | 3.6 kB  00:00:00     +local_epel                             | 2.9 kB  00:00:00     +local_rpm_forge                        | 1.9 kB  00:00:00     +local_updates                          | 3.4 kB  00:00:00     +spideroak-one-stable                   | 2.9 kB  00:00:00     +zfs                                    | 2.9 kB  00:00:00     +(1/6): local_base/group_gz             | 166 kB  00:00:00     +(2/6): local_updates/primary_db        | 2.7 MB  00:00:00     +(3/6): local_base/primary_db           | 5.9 MB  00:00:00     +(4/6): spideroak-one-stable/primary_db |  12 kB  00:00:00     +(5/6): local_epel/primary_db           | 6.3 MB  00:00:00     +(6/6): zfs/x86_64/primary_db           |  78 kB  00:00:00     +local_rpm_forge/primary_db             | 125 kB  00:00:00     +Determining fastest mirrors +Resolving Dependencies +--> Running transaction check +``` + +If you are sure you want yum to execute any command without stopping for input, you can put the `-y` flag in the command, such as `yum update -y`. + +Installing a new package is just as easy. First, search for the name of the package with `yum search`: +``` +[user@centos ~]$ yum search kate + +artwiz-aleczapka-kates-fonts.noarch : Kates font in Artwiz family +ghc-highlighting-kate-devel.x86_64 : Haskell highlighting-kate library development files +kate-devel.i686 : Development files for kate +kate-devel.x86_64 : Development files for kate +kate-libs.i686 : Runtime files for kate +kate-libs.x86_64 : Runtime files for kate +kate-part.i686 : Kate kpart plugin +``` + +Once you have the name of the package, you can simply install the package with `sudo yum install kate-devel -y`. If you installed a package you no longer need, you can remove it with `sudo yum remove kate-devel -y`. By default, yum will remove the package plus its dependencies. + +There may be times when you do not know the name of the package, but you know the name of the utility. For example, suppose you are looking for the utility `updatedb`, which creates/updates the database used by the `locate` command. Attempting to install `updatedb` returns the following results: +``` +[user@centos ~]$ sudo yum install updatedb +Loaded plugins: fastestmirror, langpacks +Loading mirror speeds from cached hostfile +No package updatedb available. +Error: Nothing to do +``` + +You can find out what package the utility comes from by running: +``` +[user@centos ~]$ yum whatprovides *updatedb +Loaded plugins: fastestmirror, langpacks +Loading mirror speeds from cached hostfile + +bacula-director-5.2.13-23.1.el7.x86_64 : Bacula Director files +Repo        : local_base +Matched from: +Filename    : /usr/share/doc/bacula-director-5.2.13/updatedb + +mlocate-0.26-8.el7.x86_64 : An utility for finding files by name +Repo        : local_base +Matched from: +Filename    : /usr/bin/updatedb +``` + +The reason I have used an asterisk `*` in front of the command is because `yum whatprovides` uses the path to the file in order to make a match. Since I was not sure where the file was located, I used an asterisk to indicate any path. + +There are, of course, many more options available to yum. I encourage you to view the man page for yum for additional options. + +[Dandified Yum (DNF)][7] is a newer iteration on yum. Introduced in Fedora 18, it has not yet been adopted in the enterprise distributions, and as such is predominantly used in Fedora (and derivatives). Its usage is almost exactly the same as that of yum, but it was built to address poor performance, undocumented APIs, slow/broken dependency resolution, and occasional high memory usage. DNF is meant as a drop-in replacement for yum, and therefore I won't repeat the commands—wherever you would use `yum`, simply substitute `dnf`. + +#### Working with Zypper + +[Zypper][8] is another package manager meant to help manage RPMs. This package manager is most commonly associated with [SUSE][9] (and [openSUSE][10]) but has also seen adoption by [MeeGo][11], [Sailfish OS][12], and [Tizen][13]. It was originally introduced in 2006 and has been iterated upon ever since. There is not a whole lot to say other than Zypper is used as the back end for the system administration tool [YaST][14] and some users find it to be faster than yum. + +Zypper's usage is very similar to that of yum. To search for, update, install or remove a package, simply use the following: +``` +zypper search kate +zypper update +zypper install kate +zypper remove kate +``` +Some major differences come into play in how repositories are added to the system with `zypper`. Unlike the package managers discussed above, `zypper` adds repositories using the package manager itself. The most common way is via a URL, but `zypper` also supports importing from repo files. +``` +suse:~ # zypper addrepo http://download.videolan.org/pub/vlc/SuSE/15.0 vlc +Adding repository 'vlc' [done] +Repository 'vlc' successfully added + +Enabled     : Yes +Autorefresh : No +GPG Check   : Yes +URI         : http://download.videolan.org/pub/vlc/SuSE/15.0 +Priority    : 99 +``` + +You remove repositories in a similar manner: +``` +suse:~ # zypper removerepo vlc +Removing repository 'vlc' ...................................[done] +Repository 'vlc' has been removed. +``` + +Use the `zypper repos` command to see what the status of repositories are on your system: +``` +suse:~ # zypper repos +Repository priorities are without effect. All enabled repositories share the same priority. + +#  | Alias                     | Name                                    | Enabled | GPG Check | Refresh +---|---------------------------|-----------------------------------------|---------|-----------|-------- + 1 | repo-debug                | openSUSE-Leap-15.0-Debug                | No      | ----      | ----   + 2 | repo-debug-non-oss        | openSUSE-Leap-15.0-Debug-Non-Oss        | No      | ----      | ----   + 3 | repo-debug-update         | openSUSE-Leap-15.0-Update-Debug         | No      | ----      | ----   + 4 | repo-debug-update-non-oss | openSUSE-Leap-15.0-Update-Debug-Non-Oss | No      | ----      | ----   + 5 | repo-non-oss              | openSUSE-Leap-15.0-Non-Oss              | Yes     | ( p) Yes  | Yes     + 6 | repo-oss                  | openSUSE-Leap-15.0-Oss                  | Yes     | ( p) Yes  | Yes     +``` + +`zypper` even has a similar ability to determine what package name contains files or binaries. Unlike YUM, it uses a hyphen in the command (although this method of searching is deprecated): +``` +localhost:~ # zypper what-provides kate +Command 'what-provides' is replaced by 'search --provides --match-exact'. +See 'help search' for all available options. +Loading repository data... +Reading installed packages... + +S  | Name | Summary              | Type       +---|------|----------------------|------------ +i+ | Kate | Advanced Text Editor | application +i  | kate | Advanced Text Editor | package   +``` + +As with YUM and DNF, Zypper has a much richer feature set than covered here. Please consult with the official documentation for more in-depth information. + +#### Debian-based package managers + +One of the oldest Linux distributions currently maintained, Debian's system is very similar to RPM-based systems. They use `.deb` packages, which can be managed by a tool called dpkg. dpkg is very similar to rpm in that it was designed to manage packages that are available locally. It does no dependency resolution (although it does dependency checking), and has no reliable way to interact with remote repositories. In order to improve the user experience and ease of use, the Debian project commissioned a project called Deity. This codename was eventually abandoned and changed to [Advanced Package Tool (APT)][15]. + +Released as test builds in 1998 (before making an appearance in Debian 2.1 in 1999), many users consider APT one of the defining features of Debian-based systems. It makes use of repositories in a similar fashion to RPM-based systems, but instead of individual `.repo` files that `yum` uses, `apt` has historically used `/etc/apt/sources.list` to manage repositories. More recently, it also ingests files from `/etc/apt/sources.d/`. Following the examples in the RPM-based package managers, to accomplish the same thing on Debian-based distributions you have a few options. You can edit/create the files manually in the aforementioned locations from the terminal, or in some cases, you can use a UI front end (such as `Software & Updates` provided by Ubuntu et al.). To provide the same treatment to all distributions, I will cover only the command-line options. To add a repository without directly editing a file, you can do something like this: +``` +user@ubuntu:~$ sudo apt-add-repository "deb http://APT.spideroak.com/ubuntu-spideroak-hardy/ release restricted" + +``` + +This will create a `spideroakone.list` file in `/etc/apt/sources.list.d`. Obviously, these lines change depending on the repository being added. If you are adding a Personal Package Archive (PPA), you can do this: +``` +user@ubuntu:~$ sudo apt-add-repository ppa:gnome-desktop + +``` + +NOTE: Debian does not support PPAs natively. + +After a repository has been added, Debian-based systems need to be made aware that there is a new location to search for packages. This is done via the `apt-get update` command: +``` +user@ubuntu:~$ sudo apt-get update +Get:1 http://security.ubuntu.com/ubuntu xenial-security InRelease [107 kB] +Hit:2 http://APT.spideroak.com/ubuntu-spideroak-hardy release InRelease +Hit:3 http://ca.archive.ubuntu.com/ubuntu xenial InRelease +Get:4 http://ca.archive.ubuntu.com/ubuntu xenial-updates InRelease [109 kB]               +Get:5 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [517 kB] +Get:6 http://security.ubuntu.com/ubuntu xenial-security/main i386 Packages [455 kB]       +Get:7 http://security.ubuntu.com/ubuntu xenial-security/main Translation-en [221 kB]     +... + +Fetched 6,399 kB in 3s (2,017 kB/s)                                           +Reading package lists... Done +``` + +Now that the new repository is added and updated, you can search for a package using the `apt-cache` command: +``` +user@ubuntu:~$ apt-cache search kate +aterm-ml - Afterstep XVT - a VT102 emulator for the X window system +frescobaldi - Qt4 LilyPond sheet music editor +gitit - Wiki engine backed by a git or darcs filestore +jedit - Plugin-based editor for programmers +kate - powerful text editor +kate-data - shared data files for Kate text editor +kate-dbg - debugging symbols for Kate +katepart - embeddable text editor component +``` + +To install `kate`, simply run the corresponding install command: +``` +user@ubuntu:~$ sudo apt-get install kate + +``` + +To remove a package, use `apt-get remove`: +``` +user@ubuntu:~$ sudo apt-get remove kate + +``` + +When it comes to package discovery, APT does not provide any functionality that is similar to `yum whatprovides`. There are a few ways to get this information if you are trying to find where a specific file on disk has come from. + +Using dpkg +``` +user@ubuntu:~$ dpkg -S /bin/ls +coreutils: /bin/ls +``` + +Using apt-file +``` +user@ubuntu:~$ sudo apt-get install apt-file -y + +user@ubuntu:~$ sudo apt-file update + +user@ubuntu:~$ apt-file search kate +``` + +The problem with `apt-file search` is that it, unlike `yum whatprovides`, it is overly verbose unless you know the exact path, and it automatically adds a wildcard search so that you end up with results for anything with the word kate in it: +``` +kate: /usr/bin/kate +kate: /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/katebacktracebrowserplugin.so +kate: /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/katebuildplugin.so +kate: /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/katecloseexceptplugin.so +kate: /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/katectagsplugin.so +``` + +Most of these examples have used `apt-get`. Note that most of the current tutorials for Ubuntu specifically have taken to simply using `apt`. The single `apt` command was designed to implement only the most commonly used commands in the APT arsenal. Since functionality is split between `apt-get`, `apt-cache`, and other commands, `apt` looks to unify these into a single command. It also adds some niceties such as colorization, progress bars, and other odds and ends. Most of the commands noted above can be replaced with `apt`, but not all Debian-based distributions currently receiving security patches support using `apt` by default, so you may need to install additional packages. + +#### Arch-based package managers + +[Arch Linux][16] uses a package manager called [pacman][17]. Unlike `.deb` or `.rpm` files, pacman uses a more traditional tarball with the LZMA2 compression (`.tar.xz`). This enables Arch Linux packages to be much smaller than other forms of compressed archives (such as gzip). Initially released in 2002, pacman has been steadily iterated and improved. One of the major benefits of pacman is that it supports the [Arch Build System][18], a system for building packages from source. The build system ingests a file called a PKGBUILD, which contains metadata (such as version numbers, revisions, dependencies, etc.) as well as a shell script with the required flags for compiling a package conforming to the Arch Linux requirements. The resulting binaries are then packaged into the aforementioned `.tar.xz` file for consumption by pacman. + +This system led to the creation of the [Arch User Repository][19] (AUR) which is a community-driven repository containing PKGBUILD files and supporting patches or scripts. This allows for a virtually endless amount of software to be available in Arch. The obvious advantage of this system is that if a user (or maintainer) wishes to make software available to the public, they do not have to go through official channels to get it accepted in the main repositories. The downside is that it relies on community curation similar to [Docker Hub][20], Canonical's Snap packages, or other similar mechanisms. There are numerous AUR-specific package managers that can be used to download, compile, and install from the PKGBUILD files in the AUR (we will look at this later). + +#### Working with pacman and official repositories + +Arch's main package manager, pacman, uses flags instead of command words like `yum` and `apt`. For example, to search for a package, you would use `pacman -Ss`. As with most commands on Linux, you can find both a `manpage` and inline help. Most of the commands for `pacman `use the sync (-S) flag. For example: +``` +user@arch ~ $ pacman -Ss kate + +extra/kate 18.04.2-2 (kde-applications kdebase) +    Advanced Text Editor +extra/libkate 0.4.1-6 [installed] +    A karaoke and text codec for embedding in ogg +extra/libtiger 0.3.4-5 [installed] +    A rendering library for Kate streams using Pango and Cairo +extra/ttf-cheapskate 2.0-12 +    TTFonts collection from dustimo.com +community/haskell-cheapskate 0.1.1-100 +    Experimental markdown processor. +``` + +Arch also uses repositories similar to other package managers. In the output above, search results are prefixed with the repository they are found in (`extra/` and `community/` in this case). Similar to both Red Hat and Debian-based systems, Arch relies on the user to add the repository information into a specific file. The location for these repositories is `/etc/pacman.conf`. The example below is fairly close to a stock system. I have enabled the `[multilib]` repository for Steam support: +``` +[options] +Architecture = auto + +Color +CheckSpace + +SigLevel    = Required DatabaseOptional +LocalFileSigLevel = Optional + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +[community] +Include = /etc/pacman.d/mirrorlist + +[multilib] +Include = /etc/pacman.d/mirrorlist +``` + +It is possible to specify a specific URL in `pacman.conf`. This functionality can be used to make sure all packages come from a specific point in time. If, for example, a package has a bug that affects you severely and it has several dependencies, you can roll back to a specific point in time by adding a specific URL into your `pacman.conf` and then running the commands to downgrade the system: +``` +[core] +Server=https://archive.archlinux.org/repos/2017/12/22/$repo/os/$arch +``` + +Like Debian-based systems, Arch does not update its local repository information until you tell it to do so. You can refresh the package database by issuing the following command: +``` +user@arch ~ $ sudo pacman -Sy + +:: Synchronizing package databases... + core                                                                     130.2 KiB   851K/s 00:00 [##########################################################] 100% + extra                                                                   1645.3 KiB  2.69M/s 00:01 [##########################################################] 100% + community                                                                  4.5 MiB  2.27M/s 00:02 [##########################################################] 100% + multilib is up to date +``` + +As you can see in the above output, `pacman` thinks that the multilib package database is up to date. You can force a refresh if you think this is incorrect by running `pacman -Syy`. If you want to update your entire system (excluding packages installed from the AUR), you can run `pacman -Syu`: +``` +user@arch ~ $ sudo pacman -Syu + +:: Synchronizing package databases... + core is up to date + extra is up to date + community is up to date + multilib is up to date +:: Starting full system upgrade... +resolving dependencies... +looking for conflicting packages... + +Packages (45) ceph-13.2.0-2  ceph-libs-13.2.0-2  debootstrap-1.0.105-1  guile-2.2.4-1  harfbuzz-1.8.2-1  harfbuzz-icu-1.8.2-1  haskell-aeson-1.3.1.1-20 +              haskell-attoparsec-0.13.2.2-24  haskell-tagged-0.8.6-1  imagemagick-7.0.8.4-1  lib32-harfbuzz-1.8.2-1  lib32-libgusb-0.3.0-1  lib32-systemd-239.0-1 +              libgit2-1:0.27.2-1  libinput-1.11.2-1  libmagick-7.0.8.4-1  libmagick6-6.9.10.4-1  libopenshot-0.2.0-1  libopenshot-audio-0.1.6-1  libosinfo-1.2.0-1 +              libxfce4util-4.13.2-1  minetest-0.4.17.1-1  minetest-common-0.4.17.1-1  mlt-6.10.0-1  mlt-python-bindings-6.10.0-1  ndctl-61.1-1  netctl-1.17-1 +              nodejs-10.6.0-1   + +Total Download Size:      2.66 MiB +Total Installed Size:   879.15 MiB +Net Upgrade Size:      -365.27 MiB + +:: Proceed with installation? [Y/n] +``` + +In the scenario mentioned earlier regarding downgrading a system, you can force a downgrade by issuing `pacman -Syyuu`. It is important to note that this should not be undertaken lightly. This should not cause a problem in most cases; however, there is a chance that downgrading of a package or several packages will cause a cascading failure and leave your system in an inconsistent state. USE WITH CAUTION! + +To install a package, simply use `pacman -S kate`: +``` +user@arch ~ $ sudo pacman -S kate + +resolving dependencies... +looking for conflicting packages... + +Packages (7) editorconfig-core-c-0.12.2-1  kactivities-5.47.0-1  kparts-5.47.0-1  ktexteditor-5.47.0-2  syntax-highlighting-5.47.0-1  threadweaver-5.47.0-1 +             kate-18.04.2-2 + +Total Download Size:   10.94 MiB +Total Installed Size:  38.91 MiB + +:: Proceed with installation? [Y/n] +``` + +To remove a package, you can run `pacman -R kate`. This removes only the package and not its dependencies: +``` +user@arch ~ $ sudo pacman -S kate + +checking dependencies... + +Packages (1) kate-18.04.2-2 + +Total Removed Size:  20.30 MiB + +:: Do you want to remove these packages? [Y/n] +``` + +If you want to remove the dependencies that are not required by other packages, you can run `pacman -Rs:` +``` +user@arch ~ $ sudo pacman -Rs kate + +checking dependencies... + +Packages (7) editorconfig-core-c-0.12.2-1  kactivities-5.47.0-1  kparts-5.47.0-1  ktexteditor-5.47.0-2  syntax-highlighting-5.47.0-1  threadweaver-5.47.0-1 +             kate-18.04.2-2 + +Total Removed Size:  38.91 MiB + +:: Do you want to remove these packages? [Y/n] +``` + +Pacman, in my opinion, offers the most succinct way of searching for the name of a package for a given utility. As shown above, `yum` and `apt` both rely on pathing in order to find useful results. Pacman makes some intelligent guesses as to which package you are most likely looking for: +``` +user@arch ~ $ sudo pacman -Fs updatedb +core/mlocate 0.26.git.20170220-1 +    usr/bin/updatedb + +user@arch ~ $ sudo pacman -Fs kate +extra/kate 18.04.2-2 +    usr/bin/kate +``` + +#### Working with the AUR + +There are several popular AUR package manager helpers. Of these, `yaourt` and `pacaur` are fairly prolific. However, both projects are listed as discontinued or problematic on the [Arch Wiki][21]. For that reason, I will discuss `aurman`. It works almost exactly like `pacman,` except it searches the AUR and includes some helpful, albeit potentially dangerous, options. Installing a package from the AUR will initiate use of the package maintainer's build scripts. You will be prompted several times for permission to continue (I have truncated the output for brevity): +``` +aurman -S telegram-desktop-bin +~~ initializing aurman... +~~ the following packages are neither in known repos nor in the aur +... +~~ calculating solutions... + +:: The following 1 package(s) are getting updated: +   aur/telegram-desktop-bin  1.3.0-1  ->  1.3.9-1 + +?? Do you want to continue? Y/n: Y + +~~ looking for new pkgbuilds and fetching them... +Cloning into 'telegram-desktop-bin'... + +remote: Counting objects: 301, done. +remote: Compressing objects: 100% (152/152), done. +remote: Total 301 (delta 161), reused 286 (delta 147) +Receiving objects: 100% (301/301), 76.17 KiB | 639.00 KiB/s, done. +Resolving deltas: 100% (161/161), done. +?? Do you want to see the changes of telegram-desktop-bin? N/y: N + +[sudo] password for user: + +... +==> Leaving fakeroot environment. +==> Finished making: telegram-desktop-bin 1.3.9-1 (Thu 05 Jul 2018 11:22:02 AM EDT) +==> Cleaning up... +loading packages... +resolving dependencies... +looking for conflicting packages... + +Packages (1) telegram-desktop-bin-1.3.9-1 + +Total Installed Size:  88.81 MiB +Net Upgrade Size:       5.33 MiB + +:: Proceed with installation? [Y/n] +``` + +Sometimes you will be prompted for more input, depending on the complexity of the package you are installing. To avoid this tedium, `aurman` allows you to pass both the `--noconfirm` and `--noedit` options. This is equivalent to saying "accept all of the defaults, and trust that the package maintainers scripts will not be malicious." **USE THIS OPTION WITH EXTREME CAUTION!** While these options are unlikely to break your system on their own, you should never blindly accept someone else's scripts. + +### Conclusion + +This article, of course, only scratches the surface of what package managers can do. There are also many other package managers available that I could not cover in this space. Some distributions, such as Ubuntu or Elementary OS, have gone to great lengths to provide a graphical approach to package management. + +If you are interested in some of the more advanced functions of package managers, please post your questions or comments below and I would be glad to write a follow-up article. + +### Appendix +``` +# search for packages +yum search +dnf search +zypper search +apt-cache search +apt search +pacman -Ss + +# install packages +yum install +dnf install +zypper install +apt-get install +apt install +pacman -Ss + +# update package database, not required by yum, dnf and zypper +apt-get update +apt update +pacman -Sy + +# update all system packages +yum update +dnf update +zypper update +apt-get upgrade +apt upgrade +pacman -Su + +# remove an installed package +yum remove +dnf remove +apt-get remove +apt remove +pacman -R +pacman -Rs + +# search for the package name containing specific file or folder +yum whatprovides * +dnf whatprovides * +zypper what-provides +zypper search --provides +apt-file search +pacman -Sf +``` + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/evolution-package-managers + +作者:[Steve Ovens][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/stratusss +[1]:https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures +[2]:https://en.wikipedia.org/wiki/Yum_(software) +[3]:https://fedoraproject.org/wiki/DNF +[4]:https://en.wikipedia.org/wiki/Rpm_(software) +[5]:https://en.wikipedia.org/wiki/Yellow_Dog_Linux +[6]:https://searchdatacenter.techtarget.com/definition/Yellowdog-Updater-Modified-YUM +[7]:https://en.wikipedia.org/wiki/DNF_(software) +[8]:https://en.opensuse.org/Portal:Zypper +[9]:https://www.suse.com/ +[10]:https://www.opensuse.org/ +[11]:https://en.wikipedia.org/wiki/MeeGo +[12]:https://sailfishos.org/ +[13]:https://www.tizen.org/ +[14]:https://en.wikipedia.org/wiki/YaST +[15]:https://en.wikipedia.org/wiki/APT_(Debian) +[16]:https://www.archlinux.org/ +[17]:https://wiki.archlinux.org/index.php/pacman +[18]:https://wiki.archlinux.org/index.php/Arch_Build_System +[19]:https://aur.archlinux.org/ +[20]:https://hub.docker.com/ +[21]:https://wiki.archlinux.org/index.php/AUR_helpers#Discontinued_or_problematic diff --git a/sources/tech/20180727 4 Ways to Customize Xfce and Give it a Modern Look.md b/sources/tech/20180727 4 Ways to Customize Xfce and Give it a Modern Look.md new file mode 100644 index 0000000000..c4372724f7 --- /dev/null +++ b/sources/tech/20180727 4 Ways to Customize Xfce and Give it a Modern Look.md @@ -0,0 +1,145 @@ +4 Ways to Customize Xfce and Give it a Modern Look +====== +**Brief: Xfce is a great lightweight desktop environment with one drawback. It looks sort of old. But you don’t have to stick with the default looks. Let’s see various ways you can customize Xfce to give it a modern and beautiful look.** + +![Customize Xfce desktop envirnment][1] + +To start with, Xfce is one of the most [popular desktop environments][2]. Being a lightweight DE, you can run Xfce on very low resource and it still works great. This is one of the reasons why many [lightweight Linux distributions][3] use Xfce by default. + +Some people prefer it even on a high-end device stating its simplicity, easy of use and non-resource hungry nature as the main reasons. + +[Xfce][4] is in itself minimal and provides just what you need. The one thing that bothers is its look and feel which feel old. However, you can easily customize Xfce to look modern and beautiful without reaching the limit where a Unity/GNOME session eats up system resources. + +### 4 ways to Customize Xfce desktop + +Let’s see some of the ways by which we can improve the look and feel of your Xfce desktop environment. + +The default Xfce desktop environment looks something like this : + +![Xfce default screen][5] + +As you can see, the default Xfce desktop is kinda boring. We will use some themes, icon packs and change the default dock to make it look fresh and a bit revealing. + +#### 1. Change themes in Xfce + +The first thing we will do is pick up a theme from [xfce-look.org][6]. My favorite Xfce theme is [XFCE-D-PRO][7]. + +You can download the theme from [here][8] and extract it somewhere. + +You can copy this extracted file to **.theme** folder in your home directory. If the folder is not present by default, you can create one and the same goes for icons which needs a **.icons** folder in the home directory. + +Open **Settings > Appearance > Style** to select the theme, log out and login to see the change. Adwaita-dark from default is also a nice one. + +![Appearance Xfce][9] + +You can use any [good GTK theme][10] on Xfce. + +#### 2. Change icons in Xfce + +Xfce-look.org also provides icon themes which you can download, extract and put it in your home directory under **.icons** directory. Once you have added the icon theme in the .icons directory, go to **Settings > Appearance > Icons** to select that icon theme. + +![Moka icon theme][11] + +I have installed [Moka icon set][12] that looks awesome. + +![Moka theme][13] + +You can also refer to our list of [awesome icon themes][14]. + +##### **Optional: Installing themes through Synaptic** + +If you want to avoid the manual search and copying of the files, install Synaptic Manager in your system. You can look for some best themes over web and icon sets, and using synaptic manager you can search and install it. +``` +sudo apt-get install synaptic + +``` + +**Searching and installing theme/icons through Synaptic** + +Open synaptic and click on **Search**. Enter your desired theme, and it will display the list of matching items. Mark all the additional required changes and click on **Apply**. This will download the theme and then install it. + +![Arc Theme][15] + +Once done, you can open the **Appearance** option to select the desired theme. + +In my opinion, this is not the best way to install themes in Xfce. + +#### 3. Change wallpapers in Xfce + +Again, the default Xfce wallpaper is not bad at all. But you can change the wallpaper to something that matches with your icons and themes. + +To change wallpapers in Xfce, right click on the desktop and click on Desktop Settings. You can change the desktop background from your custom collection or the defaults one given. + +Right click on the desktop and click on **Desktop Settings**. Choose **Background** from the folder option, and choose any one of the default backgrounds or a custom one. + +![Changing desktop wallpapers][16] + +#### 4. Change the dock in Xfce + +The default dock is nice and pretty much does what it is for. But again, it looks a bit boring. + +![Docky][17] + +However, if you want your dock to be better and with a little more customization options, you can install another dock. + +Plank is one of the simplest and lightweight docks and is highly configurable. + +To install Plank use the command below: + +`sudo apt-get install plank` + +If Plank is not available in the default repository, you can install it from this PPA. +``` +sudo add-apt-repository ppa:ricotz/docky +sudo apt-get update +sudo apt-get install plank + +``` + +Before you use Plank, you should remove the default dock by right-clicking in it and under Panel Settings, clicking on delete. + +Once done, go to **Accessory > Plank** to launch Plank dock. + +![Plank][18] + +Plank picks up icons from the one you are using. So if you change the icon themes, you’ll see the change is reflected in the dock also. + +### Wrapping Up + +XFCE is a lightweight, fast and highly customizable. If you are limited on system resource, it serves good and you can easily customize it to look better. Here’s how my screen looks after applying these steps. + +![XFCE desktop][19] + +This is just with half an hour of effort. You can make it look much better with different themes/icons customization. Feel free to share your customized XFCE desktop screen in the comments and the combination of themes and icons you are using. + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/customize-xfce/ + +作者:[Ambarish Kumar][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/ambarish/ +[1]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/xfce-customization.jpeg +[2]:https://itsfoss.com/best-linux-desktop-environments/ +[3]:https://itsfoss.com/lightweight-linux-beginners/ +[4]:https://xfce.org/ +[5]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/06/1-1-800x410.jpg +[6]:http://xfce-look.org +[7]:https://www.xfce-look.org/p/1207818/XFCE-D-PRO +[8]:https://www.xfce-look.org/p/1207818/startdownload?file_id=1523730502&file_name=XFCE-D-PRO-1.6.tar.xz&file_type=application/x-xz&file_size=105328&url=https%3A%2F%2Fdl.opendesktop.org%2Fapi%2Ffiles%2Fdownloadfile%2Fid%2F1523730502%2Fs%2F6019b2b57a1452471eac6403ae1522da%2Ft%2F1529360682%2Fu%2F%2FXFCE-D-PRO-1.6.tar.xz +[9]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/4.jpg +[10]:https://itsfoss.com/best-gtk-themes/ +[11]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/6.jpg +[12]:https://snwh.org/moka +[13]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/11-800x547.jpg +[14]:https://itsfoss.com/best-icon-themes-ubuntu-16-04/ +[15]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/5-800x531.jpg +[16]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/7-800x546.jpg +[17]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/8.jpg +[18]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/9.jpg +[19]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2018/07/10-800x447.jpg diff --git a/sources/tech/20180727 How to analyze your system with perf and Python.md b/sources/tech/20180727 How to analyze your system with perf and Python.md new file mode 100644 index 0000000000..c1be98cc0e --- /dev/null +++ b/sources/tech/20180727 How to analyze your system with perf and Python.md @@ -0,0 +1,1479 @@ +How to analyze your system with perf and Python +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/metrics_data_dashboard_system_computer_analytics.png?itok=oxAeIEI-) + +Modern computers are ever increasing in performance and capacity. This matters little if that increasing capacity is not well utilized. Following is a description of the motivation and work behind "curt," a new tool for Linux systems for measuring and breaking down system utilization by process, by task, and by CPU using the `perf` command's Python scripting capabilities. + +I had the privilege of presenting this topic at [Texas Linux Fest 2018][1], and here I've gone a bit deeper into the details, included links to further information, and expanded the scope of my talk. + +### System utilization + +In discussing computation, let's begin with some assertions: + + 1. Every computational system is equally fast at doing nothing. + 2. Computational systems were created to do things. + 3. A computational system is better at doing things when it is doing something than when it is doing nothing. + + + +Modern computational systems have many streams of execution: + + * Often, very large systems are created by literally wiring together smaller systems. At IBM, these smaller systems are sometimes called CECs (short for Central Electronics Complexes and pronounced "keks"). + * There are multiple sockets for processor modules in each system. + * There are sometimes multiple chips per socket (in the form of dual-chip modules—DCMs—or multi-chip modules—MCMs). + * There are multiple cores per chip. + * There are multiple threads per core. + + + +In sum, there are potentially thousands of execution threads across a single computational system. + +Ideally, all these execution streams are 100% busy doing useful work. One measure of **utilization** for an individual execution stream (CPU thread) is the percentage of time that thread has tasks scheduled and running. (Note that I didn't say "doing useful work." Creating a tool that measures useful work is left as an exercise for the reader.) By extension, **system utilization** is the overall percentage of time that all execution streams of a system have tasks scheduled and running. Similarly, utilization can be defined with respect to an individual task. **Task utilization** is the percentage of the lifetime of the task that was spent actively running on any CPU thread. By extension, **process utilization** is the collective utilization of its tasks. + +### Utilization measurement tools + +There are tools that measure system utilization: `uptime`, `vmstat`, `mpstat`, `nmon`, etc. There are tools that measure individual process utilization: `time`. There are not many tools that measure system-wide per-process and per-task utilization. One such command is `curt` on AIX. According to [IBM's Knowledge Center][2]: "The `curt` command takes an AIX trace file as input and produces a number of statistics related to processor (CPU) utilization and process/thread/pthread activity." + +The AIX `curt` command reports system-wide, per-processor, per-process, and per-task statistics for application processing (user time), system calls (system time), hypervisor calls, kernel threads, interrupts, and idle time. + +This seems like a good model for a similar command for a Linux system. + +### Utilization data + +Before starting to create any tools for utilization analysis, it is important to know what data is required. Since utilization is directly related to whether a task is actively running or not, related scheduling events are required: When is the task made to run, and when is it paused? Tracking on which CPU the task runs is important, so migration events are required for implicit migrations. There are also certain system calls that force explicit migrations. Creation and deletion of tasks are obviously important. Since we want to understand user time, system time, hypervisor time, and interrupt time, events that show the transitions between those task states are required. + +The Linux kernel contains "tracepoints" for all those events. It is possible to enable tracing for those events directly in the kernel's `debugfs` filesystem, usually mounted at `/sys/kernel/debug`, in the `tracing` directory (`/sys/kernel/debug/tracing`). + +An easier way to record tracing data is with the Linux `perf` command. + +### The perf command + +`perf` is a very powerful userspace command for tracing or counting both hardware and software events. + +Software events are predefined in the kernel, can be predefined in userspace code, and can be dynamically created (as "probes") in kernel or userspace code. + +`perf` can do much more than just trace and count, though. + +#### perf stat + +The `stat` subcommand of `perf` will run a command, count some events commonly found interesting, and produce a simple report: +``` +Performance counter stats for './load 100000': +  +      90537.006424      task-clock:u (msec)       #    1.000 CPUs utilized           +                 0      context-switches:u        #    0.000 K/sec                   +                 0      cpu-migrations:u          #    0.000 K/sec                   +               915      page-faults:u             #    0.010 K/sec                   +   386,836,206,133      cycles:u                  #    4.273 GHz                      (66.67%) +     3,488,523,420      stalled-cycles-frontend:u #    0.90% frontend cycles idle     (50.00%) +   287,222,191,827      stalled-cycles-backend:u  #   74.25% backend cycles idle      (50.00%) +   291,102,378,513      instructions:u            #    0.75  insn per cycle         +                                                  #    0.99  stalled cycles per insn  (66.67%) +    43,730,320,236      branches:u                #  483.010 M/sec                    (50.00%) +       822,030,340      branch-misses:u           #    1.88% of all branches          (50.00%) +  +      90.539972837 seconds time elapsed +``` + +#### perf record, perf report, and perf annotate + +For much more interesting analysis, the `perf` command can also be used to record events and information associated with the task state at the time the event occurred: +``` +$ perf record ./some-command +[ perf record: Woken up 55 times to write data ] +[ perf record: Captured and wrote 13.973 MB perf.data (366158 samples) ] +$ perf report --stdio --show-nr-samples --percent-limit 4 +# Samples: 366K of event 'cycles:u' +# Event count (approx.): 388851358382 +# +# Overhead       Samples  Command  Shared Object      Symbol                                           +# ........  ............  .......  .................  ................................................ +# +    62.31%        228162  load     load               [.] main +    19.29%         70607  load     load               [.] sum_add +    18.33%         67117  load     load               [.] sum_sub +``` + +This example shows a program that spends about 60% of its running time in the function `main` and about 20% each in subfunctions `sum_sub` and `sum_add`. Note that the default event used by `perf record` is "cycles." Later examples will show how to use `perf record` with other events. + +`perf report` can further report runtime statistics by source code line (if the compilation was performed with the `-g` flag to produce debug information): +``` +$ perf report --stdio --show-nr-samples --percent-limit 4 --sort=srcline +# Samples: 366K of event 'cycles:u' +# Event count (approx.): 388851358382 +# +# Overhead       Samples  Source:Line                         +# ........  ............  ................................... +# +    19.40%         71031  load.c:58 +    16.16%         59168  load.c:18 +    15.11%         55319  load.c:14 +    13.30%         48690  load.c:66 +    13.23%         48434  load.c:70 +     4.58%         16767  load.c:62 +     4.01%         14677  load.c:56 +``` + +Further, `perf annotate` can show statistics for each instruction of the program: +``` +$ perf annotate --stdio +Percent |      Source code & Disassembly of load for cycles:u (70607 samples) +------------------------------------------------------------------------------ +         :      0000000010000774 : +         :      int sum_add(int sum, int value) { +   12.60 :        10000774:   std     r31,-8(r1) +    0.02 :        10000778:   stdu    r1,-64(r1) +    0.00 :        1000077c:   mr      r31,r1 +   41.90 :        10000780:   mr      r10,r3 +    0.00 :        10000784:   mr      r9,r4 +    0.05 :        10000788:   stw     r10,32(r31) +   23.78 :        1000078c:   stw     r9,36(r31) +         :              return (sum + value); +    0.76 :        10000790:   lwz     r10,32(r31) +    0.00 :        10000794:   lwz     r9,36(r31) +   14.75 :        10000798:   add     r9,r10,r9 +    0.00 :        1000079c:   extsw   r9,r9 +         :      } +    6.09 :        100007a0:   mr      r3,r9 +    0.02 :        100007a4:   addi    r1,r31,64 +    0.03 :        100007a8:   ld      r31,-8(r1) +    0.00 :        100007ac:   blr +``` + +(Note: this code is not optimized.) + +#### perf top + +Similar to the `top` command, which displays (at a regular update interval) the processes using the most CPU time, `perf top` will display the functions using the most CPU time among all processes on the system, a nice leap in granularity. + +![](https://opensource.com/sites/default/files/uploads/perf-top.gif) + +#### perf list + +The examples thus far have used the default event, run cycles. There are hundreds and perhaps thousands of events of different types. `perf list` will show them all. Following are just a few examples: +``` +$ perf list +  instructions                                       [Hardware event] +  context-switches OR cs                             [Software event] +  L1-icache-loads                                    [Hardware cache event] +  mem_access OR cpu/mem_access/                      [Kernel PMU event] +cache: +  pm_data_from_l2                                   +       [The processor's data cache was reloaded from local core's L2 due to a demand load] +floating point: +  pm_fxu_busy                                       +       [fxu0 busy and fxu1 busy] +frontend: +  pm_br_mpred_cmpl                                   +       [Number of Branch Mispredicts] +memory: +  pm_data_from_dmem                                 +       [The processor's data cache was reloaded from another chip's memory on the same Node or Group (Distant) due to a demand load] +  pm_data_from_lmem                                 +       [The processor's data cache was reloaded from the local chip's Memory due to a demand load] +  rNNN                                               [Raw hardware event descriptor] +  raw_syscalls:sys_enter                             [Tracepoint event] +  syscalls:sys_enter_chmod                           [Tracepoint event] +  sdt_libpthread:pthread_create                      [SDT event] +``` + +Events labeled as `Hardware event`, `Hardware cache event`, `Kernel PMU event`, and most (if not all) of the events under the categories like `cache`, `floating point`, `frontend`, and `memory` are hardware events counted by the hardware and triggered each time a certain count is reached. Once triggered, an entry is made into the kernel trace buffer with the current state of the associated task. `Raw hardware event` codes are alphanumeric encodings of the hardware events. These are mostly needed when the hardware is newer than the kernel and the user needs to enable events that are new for that hardware. Users will rarely, if ever, need to use raw event codes. + +Events labeled `Tracepoint event` are embedded in the kernel. These are triggered when that section of code is executed by the kernel. There are "syscalls" events for every system call supported by the kernel. `raw_syscalls` events are triggered for every system call. Since there is a limit to the number of events being actively traced, the `raw_syscalls` events may be more practical when a large number of system calls need to be traced. + +Events labeled `SDT event` are for software-defined tracepoints (SDTs). These can be embedded in application or library code and enabled as needed. When enabled, they behave just like other events: When that section of code is executed (by any task being traced on the system), an entry is made in the kernel trace buffer with the current state of the associated task. This is a very powerful capability that can prove very useful. + +#### perf buildid-cache and perf probe + +Enabling SDTs is easy. First, make the SDTs for a certain library known to `perf`: +``` +$ perf buildid-cache -v --add /lib/powerpc64le-linux-gnu/libpthread.so.0 +$ perf list | grep libpthread +[…] +  sdt_libpthread:pthread_create                      [SDT event] +[…] +``` + +Then, turn SDT definitions into available tracepoints: +``` +$ /usr/bin/sudo perf probe sdt_libpthread:pthread_create +Added new event: +  sdt_libpthread:pthread_create (on %pthread_create in /lib/powerpc64le-linux-gnu/libpthread-2.27.so) +You can now use it in all perf tools, such as: +    perf record -e sdt_libpthread:pthread_create -aR sleep 1 +$ perf record -a -e sdt_libpthread:pthread_create ./test +[ perf record: Woken up 1 times to write data ] +[ perf record: Captured and wrote 0.199 MB perf.data (9 samples) ] +``` + +Note that any location in an application or library can be made into a tracepoint. To find functions in an application that can be made into tracepoints, use `perf probe` with `–funcs`: +``` +$ perf probe –x ./load --funcs +[…] +main +sum_add +sum_sub +``` + +To enable the function `main` of the `./load` application as a tracepoint: +``` +/usr/bin/sudo perf probe –x ./load main +Added new event: +  probe_load:main      (on main in /home/pc/projects/load-2.1pc/load) +You can now use it in all perf tools, such as: +    perf record –e probe_load:main –aR sleep 1 +$ perf list | grep load:main +  probe_load:main                                     [Tracepoint event] +$ perf record –e probe_load:main ./load +[ perf record: Woken up 1 times to write data ] +[ perf record: Captured and wrote 0.024 MB perf.data (1 samples) ] +``` + +#### perf script + +Continuing the previous example, `perf script` can be used to walk through the `perf.data` file and output the contents of each record: +``` +$ perf script +            Load 16356 [004] 80526.760310: probe_load:main: (4006a2) +``` + +### Processing perf trace data + +The preceding discussion and examples show that `perf` can collect the data required for system utilization analysis. However, how can that data be processed to produce the desired results? + +#### perf eBPF + +A relatively new and emerging technology with `perf` is called [eBPF][3]. BPF is an acronym for Berkeley Packet Filter, and it is a C-like language originally for, not surprisingly, network packet filtering in the kernel. eBPF is an acronym for extended BPF, a similar, but more robust C-like language based on BPF. + +Recent versions of `perf` can be used to incorporate compiled eBPF code into the kernel to securely and intelligently handle events for any number of purposes, with some limitations. + +The capability is very powerful and quite useful for real-time, continuous updates of event-related data and statistics. + +However, as this capability is emerging, support is mixed on current releases of Linux distributions. It's a bit complicated (or, put differently, I have not figured it out yet). It's also only for online use; there is no offline capability. For these reasons, I won't cover it further here. + +#### perf data file + +`perf record` produces a `perf.data` file. The file is a structured binary file, is not particularly well documented, has no programming interface for access, and is unclear on what compatibility guarantees exist. For these reasons, I chose not to directly use the `perf.data` file. + +#### perf script + +One of the last examples above showed how `perf script` is used for walking through the `perf.data` file and emitting basic information about each record there. This is an appropriate model for what would be needed to process the file and track the state changes and compute the statistics required for system utilization analysis. + +`perf script` has several modes of operation, including several higher-level scripts that come with `perf` that produce statistics based on the trace data in a `perf.data` file. +``` +$ perf script -l +List of available trace scripts: +  rw-by-pid                            system-wide r/w activity +  rwtop [interval]                     system-wide r/w top +  wakeup-latency                       system-wide min/max/avg wakeup latency +  failed-syscalls [comm]               system-wide failed syscalls +  rw-by-file                    r/w activity for a program, by file +  failed-syscalls-by-pid [comm]        system-wide failed syscalls, by pid +  intel-pt-events                      print Intel PT Power Events and PTWRITE +  syscall-counts-by-pid [comm]         system-wide syscall counts, by pid +  export-to-sqlite [database name] [columns] [calls] export perf data to a sqlite3 database +  futex-contention                     futext contention measurement +  sctop [comm] [interval]              syscall top +  event_analyzing_sample               analyze all perf samples +  net_dropmonitor                      display a table of dropped frames +  compaction-times [-h] [-u] [-p|-pv] [-t | [-m] [-fs] [-ms]] [pid|pid-range|comm-regex] display time taken by mm compaction +  export-to-postgresql [database name] [columns] [calls] export perf data to a postgresql database +  stackcollapse                        produce callgraphs in short form for scripting use +  netdev-times [tx] [rx] [dev=] [debug] display a process of packet and processing time +  syscall-counts [comm]                system-wide syscall counts +  sched-migration                      sched migration overview +$ perf script failed-syscalls-by-pid /bin/ls +  +syscall errors: +  +comm [pid]                           count +------------------------------  ---------- +  +ls [18683] +  syscall: access           +    err = ENOENT                         1 +  syscall: statfs           +    err = ENOENT                         1 +  syscall: ioctl           +    err = ENOTTY                         3 +``` + +What do these scripts look like? Let's find out. +``` +$ locate failed-syscalls-by-pid +/usr/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py +[…] +$ rpm –qf /usr/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py +perf-4.14.0-46.el7a.x86_64 +$ $ ls /usr/libexec/perf-core/scripts +perl  python +$ perf script -s lang +  +Scripting language extensions (used in perf script -s [spec:]script.[spec]): +  +  Perl                                       [Perl] +  pl                                         [Perl] +  Python                                     [Python] +  py                                         [Python] +``` + +So, these scripts come with `perf`, and both Python and Perl are supported languages. + +Note that for the entirety of this content, I will refer exclusively to Python. + +#### perf scripts + +How do these scripts do what they do? Here are important extracts from `/usr/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py`: +``` +def raw_syscalls__sys_exit(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, id, ret): +[…] +        if ret < 0: +[…] +                        syscalls[common_comm][common_pid][id][ret] += 1 +``` + +The function `raw_syscalls__sys_exit` has parameters for all the data for the associated event. The rest of the function only increments a counter associated with the command, process ID, and system call. The rest of the code doesn't do that much. Most of the complexity is in the function signature for the event-handling routine. + +Fortunately, `perf` makes it easy to figure out the proper signatures for various tracepoint event-handling functions. + +#### perf script –gen-script + +For the `raw_syscalls` events, we can generate a trace containing just those events: +``` +$ perf list | grep raw_syscalls +  raw_syscalls:sys_enter                             [Tracepoint event] +  raw_syscalls:sys_exit                              [Tracepoint event] +$ perf record -e 'raw_syscalls:*' /bin/ls >/dev/null +[ perf record: Woken up 1 times to write data ] +[ perf record: Captured and wrote 0.025 MB perf.data (176 samples) ] +``` + +We can then have `perf` generate a script that contains sample implementations of event-handling functions for the events in the `perf.data` file: +``` +$ perf script --gen-script python +generated Python script: perf-script.py +``` + +What do we find in the script? +``` +def raw_syscalls__sys_exit(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, id, ret): +[…] +def raw_syscalls__sys_enter(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, id, args): +``` + +Both event-handling functions are specified with their signatures. Nice! + +Note that this script works with `perf script –s`: +``` +$ perf script -s ./perf-script.py +in trace_begin +raw_syscalls__sys_exit     7 94571.445908134    21117 ls                    id=0, ret=0 +raw_syscalls__sys_enter     7 94571.445942946    21117 ls                    id=45, args=���?bc���?� +[…] +``` + +Now we have a template on which to base writing a Python script to parse the events of interest for reporting system utilization. + +### perf scripting + +The Python scripts generated by `perf script –gen-script` are not directly executable. They must be invoked by `perf`: +``` +$ perf script –s ./perf-script.py +``` + +What's really going on here? + + 1. First, `perf` starts. The `script` subcommand's `-s` option indicates that an external script will be used. + + 2. `perf` establishes a Python runtime environment. + + 3. `perf` loads the specified script. + + 4. `perf` runs the script. The script can perform normal initialization and even handle command line arguments, although passing the arguments is slightly awkward, requiring a `--` separator between the arguments for `perf` and for the script: + ``` + $ perf script -s ./perf-script.py -- --script-arg1 [...] + + ``` + + 5. `perf` processes each record of the trace file, calling the appropriate event-handling function in the script. Those event-handling functions can do whatever they need to do. + + + + +### Utilization + +It appears that `perf` scripting has sufficient capabilities for a workable solution. What sort of information is required to generate the statistics for system utilization? + + * Task creation (`fork`, `pthread_create`) + * Task termination (`exit`) + * Task replacement (`exec`) + * Task migration, explicit or implicit, and current CPU + * Task scheduling + * System calls + * Hypervisor calls + * Interrupts + + + +It can be helpful to understand what portion of time a task spends in various system calls, handling interrupts, or making explicit calls out to the hypervisor. Each of these categories of time can be considered a "state" for the task, and the methods of transitioning from one state to another need to be tracked: + +![](https://opensource.com/sites/default/files/uploads/task-state-diagram.png) + +The most important point of the diagram is that there are events for each state transition. + + * Task creation: `clone` system call + * Task termination: `sched:sched_process_exit` + * Task replacement: `sched:sched_process_exec` + * Task migration: `sched_setaffinity` system call (explicit), `sched:sched_migrate_task` (implicit) + * Task scheduling: `sched:sched_switch` + * System calls: `raw_syscalls:sys_enter`, `raw_syscalls:sys_exit` + * Hypervisor calls: (POWER-specific) `powerpc:hcall_entry`, `powerpc:hcall_exit` + * Interrupts: `irq:irq_handler_entry`, `irq:irq_handler_exit` + + + +### The curt command for Linux + +`perf` provides a suitable infrastructure with which to capture the necessary data for system utilization. There are a sufficient set of events available for tracing in the Linux kernel. The Python scripting capabilities permit a powerful and flexible means of processing the trace data. It's time to write the tool. + +#### High-level design + +In processing each event, the relevant state of the affected tasks must be updated: + + * New task? Create and initialize data structures to track the task's state + * Command + * Process ID + * Task ID + * Migration count (0) + * Current CPU + * New CPU for this task? Create and initialize data structures for CPU-specific data + * User time (0) + * System time (0) + * Hypervisor time (0) + * Interrupt time (0) + * Idle time (0) + * New transaction for this task? Create and initialize data structures for transaction-specific data + * Elapsed time (0) + * Count (0) + * Minimum (maxint), maximum (0) + * Existing task? + * Accumulate time for the previous state + * Transaction ending? Accumulate time for the transaction, adjust minimum, maximum values + * Set new state + * Save current time (time current state entered) + * Migration? Increment migration count + + + +#### High-level example + +For a `raw_syscalls:sys_enter` event: + + * If this task has not been seen before, allocate and initialize a new task data structure + * If the CPU is new for this task, allocate and initialize a new CPU data structure + * If this system call is new for this task, allocate and initialize a new call data structure + * In the task data structure: + * Accumulate the time since the last state change in a bucket for the current state ("user") + * Set the new state ("system") + * Save the current timestamp as the start of this time period for the new state + + + +#### Edge cases + +##### sys_exit as a task's first event + +If the first event in the trace for a task is `raw_syscalls:sys_exit`: + + * There is no matching `raw_syscalls:sys_enter` with which to determine the start time of this system call. + * The accumulated time since the start of the trace was all spent in the system call and needs to be added to the overall elapsed time spent in all calls to this system call. + * The elapsed time of this system call is unknown. + * It would be inaccurate to account for this elapsed time in the average, minimum, or maximum statistics for this system call. + + + +In this case, the tool creates a separate bucket called "pending" for time spent in the system call that cannot be accounted for in the average, minimum, or maximum. + +A "pending" bucket is required for all transactional events (system calls, hypervisor calls, and interrupts). + +##### sys_enter as a task's last event + +Similarly, If the last event in the trace for a task is `raw_syscalls:sys_enter`: + + * There is no matching `raw_syscalls:sys_exit` with which to determine the end time of this system call. + * The accumulated time from the start of the system call to the end of the trace was all spent in the system call and needs to be added to the overall elapsed time spent in all calls to this system call. + * The elapsed time of this system call is unknown. + * It would be inaccurate to account for this elapsed time in the average, minimum, or maximum statistics for this system call. + + + +This elapsed time is also accumulated in the "pending" bucket. + +A "pending" bucket is required for all transactional events (system calls, hypervisor calls, and interrupts). + +Since this condition can only be discovered at the end of the trace, a final "wrap-up" step is required in the tool where the statistics for all known tasks are completed based on their final states. + +##### Indeterminable state + +It is possible that a very busy task (or a short trace) will never see an event for a task from which the task's state can be determined. For example, if only `sched:sched_switch` or `sched:sched_task_migrate` events are seen for a task, it is impossible to determine that task's state. However, the task is known to exist and to be running. + +Since the actual state cannot be determined, the runtime for the task is accumulated in a separate bucket, arbitrarily called "busy-unknown." For completeness, this time is also displayed in the final report. + +##### Invisible tasks + +For very, very busy tasks (or a short trace), it is possible that a task was actively running during the entire time the trace was being collected, but no events for that task appear in the trace. It was never migrated, paused, or forced to wait. + +Such tasks cannot be known to exist by the tool and will not appear in the report. + +#### curt.py Python classes + +##### Task + + * One per task + * Holds all task-specific data (command, process ID, state, CPU, list of CPU data structures [see below], migration count, lists of per-call data structures [see below]) + * Maintains task state + + + +##### Call + + * One per unique transaction, per task (for example, one for the "open" system call, one for the "close" system call, one for IRQ 27, etc.) + * Holds call-specific data (e.g., start timestamp, count, elapsed time, minimum, maximum) + * Allocated as needed (lazy allocation) + * Stored within a task in a Python dictionary indexed by the unique identifier of the call (e.g., system call code, IRQ number, etc.) + + + +##### CPU + + * One per CPU on which this task has been observed to be running + * Holds per-CPU task data (e.g., user time, system time, hypervisor call time, interrupt time) + * Allocated as needed (lazy allocation) + * Stored within a task in a Python dictionary indexed by the CPU number + + + +#### curt.py event processing example + +As previously discussed, `perf script` will iterate over all events in the trace and call the appropriate event-handling function for each event. + +A first attempt at an event-handling function for `sys_exit`, given the high-level example above, might be: +``` +tasks = {} + +def raw_syscalls__sys_enter(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, args): + + # convert the multiple timestamp values into a single value + timestamp = nsecs(common_secs, common_nsecs) + + # find this task's data structure + try: + task = tasks[common_pid] + except: + # new task! + task = Task() + # save the command string + task.comm = common_comm + # save the new task in the global list (dictionary) of tasks + tasks[common_pid] = task + + if common_cpu not in task.cpus: + # new CPU! + task.cpu = common_cpu + task.cpus[common_cpu] = CPU() + + # compute time spent in the previous state ('user') + delta = timestamp – task.timestamp + # accumulate 'user' time for this task/CPU + task.cpus[task.cpu].user += delta + if id not in task.syscalls: + # new system call for this task! + task.syscalls[id] = Call() + + # change task's state + task.mode = 'sys' + + # save the timestamp for the last event (this one) for this task + task.timestamp = timestamp + +def raw_syscalls__sys_exit(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, ret): + + # convert the multiple timestamp values into a single value + timestamp = nsecs(common_secs, common_nsecs) + + # get the task data structure + task = tasks[common_pid] + + # compute elapsed time for this system call + delta = task.timestamp - timestamp + + # accumulate time for this task/system call + task.syscalls[id].elapsed += delta + # increment the tally for this task/system call + task.syscalls[id].count += 1 + # adjust statistics + if delta < task.syscalls[id].min: + task.syscalls[id].min = delta + if delta > task.syscalls[id].max: + task.syscalls[id].max = delta + + # accumulate time for this task's state on this CPU + task.cpus[common_cpu].system += delta + + # change task's state + task.mode = 'user' + + # save the timestamp for the last event (this one) for this task + task.timestamp = timestamp +``` + +### Handling the edge cases + +Following are some of the edge cases that are possible and must be handled. + +#### Sys_exit as first event + +As a system-wide trace can be started at an arbitrary time, it is certainly possible that the first event for a task is `raw_syscalls:sys_exit`. This requires adding the same code for new task discovery from the event-handling function for `raw_syscalls:sys_enter` to the handler for `raw_syscalls:sys_exit`. This: +``` +  # get the task data structure +  task = tasks[common_pid] +``` + +becomes this: +``` +  # find this task's data structure +  try: +    task = tasks[common_pid] +  except: +    # new task! +    task = Task() +    # save the command string +    task.comm = common_comm +    # save the new task in the global list (dictionary) of tasks +    tasks[common_pid] = task +``` + +Another issue is that it is impossible to properly accumulate the data for this system call since there is no timestamp for the start of the system call. The time from the start of the trace until this event has been spent by this task in the system call. It would be inaccurate to ignore this time. It would also be inaccurate to incorporate this time such that it is used to compute the average, minimum, or maximum. The only reasonable option is to accumulate this separately, calling it "pending" system time. To accurately compute this time, the timestamp of the first event of the trace must be known. Since any event could be the first event in the trace, every event must conditionally save its timestamp if it is the first event. A global variable is required: +``` +start_timestamp = 0 + +``` + +And every event-handling function must conditionally save its timestamp: +``` +  # convert the multiple timestamp values into a single value +  timestamp = nsecs(common_secs, common_nsecs) + +  If start_timestamp = 0: +    start_timestamp = timestamp +``` + +So, the event-handling function for `raw_syscalls:sys_exit` becomes: +``` +def raw_syscalls__sys_exit(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, ret): + +  # convert the multiple timestamp values into a single value +  timestamp = nsecs(common_secs, common_nsecs) + +  If start_timestamp = 0: +    start_timestamp = timestamp + +  # find this task's data structure +  try: +    task = tasks[common_pid] + +    # compute elapsed time for this system call +    delta =  task.timestamp - timestamp + +    # accumulate time for this task/system call +    task.syscalls[id].elapsed += delta +    # increment the tally for this task/system call +    task.syscalls[id].count += 1 +    # adjust statistics +    if delta < task.syscalls[id].min: +      task.syscalls[id].min = delta +    if delta > task.syscalls[id].max: +      task.syscalls[id].max = delta + +  except: +    # new task! +    task = Task() +    # save the command string +    task.comm = common_comm +    # save the new task in the global list (dictionary) of tasks +    tasks[common_pid] = task + +    # compute elapsed time for this system call +    delta =  start_timestamp - timestamp + +    # accumulate time for this task/system call +    task.syscalls[id].pending += delta + +  # accumulate time for this task's state on this CPU +  task.cpus[common_cpu].system += delta + +  # change task's state +  task.mode = 'user' + +  # save the timestamp for the last event (this one) for this task +  task.timestamp = timestamp +``` +### Sys_enter as last event + +A similar issue to having `sys_exit` as the first event for a task is when `sys_enter` is the last event seen for a task. The time spent in the system call must be accumulated for completeness but can't accurately impact the average, minimum, nor maximum. This time will also be accumulated in for a separate "pending" state. + +To accurately determine the elapsed time of the pending system call, from `sys_entry` to the end of the trace period, the timestamp of the final event in the trace file is required. Unfortunately, there is no way to know which event is the last event until that event has already been processed. So, all events must save their respective timestamps in a global variable. + +It may be that many tasks are in the state where the last event seen for them was `sys_enter`. Thus, after the last event is processed, a final "wrap up" step is required to complete the statistics for those tasks. Fortunately, there is a `trace_end` function which is called by `perf` after the final event has been processed. + +Last, we need to save the `id` of the system call in every `sys_enter`. +``` +curr_timestamp = 0 + +def raw_syscalls__sys_enter(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, args): + +  # convert the multiple timestamp values into a single value +  curr_timestamp = nsecs(common_secs, common_nsecs) +[…] +  task.syscall = id +[…] + +def trace_end(): +        for tid in tasks.keys(): +                task = tasks[tid] +                # if this task ended while executing a system call +                if task.mode == 'sys': +                        # compute the time from the entry to the system call to the end of the trace period +                        delta = curr_timestamp - task.timestamp +                        # accumulate the elapsed time for this system call +                        task.syscalls[task.syscall].pending += delta +                        # accumulate the system time for this task/CPU +                        task.cpus[task.cpu].sys += delta +``` + +### Migrations + +A task migration is when a task running on one CPU is moved to another CPU. This can happen by either: + + 1. Explicit request (e.g., a call to `sched_setaffinity`), or + 2. Implicitly by the kernel (e.g., load balancing or vacating a CPU being taken offline) + + + +When detected: + + * The migration count for the task should be incremented + * The statistics for the previous CPU should be updated + * A new CPU data structure may need to be updated and initialized if the CPU is new for the task + * The task's current CPU is set to the new CPU + + + +For accurate statistics, task migrations must be detected as soon as possible. The first case, explicit request, happens within a system call and can be detected in the `sys_exit` event for that system call. The second case has its own event, `sched:sched_migrate_task`, so it will need a new event-handling function. +``` +def raw_syscalls__sys_exit(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, ret): + +  # convert the multiple timestamp values into a single value +  timestamp = nsecs(common_secs, common_nsecs) + +  If start_timestamp = 0: +    start_timestamp = timestamp + +  # find this task's data structure +  try: +    task = tasks[common_pid] + +    # compute elapsed time for this system call +    delta =  task.timestamp - timestamp + +    # accumulate time for this task/system call +    task.syscalls[id].elapsed += delta +    # increment the tally for this task/system call +    task.syscalls[id].count += 1 +    # adjust statistics +    if delta < task.syscalls[id].min: +      task.syscalls[id].min = delta +    if delta > task.syscalls[id].max: +      task.syscalls[id].max = delta + +  except: +    # new task! +    task = Task() +    # save the command string +    task.comm = common_comm +    # save the new task in the global list (dictionary) of tasks +    tasks[common_pid] = task + +    task.cpu = common_cpu + +    # compute elapsed time for this system call +    delta =  start_timestamp - timestamp + +    # accumulate time for this task/system call +    task.syscalls[id].pending += delta + +  If common_cpu != task.cpu: +    task.migrations += 1 +    # divide the time spent in this syscall in half... +    delta /= 2 +    # and give have to the previous CPU, below, and half to the new CPU, later +    task.cpus[task.cpu].system += delta + +  # accumulate time for this task's state on this CPU +  task.cpus[common_cpu].system += delta + +  # change task's state +  task.mode = 'user' + +  # save the timestamp for the last event (this one) for this task +  task.timestamp = timestamp + +def sched__sched_migrate_task(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, comm, pid, prio, orig_cpu, +        dest_cpu, perf_sample_dict): + +  If start_timestamp = 0: +    start_timestamp = timestamp + +  # find this task's data structure +  try: +    task = tasks[common_pid] +  except: +    # new task! +    task = Task() +    # save the command string +    task.comm = common_comm +    # save the new task in the global list (dictionary) of tasks +    tasks[common_pid] = task + +    task.cpu = common_cpu + +    If common_cpu not in task.cpus: +      task.cpus[common_cpu] = CPU() + +    task.migrations += 1 +``` + +### Task creation + +To accurately collect statistics for a task, it is essential to know when the task is created. Tasks can be created with `fork()`, which creates a new process, or `pthread_create()`, which creates a new task within the same process. Fortunately, both are manifested by a `clone` system call and made evident by a `sched:sched_process_fork` event. The lifetime of the task starts at the `sched_process_fork` event. The edge case that arises is that the first likely events for the new task are: + + 1. `sched_switch` when the new task starts running. The new task should be considered idle at creation until this event occurs + 2. `sys_exit` for the `clone` system call. The initial state of the new task needs to be based on the state of the task that creates it, including being within the `clone` system call. + + + +One edge case that must be handled is if the creating task (parent) is not yet known, it must be created and initialized, and the presumption is that it has been actively running since the start of the trace. +``` +def sched__sched_process_fork(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, parent_comm, parent_pid, child_comm, child_pid): +  global start_timestamp, curr_timestamp +  curr_timestamp = self.timestamp +  if (start_timestamp == 0): +    start_timestamp = curr_timestamp +  # find this task's data structure +  try: +    task = tasks[common_pid] +  except: +    # new task! +    task = Task() +    # save the command string +    task.comm = common_comm +    # save the new task in the global list (dictionary) of tasks +    tasks[common_pid] = task +  try: +    parent = tasks[self.parent_tid] +  except: +    # need to create parent task here! +    parent = Task(start_timestamp, self.command, 'sys', self.pid) +    parent.sched_stat = True # ? +    parent.cpu = self.cpu +    parent.cpus[parent.cpu] = CPU() +    tasks[self.parent_tid] = parent +  +    task.resume_mode = parent.mode +    task.syscall = parent.syscall +    task.syscalls[task.syscall] = Call() +    task.syscalls[task.syscall].timestamp = self.timestamp +``` + +### Task exit + +Similarly, for complete and accurate task statistics, it is essential to know when a task has terminated. There's an event for that: `sched:sched_process_exit`. This one is pretty easy to handle, in that the effort is just to close out the statistics and set the mode appropriately, so any end-of-trace processing will not think the task is still active: +``` +def sched__sched_process_exit_old(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, comm, pid, prio): +  global start_timestamp, curr_timestamp +  curr_timestamp = self.timestamp +  if (start_timestamp == 0): +    start_timestamp = curr_timestamp + +  # find this task's data structure +  try: +    task = tasks[common_pid] +  except: +    # new task! +    task = Task() +    # save the command string +    task.comm = common_comm +    task.timestamp = curr_timestamp +    # save the new task in the global list (dictionary) of tasks +    tasks[common_pid] = task + +  delta = timestamp – task.timestamp +  task.sys += delta +  task.mode = 'exit' +``` + +### Output + +What follows is an example of the report displayed by `curt`, slightly reformatted to fit on a narrower page width and with the idle-time classification data (which makes the output very wide) removed, and for brevity. Seen are two processes, 1497 and 2857. Process 1497 has two tasks, 1497 and 1523. Each task has a per-CPU summary and system-wide ("ALL" CPUs) summary. Each task's data is followed by the system call data for that task (if any), hypervisor call data (if any), and interrupt data (if any). After each process's respective tasks is a per-process summary. Process 2857 has a task 2857-0 that is the previous task image before an exec() system call replaced the process image. After all processes is a system-wide summary. +``` +1497: +-- [  task] command     cpu      user       sys       irq        hv      busy      idle |  util% moves +   [  1497] X             2  0.076354  0.019563  0.000000  0.000000  0.000000 15.818719 |   0.6% +   [  1497] X           ALL  0.076354  0.019563  0.000000  0.000000  0.000000 15.818719 |   0.6%     0 +  +  -- ( ID)name             count   elapsed      pending      average      minimum      maximum +     (  0)read                 2  0.004699     0.000000     0.002350     0.002130     0.002569 +     (232)epoll_wait           1  9.968375     5.865208     9.968375     9.968375     9.968375 +  +-- [  task] command     cpu      user       sys       irq        hv      busy      idle |  util% moves +   [  1523] InputThread   1  0.052598  0.037073  0.000000  0.000000  0.000000 15.824965 |   0.6% +   [  1523] InputThread ALL  0.052598  0.037073  0.000000  0.000000  0.000000 15.824965 |   0.6%     0 +  +  -- ( ID)name             count   elapsed      pending      average      minimum      maximum +     (  0)read                14  0.011773     0.000000     0.000841     0.000509     0.002185 +     (  1)write                2  0.010763     0.000000     0.005381     0.004974     0.005789 +     (232)epoll_wait           1  9.966649     5.872853     9.966649     9.966649     9.966649 +  +-- [  task] command     cpu      user       sys       irq        hv      busy      idle |  util% moves +   [   ALL]             ALL  0.128952  0.056636  0.000000  0.000000  0.000000 31.643684 |   0.6%     0 +  +2857: +-- [  task] command     cpu      user       sys       irq        hv      busy      idle |  util% moves +   [  2857] execs.sh      1  0.257617  0.249685  0.000000  0.000000  0.000000  0.266200 |  65.6% +   [  2857] execs.sh      2  0.000000  0.023951  0.000000  0.000000  0.000000  0.005728 |  80.7% +   [  2857] execs.sh      5  0.313509  0.062271  0.000000  0.000000  0.000000  0.344279 |  52.2% +   [  2857] execs.sh      6  0.136623  0.128883  0.000000  0.000000  0.000000  0.533263 |  33.2% +   [  2857] execs.sh      7  0.527347  0.194014  0.000000  0.000000  0.000000  0.990625 |  42.1% +   [  2857] execs.sh    ALL  1.235096  0.658804  0.000000  0.000000  0.000000  2.140095 |  46.9%     4 +  +  -- ( ID)name             count   elapsed      pending      average      minimum      maximum +     (  9)mmap                15  0.059388     0.000000     0.003959     0.001704     0.017919 +     ( 14)rt_sigprocmask      12  0.006391     0.000000     0.000533     0.000431     0.000711 +     (  2)open                 9  2.253509     0.000000     0.250390     0.008589     0.511953 +     (  3)close                9  0.017771     0.000000     0.001975     0.000681     0.005245 +     (  5)fstat                9  0.007911     0.000000     0.000879     0.000683     0.001182 +     ( 10)mprotect             8  0.052198     0.000000     0.006525     0.003913     0.018073 +     ( 13)rt_sigaction         8  0.004281     0.000000     0.000535     0.000458     0.000751 +     (  0)read                 7  0.197772     0.000000     0.028253     0.000790     0.191028 +     ( 12)brk                  5  0.003766     0.000000     0.000753     0.000425     0.001618 +     (  8)lseek                3  0.001766     0.000000     0.000589     0.000469     0.000818 +  +-- [  task] command     cpu      user       sys       irq        hv      busy      idle |  util% moves +   [2857-0] perf          6  0.053925  0.191898  0.000000  0.000000  0.000000  0.827263 |  22.9% +   [2857-0] perf          7  0.000000  0.656423  0.000000  0.000000  0.000000  0.484107 |  57.6% +   [2857-0] perf        ALL  0.053925  0.848321  0.000000  0.000000  0.000000  1.311370 |  40.8%     1 +  +  -- ( ID)name             count   elapsed      pending      average      minimum      maximum +     (  0)read                 0  0.000000     0.167845           --           --           -- +     ( 59)execve               0  0.000000     0.000000           --           --           -- +  +ALL: +-- [  task] command     cpu      user       sys       irq        hv      busy      idle |  util% moves +   [   ALL]             ALL 10.790803 29.633170  0.160165  0.000000  0.137747 54.449823 |   7.4%    50 +  +  -- ( ID)name             count   elapsed      pending      average      minimum      maximum +     (  1)write             2896  1.623985     0.000000     0.004014     0.002364     0.041399 +     (102)getuid            2081  3.523861     0.000000     0.001693     0.000488     0.025157 +     (142)sched_setparam     691  7.222906    32.012841     0.024925     0.002024     0.662975 +     ( 13)rt_sigaction       383  0.235087     0.000000     0.000614     0.000434     0.014402 +     (  8)lseek              281  0.169157     0.000000     0.000602     0.000452     0.013404 +     (  0)read               133  2.782795     0.167845     0.020923     0.000509     1.864439 +     (  7)poll                96  8.583354   131.889895     0.193577     0.000626     4.596280 +     (  4)stat                93  7.036355     1.058719     0.183187     0.000981     3.661659 +     ( 47)recvmsg             85  0.146644     0.000000     0.001725     0.000646     0.019067 +     (  3)close               79  0.171046     0.000000     0.002165     0.000428     0.020659 +     (  9)mmap                78  0.311233     0.000000     0.003990     0.001613     0.017919 +     (186)gettid              74  0.067315     0.000000     0.000910     0.000403     0.014075 +     (  2)open                71  3.081589     0.213059     0.184248     0.001921     0.937946 +     (202)futex               62  5.145112   164.286154     0.405566     0.000597    11.587437 +  +  -- ( ID)name             count   elapsed      pending      average      minimum      maximum +     ( 12)i8042               10  0.160165     0.000000     0.016016     0.010920     0.032805 +  +Total Trace Time: 15.914636 ms +``` + +### Hurdles and issues + +Following are some of the issues encountered in the development of `curt`. + +#### Out-of-order events + +One of the more challenging issues is the discovery that events in a `perf.data` file can be out of time order. For a program trying to monitor state transitions carefully, this is a serious issue. For example, a trace could include the following sequence of events, displayed as they appear in the trace file: +``` +time 0000:  sys_enter syscall1 +time 0007:  sys_enter syscall2 +time 0006:  sys_exit syscall1 +time 0009:  sys_exit syscall2 +``` + +Just blindly processing these events in the order they are presented to their respective event-handling functions (in the wrong time order) will result in incorrect statistics (or worse). + +The most user-friendly ways to handle out-of-order events include: + + * Prevent traces from having out-of-order events in the first place by changing the way `perf record` works + * Providing a means to reorder events in a trace file, perhaps by enhancing `perf inject` + * Modifying how `perf script` works to present the events to the event-handling functions in time order + + + +But user-friendly is not the same as straightforward, nor easy. Also, none of the above are in the user's control. + +I chose to implement a queue for incoming events that would be sufficiently deep to allow for proper reordering of all events. This required a significant redesign of the code, including implementation of classes for each event, and moving the event processing for each event type into a method in that event's class. + +In the redesigned code, the actual event handlers' only job is to save the relevant data from the event into an instance of the event class, queue it, then process the top (oldest in time) event from the queue: +``` +def raw_syscalls__sys_enter(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, args): +         event = Event_sys_enter(nsecs(common_secs,common_nsecs), common_cpu, common_pid, common_comm, id) +        process_event(event) +``` + +The simple reorderable queuing mechanism is in a common function: +``` +events = [] +n_events = 0 +def process_event(event): +        global events,n_events,curr_timestamp +        i = n_events +        while i > 0 and events[i-1].timestamp > event.timestamp: +                i = i-1 +        events.insert(i,event) +        if n_events < params.window: +                n_events = n_events+1 +        else: +                event = events[0] +                # need to delete from events list now, +                # because event.process() could reenter here +                del events[0] +                if event.timestamp < curr_timestamp: +                        sys.stderr.write("Error: OUT OF ORDER events detected.\n  Try increasing the size of the look-ahead window with --window=\n") +                event.process() +``` + +Note that the size of the queue is configurable, primarily for performance and to limit memory consumption. The function will report when that queue size is insufficient to eliminate out-of-order events. It is worth considering whether to consider this case a catastrophic failure and elect to terminate the program. + +Implementing a class for each event type led to some consideration for refactoring, such that common code could coalesce into a base class: +``` +class Event (object): +  +        def __init__(self): +                self.timestamp = 0 +                self.cpu = 0 +                self.tid = 0 +                self.command = 'unknown' +                self.mode = 'unknown' +                self.pid = 0 +  +        def process(self): +                global start_timestamp +  +                try: +                        task = tasks[self.tid] +                        if task.pid == 'unknown': +                                tasks[self.tid].pid = self.pid +                except: +                        task = Task(start_timestamp, self.command, self.mode, self.pid) +                        tasks[self.tid] = task +  +                if self.cpu not in task.cpus: +                        task.cpus[self.cpu] = CPU() +                        if task.cpu == 'unknown': +                                task.cpu = self.cpu +  +                if self.cpu != task.cpu: +                        task.cpu = self.cpu +                        task.migrations += 1 +  +                return task +``` + +Then a class for each event type would be similarly constructed: +``` +class Event_sys_enter ( Event ): +  +        def __init__(self, timestamp, cpu, tid, comm, id, pid): +                self.timestamp = timestamp +                self.cpu = cpu +                self.tid = tid +                self.command = comm +                self.id = id +                self.pid = pid +                self.mode = 'busy-unknown' +                +        def process(self): +                global start_timestamp, curr_timestamp +                curr_timestamp = self.timestamp +                if (start_timestamp == 0): +                        start_timestamp = curr_timestamp +  +                task = super(Event_sys_enter, self).process() +  +                if task.mode == 'busy-unknown': +                        task.mode = 'user' +                        for cpu in task.cpus: +                                task.cpus[cpu].user = task.cpus[cpu].busy_unknown +                                task.cpus[cpu].busy_unknown = 0 +  +                task.syscall = self.id +                if self.id not in task.syscalls: +                        task.syscalls[self.id] = Call() +  +                task.syscalls[self.id].timestamp = curr_timestamp +                task.change_mode(curr_timestamp, 'sys') +``` + +Further refactoring is evident above, as well, moving the common code that updates relevant statistics based on a task's state change and the state change itself into a `change_mode` method of the `Task` class. + +### Start-of-trace timestamp + +As mentioned above, for scripts that depend on elapsed time, there should be an easier way to get the first timestamp in the trace other than forcing every event-handling function to conditionally save its timestamp as the start-of-trace timestamp. + +### Awkward invocation + +The syntax for invoking a `perf` Python script, including script parameters, is slightly awkward: +``` +$ perf script –s ./curt.py -- --window=80 +``` + +Also, it's awkward that `perf` Python scripts are not themselves executable. + +The `curt.py` script was made directly executable and will invoke `perf`, which will in turn invoke the script. Implementation is a bit confusing but it's easy to use: +``` +$ ./curt.py --window=80 +``` + +This script must detect when it has been directly invoked. The Python environment established by `perf` is a virtual module from which the `perf` Python scripts import: +``` +try: +        from perf_trace_context import * +``` + +If this import fails, the script was directly invoked. In this case, the script will `exec perf`, specifying itself as the script to run, and passing along any command line parameters: +``` +except: +        if len(params.file_or_command) == 0: +                params.file_or_command = [ "perf.data" ] +        sys.argv = ['perf', 'script', '-i' ] + params.file_or_command + [ '-s', sys.argv[0] ] +        sys.argv.append('--') +        sys.argv += ['--window', str(params.window)] +        if params.debug: +                sys.argv.append('--debug') +        sys.argv += ['--api', str(params.api)] +        if params.debug: +                print sys.argv +        os.execvp("perf", sys.argv) +        sys.exit(1) +``` + +In this way, the script can not only be run directly, it can still be run by using the `perf script` command. + +#### Simultaneous event registration required + +An artifact of the way `perf` enables events can lead to unexpected trace data. For example, specifying: +``` +$ perf record –a –e raw_syscalls:sys_enter –e raw_syscalls:sys_exit ./command +``` + +Will result in a trace file that begins with the following series of events for a single task (the `perf` command itself): +``` +sys_enter +sys_enter +sys_enter +… + +``` + +This happens because `perf` will register the `sys_enter` event for every CPU on the system (because of the `-a` argument), then it will register the `sys_exit` event for every CPU. In the latter case, since the `sys_enter` event has already been enabled for each CPU, that event shows up in the trace; but since the `sys_exit` has not been enabled on each CPU until after the call returns, the `sys_exit` call does not show up in the trace. The reverse issue happens at the end of the trace file, with a series of `sys_exit` events in the trace because the `sys_enter` event has already been disabled. + +The solution to this issue is to group the events, which is not well documented: +``` +$ perf record –e '{raw_syscalls:sys_enter,raw_syscalls:sys_exit}' ./command +``` + +With this syntax, the `sys_enter` and `sys_exit` events are enabled simultaneously. + +#### Awkward recording step + +There are a lot of different events required for computation of the full set of statistics for tasks. This leads to a very long, complicated command for recording: +``` +$ perf record -e '{raw_syscalls:*,sched:sched_switch,sched:sched_migrate_task,sched:sched_process_exec,sched:sched_process_fork,sched:sched_process_exit,sched:sched_stat_runtime,sched:sched_stat_wait,sched:sched_stat_sleep,sched:sched_stat_blocked,sched:sched_stat_iowait,powerpc:hcall_entry,powerpc:hcall_exit}' -a *command --args* + +``` + +The solution to this issue is to enable the script to perform the record step itself, by itself invoking `perf`. A further enhancement is to proceed after the recording is complete and report the statistics from that recording: +``` +if params.record: +        # [ed. Omitting here the list of events for brevity] +        eventlist = '{' + eventlist + '}' # group the events +        command = ['perf', 'record', '--quiet', '--all-cpus', +                '--event', eventlist ] + params.file_or_command +        if params.debug: +                print command +        subprocess.call(command) +``` + +The command syntax required to record and report becomes: +``` +$ ./curt.py --record ./command +``` + +### Process IDs and perf API change + +Process IDs are treated a bit cavalierly by `perf` scripting. Note well above that one of the common parameters for the generated event-handling functions is named `common_pid`. This is not the process ID, but the task ID. In fact, on many current Linux-based distributions, there is no way to determine a task's process ID from within a `perf` Python script. This presents a serious problem for a script that wants to compute statistics for a process. + +Fortunately, in Linux kernel v4.14, an additional parameter was provided to each of the event-handling functions—`perf_sample_dict`—a dictionary from which the process ID could be extracted: (`perf_sample_dict['sample']['pid']`). + +Unfortunately, current Linux distributions may not have that version of the Linux kernel. If the script is written to expect that extra parameter, the script will fail and report an error: +``` +TypeError: irq__irq_handler_exit_new() takes exactly 11 arguments (10 given) +``` + +Ideally, a means to automatically discover if the additional parameter is passed would be available to permit a script to easily run with both the old and new APIs and to take advantage of the new API if it is available. Unfortunately, such a means is not readily apparent. + +Since there is clearly value in using the new API to determine process-wide statistics, `curt` provides a command line option to use the new API. `curt` then takes advantage of Python's lazy function binding to adjust, at run-time, which API to use: +``` +if params.api == 1: +        dummy_dict = {} +        dummy_dict['sample'] = {} +        dummy_dict['sample']['pid'] = 'unknown' +        raw_syscalls__sys_enter = raw_syscalls__sys_enter_old +        […] +else: +        raw_syscalls__sys_enter = raw_syscalls__sys_enter_new +        […] +``` + +This requires two functions for each event: +``` +def raw_syscalls__sys_enter_new(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, args, perf_sample_dict): +  +        event = Event_sys_enter(nsecs(common_secs,common_nsecs), common_cpu, common_pid, common_comm, id, perf_sample_dict['sample']['pid']) +        process_event(event) +  +def raw_syscalls__sys_enter_old(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, args): +        global dummy_dict +        raw_syscalls__sys_enter_new(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, id, args, dummy_dict) +``` + +Note that the event-handling function for the older API will make use of the function for the newer API, passing a statically defined dictionary containing just enough data such that accessing it as `perf_sample_dict['sample']['pid']` will work (resulting in `'unknown'`). + +#### Events reported on other CPUs + +Not all events that refer to a task are reported from a CPU on which the task is running. This could result in an artificially high migration count and other incorrect statistics. For these types of events (`sched_stat`), the event CPU is ignored. + +#### Explicit migrations (no sched_migrate event) + +While there is conveniently an event for when the kernel decides to migrate a task from one CPU to another, there is no event for when the task requests a migration on its own. These are effected by system calls (`sched_setaffinity`), so the `sys_exit` event handler must compare the event CPU to the task's CPU, and if different, presume a migration has occurred. (This is described above, but repeated here in the "issues" section for completeness.) + +#### Mapping system call IDs to names is architecture-specific + +System calls are identified in events only as unique numeric identifiers. These identifiers are not readily interpreted by humans in the report. These numeric identifiers are not readily mapped to their mnemonics because they are architecture-specific, and new system calls can be added in newer kernels. Fortunately, `perf` provides a means to map system call numeric identifiers to system call names. A simple example follows: +``` +from Util import syscall_name +def raw_syscalls__sys_enter(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, id, args, perf_sample_dict): +                print "%s id=%d" % (syscall_name(id), id) +``` + +Unfortunately, using syscall_name introduces a dependency on the `audit` python bindings. This dependency is being removed in upstream versions of perf. + +#### Mapping hypervisor call IDs to names is non-existent + +Similar to system calls, hypervisor calls are also identified only with numeric identifiers. For IBM's POWER hypervisor, they are statically defined. Unfortunately, `perf` does not provide a means to map hypervisor call identifiers to mnemonics. `curt` includes a (hardcoded) function to do just that: +``` +hcall_to_name = { +        '0x4':'H_REMOVE', +        '0x8':'H_ENTER',       +        '0xc':'H_READ',       +        '0x10':'H_CLEAR_MOD', +[…] +} +  +def hcall_name(opcode): +        try: +                return hcall_to_name[hex(opcode)] +        except: +                return str(opcode) +``` + +### Command strings as bytearrays + +`perf` stores command names and string arguments in Python bytearrays. Unfortunately, printing bytearrays in Python prints every character in the bytearray—even if the string is null-terminated. For example: +``` +$ perf record –a –e 'sched:sched_switch' sleep 3 +$ perf script –g Python +generated Python script: perf-script.py +$ perf script -s ./perf-script.py +in trace_begin +sched__sched_switch      3 664597.912692243    21223 perf                  prev_comm=perf^@-terminal-^@, prev_pid=21223, prev_prio=120, prev_state=, next_comm=migration/3^@^@^@^@^@, next_pid=23, next_prio=0 +[…] +``` + +One solution is to truncate the length of these bytearrays based on null termination, as needed before printing: +``` +def null(ba): +        null = ba.find('\x00') +        if null >= 0: +                ba = ba[0:null] +        return ba + +def sched__sched_switch(event_name, context, common_cpu, +        common_secs, common_nsecs, common_pid, common_comm, +        common_callchain, prev_comm, prev_pid, prev_prio, prev_state, +        next_comm, next_pid, next_prio, perf_sample_dict): + +                print "prev_comm=%s, prev_pid=%d, prev_prio=%d, " \ +                "prev_state=%s, next_comm=%s, next_pid=%d, " \ +                "next_prio=%d" % \ +                (null(prev_comm), prev_pid, prev_prio, +                flag_str("sched__sched_switch", "prev_state", prev_state), +                null(next_comm), next_pid, next_prio) +``` + +Which nicely cleans up the output: +``` +sched__sched_switch      3 664597.912692243    21223 perf                  prev_comm=perf, prev_pid=21223, prev_prio=120, prev_state=, next_comm=migration/3, next_pid=23, next_prio=0 +``` + +### Dynamic mappings, like IRQ number to name + +Dissimilar to system calls and hypervisor calls, interrupt numbers (IRQs) are dynamically assigned by the kernel on demand, so there can't be a static table mapping an IRQ number to a name. Fortunately, `perf` passes the name to the event's `irq_handler_entry` routine. This allows a script to create a dictionary that maps the IRQ number to a name: +``` +irq_to_name = {} +def irq__irq_handler_entry_new(event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, irq, name, perf_sample_dict): +        irq_to_name[irq] = name +        event = Event_irq_handler_entry(nsecs(common_secs,common_nsecs), common_cpu, common_pid, common_comm, irq, name, getpid(perf_sample_dict)) +        process_event(event) +``` + +Somewhat oddly, `perf` does not pass the name to the `irq_handler_exit` routine. So, it is possible that a trace may only see an `irq_handler_exit` for an IRQ and must be able to tolerate that. Here, instead of mapping the IRQ to a name, the IRQ number is returned as a string instead: +``` +def irq_name(irq): +        if irq in irq_to_name: +                return irq_to_name[irq] +        return str(irq) +``` +#### Task 0 +Task 0 shows up everywhere. It's not a real task. It's a substitute for the "idle" state. It's the task ID given to the `sched_switch` event handler when the CPU is going to (or coming from) the "idle" state. It's often the task that is "interrupted" by interrupts. Tracking the statistics for task 0 as if it were a real task would not make sense. Currently, `curt` ignores task 0. However, this loses some information, like some time spent in interrupt processing. `curt` should, but currently doesn't, track interesting (non-idle) time for task 0. + +#### Spurious sched_migrate_task events (same CPU) + +Rarely, a `sched_migrate_task` event occurs in which the source and target CPUs are the same. In other words, the task is not migrated. To avoid artificially inflated migration counts, this case must be explicitly ignored: +``` +class Event_sched_migrate_task (Event): +        def process(self): +[…] +                if self.cpu == self.dest_cpu: +                        return +``` + +#### exec + +The semantics of the `exec` system call are that the image of the current process is replaced by a completely new process image without changing the process ID. This is awkward for tracking the statistics of a process (really, a task) based on the process (task) ID. The change is significant enough that the statistics for each task should be accumulated separately, so the current task's statistics need to be closed out and a new set of statistics should be initialized. The challenge is that both the old and new tasks have the same process (task) ID. `curt` addresses this by tagging the task's task ID with a numeric suffix: +``` +class Event_sched_process_exec (Event): +  def process(self): +    global start_timestamp, curr_timestamp +    curr_timestamp = self.timestamp +    if (start_timestamp == 0): +      start_timestamp = curr_timestamp +  +    task = super(Event_sched_process_exec, self).process() +  +    new_task = Task(self.timestamp, self.command, task.mode, self.pid) +    new_task.sched_stat = True +    new_task.syscall = task.syscall +    new_task.syscalls[task.syscall] = Call() +    new_task.syscalls[task.syscall].timestamp = self.timestamp +  +    task.change_mode(curr_timestamp, 'exit') +  +    suffix=0 +    while True: +      old_tid = str(self.tid)+"-"+str(suffix) +      if old_tid in tasks: +        suffix += 1 +      else: +        break +  +    tasks[old_tid] = tasks[self.tid] +  +    del tasks[self.tid] +  +    tasks[self.tid] = new_task +``` + +This will clearly separate the statistics for the different process images. In the example below, the `perf` command (task "9614-0") `exec`'d `exec.sh` (task "9614-1"), which in turn `exec`'d itself (task "9614"): +``` +-- [  task] command   cpu      user       sys       irq        hv      busy      idle |  util% moves +    [  9614] execs.sh    4  1.328238  0.485604  0.000000  0.000000  0.000000  2.273230 |  44.4% +    [  9614] execs.sh    7  0.000000  0.201266  0.000000  0.000000  0.000000  0.003466 |  98.3% +    [  9614] execs.sh  ALL  1.328238  0.686870  0.000000  0.000000  0.000000  2.276696 |  47.0%     1 + +-- [  task] command   cpu      user       sys       irq        hv      busy      idle |  util% moves +    [9614-0] perf        3  0.000000  0.408588  0.000000  0.000000  0.000000  2.298722 |  15.1% +    [9614-0] perf        4  0.059079  0.028269  0.000000  0.000000  0.000000  0.611355 |  12.5% +    [9614-0] perf        5  0.000000  0.067626  0.000000  0.000000  0.000000  0.004702 |  93.5% +    [9614-0] perf      ALL  0.059079  0.504483  0.000000  0.000000  0.000000  2.914779 |  16.2%     2 +  +-- [  task] command   cpu      user       sys       irq        hv      busy      idle |  util% moves +    [9614-1] execs.sh    3  1.207972  0.987433  0.000000  0.000000  0.000000  2.435908 |  47.4% +    [9614-1] execs.sh    4  0.000000  0.341152  0.000000  0.000000  0.000000  0.004147 |  98.8% +    [9614-1] execs.sh  ALL  1.207972  1.328585  0.000000  0.000000  0.000000  2.440055 |  51.0%     1 +``` + +#### Distribution support + +Surprisingly, there is currently no support for `perf`'s Python bindings in Ubuntu. [Follow the saga][4] for more detail. + +#### Limit on number of traced events + +As `curt` gets more sophisticated, it is likely that more and more events may be required to be included in the trace file. `perf` currently requires one file descriptor per event per CPU. This becomes a problem when the maximum number of open file descriptors is not a large multiple of the number of CPUs on the system. On systems with large numbers of CPUs, this quickly becomes a problem. For example, the default maximum number of open file descriptors is often 1,024. An IBM POWER8 system with four sockets may have 12 cores per socket and eight threads (CPUs) per core. Such a system has 4 * 12 * 8 = 392 CPUs. In that case, `perf` could trace only about two events! A workaround is to (significantly) increase the maximum number of open file descriptors (`ulimit –n` if the system administrator has configured the hard limits high enough; or the administrator can set the limits higher in `/etc/security/limits.conf` for `nofile`). + +### Summary + +I hope this article shows the power of `perf`—and specifically the utility and flexibility of the Python scripting enabled with `perf`—to perform sophisticated processing of kernel trace data. Also, it shows some of the issues and edge cases that can be encountered when the boundaries of such technologies are tested. + +Please feel free to download and make use of the `curt` tool described here, report problems, suggest improvements, or contribute code of your own on the [`curt` GitHub page][5]. + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/fun-perf-and-python + +作者:[Paul Clarke][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/thinkopenly +[1]:https://2018.texaslinuxfest.org/ +[2]:https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.cmds1/curt.htm +[3]:https://opensource.com/article/17/9/intro-ebpf +[4]:https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1707875 +[5]:https://github.com/open-power-sdk/curt diff --git a/sources/tech/20180727 Three Graphical Clients for Git on Linux.md b/sources/tech/20180727 Three Graphical Clients for Git on Linux.md new file mode 100644 index 0000000000..ce545fee01 --- /dev/null +++ b/sources/tech/20180727 Three Graphical Clients for Git on Linux.md @@ -0,0 +1,134 @@ +Three Graphical Clients for Git on Linux +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/git-tools.jpg?itok=Be56iPT0) + +Those that develop on Linux are likely familiar with [Git][1]. With good reason. Git is one of the most widely used and recognized version control systems on the planet. And for most, Git use tends to lean heavily on the terminal. After all, much of your development probably occurs at the command line, so why not interact with Git in the same manner? + +In some instances, however, having a GUI tool to work with can make your workflow slightly more efficient (at least for those that tend to depend upon a GUI). To that end, what options do you have for Git GUI tools? Fortunately, we found some that are worthy of your time and (in some cases) money. I want to highlight three such Git clients that run on the Linux operating system. Out of these three, you should be able to find one that meets all of your needs. +I am going to assume you understand how Git and repositories like GitHub function, [which I covered previously][2], so I won’t be taking the time for any how-tos with these tools. Instead, this will be an introduction, so you (the developer) know these tools are available for your development tasks. + +A word of warning: Not all of these tools are free, and some are released under proprietary licenses. However, they all work quite well on the Linux platform and make interacting with GitHub a breeze. + +With that said, let’s look at some outstanding Git GUIs. + +### SmartGit + +[SmartGit][3] is a proprietary tool that’s free for non-commercial usage. If you plan on employing SmartGit in a commercial environment, the license cost is $99 USD per year for one license or $5.99 per month. There are other upgrades (such as Distributed Reviews and SmartSynchronize), which are both $15 USD per licence. You can download either the source or a .deb package for installation. I tested SmartGit on Ubuntu 18.04 and it worked without issue. + +But why would you want to use SmartGit? There are plenty of reasons. First and foremost, SmartGit makes it incredibly easy to integrate with the likes of GitHub and Subversion servers. Instead of spending your valuable time attempting to configure the GUI to work with your remote accounts, SmartGit takes the pain out of that task. The SmartGit GUI (Figure 1) is also very well designed to be uncluttered and intuitive. + + +![SmartGit][5] + +Figure 1: The SmartGit UI helps to simplify your workflow. + +[Used with permission][6] + +After installing SmartGit, I had it connected with my personal GitHub account in seconds. The default toolbar makes working with a repository, incredibly simple. Push, pull, check out, merge, add branches, cherry pick, revert, rebase, reset — all of Git’s most popular features are there to use. Outside of supporting most of the standard Git and GitHub functions/features, SmartGit is very stable. At least when using the tool on the Ubuntu desktop, you feel like you’re working with an application that was specifically designed and built for Linux. + +SmartGit is probably one of the best tools that makes working with even advanced Git features easy enough for any level of user. To learn more about SmartGit, take a look at the [extensive documentation][7]. + +### GitKraken + +[GitKraken][8] is another proprietary GUI tool that makes working with both Git and GitHub an experience you won’t regret. Where SmartGit has a very simplified UI, GitKraken has a beautifully designed interface that offers a bit more feature-wise at the ready. There is a free version of GitKraken available (and you can test the full-blown paid version with a 15 day trial period). After the the trial period ends, you can continue using the free version, but for non-commercial use only. + +For those who want to get the most out of their development workflow, GitKraken might be the tool to choose. This particular take on the Git GUI features the likes of visual interactions, resizable commit graphs, drag and drop, seamless integration (with GitHub, GitLab, and BitBucket), easy in-app tasks, in-app merge tools, fuzzy finder, gitflow support, 1-click undo & redo, keyboard shortcuts, file history & blame, submodules, light & dark themes, git hooks support, git LFS, and much more. But the one feature that many users will appreciate the most is the incredibly well-designed interface (Figure 2). + + +![GitKraken][10] + +Figure 2: The GitKraken interface is tops. + +[Used with permission][6] + +Outside of the amazing interface, one of the things that sets GitKraken above the rest of the competition is how easy it makes working with multiple remote repositories and multiple profiles. The one caveat to using GitKraken (besides it being proprietary) is the cost. If you’re looking at using GitKraken for commercial use, the license costs are: + + * $49 per user per year for individual + + * $39 per user per year for 10+ users + + * $29 per user per year for 100+ users + + + + +The Pro accounts allow you to use both the Git Client and the Glo Boards (which is the GitKraken project management tool) commercially. The Glo Boards are an especially interesting feature as they allow you to sync your Glo Board to GitHub Issues. Glo Boards are sharable and include search & filters, issue tracking, markdown support, file attachments, @mentions, card checklists, and more. All of this can be accessed from within the GitKraken GUI. +GitKraken is available for Linux as either an installable .deb file, or source. + +### Git Cola + +[Git Cola][11] is our free, open source entry in the list. Unlike both GitKraken and Smart Git, Git Cola is a pretty bare bones, no-nonsense Git client. Git Cola is written in Python with a GTK interface, so no matter what distribution and desktop combination you use, it should integrate seamlessly. And because it’s open source, you should find it in your distribution's package manager. So installation is nothing more than a matter of opening your distribution’s app store, searching for “Git Cola” and installing. You can also install from the command line like so: +``` +sudo apt install git-cola + +``` + +Or: +``` +sudo dnf install git-cola + +``` + +The Git Cola interface is pretty simple (Figure 3). In fact, you won’t find much in the way of too many bells and whistles, as Git Cola is all about the basics. + + +![Git Cola][13] + +Figure 3: The Git Cola interface is a much simpler affair. + +[Used with permission][6] + +Because of Git Cola’s return to basics, there will be times when you must interface with the terminal. However, for many Linux users this won’t be a deal breaker (as most are developing within the terminal anyway). Git Cola does include features like: + + * Multiple subcommands + + * Custom window settings + + * Configurable and environment variables + + * Language settings + + * Supports custom GUI settings + + * Keyboard shortcuts + + + + +Although Git Cola does support connecting to remote repositories, the integration to the likes of Github isn’t nearly as intuitive as it is on either GitKraken or SmartGit. But if you’re doing most of your work locally, Git Cola is an outstanding tool that won’t get in between you and Git. + +Git Cola also comes with an advanced (Directed Acyclic Graph) DAG visualizer, called Git Dag. This tool allows you to get a visual representation of your branches. You start Git Dag either separately from Git Cola or within Git Cola from the View > DAG menu entry. Git DAG is a very powerful tool, which helps to make Git Cola one of the top open source Git GUIs on the market. + +### There’s more where that came from + +There are plenty more Git GUI tools available. However, from these three tools you can do some serious work. Whether you’re looking for a tool with all the bells and whistles (regardless of license) or if you’re a strict GPL user, one of these should fit the bill. + +Learn more about Linux through the free ["Introduction to Linux" ][14]course from The Linux Foundation and edX. + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/intro-to-linux/2018/7/three-graphical-clients-git-linux + +作者:[Jack Wallen][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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 +[1]:https://git-scm.com/ +[2]:https://www.linux.com/learn/intro-to-linux/2018/7/introduction-using-git +[3]:https://www.syntevo.com/smartgit/ +[4]:/files/images/gitgui1jpg +[5]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/gitgui_1.jpg?itok=LEZ_PYIf (SmartGit) +[6]:/licenses/category/used-permission +[7]:http://www.syntevo.com/doc/display/SG/Manual +[8]:https://www.gitkraken.com/ +[9]:/files/images/gitgui2jpg +[10]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/gitgui_2.jpg?itok=Y8crSLhf (GitKraken) +[11]:https://git-cola.github.io/ +[12]:/files/images/gitgui3jpg +[13]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/gitgui_3.jpg?itok=bS9OYPQo (Git Cola) +[14]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/translated/talk/20180115 Why DevSecOps matters to IT leaders.md b/translated/talk/20180115 Why DevSecOps matters to IT leaders.md deleted file mode 100644 index aaf03510a7..0000000000 --- a/translated/talk/20180115 Why DevSecOps matters to IT leaders.md +++ /dev/null @@ -1,86 +0,0 @@ -为什么DevSecOps对领导来说如此重要 -====== - -![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/images/TEP_SecurityTraining1_620x414_1014.png?itok=zqxqJGDG) - -如果[DevOps][1] 最终是关于创造更好的软件,那也就意味着是更安全的软件。 - -输入术语“DevSecOps.”像任何其他IT术语一样,DevSecOps - 一个整容后的DevOps的后代 -可能容易被炒作和盗用。但这个术语对那些拥抱DevOps文化的领导者们,帮助他们实现其承诺的实践和工具来说具有重要的意义。 - -说道这里:“DevSecOps”是什么意思? - -“DevSecOps是开发、安全、运营的混合,”来自[Datical][2]的首席技术官和联合创始人罗伯特说。“这提醒我们安全对我们的应用程序来说和创建并部署应用到生产中一样重要。” -**[想阅读其他首席技术官的DevOps文章吗?查阅我们广泛的资源,[DevOps:IT领导者的指南][3].]** - -向非技术人员解释DevSecOps的一个简单的方法是:它是指将安全有意并提前加入到开发过程中。 - -”安全团队从历史上一直都被从开发团队中所孤立-每个团队在IT的不同领域都开发了很强的专业能力,”来自红帽安全策的专家Kirsten最近告诉我们。“它不需要这样,非常关注安全也关注他们通过软件来兑现商业价值的能力的企业正在寻找能够在应用开发生命周期中加入安全的方法。他们通过在整个CI/CD管道中集成安全实践,工具和自动化来采用DevSecOps.” - -"为了能够做的更好,他们正在整合他们的团队-专业的安全人员从开始设计到部署到生产中都嵌入到了应开发团队中了,"她说。“双方都收获了价值-每个团队都拓展了他们的技能和基础知识,使他们自己都成更有价值的技术人员。DevOps做的很正确-或者说DevSecOps-提高了IT的安全性。” - -IT团队比任何以往都要求要快速频繁的交付服务。DevOps在某种程度上可以成为一个很棒的推动者,因为它能够消除开发和运营之间通常遇到的一些摩擦,运营一直被排挤在整个过程之外直到要部署的时候,开发者把代码随便一放之后就不再去管理,他们承担更少的基础架构的责任。那种孤立的方法引起了很多问题,委婉的说,在数字时代,如果将安全孤立起来同样的情况也会发生。 - -“我们已经采用了DevOps因为它已经被证明通过移除开发和运营之间的阻碍来提高IT的绩效,”Reevess说。“就像我们不应该在开发周期要结束时才加入运营,我们不应该在快要结束时才加入安全。” - -### 为什么DevSecOps在此停留 -或许会把DevSecOps看作是另一个时髦词,但对于安全意识很强的IT领导者来说,它是一个实质性的术语:在软件开发管道中安全必须是第一流的公民,而不是部署前的最后一步的螺栓,或者更糟的是,作为一个团队只有当一个实际的事故发生的时候安全人员才会被重用争抢。 - -“DevSecOps不只是一个时髦的术语-因为多种原因它是现在和未来IT将呈现的状态,”来自[Sumo Logic]的安全和合规副总裁George说道,“最重要的好处是将安全融入到开发和运营当中开提供保护的能力” - -此外,DevSecOps的出现可能是DevOps自身逐渐成熟并扎根于IT之中的一个征兆。 - -“企业中的DevOps文化就在这里,而且那意味着开发者们正以不断增长的速度交付功能和更新,特别是自我管理的组织对合作和衡量的结果更加满意时,”来自[CYBRIC] -的首席技术官和联合创始人Mike说道。 - -在实施DevOps的同时继续保留原有安全措施的团队和公司,随着他们继续部署的更快更频繁可能正在经历越来越多的安全管理风险上的痛苦。 - -“现在的手工的安全测试方法会继续远远被甩在后面。” - -“如今,手动的安全测试方法正被甩得越来越远,利用自动化和协作将安全测试转移到软件开发生命周期中,因此推动DevSecOps的文化是IT领导者们增加整体的灵活性提供安全保证的唯一途径,”Kail说。 - -转移安全测试也使开发者受益:而不是在一个新的服务或者更新部署之前在他们的代码中发现一个明显的漏洞,他们能够在开放的较早的阶段验证并解决潜在的问题-经常 -是很少需要或者甚至不需要安全人员的介入。 - -“做的正确,DevSecOps能够将安全融入到开发生命周期中,允许开发者们在没有安全中断的情况下更加快速容易的保证他们应用的安全,”来自[SAS][8]的首席信息安全员Wilson说道。 - -Wilson指出静态(SAST)和源组合工具(SCA),集成到团队的持续交付管道中,作为有用的技术通过给予开发者关于他们的代码中的潜在问题和第三方依赖中的漏洞的反馈 -来使之逐渐成为可能。 - -“因此,开发者们能够主动和迭代的缓解应用安全的问题,然后在不需要安全人员介入的情况下重新进行安全扫描。”Wilson说。他同时指出DevSecOps能够帮助开发者简化更新和打补丁。 - -DevSecOps并不意味着你不再需要安全组的意见了,就如同DevOps并不意味着你不再需要基础架构专家;它只是帮助减少在生产中发现缺陷的可能性,或者减少导致是降低部署的速度的阻碍,因为缺陷已经在开放周期中被发现解决了。 - -“如果他们有问题或者需要帮助,我们就在这儿,但是因为已经给了开发者他们需要的保护他们应用安全的工具,我们很少在一个深入的测试中发现一个导致中断的问题,”Wilson说道。 - -### DevSecOps 遇到危机 - -Sumo Locic's的Gerchow向我们分享了一个在运转中的DevSecOps文化的一个及时的案列:当最近[危机和幽灵]的消息传来的时候,团队的DevSecOps方法使得有了一个快速的响应来减轻风险,没有任何的通知去打扰内部或者外部的顾客,Gerchow所说的这点对原生云高监管的公司来说特别的重要。 - -第一步:Gerchow的小的安全团队,都具有一定的开发能力,能够通过Slack和它的主要云供应商协同工作来确保它的基础架构能够在24小时之内完成修复。 - -“接着我的团队立即开始进行系统级的修复,实现终端客户的零停机时间,不需要去开单给工程师,如果那样那意味着你需要等待很长的变更过程。所有的变更都是通过Slack自动jira票据进行,通过我们的日志监控和分析解决方案,”Gerchow解释道。 - -在本质上,它听起来非常像DevOps的文化,匹配正确的人员,进程和工具,但它明确的包括了安全作为文化中的一部分进行混合。 - -“在传统的环境中,这将花费数周或数月的停机时间来处理,因为开发,运维和安全三者是相互独立的,”Gerchow说道."通过一个DevSecOps的过程和习惯,终端用户可以通过简单的沟通和当日修复获得无缝的体验。" - --------------------------------------------------------------------------------- - -via: https://enterprisersproject.com/article/2018/1/why-devsecops-matters-it-leaders - -作者:[Kevin Casey][a] -译者:[FelixYFZ](https://github.com/FelixYFZ) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://enterprisersproject.com/user/kevin-casey -[1]:https://enterprisersproject.com/tags/devops -[2]:https://www.datical.com/ -[3]:https://enterprisersproject.com/devops?sc_cid=70160000000h0aXAAQ -[4]:https://www.redhat.com/en?intcmp=701f2000000tjyaAAA -[5]:https://enterprisersproject.com/article/2017/10/what-s-next-devops-5-trends-watch -[6]:https://www.sumologic.com/ -[7]:https://www.cybric.io/ -[8]:https://www.sas.com/en_us/home.html -[9]:https://www.redhat.com/en/blog/what-are-meltdown-and-spectre-heres-what-you-need-know?intcmp=701f2000000tjyaAAA diff --git a/translated/talk/20180128 Being open about data privacy.md b/translated/talk/20180128 Being open about data privacy.md deleted file mode 100644 index 9d7e4bd87b..0000000000 --- a/translated/talk/20180128 Being open about data privacy.md +++ /dev/null @@ -1,95 +0,0 @@ -对数据隐私持开放的态度 -====== -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/GOV_opendata.png?itok=M8L2HGVx) - - -Image by : opensource.com - -今天是[数据隐私日][1],(在欧洲叫"数据保护日"),你可能会认为现在我们处于一个开源的世界中,所有的数据都应该免费,[就像人们想的那样][2],但是现实并没那么简单。主要有两个原因: -1. 我们中的大多数(不仅仅是在开源中)认为至少有些关于我们自己的数据是不愿意分享出去的(我在之前发表的一篇文章中列举了一些列子[3]) -2. 我们很多人虽然在开源中工作,但事实上是为了一些商业公司或者其他一些组织工作,也是在合法的要求范围内分享数据。 - -所以实际上,数据隐私对于每个人来说是很重要的。 - -事实证明,在美国和欧洲之间,人们和政府认为让组织使用的数据的起点是有些不同的。前者通常为实体提供更多的自由度,更愤世嫉俗的是--大型的商业体利用他们收集到的关于我们的数据。在欧洲,完全是另一观念,一直以来持有的多是有更多约束限制的观念,而且在5月25日,欧洲的观点可以说取得了胜利。 - -## 通用数据保护条例的影响 - -那是一个相当全面的声明,其实事实上就是欧盟在2016年通过的一项关于通用数据保护的立法,使它变得可实施。数据通用保护条例在私人数据怎样才能被保存,如何才能被使用,谁能使用,能被持有多长时间这些方面设置了严格的规则。它描述了什么数据属于私人数据--而且涉及的条目范围非常广泛,从你的姓名家庭住址到你的医疗记录以及接通你电脑的IP地址。 - -通用数据保护条例的重要之处是他并不仅仅适用于欧洲的公司,如果你是阿根廷人,日本人,美国人或者是俄罗斯的公司而且你正在收集涉及到欧盟居民的数据,你就要受到这个条例的约束管辖。 - -“哼!” 你可能会这样说,“我的业务不在欧洲:他们能对我有啥约束?” 答案很简答:如果你想继续在欧盟做任何生意,你最好遵守,因为一旦你违反了通用数据保护条例的规则,你将会受到你全球总收入百分之四的惩罚。是的,你没听错,是全球总收入不是仅仅在欧盟某一国家的的收入,也不只是净利润,而是全球总收入。这将会让你去叮嘱告知你的法律团队,他们就会知会你的整个团队,同时也会立即去指引你的IT团队,确保你的行为相当短的时间内是符合要求的。 - -看上去这和欧盟之外的城市没有什么相关性,但其实不然,对大多数公司来说,对所有的他们的顾客、合作伙伴以及员工实行同样的数据保护措施是件既简单又有效的事情,而不是只是在欧盟的城市实施,这将会是一件很有利的事情。2 - -然而,数据通用保护条例不久将在全球实施并不意味着一切都会变的很美好:事实并非如此,我们一直在丢弃关于我们自己的信息--而且允许公司去使用它。 - -有一句话是这么说的(尽管很争议):“如果你没有在付费,那么你就是产品。”这句话的意思就是如果你没有为某一项服务付费,那么其他的人就在付费使用你的数据。 -你有付费使用Facebook、推特?谷歌邮箱?你觉得他们是如何赚钱的?大部分是通过广告,一些人会争论那是他们向你提供的一项服务而已,但事实上是他们在利用你的数据从广告商里获取收益。你不是一个真正的广告的顾客-只有当你从看了广告后买了他们的商品之后你才变成了他们的顾客,但直到这个发生之前,都是广告平台和广告商的关系。 - -有些服务是允许你通过付费来消除广告的(流媒体音乐平台声破天就是这样的),但从另一方面来讲,即使你认为付费的服务也可以启用广告(列如,亚马逊正在允许通过Alexa广告)除非我们想要开始为这些所有的免费服务付费,我们需要清除我们所放弃的,而且在我们想要揭发和不想的里面做一些选择。 - -### 谁是顾客? - -关于数据的另一个问题一直在困扰着我们,它是产生的数据量的直接结果。有许多组织一直在产生巨量的数据,包括公共的组织比如大学、医院或者是政府部门4-- -而且他们没有能力去储存这些数据。如果这些数据没有长久的价值也就没什么要紧的,但事实正好相反,随着处理大数据的工具正在开发中,而且这些组织也认识到他们现在以及在不久的将来将能够去开采这些数据。 - -然而他们面临的是,随着数据的增长和存储量的不足他们是如何处理的。幸运--而且我是带有讽刺意味的使用了这个词,5大公司正在介入去帮助他们。“把你们的数据给我们,”他们说,“我们将免费保存。我们甚至让你随时能够使用你所收集到的数据!”这听起来很棒,是吗?这是大公司的一个极具代表性的列子,站在慈善的立场上帮助公共组织管理他们收集到的关于我们的数据。 - -不幸的是,慈善不是唯一的理由。他们是附有条件的:作为同意保存数据的交换条件,这些公司得到了将数据访问权限出售非第三方的权利。你认为公共组织,或者是被收集数据的人在数据被出售使用权使给第三方在他们如何使用上面能有发言权吗?我将把这个问题当做一个练习留给读者去思考。7 - -### 开放和积极 - -然而并不只有坏消息。政府中有一项在逐渐发展起来的“开放数据”运动鼓励部门能够将免费开放他们的数据给公众或者其他组织。这项行动目前正在被实施立法。许多 -支援组织--尤其是那些收到公共基金的--正在开始推动同样的活动。即使商业组织也有些许的兴趣。而且,在技术上已经可行了,例如围绕不同的隐私和多方计算上,正在允许我们根据数据设置和不揭露太多关于个人的前提下开采数据--一个历史性的计算问题比你想象的要容易处理的多。 - -这些对我们来说意味着什么呢?我之前在网站Opensource.com上写过关于[开源的共享福利][4],而且我越来越相信我们需要把我们的视野从软件拓展到其他区域:硬件,组织,和这次讨论有关的,数据。让我们假设一下你是A公司要提向另一家公司提供一项服务,客户B。在游戏中有四种不同类型的数据: - 1. 数据完全开放:对A和B都是可得到的,世界上任何人都可以得到 - 2. 数据是已知的,共享的,和机密的:A和B可得到,但其他人不能得到。 - 3. 数据是公司级别上保密的:A公司可以得到,但B顾客不能 - 4. 数据是顾客级别保密的:B顾客可以得到,但A公司不能 - -首先,也许我们对数据应该更开放些,将数据默认放到选项一中。如果那些数据对所有人开放--在无人驾驶、语音识别,矿藏以及人口数据统计会有相当大的作用的,9 -如果我们能够找到方法将数据放到选项2,3和4中,不是很好嘛--或者至少它们中的一些--在选项一中是可以实现的,同时仍将细节保密?这就是研究这些新技术的希望。 -然而又很长的路要走,所以不要太兴奋,同时,开始考虑将你的的一些数据默认开放。 - -### 一些具体的措施 - -我们如何处理数据的隐私和开放?下面是我想到的一些具体的措施:欢迎大家评论做出更多的贡献。 - * 检查你的组织是否正在认真严格的执行通用数据保护条例。如果没有,去推动实施它。 - * 要默认去加密敏感数据(或者适当的时候用散列算法),当不再需要的时候及时删掉--除非数据正在被处理使用否则没有任何借口让数据清晰可见。 - * 当你注册一个服务的时候考虑一下你公开了什么信息,特别是社交媒体类的。 - * 和你的非技术朋友讨论这个话题。 - * 教育你的孩子,你朋友的孩子以及他们的朋友。然而最好是去他们的学校和他们的老师交谈在他们的学校中展示。 - * 鼓励你工作志愿服务的组织,或者和他们互动推动数据的默认开放。不是去思考为什么我要使数据开放而是以我为什么不让数据开放开始。 - * 尝试去访问一些开源数据。开采使用它。开发应用来使用它,进行数据分析,画漂亮的图,10 制作有趣的音乐,考虑使用它来做些事。告诉组织去使用它们,感谢它们,而且鼓励他们去做更多。 - - - -1. 我承认你可能尽管不会 -2. 假设你坚信你的个人数据应该被保护。 -3. 如果你在思考“极好的”的寓意,在这点上你并不孤独。 -4. 事实上这些机构能够有多开放取决于你所居住的地方。 -5. 假设我是英国人,那是非常非常大的剂量。 -6. 他们可能是巨大的公司:没有其他人能够负担得起这么大的存储和基础架构来使数据保持可用。 -7. 不,答案是“不”。 -8. 尽管这个列子也同样适用于个人。看看:A可能是Alice,B 可能是BOb... -9. 并不是说我们应该暴露个人的数据或者是这样的数据应该被保密,当然--不是那类的数据。 -10. 我的一个朋友当她接孩子放学的时候总是下雨,所以为了避免确认失误,她在整个学年都访问天气信息并制作了图表分享到社交媒体上。 --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/1/being-open-about-data-privacy - -作者:[Mike Bursell][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者FelixYFZ](https://github.com/FelixYFZ) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/mikecamel -[1]:https://en.wikipedia.org/wiki/Data_Privacy_Day -[2]:https://en.wikipedia.org/wiki/Information_wants_to_be_free -[3]:https://aliceevebob.wordpress.com/2017/06/06/helping-our-governments-differently/ -[4]:https://opensource.com/article/17/11/commonwealth-open-source -[5]:http://www.outpost9.com/reference/jargon/jargon_40.html#TAG2036 diff --git a/translated/talk/20180305 What-s next in IT automation- 6 trends to watch.md b/translated/talk/20180305 What-s next in IT automation- 6 trends to watch.md deleted file mode 100644 index f5e93d0a0c..0000000000 --- a/translated/talk/20180305 What-s next in IT automation- 6 trends to watch.md +++ /dev/null @@ -1,130 +0,0 @@ -IT自动化的下一步是什么: 6 大趋势 -====== - -![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/cio_ai_artificial_intelligence.png?itok=o0csm9l2) - -我们最近介绍了 [促进自动化的因素][1] ,目前正在被人们采用的 [趋势][2], 以及那些刚开始使用自动化部分流程组织 [有用的技巧][3] 。 - -噢, 我们也分享了在你的公司[如何使用自动化的案例][4] , 以及 [长期成功的关键][5]. - -现在, 只有一个问题: 自动化的下一步是什么? 我们邀请一系列专家分享一下 [自动化][6]不远的将来。 以下是他们建议IT领域领导需密切关注的六大趋势。 - -### 1. 机器学习的成熟 - -对于关于 [机器学习][7]的讨论 (与“自我学习系统”相似的定义),对于绝大多数组织的项目来说,实际执行起来它仍然为时过早。但预计这将发生变化,机器学习将在下一次IT自动化浪潮中将扮演着至关重要的角色。 - -[Advanced Systems Concepts, Inc.][8]公司工程总监 Mehul Amin 指出机器学习是IT自动化下一个关键增长领域之一。 - -“随着数据化的发展, 自动化软件理应可以自我决策,否则这就是开发人员的责任了”, Amin 说。 “例如, 开发者需要执行构建内容, 但是识别系统最佳执行流程的,可能是由系统内软件分析完成。” - -假设将这个系统延伸到其他地方中。Amin 指出,机器学习可以使自动化系统在必要的时候提供额外的资源,以需要满足时间线或SLA,同样在不需要资源的时候退出以及其他的可能性。 - -显然不只有 Amin 一个人这样认为。 - -[Sungard Availability Services][9] 公司首席架构师 Kiran Chitturi 表示,“IT自动化正在走向自我学习的方向” 。“系统将会能测试和监控自己,加强业务流程和软件交付能力。” - -Chitturi 指出自动化测试就是个例子。脚本测试已经被广泛采用,但很快这些自动化测试流程将会更容易学习,更快发展,例如开发出新的代码或将更为广泛地影响生产环境。 - -### 2. 人工智能催生的自动化 - -上述原则同样适合 [人工智能][10](但是为独立)的领域。假定新兴的人工智能技术将也会产生新的自动化机会。根据对人工智能的定义,机器学习在短时间内可能会对IT领域产生巨大的影响(并且我们可能会看到这两个领域的许多重叠的定义和理解)。 - -[SolarWinds][11]公司技术负责人 Patrick Hubbard说,“人工智能(AI)和机器学习的整合普遍被认为对未来几年的商业成功起至关重要的作用。” - -### 3. 这并不意味着不再需要人力 - -让我们试着安慰一下那些不知所措的人:前两种趋势并不一定意味着我们将失去工作。 - -这很可能意味着各种角色的改变以及[全新角色][12]的创造。 - -但是在可预见的将来,至少,你不必需要机器人鞠躬。 - -“一台机器只能运行在给定的环境变量中它不能选择包含新的变量,在今天只有人类可以这样做,” Hubbard 解释说。“但是,对于IT专业人员来说,这将是需要培养AI和自动化技能的时代。如对程序设计、编程、管理人工智能和机器学习功能算法的基本理解,以及用强大的安全状态面对更复杂的网络攻击。” - -Hubbard 分享一些新的工具或功能例子,例如支持人工智能的安全软件或机器学习的应用程序,这些应用程序可以远程发现石油管道中的维护需求。两者都可以提高效益和效果,自然不会代替需要信息安全或管道维护的人员。 - -“许多新功能仍需要人工监控,”Hubbard 说。“例如,为了让机器确定一些‘预测’是否可能成为‘规律’,人为的管理是必要的。” - -即使你把机器学习和AI先放在一边,看待一般地IT自动化,同样原理也是成立的,尤其是在软件开发生命周期中。 - -[Juniper Networks][13]公司自动化首席架构师 Matthew Oswalt ,指出IT自动化增长的根本原因是它通过减少操作基础设施所需的人工工作量来创造直接价值。 - -在代码上,操作工程师可以使用事件驱动的自动化提前定义他们的工作流程,而不是在凌晨3点来应对基础设施的问题。 - -“它也将操作工作流程作为代码而不再是容易过时的文档或系统知识阶段,”Oswalt解释说。“操作人员仍然需要在[自动化]工具响应事件方面后发挥积极作用。采用自动化的下一个阶段是建立一个能够跨IT频谱识别发生的有趣事件的系统,并以自主方式进行响应。在代码上,操作工程师可以使用事件驱动的自动化提前定义他们的工作流程,而不是在凌晨3点来应对基础设施的问题。他们可以依靠这个系统在任何时候以同样的方式作出回应。” - -### 4. 对自动化的焦虑将会减少 - -SolarWinds公司的 Hubbard 指出,“自动化”一词本身就产生大量的不确定性和担忧,不仅仅是在IT领域,而且是跨专业领域,他说这种担忧是合理的。但一些随之而来的担忧可能被夸大了,甚至是科技产业本身。现实可能实际上是这方面的镇静力:当自动化的实际实施和实践帮助人们认识到这个列表中的“3”时,我们将看到“4”的出现。 - -“今年我们可能会看到对自动化焦虑的减少,更多的组织开始接受人工智能和机器学习作为增加现有人力资源的一种方式,”Hubbard说。“自动化历史上的今天为更多的工作创造了空间,通过降低成本和时间来完成较小任务,并将劳动力重新集中到无法自动化并需要人力的事情上。人工智能和机器学习也是如此。” - -自动化还将减少IT领导者神经紧张主题的一些焦虑:安全。正如[红帽][14]公司首席架构师 Matt Smith 最近[指出][15]的那样,自动化将越来越多地帮助IT部门降低与维护任务相关的安全风险。 - -他的建议是:“首先在维护活动期间记录和自动化IT资产之间的交互。通过依靠自动化,您不仅可以消除历史上需要大量手动操作和手术技巧的任务,还可以降低人为错误的风险,并展示当您的IT组织采纳变更和新工作方法时可能发生的情况。最终,这将迅速减少对应用安全补丁的抵制。而且它还可以帮助您的企业在下一次重大安全事件中摆脱头条新闻。” - -**[ 阅读全文: [12个企业安全坏习惯要打破。][16] ] ** - -### 5. 脚本和自动化工具将持续发展 - -看到许多组织增加自动化的第一步 - 通常以脚本或自动化工具(有时称为配置管理工具)的形式 - 作为“早期”工作。 - -但是随着各种自动化技术的使用,对这些工具的观点也在不断发展。 - -[DataVision][18]首席运营官 Mark Abolafia 表示:“数据中心环境中存在很多重复性过程,容易出现人为错误,[Ansible][17]等技术有助于缓解这些问题。“通过 Ansible ,人们可以为一组操作编写特定的步骤,并输入不同的变量,例如地址等,使过去长时间的过程链实现自动化,而这些过程以前都需要人为触摸和更长的交货时间。” - -**[想了解更多关于Ansible这个方面的知识吗?阅读相关文章:[使用Ansible时的成功秘诀][19]。 ]** - -另一个因素是:工具本身将继续变得更先进。 - -“使用先进的IT自动化工具,开发人员将能够在更短的时间内构建和自动化工作流程,减少易出错的编码,” ASCI 公司的 Amin 说。“这些工具包括预先构建的,预先测试过的拖放式集成,API作业,丰富的变量使用,参考功能和对象修订历史记录。” - -### 6. 自动化开创了新的指标机会 - -正如我们在此前所说的那样,IT自动化不是万能的。它不会修复被破坏的流程,或者以其他方式为您的组织提供全面的灵丹妙药。这也是持续不断的:自动化并不排除衡量性能的必要性。 - -**[ 参见我们的相关文章 [DevOps指标:你在衡量什么重要吗?][20] ]** - -实际上,自动化应该打开新的机会。 - -[Janeiro Digital][21]公司架构师总裁 Josh Collins 说,“随着越来越多的开发活动 - 源代码管理,DevOps管道,工作项目跟踪 - 转向API驱动的平台 - 将这些原始数据拼接在一起以描绘组织效率提升的机会和图景”。 - -Collins 认为这是一种可能的新型“开发组织度量指标”。但不要误认为这意味着机器和算法可以突然预测IT所做的一切。 - -“无论是衡量个人资源还是整体团队,这些指标都可以很强大 - 但应该用大量的背景来衡量。”Collins说,“将这些数据用于高层次趋势并确认定性观察 - 而不是临床评级你的团队。” - -**想要更多这样知识, IT领导者?[注册我们的每周电子邮件通讯][22]。** - --------------------------------------------------------------------------------- - -via: https://enterprisersproject.com/article/2018/3/what-s-next-it-automation-6-trends-watch - -作者:[Kevin Casey][a] -译者:[MZqk](https://github.com/MZqk) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://enterprisersproject.com/user/kevin-casey -[1]:https://enterprisersproject.com/article/2017/12/5-factors-fueling-automation-it-now -[2]:https://enterprisersproject.com/article/2017/12/4-trends-watch-it-automation-expands -[3]:https://enterprisersproject.com/article/2018/1/getting-started-automation-6-tips -[4]:https://enterprisersproject.com/article/2018/1/how-make-case-it-automation -[5]:https://enterprisersproject.com/article/2018/1/it-automation-best-practices-7-keys-long-term-success -[6]:https://enterprisersproject.com/tags/automation -[7]:https://enterprisersproject.com/article/2018/2/how-spot-machine-learning-opportunity -[8]:https://www.advsyscon.com/en-us/ -[9]:https://www.sungardas.com/en/ -[10]:https://enterprisersproject.com/tags/artificial-intelligence -[11]:https://www.solarwinds.com/ -[12]:https://enterprisersproject.com/article/2017/12/8-emerging-ai-jobs-it-pros -[13]:https://www.juniper.net/ -[14]:https://www.redhat.com/en?intcmp=701f2000000tjyaAAA -[15]:https://enterprisersproject.com/article/2018/2/12-bad-enterprise-security-habits-break -[16]:https://enterprisersproject.com/article/2018/2/12-bad-enterprise-security-habits-break?sc_cid=70160000000h0aXAAQ -[17]:https://opensource.com/tags/ansible -[18]:https://datavision.com/ -[19]:https://opensource.com/article/18/2/tips-success-when-getting-started-ansible?intcmp=701f2000000tjyaAAA -[20]:https://enterprisersproject.com/article/2017/7/devops-metrics-are-you-measuring-what-matters?sc_cid=70160000000h0aXAAQ -[21]:https://www.janeirodigital.com/ -[22]:https://enterprisersproject.com/email-newsletter?intcmp=701f2000000tsjPAAQ diff --git a/translated/talk/20180306 Try, learn, modify- The new IT leader-s code.md b/translated/talk/20180306 Try, learn, modify- The new IT leader-s code.md new file mode 100644 index 0000000000..ce65693a2b --- /dev/null +++ b/translated/talk/20180306 Try, learn, modify- The new IT leader-s code.md @@ -0,0 +1,56 @@ +尝试,学习,修改:新 IT 领导者的代码 +===== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/ship_wheel_gear_devops_kubernetes.png?itok=xm4a74Kv) + +几乎每一天,新的技术发展都在威胁破坏,甚至是那些最复杂,最完善的商业计划。组织经常发现自己正在努力适应新的环境,这导致了他们对未来规划的转变。 + +根据 CompTIA 2017 年的[研究][1],目前只有 34% 的公司正在制定超过 12 个月的 IT 架构计划。从长期计划转变的一个原因是:商业环境变化如此之快,以至于几乎不可能进一步规划未来。[CIO.com 说道][1]“如果你的公司正视图制定一项将持续五到十年的计划,那就忘了它。” + +我听过来自世界各地无数客户和合作伙伴的类似声明:技术创新正以一种前所未有的速度发生着。 + +其结果是长期规划已不复存在。如果我们要在这个新世界取得成功,我们需要以不同的方式思考我们运营组织的方式。 + +### 计划是怎么死的 + +正如我在 Open Organization(开源组织)中写的那样,传统经营组织针对工业经济进行了优化。他们采用等级结构和严格规定的流程,以实现地位竞争优势。要取得成功,他们必须确定他们想要实现的战略地位。然后,他们必须制定并规划实现目标的计划,并以最有效的方式执行这些计划,通过协调活动和推动合规性。 + +管理层的职责是优化这一过程:计划,规定,执行。包括:让我们想象一个有竞争力的优势地位;让我们来配置组织以最终到达那里;然后让我们通过确保组织的所有方面都遵守规定来推动执行。这就是我所说的“机械管理”,对于不同时期来说它都是一个出色的解决方案。 + +在当今动荡不定的世界中,我们预测和定义战略位置的能力正在下降,因为变化的速度,新变量的引入速度正在加速。传统的,长期的,战略性规划和执行不像以前那么有效。 + +如果长期规划变得如此困难,那么规定必要的行为就更具有挑战性。并且衡量对计划的合规性几乎是不可能的。 + +这一切都极大地影响了人们的工作方式。与过去传统经营组织中的工人不同,他们为自己能够重复行动而感到自豪,几乎没有变化和舒适的确定性 -- 今天的工人在充满模糊性的环境中运作。他们的工作需要更大的创造力,直觉和批判性判断 -- 有更大的要求是背离过去的“正常”,适应当今的新情况。 + +以这种新方式工作对于价值创造变得更加重要。我们的管理系统必须专注于构建结构,系统和流程,以帮助创建积极主动的工人,他们能够以快速和敏捷的方式进行创新和行动。 + +我们需要提出一个不同的解决方案来优化组织,以适应不同的经济时代,从自下而上而不是自上而下开始。我们需要替换过去的三步骤 -- 计划,规定,执行,以一种更适应当今动荡天气的方法来取得成功 -- 尝试,学习,修改。 + +### 尝试,学习,修改 + +因为环境变化如此之快,而且几乎没有任何预警,并且因为我们需要采取的步骤不再提前计划,我们需要培养鼓励创造性尝试和错误的环境,而不是坚持对五年计划的忠诚。以下是以这种方式开始工作的一些暗示: + + * **更短的计划周期(尝试)。** 管理者需要考虑的是他们可以快速尝试的短期实验,而不是在长期战略方向上苦恼。他们应该寻求方法来帮助他们的团队承担计算风险,并利用他们掌握的数据来对最有利的路径做出最好的猜测。他们可以通过降低开销和让团队自由快速尝试新方法来做到这一点。 + * **更高的失败容忍度(学习)。** 更多的实验频率意味着更大的失败机会。与传统组织相比,富有创造力和有弹性的组织[对失败的容忍度要高得多][2]。管理者应将失败视为学习的机会,在他们的团队正在运行的测试中收集反馈的时刻。 + * **更具适应性的结构(修改)。** 能够轻松修改组织结构和战略方向,以及在条件需要时愿意这样做,是确保组织能够根据快速变化的环境条件发展的关键。管理者不能再拘泥于任何想法,因为这个想法证明自己对实现短期目标很有用。 + +如果长期计划已经消亡,那么就可以进行长期的短期实验。尝试,学习和修改,这是在不确定时期前进的最佳途径。 + +[订阅我们的每周实事通讯][3]以了解有关开源组织的更多信息。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/open-organization/18/3/try-learn-modify + +作者:[Jim Whitehurst][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/remyd +[1]:https://www.cio.com/article/3246027/enterprise-architecture/the-death-of-long-term-it-planning.html?upd=1515780110970 +[2]:https://opensource.com/open-organization/16/12/building-culture-innovation-your-organization +[3]:https://opensource.com/open-organization/resources/newsletter diff --git a/translated/talk/20180626 How to build a professional network when you work in a bazaar.md b/translated/talk/20180626 How to build a professional network when you work in a bazaar.md new file mode 100644 index 0000000000..5a94dd8c2f --- /dev/null +++ b/translated/talk/20180626 How to build a professional network when you work in a bazaar.md @@ -0,0 +1,88 @@ +在市场工作时如何建立一个职业网络 +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/connection_people_team_collaboration.png?itok=0_vQT8xV) + +职业社交网络——在同事或专业人员之间建立人际联系——可以采用多种形式、在产业内跨组织进行。建立职业网络需要花费时间和精力,并且当某位成员加入或离开一个组织时,此人的网络通常需要被在一个新的工作环境中重建。 + +职业社交网络在不同组织中起相似作用——信息共享,导师制,机会,工作利益和其他作用——然而传统组织与开放组织在组织内构建特定联系的方法和原因可能不尽相同。这些差异有其影响:同事联系方式、如何建立信任、组织内多元化的程度和种类以及建立合作的能力,所有这些因素都是相互关联的,而且他们参与并塑造了人们所建立的社交网络。 + +一个开放的组织对包容性的强调可以使社交网络在解决商业问题上比传统等级制组织更加高效。这种观念在开源的思考中有很久的历史。例如,在[《教堂与市场》][1]The Cathedral and the Bazaar中,埃里克·雷蒙德写道:“许多年前社会学家发现, 相比一个随机选择的观察者的观点,许多同等专业的(或是同等无知的)观察家的普遍观点是可靠得多的预言。”所以让我们了解社交网络的结构和目的如何影响各类组织的价值观。 + +### 传统组织中的社交网络 + +当我在传统组织工作并要描述我为工作做了什么时,人们问我的第一件事就是我与其他人如何关联,通常是主任级的领导。“你在希拉手下吗?”他们会这么问。“你为马尔科姆工作吗?”这意味着以一种上下级的视角看待传统组织的作用;当试图安排工作或雇员时,人们想要从上下级的角度理解网络结构。 + +换言之,在传统组织中社交网络依赖于等级制结构,因此他们彼此追寻。事实上,甚至弄清一个雇员在关系网中处于怎样的位置也算得上是一种“上下级组织”式的担忧。 + +然而并非所有潜在等级制都是如此。它还视相关人员而定。对于上下级网络的关注会决定雇员在网络中的“价值”,因为网络本身是一个持续的权力关系的系统,它会根据人不同水平的价值给予他们不同的定位。它淡化了个人的能力和技能的重要性。因此,一个人在传统组织的联系促使其能力具有前瞻性,为人所知,有影响力并在其事业中起到支持作用。 + +相比传统等级制组织,一个开放的组织对包容性的强调能使网络解决商业问题更加高效。 + +传统组织的正式结构以特定方式决定着雇员的社交网络——有些可能是优点,有些可能是缺点,这取决于具体环境——例如: + + * 要更快速地了解“谁是谁”并看到人们如何关联是较为便捷的(通常这在特定层级内建立信任网络)。 + * 通常,这种对关系的进一步的理解意味着会有更少的过剩工作(在一个特定网络中项目有清晰的相应的归属者)和过多交流(人们知道谁对交流什么负责)。 + * 相关人员会感到在一个权力结构中感到束手无策,或好像他们不能“闯入”权力结构中,这些结构有时(或更多时候)因为裁员并不起作用。 + * 完成大量的工作和努力是困难的,并且合作会很艰难。 + * 权力转让缓慢;一个人的参与能力更多地决定于等级结构所创造的网络的结盟而非其他因素(比如个人能力),减少了被看做社区和成员利益的东西。 + * 竞争似乎更加清晰;理解“谁在竞争什么”通常发生在一个公认的、被限定了的等级结构中(权力网络中职位的缺乏增进了竞争因此竞争会更激烈)。 + * 当更严格的网络决定了灵活性的限度时,适应能力会受损。网络的“夙愿”和合作的限度也会以同样的方式受影响。 + * 在严格的网络中,方向明确,并且领导人通常靠过度指导经营,在这里,破坏更容易发生。 + * 当社交网络不那么灵活时,风险下降;人们知道什么需要发生,怎样发生,何时发生(但是考虑到在一个组织中工作的广度,这不见得总是“坏事”;一些工作的职能需要较小的风险,例如:人力资源管理H R),企业并购和法律工作等。 + * 在网络中的信任是更大的,尤其当受雇者是正式网络的一部分的时候(当某人不是网络的一份子时,被排斥的人可能特别难管理或改正)。 + + + +### 开放组织中的社交网络 + +尽管开放组织必定会有等级结构,但他们并不根据那个网络运作。他们的职业网络结构更加灵活(或者说是“随时随地”)。 + +在一个开放的组织中,当我描述我做了什么工作时,几乎没人问我“我为谁而干?”一个开放的组织更多的以伙伴为中心,而不是以领导为中心。开放的价值观比如包容和特定的治理系统比如强人治理有助于此;那并不是你了解谁而是你了解什么,你怎样使用(比如:“自底而上的设计”)。在一个开放的组织当中,我并不感觉我在为展示自己的价值而奋斗;我的想法有内在的价值。有时我必须示范说明为何使用我的观点比使用别人的更加有用——但是那意味着我正在同事的社区里面诊疗我自己(包括领导层),而不是单独被自上而下的领导层诊疗。 + +如此说来,开放的组织并不基于网络评估员工,而是基于他们对作为个人的同事的了解。这个人有想法吗?她会努力通过利用开放组织的价值实现那些想法吗(领导它们)(也就是说,在开放组织中分享那些观点并且实践以将他人囊括并透明公开的工作等等)? + +开放组织也会以特定的方式构造社交网络(这种方式同样可能会视个人的目的性和渴望程度而很有益或很有害),这包括: + + * 人们会对他们的网络、声望、技能和事业更加负责。 + * 竞争(为了资源、权力、晋升等)会因这些组织天性更具合作性而变得更少。最好的结果是协商,而不是单赢,并且竞争会磨练创意,而不会在人与人之间筑篱设笆。 + * 权力是更加流动和有活力的,在人与人之间流动(但这同时也意味着可能有对可说明性或者责任的误解,而且活动可能会因为没有明晰的[主人翁意识][2]而不被完成)。 + * 信任是“一次一同事”地被建立起来的而不会借助社交网络,在网络中,人是被定位着的。 + * 网络在多样的运转和事件中会自配置,一有机会便会反应性地自启(这帮助了更新但却会造成混乱,因为谁在决策、谁在“受控”是不那么明确的)。 + * 执行速度在混乱的环境中会下降,因为所做之事、做事方式和处事时间需要在制定目标和涵养好整以暇的员工方面上的领导力。 + * 灵活的社交网络同样会增加变革和风险;创意会流通得更快而且更神奇,并且执行会更加自信。 + * 信任建立在同事合作之上(它本该如此!),而不是在对架构的尊重之上。 + + + +### 让它有效 + +如果你正在考虑从一种组织架构转变为另一种,当你在构建并维持你的职业社交网络时思考一下如下所述内容。 + +#### 来自传统组织的小建议 + + * 对决策的架构和管控不是坏事; 运作中的框架需要明晰透明,而且决策者需要考虑他们的决定。 + * 在执行上突出需要经理提供关注,还需要有在滤出任何让人分心或混乱的事务的同时仍能提供足够的来龙去脉的能力。 + * 已经确立的网络帮助了一大批人同步工作并且能管控风险。 + +#### 来自开放组织的小建议 + * 能力强的领导人是那些可以根据多样的风格和对同事、团队的不同偏好提供不同层次的透明度和指导,同时又不会构建出不灵活的网络的人。。 + * 伟大的想法比已建立的组织会赢得更多。 + * 人们对他们得名声会更加负责任。 + * 创意和信息的流转是变革的关键。松散组织中的关系网络可以使这两种元素生发的频度更高、幅度更广。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/open-organization/18/6/building-professional-social-networks-openly + +作者:[Heidi Hess;von Ludewig][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[ZenMoore](https://github.com/ZenMoore) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/heidi-hess-von-ludewig +[1]:http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s04.html +[2]:https://opensource.com/open-organization/18/4/rethinking-ownership-across-organization diff --git a/translated/talk/20180627 CIP- Keeping the Lights On with Linux.md b/translated/talk/20180627 CIP- Keeping the Lights On with Linux.md new file mode 100644 index 0000000000..41c8e79008 --- /dev/null +++ b/translated/talk/20180627 CIP- Keeping the Lights On with Linux.md @@ -0,0 +1,57 @@ +CIP:延续 Linux 之光 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/cip-lights.jpg?itok=6LAUoIzt) + + +现如今,现代民用基础设施遍及各处 —— 发电厂、雷达系统、交通信号灯、水坝和天气系统等。这些基础设施项目已然存在数十年,这些设施还将继续提供更长时间的服务,所以安全性和使用寿命是至关重要的。 + + +并且,其中许多系统都是由 Linux 提供支持,它为技术提供商提供了对这些问题的更多控制。然而,如果每个提供商都在构建自己的解决方案,这可能会导致分散和重复工作。因此,[民用基础设施平台(CIP)][1]最首要的目标是创造一个开源基础层,提供给工业设施,例如嵌入式控制器或是网关设备。 + +Yoshitake Kobayashi,担任 CIP 的技术指导委员会主席说过,“我们在这个领域有一种非常保守的文化,因为一旦我们建立了一个系统,它必须得到长达十多年的支持,在某些情况下超过 60 年。这就是为什么这个项目被创建的原因,因为这个行业的每个使用者都有同样的问题,即能够长时间使用 Linux。” + +CIP 的架构是创建一个基础系统,能够在控制器上使用开源软件。其中,该基础层包括 Linux 内核和一系列常见的开源软件如 libc、busybox 等。由于软件的使用寿命是一个最主要的问题,CIP 选择使用 Linux 4.4 版本的内核,这是一个由 Greg Kroah-Hartman 维护的长期支持版本。 + +### 合作 + +由于 CIP 有上游优先政策,因此他们在项目中需要的代码必须位于上游内核中。为了与内核社区建立积极的反馈循环,CIP聘请 Ben Hutchings 作为 CIP 的官方维护者。Hutchings以他在Debian LTS 版本上所做的工作而闻名,这也促成了 CIP 与 Debian 项目之间的官方合作。 + +在新的合作下,CIP 将使用 Debian LTS 版本构建平台。 CIP 还将支持 Debian 长期支持版本(LTS),延长所有 Debian 稳定版的生命周期。CIP 还将与 Freexian 进行密切合作,后者是一家围绕 Debian LTS 版本提供商业服务的公司。这两个组织将专注于嵌入式系统的开源软件的操作性、安全性和维护。CIP 还会为一些 Debian LTS 版本提供资金支持。 + +Chris Lamb,Debian 项目负责人表示,“我们对此次合作以及 CIP 对 Debian LTS 项目的支持感到非常兴奋,这样将使支持生命周期延长至五年以上。我们将一起致力于为用户提供长期支持,并为未来的城市奠定基础。” + +### 安全性 + + +Kobayashi 说过,其中最需要担心的是安全性。虽然出于明显的安全原因,大部分民用基础设施没有接入互联网(你肯定不想让一座核电站连接到互联网),况且也存在其他风险。 + +仅仅因为系统本身没有连接到互联网,这并不意味着能避开所有危险。其他系统,比如个人移动电脑也能够通过接入互联网而间接入侵到本地系统中。如若有人收到一封带有恶意文件作为电子邮件的附件,这将会“污染”系统内部的基础设备。 + +因此,保持所有软件在这些控制器上运行是最新的并且完全修补是至关重要的。为了确保安全性,CIP 还向后移植了内核自我保护项目的许多组件。CIP还遵循最严格的网络安全标准之一 —— IEC 62443,该标准定义了软件的流程和相应的测试,以确保系统更安全。 + + +### 展望未来 + + +随着 CIP 日趋成熟,官方正在加大与各个 Linux 提供商的合作力度。除了与 Debian 和 freexian 的合作外,CIP最近还邀请了企业 Linux 操作系统供应商 Cybertrust Japan Co., Ltd. 作为新的银牌成员。 + +Cybertrust 与其他行业领军者合作,如西门子,东芝,Codethink,日立,Moxa,Plat'Home 和瑞萨,致力于打造在未来数十年里,一个可靠、安全的基于 Linux 的嵌入式软件平台。 + +这些公司在 CIP 的保护下所进行的工作,将确保管理我们现代社会中的民用基础设施的完整性。 + +想要了解更多信息,请访问 [民用基础设施官网][1]。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/2018/6/cip-keeping-lights-linux + +作者:[Swapnil Bhartiya][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[wyxplus](https://github.com/wyxplus) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/arnieswap +[1]:https://www.cip-project.org/ diff --git a/translated/talk/20180703 How to make a career move from proprietary to open source technology.md b/translated/talk/20180703 How to make a career move from proprietary to open source technology.md new file mode 100644 index 0000000000..c6400d3201 --- /dev/null +++ b/translated/talk/20180703 How to make a career move from proprietary to open source technology.md @@ -0,0 +1,58 @@ +怎样实现由专有环境向开源环境的职业转变 +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/open%20source_collaboration_0.png?itok=YEl_GXbv) + +作为一名软件工程师,我的职业生涯是从 Northern Telecom 开始的,在这里我开发出了电信级的通讯转换设备可以使用的专有软件等。 即使我已经在大学中学习了 Pascal 语言,公司还是给我进行了以 C 语言为基础是专有编程语言培养。在公司中我使用的也是专有操作系统和专有版本控制软件。 + +我很享受专有环境下的工作,并有幸接触了很多有趣的项目,这样过了很多年,直到一场招聘会,我遇到了事业转折点。那时我受邀在当地一所中学的 STEM 行业座谈会进行演讲,给学生们讲述了作为一名软件工程师的主要工作内容和责任,一名学生问我:“这些事是你一直梦想要做的吗?你热爱你现在的工作吗?” + +每次领导问我这个问题时,保险起见,我都会回答他,“我当然热爱工作了!”但从来没有一名还在读六年级的单纯的 STEM 小爱好者问过我这个问题。我的回答还是一样,“我当然喜欢!” + +我确实很热爱我当时的事业,但那名学生的话让我忍不住思考,我开始重新审视我的事业,重新审视专有环境。在我的领域里我如鱼得水,但这也有局限性:我只能用代码来定义我的领域。我忍不住反思,这些年我有没有试着去学一些其他可应用于专有环境的技术?在同行中我的技能组还算得上先进吗?我有没有混日子?我真的想继续为这项事业奋斗吗? + +我想了很多,忍不住问自己:当年的激情和创意还在吗? + +时间不会停止,但我的生活发生了改变。我离开了 Nortel Networks ,打算休息一段时间来陪陪我的家人。 + +在我准备返回工作岗位时,那个小朋友的话又在我的脑海中响起,这真的是我想要的工作吗?我投了很多份简历,有一个岗位是我最中意的,但那家公司的回复是,他们想要的是拥有五年及以上 Java and Python 工作经验的人。在过去十五年里我以之为生的知识和技术看起来已经过时了。 + +### 机遇与挑战 + +我的第一项挑战是学会在新的环境下应用我先前在封闭环境学到的技能。IT 行业由专有环境转向开源后发生了天翻地覆的变化。我打算先自学眼下最需要的 Python 。接触 Python 后我意识到,我需要一个项目来证明自己的能力,让自己更具有竞争力。 + +我的第二个挑战是怎么获得 Python 相关的项目经验。我丈夫和之前的同事都向我推荐了开源软件,通过谷歌搜索我发现网上有许许多多的开源项目,它们分别来源于一个人的小团队,50 人左右的团队,还有跨国的百人大团队。 + + 在 Github 上我用相关专业术语搜索出了许多适合我的项目。综合我的兴趣和网络相关的工作经验,我打算把第一个项目贡献给 OpenStack 。 我还注意到了 [Outreachy][1] 项目,它为不具备相关技术基础的人员提供三个月的实习期。 + +### 经验与教训 + +我学到的第一件事是我发现可以通过许多方式进行贡献。不论是文件编制、用户设计,还是测试用例,都是贡献的形式。我在探索中丰富了我的技能组,根本用不着5年的时间,只需要在开源平台上接受委托,之后做出成果。 + +在我为 OpenStack 做出的第一个贡献被合并、发表后,我正式成为了 Outreachy 项目的一员。 Outreachy 项目最好的一点是,项目分配给我的导师能够引领我在开源世界中找到方向。 + +下面还有三个宝贵的提示: + +**持之以恒** 你需要找到最适合你核心技能组的项目,当然,最好有行为准则和新人入门指南,这样的项目比较适合初学者加入。找到了合适的项目你可以持之以恒地在社区中进行贡献。 + +**不厌其烦** 适应开源环境需要一段时间。融入开源社区需要时间。进行深思熟虑的反馈需要时间。阅读反馈并经行改进也需要时间。在这其中你需要耐心等待。 + +**参与其中** 在开源社区,从事什么领域或技术的工作不需要特殊批准,你可以自己选择工作的领域,并深入其中。 + +7 月 16-19 日,俄勒冈州波特兰,第 20 届 [开源大会][3] 上,Petra Sargent 将为您展示:[老狗也能学会新把戏——封闭环境工作者如何适应开源环境][2]。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/career-move + +作者:[Petra Sargent][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[Valoniakim](https://github.com/Valoniakim) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/psargent +[1]:https://www.outreachy.org/ +[2]:https://conferences.oreilly.com/oscon/oscon-or/public/schedule/speaker/307631 +[3]:https://conferences.oreilly.com/oscon/oscon-or diff --git a/translated/tech/20170706 Docker Guide Dockerizing Python Django Application.md b/translated/tech/20170706 Docker Guide Dockerizing Python Django Application.md new file mode 100644 index 0000000000..98fd65b47d --- /dev/null +++ b/translated/tech/20170706 Docker Guide Dockerizing Python Django Application.md @@ -0,0 +1,415 @@ +Docker 指南:Docker 化 Python Django 应用程序 +====== + +### 目录 + +1. [我们要做什么?][6] + +2. [步骤 1 - 安装 Docker-ce][7] + +3. [步骤 2 - 安装 Docker-compose][8] + +4. [步骤 3 - 配置项目环境][9] + 1. [创建一个新的 requirements.txt 文件][1] + + 2. [创建 Nginx 虚拟主机文件 django.conf][2] + + 3. [创建 Dockerfile][3] + + 4. [创建 Docker-compose 脚本][4] + + 5. [配置 Django 项目][5] + +5. [步骤 4 - 构建并运行 Docker 镜像][10] + +6. [步骤 5 - 测试][11] + +7. [参考][12] + + +Docker 是一个开源项目,为开发人员和系统管理员提供了一个开放平台,作为一个轻量级容器,它可以在任何地方构建,打包和运行应用程序。Docker 在软件容器中自动部署应用程序。 + +Django 是一个用 Python 编写的 Web 应用程序框架,遵循 MVC(模型-视图-控制器)架构。它是免费的,并在开源许可下发布。它速度很快,旨在帮助开发人员尽快将他们的应用程序上线。 + +在本教程中,我将逐步向你展示在 Ubuntu 16.04 如何为现有的 Django 应用程序创建 docker 镜像。我们将学习如何 docker 化一个 Python Django 应用程序,然后使用一个 docker-compose 脚本将应用程序作为容器部署到 docker 环境。 + +为了部署我们的 Python Django 应用程序,我们需要其他 docker 镜像:一个用于 Web 服务器的 nginx docker 镜像和用于数据库的 PostgreSQL 镜像。 + +### 我们要做什么? + +1. 安装 Docker-ce + +2. 安装 Docker-compose + +3. 配置项目环境 + +4. 构建并运行 + +5. 测试 + +### 步骤 1 - 安装 Docker-ce + +在本教程中,我们将重 docker 仓库安装 docker-ce 社区版。我们将安装 docker-ce 社区版和 docker-compose,其支持 compose 文件版本 3(to 校正者:此处不太明白具体意思)。 + +在安装 docker-ce 之前,先使用 apt 命令安装所需的 docker 依赖项。 + +``` +sudo apt install -y \ +    apt-transport-https \ +    ca-certificates \ +    curl \ +    software-properties-common +``` + +现在通过运行以下命令添加 docker 密钥和仓库。 + +``` +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +sudo add-apt-repository \ +   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ +   $(lsb_release -cs) \ +   stable" +``` + + [![安装 Docker-ce](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/1.png)][14] + +更新仓库并安装 docker-ce。 + +``` +sudo apt update +sudo apt install -y docker-ce +``` + +安装完成后,启动 docker 服务并使其能够在每次系统引导时启动。 + +``` +systemctl start docker +systemctl enable docker +``` + +接着,我们将添加一个名为 'omar' 的新用户并将其添加到 docker 组。 + +``` +useradd -m -s /bin/bash omar +usermod -a -G docker omar +``` + + [![启动 Docker](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/2.png)][15] + +以 omar 用户身份登录并运行 docker 命令,如下所示。 + +``` +su - omar +docker run hello-world +``` + +确保你能从 Docker 获得 hello-world 消息。 + + [![检查 Docker 安装](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/3.png)][16] + + Docker-ce 安装已经完成。 + + ### 步骤 2 - 安装 Docker-compose + +在本教程中,我们将使用最新的 docker-compose 支持 compose 文件版本 3。我们将手动安装 docker-compose。 + +使用 curl 命令将最新版本的 docker-compose 下载到 `/usr/local/bin` 目录,并使用 chmod 命令使其有执行权限。 + +运行以下命令: + +``` +sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose +``` + +现在检查 docker-compose 版本。 + +``` +docker-compose version +``` + +确保你安装的是最新版本的 docker-compose 1.21。 + + [![安装 Docker-compose](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/4.png)][17] + +已安装支持 compose 文件版本 3 的 docker-compose 最新版本。 + +### 步骤 3 - 配置项目环境 + +在这一步中,我们将配置 Python Django 项目环境。我们将创建新目录 'guide01',并使其成为我们项目文件的主目录,例如 Dockerfile,Django 项目,nginx 配置文件等。 + +登录到 'omar' 用户。 + +``` +su - omar +``` + +创建一个新目录 'guide01',并进入目录。 + +``` +mkdir -p guide01 +cd guide01/ +``` + +现在在 'guide01' 目录下,创建两个新目录 'project' 和 'config'。 + +``` +mkdir project/ config/ +``` + +注意: + +* 'project' 目录:我们所有的 python Django 项目文件都将放在该目录中。 + +* 'config' 目录:项目配置文件的目录,包括 nginx 配置文件,python pip requirements 文件等。 + +### 创建一个新的 requirements.txt 文件 + +接下来,使用 vim 命令在 'config' 目录中创建一个新的 requirements.txt 文件 + +``` +vim config/requirements.txt +``` + +粘贴下面的配置。 + +``` +Django==2.0.4  + gunicorn==19.7.0  + psycopg2==2.7.4 +``` + +保存并退出。 + +### 创建 Dockerfile + +在 'guide01' 目录下创建新文件 'Dockerfile'。 + +运行以下命令。 + +``` +vim Dockerfile +``` + +现在粘贴下面的 Dockerfile 脚本。 + +``` +FROM python:3.5-alpine + ENV PYTHONUNBUFFERED 1  + + RUN apk update && \ +     apk add --virtual build-deps gcc python-dev musl-dev && \ +     apk add postgresql-dev bash + + RUN mkdir /config  + ADD /config/requirements.txt /config/  + RUN pip install -r /config/requirements.txt + RUN mkdir /src + WORKDIR /src +``` + +保存并退出。 + +注意: + +我们想要为我们的 Django 项目构建基于 Alpine Linux 的 Docker 镜像,Alpine 是最小的 Linux 版本。我们的 Django 项目将运行在带有 Python3.5 的 Alpine Linux 上,并添加 postgresql-dev 包以支持 PostgreSQL 数据库。然后,我们将使用 python pip 命令安装在 'requirements.txt' 上列出的所有 Python 包,并为我们的项目创建新目录 '/src'。 + +### 创建 Docker-compose 脚本 + +使用 [vim][18] 命令在 'guide01' 目录下创建 'docker-compose.yml' 文件。 + +``` +vim docker-compose.yml +``` + +粘贴以下配置内容。 + +``` +version: '3' + services: +   db: +     image: postgres:10.3-alpine +     container_name: postgres01 +   nginx: +     image: nginx:1.13-alpine +     container_name: nginx01 +     ports: +       - "8000:8000" +     volumes: +       - ./project:/src +       - ./config/nginx:/etc/nginx/conf.d +     depends_on: +       - web +   web: +     build: . +     container_name: django01 +     command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput && gunicorn hello_django.wsgi -b 0.0.0.0:8000" +     depends_on: +       - db +     volumes: +       - ./project:/src +     expose: +       - "8000" +     restart: always +``` + +保存并退出。 + +注意: + +使用这个 docker-compose 文件脚本,我们将创建三个服务。使用 PostgreSQL alpine Linux 创建名为 'db' 的数据库服务,再次使用 Nginx alpine Linux 创建 'nginx' 服务,并使用从 Dockerfile 生成的自定义 docker 镜像创建我们的 python Django 容器。 + + [![配置项目环境](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/5.png)][19] + + ### 配置 Django 项目 + +将 Django 项目文件复制到 'project' 目录。 + +``` +cd ~/django +cp -r * ~/guide01/project/ +``` + +进入 'project' 目录并编辑应用程序设置 'settings.py'。 + +``` +cd ~/guide01/project/ +vim hello_django/settings.py +``` + +注意: + +我们将部署名为 'hello_django' 的简单 Django 应用程序。 + +在 'ALLOW_HOSTS' 行中,添加服务名称 'web'。 + +``` +ALLOW_HOSTS = ['web'] +``` + +现在更改数据库设置,我们将使用 PostgreSQL 数据库,'db' 数据库作为服务运行,使用默认用户和密码。 + +``` +DATABASES = {  +     'default': { +         'ENGINE': 'django.db.backends.postgresql_psycopg2', +         'NAME': 'postgres', +         'USER': 'postgres', +         'HOST': 'db', +         'PORT': 5432, +     } + } +``` + +至于 'STATIC_ROOT' 配置目录,将此行添加到文件行的末尾。 + +``` +STATIC_ROOT = os.path.join(BASE_DIR, 'static/') +``` + +保存并退出。 + + [![配置 Django 项目](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/6.png)][20] + +现在我们准备在 docker 容器下构建和运行 Django 项目。 + +### 步骤 4 - 构建并运行 Docker 镜像 + +在这一步中,我们想要使用 'guide01' 目录中的配置为我们的 Django 项目构建一个 Docker 镜像。 + +进入 'guide01' 目录。 + +``` +cd ~/guide01/ +``` + +现在使用 docker-compose 命令构建 docker 镜像。 + +``` +docker-compose build +``` + +[![运行 docker 镜像](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/7.png)][21] + +启动 docker-compose 脚本中的所有服务。 + +``` +docker-compose up -d +``` + +等待几分钟让 Docker 构建我们的 Python 镜像并下载 nginx 和 postgresql docker 镜像。 + +[![使用 docker-compose 构建镜像](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/8.png)][22] + +完成后,使用以下命令检查运行容器并在系统上列出 docker 镜像。 + +``` +docker-compose ps +docker-compose images +``` + +现在,你将在系统上运行三个容器并列出 Docker 镜像,如下所示。 + +[![docke-compose ps 命令](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/9.png)][23] + +我们的 Python Django 应用程序现在在 docker 容器内运行,并且已经创建了为我们服务的 docker 镜像。 + +### 步骤 5 - 测试 + +打开 Web 浏览器并使用端口 8000 键入服务器地址,我的是:http://ovh01:8000/ + +现在你将获得默认的 Django 主页。 + +[![默认 Django 项目主页](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/10.png)][24] + +接下来,通过在 URL 上添加 “/admin” 路径来测试管理页面。 + +http://ovh01:8000/admin/ + +然后你将会看到 Django admin 登录页面。 + +[![Django administration](https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/11.png)][25] + +Docker 化 Python Django 应用程序已成功完成。 + +### 参考 + +* [https://docs.docker.com/][13] + + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/ + +作者:[Muhammad Arul][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/ +[1]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#create-a-new-requirementstxt-file +[2]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#create-the-nginx-virtual-host-file-djangoconf +[3]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#create-the-dockerfile +[4]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#create-dockercompose-script +[5]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#configure-django-project +[6]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#what-we-will-do +[7]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#step-install-dockerce +[8]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#step-install-dockercompose +[9]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#step-configure-project-environment +[10]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#step-build-and-run-the-docker-image +[11]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#step-testing +[12]:https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/#reference +[13]:https://docs.docker.com/ +[14]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/1.png +[15]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/2.png +[16]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/3.png +[17]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/4.png +[18]:https://www.howtoforge.com/vim-basics +[19]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/5.png +[20]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/6.png +[21]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/7.png +[22]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/8.png +[23]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/9.png +[24]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/10.png +[25]:https://www.howtoforge.com/images/docker_guide_dockerizing_python_django_application/big/11.png diff --git a/translated/tech/20170709 The Extensive Guide to Creating Streams in RxJS.md b/translated/tech/20170709 The Extensive Guide to Creating Streams in RxJS.md new file mode 100644 index 0000000000..66b0e920e9 --- /dev/null +++ b/translated/tech/20170709 The Extensive Guide to Creating Streams in RxJS.md @@ -0,0 +1,1029 @@ +在 RxJS 中创建流的延伸教程 +============================================================ + +![](https://cdn-images-1.medium.com/max/900/1*hj8mGnl5tM_lAlx5_vqS-Q.jpeg) + +对大多数开发者来说,RxJS 是以库的形式与之接触,就像 Angular。一些函数会返回流,要使用它们就得把注意力放在操作符上。 + +有些时候,混用响应式和非响应式代码似乎很有用。然后大家就开始热衷流的创造。不论是在编写异步代码或者是数据处理时,流都是一个不错的方案。 + +RxJS 提供很多方式来创建流。不管你遇到的是什么情况,都会有一个完美的创建流的方式。你可能根本用不上它们,但了解它们可以节省你的时间,让你少码一些代码。 + +我把所有可能的方法,按它们的主要目的,分放在四个目录中: + +* 流式化现有数据 + +* 生成数据 + +* 使用现有 APIs 进行交互 + +* 选择现有的流,并结合起来 + +注意:示例用的是 RxJS 6,可能会以前的版本有所不同。已知的区别是你导入函数的方式不同了。 + +RxJS 6 + +``` +import {of, from} from 'rxjs'; +``` + +``` +of(...); +from(...); +``` + +RxJS < 6 + +``` +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/observable/from'; +``` + +``` +Observable.of(...); +Observable.from(...); +``` + +``` +//or +``` + +``` +import { of } from 'rxjs/observable/of'; +import { from } from 'rxjs/observable/from'; +``` + +``` +of(...); +from(...); +``` + +流的图示中的标记: + +* | 表示流结束了 + +* X 表示流出现错误并被终结 + +* … 表示流的走向不定 + +* * * + +### 流式化已有数据 + +你有一些数据,想把它们放到流中。有三种方式,并且都允许你把调度器当作最后一个参数传入(你如果想深入了解调度器,可以看看我的 [上一篇文章][5])。这些生成的流都是静态的。 + +#### of + +如果只有一个或者一些不同的元素,使用 _of_ : + +``` +of(1,2,3) + .subscribe(); +``` + +``` +// 结果 +// 1 2 3 | +``` + +#### from + +如果有一个数组或者 _可迭代的_ 对象,而且你想要其中的所有元素发送到流中,使用 _from_。你也可以用它来把一个 promise 对象变成可观测的。 + +``` +const foo = [1,2,3]; +``` + +``` +from(foo) + .subscribe(); +``` + +``` +// 结果 +// 1 2 3 | +``` + +#### pairs + +流式化一个对象的键/值对。用这个对象表示字典时特别有用。 + +``` +const foo = { a: 1, b: 2}; +``` + +``` +pairs(foo) + .subscribe(); +``` + +``` +// 结果 +// [a,1] [b,2] | +``` + +#### 那么其他的数据结构呢? + +也许你的数据存储在自定义的结构中,而它又没有实现 _Iterable_ 接口,又或者说你的结构是递归的,树状的。也许下面某种选择适合这些情况: + +* 先将数据提取到数组里 + +* 使用下一节将会讲到的 _generate_ 函数,遍历所有数据 + +* 创建一个自定义流(见下一节) + +* 创建一个迭代器 + +稍后会讲到选项 2 和 3 ,因此这里的重点是创建一个迭代器。我们可以对一个 _iterable_ 对象调用 _from_ 创建一个流。 _iterable_ 是一个对象,可以产生一个迭代器(如果你对细节感兴趣,参考 [这篇 mdn 文章][6])。 + +创建一个迭代器的简单方式是 [generator function][7]。当你调用一个生成函数(generator function)时,它返回一个对象,该对象同时遵循 _iterable_ 接口和 _iterator_ 接口。 + +``` +// 自定义的数据结构 +class List { + add(element) ... + get(index) ... + get size() ... + ... +} +``` + +``` +function* listIterator(list) { + for (let i = 0; i console.log("foo"); +// 5 秒后打印 foo +``` + +大多数定时器将会用来周期性的处理数据: + +``` +interval(10000).pipe( + flatMap(i => fetch("https://server/stockTicker") +).subscribe(updateChart) +``` + +这段代码每 10 秒获取一次数据,更新屏幕。 + +#### generate + +这是个更加复杂的函数,允许你发送一系列任意类型的对象。它有一些重载,这里你看到的是最有意思的部分: + +``` +generate( + 0, // 从这个值开始 + x => x < 10, // 条件:只要值小于 10,就一直发送 + x => x*2 // 迭代:前一个值加倍 +).subscribe(); +``` + +``` +// 结果 +// 1 2 4 8 | +``` + +你也可以用它来迭代值,如果一个结构没有实现 _Iterable_ 接口。我们用前面的 list 例子来进行演示: + +``` +const myList = new List(); +myList.add(1); +myList.add(3); +``` + +``` +generate( + 0, // 从这个值开始 + i => i < list.size, // 条件:发送数据,直到遍历完整个列表 + i => ++i, // 迭代:获取下一个索引 + i => list.get(i) // 选择器:从列表中取值 +).subscribe(); +``` + +``` +// 结果 +// 1 3 | +``` + +如你所见,我添加了另一个参数:选择器(selector)。它和 _map_ 操作符作用类似,将生成的值转换为更有用的东西。 + +* * * + +### 空的流 + +有时候你要传递或返回一个不用发送任何数据的流。有三个函数分别用于不同的情况。你可以给这三个函数传递调度器。_empty_ 和 _throwError_ 接收一个调度器参数。 + +#### empty + +创建一个空的流,一个值也不发送。 + +``` +empty() + .subscribe(); +``` + +``` +// 结果 +// | +``` + +#### never + +创建一个永远不会结束的流,仍然不发送值。 + +``` +never() + .subscribe(); +``` + +``` +// 结果 +// ... +``` + +#### throwError + +创建一个流,流出现错误,不发送数据。 + +``` +throwError('error') + .subscribe(); +``` + +``` +// 结果 +// X +``` + +* * * + +### 挂钩已有的 API + +不是所有的库和所有你之前写的代码使用或者支持流。幸运的是 RxJS 提供函数用来桥接非响应式和响应式代码。这一节仅仅讨论 RxJS 为桥接代码提供的模版。 + +你可能还对这篇出自 [Ben Lesh][9] 的 [延伸阅读][8] 感兴趣,这篇文章讲了几乎所有能与 promises 交互操作的方式。 + +#### from + +我们已经用过它,把它列在这里是因为,它可以封装一个含有 observable 对象的 promise 对象。 + +``` +from(new Promise(resolve => resolve(1))) + .subscribe(); +``` + +``` +// 结果 +// 1 | +``` + +#### fromEvent + +fromEvent 为 DOM 元素添加一个事件监听器,我确定你知道这个。但你可能不知道的是,也可以通过其它类型来添加事件监听器,例如,一个 jQuery 对象。 + +``` +const element = $('#fooButton'); // 从 DOM 元素中创建一个 jQuery 对象 +``` + +``` +from(element, 'click') + .subscribe(); +``` + +``` +// 结果 +// clickEvent ... +``` + +#### fromEventPattern + +要理解为什么有 fromEvent 了还需要 fromEventPattern,我们得先理解 fromEvent 是如何工作的。看这段代码: + +``` +from(document, 'click') + .subscribe(); +``` + +这告诉 RxJS 我们想要监听 document 中的点击事件。在提交过程中,RxJS 发现 document 是一个 _EventTarget_ 类型,因此它可以调用它的 _addEventListener_ 方法。如果我们传入的是一个 jQuery 对象而非 document,那么 RxJs 知道它得调用 _on_ 方法。 + +这个例子用的是 _fromEventPattern_,和 _fromEvent_ 的工作基本上一样: + +``` +function addClickHandler(handler) { + document.addEventListener('click', handler); +} +``` + +``` +function removeClickHandler(handler) { + document.removeEventListener('click', handler); +} +``` + +``` +fromEventPattern( + addClickHandler, + removeClickHandler, +) +.subscribe(console.log); +``` + +``` +// 等效于 +fromEvent(document, 'click') +``` + +RxJS 自动创建实际的监听器( _handler_ )你的工作是添加或者移除监听器。_fromEventPattern_ 的目的基本上是告诉 RxJS 如何注册和移除事件监听器。 + +现在想象一下你使用了一个库,你可以调用一个叫做 _registerListener_ 的方法。我们不能再用 _fromEvent_,因为它并不知道该怎么处理这个对象。 + +``` +const listeners = []; +``` + +``` +class Foo { + registerListener(listener) { + listeners.push(listener); + } +``` + +``` + emit(value) { + listeners.forEach(listener => listener(value)); + } +} +``` + +``` +const foo = new Foo(); +``` + +``` +fromEventPattern(listener => foo.registerListener(listener)) + .subscribe(); +``` + +``` +foo.emit(1); +``` + +``` +// Produces +// 1 ... +``` + +当我们调用 foo.emit(1) 时,RxJS 中的监听器将被调用,然后它就能把值发送到流中。 + +你也可以用它来监听多个事件类型,或者结合所有可以通过回调进行通讯的 API,例如,WebWorker API: + +``` +const myWorker = new Worker('worker.js'); +``` + +``` +fromEventPattern( + handler => { myWorker.onmessage = handler }, + handler => { myWorker.onmessage = undefined } +) +.subscribe(); +``` + +``` +// 结果 +// workerMessage ... +``` + +#### bindCallback + +它和 fromEventPattern 相似,但它能用于单个值。就在回调函数被调用时,流就结束了。用法当然也不一样 —— 你可以用 bindCallBack 封装函数,然后它就会在调用时魔术般的返回一个流: + +``` +function foo(value, callback) { + callback(value); +} +``` + +``` +// 没有流 +foo(1, console.log); //prints 1 in the console +``` + +``` +// 有流 +const reactiveFoo = bindCallback(foo); +// 当我们调用 reactiveFoo 时,它返回一个 observable 对象 +``` + +``` +reactiveFoo(1) + .subscribe(console.log); // 在控制台打印 1 +``` + +``` +// 结果 +// 1 | +``` + +#### websocket + +是的,你完全可以创建一个 websocket 连接然后把它暴露给流: + +``` +import { webSocket } from 'rxjs/webSocket'; +``` + +``` +let socket$ = webSocket('ws://localhost:8081'); +``` + +``` +// 接收消息 +socket$.subscribe( + (msg) => console.log('message received: ' + msg), + (err) => console.log(err), + () => console.log('complete') * ); +``` + +``` +// 发送消息 +socket$.next(JSON.stringify({ op: 'hello' })); +``` + +把 websocket 功能添加到你的应用中真的很简单。_websocket_ 创建一个 subject。这意味着你可以订阅它,通过调用 _next_ 来获得消息和发送消息。 + +#### ajax + +如你所知:类似于 websocket,提供 AJAX 查询的功能。你可能用了一个带有 AJAX 功能的库或者框架。或者你没有用,那么我建议使用 fetch(或者必要的话用 polyfill),把返回的 promise 封装到一个 observable 对象中(参考稍后会讲到的 _defer_ 函数)。 + +* * * + +### Custom Streams + +有时候已有的函数用起来并不是足够灵活。或者你需要对订阅有更强的控制。 + +#### Subject + +subject 是一个特殊的对象,它使得你的能够把数据发送到流中,并且能够控制数据。subject 本身就是一个 observable 对象,但如果你想要把流暴露给其它代码,建议你使用 _asObservable_ 方法。这样你就不能意外调用原始方法。 + +``` +const subject = new Subject(); +const observable = subject.asObservable(); +``` + +``` +observable.subscribe(); +``` + +``` +subject.next(1); +subject.next(2); +subject.complete(); +``` + +``` +// 结果 +// 1 2 | +``` + +注意在订阅前发送的值将会“丢失”: + +``` +const subject = new Subject(); +const observable = subject.asObservable(); +``` + +``` +subject.next(1); +``` + +``` +observable.subscribe(console.log); +``` + +``` +subject.next(2); +subject.complete(); +``` + +``` +// 结果 +// 2 +``` + +除了常规的 subject,RxJS 还提供了三种特殊的版本。 + +_AsyncSubject_ 在结束后只发送最后的一个值。 + +``` +const subject = new AsyncSubject(); +const observable = subject.asObservable(); +``` + +``` +observable.subscribe(console.log); +``` + +``` +subject.next(1); +subject.next(2); +subject.complete(); +``` + +``` +// 输出 +// 2 +``` + +_BehaviorSubject_ 使得你能够提供一个(默认的)值,如果当前没有其它值发送的话,这个值会被发送给每个订阅者。否则订阅者收到最后一个发送的值。 + +``` +const subject = new BehaviorSubject(1); +const observable = subject.asObservable(); +``` + +``` +const subscription1 = observable.subscribe(console.log); +``` + +``` +subject.next(2); +subscription1.unsubscribe(); +``` + +``` +// 输出 +// 1 +// 2 +``` + +``` +const subscription2 = observable.subscribe(console.log); +``` + +``` +// 输出 +// 2 +``` + +The _ReplaySubject_ 存储一定数量、或一定时间或所有的发送过的值。所有新的订阅者将会获得所有存储了的值。 + +``` +const subject = new ReplaySubject(); +const observable = subject.asObservable(); +``` + +``` +subject.next(1); +``` + +``` +observable.subscribe(console.log); +``` + +``` +subject.next(2); +subject.complete(); +``` + +``` +// 输出 +// 1 +// 2 +``` + +你可以在 [ReactiveX documentation][10](它提供了一些其它的连接) 里面找到更多关于 subjects 的信息。[Ben Lesh][11] 在 [On The Subject Of Subjects][12] 上面提供了一些关于 subjects 的理解,[Nicholas Jamieson][13] 在 [in RxJS: Understanding Subjects][14] 上也提供了一些理解。 + +#### Observable + +你可以简单地用 new 操作符创建一个 observable 对象。通过你传入的函数,你可以控制流,只要有人订阅了或者它接收到一个可以当成 subject 使用的 observer,这个函数就会被调用,比如,调用 next,complet 和 error。 + +让我们回顾一下列表示例: + +``` +const myList = new List(); +myList.add(1); +myList.add(3); +``` + +``` +new Observable(observer => { + for (let i = 0; i { + // 流式化 +``` + +``` + return () => { + //clean up + }; +}) +.subscribe(); +``` + +#### 继承 Observable + +在有可用的操作符前,这是一种实现自定义操作符的方式。RxJS 在内部扩展了 _Observable_。_Subject_ 就是一个例子,另一个是 _publisher_ 操作符。它返回一个 _ConnectableObservable_ 对象,该对象提供额外的方法 _connect_。 + +#### 实现 Subscribable 接口 + +有时候你已经用一个对象来保存状态,并且能够发送值。如果你实现了 Subscribable 接口,你可以把它转换成一个 observable 对象。Subscribable 接口中只有一个 subscribe 方法。 + +``` +interface Subscribable { subscribe(observerOrNext?: PartialObserver | ((value: T) => void), error?: (error: any) => void, complete?: () => void): Unsubscribable} +``` + +* * * + +### 结合和选择现有的流 + +知道怎么创建一个独立的流还不够。有时候你有好几个流但其实只需要一个。有些函数也可作为操作符,所以我不打算在这里深入展开。推荐看看 [Max NgWizard K][16] 所写的一篇 [文章][15],它还包含一些有趣的动画。 + +还有一个建议:你可以通过拖拽元素的方式交互式的使用结合操作,参考 [RxMarbles][17]。 + +#### ObservableInput 类型 + +期望接收流的操作符和函数通常不单独和 observables 一起工作。相反,他们实际上期望的参数类型是 ObservableInput,定义如下: + +``` +type ObservableInput = SubscribableOrPromise | ArrayLike | Iterable; +``` + +这意味着你可以传递一个 promises 或者数组却不需要事先把他们转换成 observables。 + +#### defer + +主要的目的是把一个 observable 对象的创建延迟(defer)到有人想要订阅的时间。在以下情况,这很有用: + +* 创建 observable 对象的开销较大 + +* 你想要给每个订阅者新的 observable 对象 + +* 你想要在订阅时候选择不同的 observable 对象 + +* 有些代码必须在订阅之后执行 + +最后一点包含了一个并不起眼的用例:Promises(defer 也可以返回一个 promise 对象)。看看这个用到了 fetch API 的例子: + +``` +function getUser(id) { + console.log("fetching data"); + return fetch(`https://server/user/${id}`); +} +``` + +``` +const userPromise = getUser(1); +console.log("I don't want that request now"); +``` + +``` +// 其它地方 +userPromise.then(response => console.log("done"); +``` + +``` +// 输出 +// fetching data +// I don't want that request now +// done +``` + +只要流在你订阅的时候执行了,promise 就会立即执行。我们调用 getUser 的瞬间,就发送了一个请求,哪怕我们这个时候不想发送请求。当然,我们可以使用 from 来把一个 promise 对象转换成 observable 对象,但我们传递的 promise 对象已经创建或执行了。defer 让我们能够等到订阅才发送这个请求: + +``` +const user$ = defer(() => getUser(1)); +``` + +``` +console.log("I don't want that request now"); +``` + +``` +// 其它地方 +user$.subscribe(response => console.log("done"); +``` + +``` +// 输出 +// I don't want that request now +// fetching data +// done +``` + +#### iif + + _iif 包含了一个关于 _defer_ 的特殊用例:在订阅时选择两个流中的一个: + +``` +iif( + () => new Date().getHours() < 12, + of("AM"), + of("PM") +) +.subscribe(); +``` + +``` +// 结果 +// AM before noon, PM afterwards +``` + +引用了文档: + +> 实际上 `[iif][3]` 能够轻松地用 `[defer][4]` 实现,它仅仅是出于方便和可读性的目的。 + +#### onErrorResumeNext + +开启第一个流并且在失败的时候继续进行下一个流。错误被忽略掉。 + +``` +const stream1$ = of(1, 2).pipe( + tap(i => { if(i>1) throw 'error'}) //fail after first element +); +``` + +``` +const stream2$ = of(3,4); +``` + +``` +onErrorResumeNext(stream1$, stream2$) + .subscribe(console.log); +``` + +``` +// 结果 +// 1 3 4 | +``` + +如果你有多个 web 服务,这就很有用了。万一主服务器开启失败,那么备份的服务就能自动调用。 + +#### forkJoin + +它让流并行运行,当流结束时发送存在数组中的最后的值。由于每个流只有最后一个值被发送,它一般用在只发送一个元素的流的情况,就像 HTTP 请求。你让请求并行运行,在所有流收到响应时执行某些任务。 + +``` +function handleResponses([user, account]) { + // 执行某些任务 +} +``` + +``` +forkJoin( + fetch("https://server/user/1"), + fetch("https://server/account/1") +) +.subscribe(handleResponses); +``` + +#### merge / concat + +发送每一个从源 observables 对象中发出的值。 + + _merge_  接收一个参数,让你定义有多少流能被同时订阅。默认是无限制的。设为 1 就意味着监听一个源流,在它结束的时候订阅下一个。由于这是一个常见的场景,RxJS 为你提供了一个显示的函数:_concat_。 + +``` +merge( + interval(1000).pipe(mapTo("Stream 1"), take(2)), + interval(1200).pipe(mapTo("Stream 2"), take(2)), + timer(0, 1000).pipe(mapTo("Stream 3"), take(2)), + 2 //two concurrent streams +) +.subscribe(); +``` + +``` +// 只订阅流 1 和流 2 +``` + +``` +// 输出 +// Stream 1 -> after 1000ms +// Stream 2 -> after 1200ms +// Stream 1 -> after 2000ms +``` + +``` +// 流 1 结束后,开始订阅流 3 +``` + +``` +// 输出 +// Stream 3 -> after 0 ms +// Stream 2 -> after 400 ms (2400ms from beginning) +// Stream 3 -> after 1000ms +``` + +``` + +merge( + interval(1000).pipe(mapTo("Stream 1"), take(2)), + interval(1200).pipe(mapTo("Stream 2"), take(2)) + 1 +) +// 等效于 +concat( + interval(1000).pipe(mapTo("Stream 1"), take(2)), + interval(1200).pipe(mapTo("Stream 2"), take(2)) +) +``` + +``` +// 输出 +// Stream 1 -> after 1000ms +// Stream 1 -> after 2000ms +// Stream 2 -> after 3200ms +// Stream 2 -> after 4400ms +``` + +#### zip / combineLatest + + _merge_ 和 _concat_ 一个接一个的发送所有从源流中读到的值,而 zip 和 combineLatest 是把每个流中的一个值结合起来一起发送。_zip_ 结合所有源流中发送的第一个值。如果流的内容相关联,那么这就很有用。 + +``` +zip( + interval(1000), + interval(1200), +) +.subscribe(); +``` + +``` +// 结果 +// [0, 0] [1, 1] [2, 2] ... +``` + +_combineLatest_ 与之类似,但结合的是源流中发送的最后一个值。直到所有源流至少发送一个值之后才会触发事件。这之后每次源流发送一个值,它都会把这个值与其他流发送的最后一个值结合起来。 + +``` +combineLatest( + interval(1000), + interval(1200), +) +.subscribe(); +``` + +``` +// 结果 +// [0, 0] [1, 0] [1, 1] [2, 1] ... +``` + +两个函数都让允许传递一个选择器函数,把元素结合成其它对象而不是数组: + +``` +zip( + interval(1000), + interval(1200), + (e1, e2) -> e1 + e2 +) +.subscribe(); +``` + +``` +// 结果 +// 0 2 4 6 ... +``` + +#### race + +选择第一个发送数据的流。产生的流基本是最快的。 + +``` +race( + interval(1000), + of("foo") +) +.subscribe(); +``` + +``` +// 结果 +// foo | +``` + +由于 _of_ 立即产生一个值,因此它是最快的流,然而这个流就被选中了。 + +* * * + +### 总结 + +已经有很多创建 observables 对象的方式了。如果你想要创造响应式的 APIs 或者想用响应式的 API 结合传统 APIs,那么了解这些方法很重要。 + +我已经向你展示了所有可用的方法,但它们其实还有很多内容可以讲。如果你想更加深入地了解,我极力推荐你查阅 [documentation][20] 或者阅读相关文章。 + +[RxViz][21] 是另一种值得了解的有意思的方式。你编写 RxJS 代码,产生的流可以用图形或动画进行显示。 + +-------------------------------------------------------------------------------- + +via: https://blog.angularindepth.com/the-extensive-guide-to-creating-streams-in-rxjs-aaa02baaff9a + +作者:[Oliver Flaggl][a] +译者:[BriFuture](https://github.com/BriFuture) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.angularindepth.com/@abetteroliver +[1]:https://rxjs-dev.firebaseapp.com/api/index/Subscribable +[2]:https://rxjs-dev.firebaseapp.com/api/index/Subscribable#subscribe +[3]:https://rxjs-dev.firebaseapp.com/api/index/iif +[4]:https://rxjs-dev.firebaseapp.com/api/index/defer +[5]:https://itnext.io/concurrency-and-asynchronous-behavior-with-rxjs-11b0c4b22597 +[6]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols +[7]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function* +[8]:https://medium.com/@benlesh/rxjs-observable-interop-with-promises-and-async-await-bebb05306875 +[9]:https://medium.com/@benlesh +[10]:http://reactivex.io/documentation/subject.html +[11]:https://medium.com/@benlesh +[12]:https://medium.com/@benlesh/on-the-subject-of-subjects-in-rxjs-2b08b7198b93 +[13]:https://medium.com/@cartant +[14]:https://blog.angularindepth.com/rxjs-understanding-subjects-5c585188c3e1 +[15]:https://blog.angularindepth.com/learn-to-combine-rxjs-sequences-with-super-intuitive-interactive-diagrams-20fce8e6511 +[16]:https://medium.com/@maximus.koretskyi +[17]:http://rxmarbles.com/#merge +[18]:https://rxjs-dev.firebaseapp.com/api/index/ObservableInput +[19]:https://rxjs-dev.firebaseapp.com/api/index/SubscribableOrPromise +[20]:http://reactivex.io/documentation/operators.html#creating +[21]:https://rxviz.com/ diff --git a/sources/tech/20170805 How to use Fio (Flexible I-O Tester) to Measure Disk Performance in Linux.md b/translated/tech/20170805 How to use Fio (Flexible I-O Tester) to Measure Disk Performance in Linux.md similarity index 66% rename from sources/tech/20170805 How to use Fio (Flexible I-O Tester) to Measure Disk Performance in Linux.md rename to translated/tech/20170805 How to use Fio (Flexible I-O Tester) to Measure Disk Performance in Linux.md index c2659f3664..d811ebad20 100644 --- a/sources/tech/20170805 How to use Fio (Flexible I-O Tester) to Measure Disk Performance in Linux.md +++ b/translated/tech/20170805 How to use Fio (Flexible I-O Tester) to Measure Disk Performance in Linux.md @@ -1,47 +1,41 @@ -How to use Fio (Flexible I/O Tester) to Measure Disk Performance in Linux + +如何在 Linux 中使用 Fio 来测评硬盘性能 ====== ![](https://wpmojo.com/wp-content/uploads/2017/08/wpmojo.com-how-to-use-fio-to-measure-disk-performance-in-linux-dotlayer.com-how-to-use-fio-to-measure-disk-performance-in-linux-816x457.jpeg) -Fio which stands for Flexible I/O Tester [is a free and open source][1] disk I/O tool used both for benchmark and stress/hardware verification developed by Jens Axboe. +Fio(Flexible I/O Tester) 是一款由 Jens Axboe 开发的用于测评和压力/硬件验证的[免费开源][1]的软件 -It has support for 19 different types of I/O engines (sync, mmap, libaio, posixaio, SG v3, splice, null, network, syslet, guasi, solarisaio, and more), I/O priorities (for newer Linux kernels), rate I/O, forked or threaded jobs, and much more. It can work on block devices as well as files. +它支持 19 种不同类型的 I/O 引擎 (sync, mmap, libaio, posixaio, SG v3, splice, null, network, syslet, guasi, solarisaio, 以及更多), I/O 优先级(针对较新的 Linux 内核),I/O 速度,复刻或线程任务,和其他更多的东西。它能够在块设备和文件上工作。 -Fio accepts job descriptions in a simple-to-understand text format. Several example job files are included. Fio displays all sorts of I/O performance information, including complete IO latencies and percentiles. +Fio 接受一种非常简单易于理解的文本格式作为任务描述。软件默认包含了许多示例任务文件。 Fio 展示了所有类型的 I/O 性能信息,包括完整的 IO 延迟和百分比。 -It is in wide use in many places, for both benchmarking, QA, and verification purposes. It supports Linux, FreeBSD, NetBSD, OpenBSD, OS X, OpenSolaris, AIX, HP-UX, Android, and Windows. +它被广泛的应用在非常多的地方,包括测评、QA,以及验证用途。它支持 Linux 、 FreeBSD 、 NetBSD、 OpenBSD、 OS X、 OpenSolaris、 AIX、 HP-UX、 Android 以及 Windows。 -In this tutorial, we will be using Ubuntu 16 and you are required to have sudo or root privileges to the computer. We will go over the installation and use of fio. +在这个教程,我们将使用 Ubuntu 16 ,你需要拥有这台电脑的 sudo 或 root 权限。我们将完整的进行安装和 Fio 的使用。 -### Installing fio from Source +### 使用源码安装 Fio + +我们要去克隆 Github 上的仓库。安装所需的依赖,然后我们将会从源码构建应用。首先,确保我们安装了 Git 。 -We are going to clone the repo on GitHub. Install the prerequisites, and then we will build the packages from the source code. Lets' start by making sure we have git installed. ``` - sudo apt-get install git - - ``` -For centOS users you can use: +CentOS 用户可以执行下述命令: ``` - sudo yum install git - - ``` -Now we change directory to /opt and clone the repo from Github: -``` +现在,我们切换到 /opt 目录,并从 Github 上克隆仓库: +``` cd /opt git clone https://github.com/axboe/fio - - ``` -You should see the output below: -``` +你应该会看到下面这样的输出 +``` Cloning into 'fio'... remote: Counting objects: 24819, done. remote: Compressing objects: 100% (44/44), done. @@ -49,72 +43,59 @@ remote: Total 24819 (delta 39), reused 62 (delta 32), pack-reused 24743 Receiving objects: 100% (24819/24819), 16.07 MiB | 0 bytes/s, done. Resolving deltas: 100% (16251/16251), done. Checking connectivity... done. - - ``` -Now, we change directory into the fio codebase by typing the command below inside the opt folder: -``` +现在,我们通过在 opt 目录下输入下方的命令切换到 Fio 的代码目录: +``` cd fio - - ``` -We can finally build fio from source using the `make` build utility bu using the commands below: -``` +最后,我们可以使用下面的命令来使用 `make` 从源码构建软件: +``` # ./configure # make # make install - - ``` -### Installing fio on Ubuntu +### 在 Ubuntu 上安装 Fio -For Ubuntu and Debian, fio is available on the main repository. You can easily install fio using the standard package managers such as yum and apt-get. +对于 Ubuntu 和 Debian 来说, Fio 已经在主仓库内。你可以很容易的使用类似 yum 和 apt-get 的标准包管理器来安装 Fio。 + +对于 Ubuntu 和 Debian ,你只需要简单的执行下述命令: -For Ubuntu and Debian you can simple use: ``` - sudo apt-get install fio - - ``` -For CentOS/Redhat you can simple use: -On CentOS, you might need to install EPEL repository to your system before you can have access to fio. You can install it by running the following command: -``` +对于 CentOS/Redhat 你只需要简单执行下述命令: +在 CentOS ,你可能在你能安装 Fio 前需要去安装 EPEL 仓库到你的系统中。你可以通过执行下述命令来安装它: +``` sudo yum install epel-release -y - - ``` -You can then install fio using the command below: -``` +你可以执行下述命令来安装 Fio: +``` sudo yum install fio -y - - ``` -### Disk Performace testing with Fio +### 使用 Fio 进行磁盘性能测试 -With Fio is installed on your system. It's time to see how to use Fio with some examples below. We are going to perform a random write, read and read and write test. -### Performing a Random Write Test +现在 Fio 已经安装到了你的系统中。现在是时候看一些如何使用 Fio 的例子了。我们将进行随机写、读和读写测试。 + +### 执行随机写测试 + +执行下面的命令来开始。这个命令将要同一时间执行两个进程,写入共计 4GB( 4 个任务 x 512MB = 2GB) 文件: -Let's start by running the following command. This command will write a total 4GB file [4 jobs x 512 MB = 2GB] running 2 processes at a time: ``` - sudo fio --name=randwrite --ioengine=libaio --iodepth=1 --rw=randwrite --bs=4k --direct=0 --size=512M --numjobs=2 --runtime=240 --group_reporting - - -``` ``` +``` ... fio-2.2.10 Starting 2 processes @@ -147,9 +128,9 @@ Disk stats (read/write): ``` -### Performing a Random Read Test +### 执行随机读测试 -We are going to perform a random read test now, we will be trying to read a random 2Gb file +我们将要执行一个随机读测试,我们将会尝试读取一个随机的 2GB 文件。 ``` sudo fio --name=randread --ioengine=libaio --iodepth=16 --rw=randread --bs=4k --direct=0 --size=512M --numjobs=4 --runtime=240 --group_reporting @@ -157,7 +138,7 @@ sudo fio --name=randread --ioengine=libaio --iodepth=16 --rw=randread --bs=4k -- ``` -You should see the output below: +你应该会看到下面这样的输出 ``` ... @@ -199,21 +180,18 @@ Disk stats (read/write): ``` -Finally, we want to show a sample read-write test to see how the kind out output that fio returns. +最后,我们想要展示一个简单的随机读-写测试来看一看 Fio 返回的输出类型。 -### Read Write Performance Test +### 读写性能测试 + +下述命令将会测试 USB Pen 驱动器 (/dev/sdc1) 的随机读写性能: -The command below will measure random read/write performance of USB Pen drive (/dev/sdc1): ``` - sudo fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=test --filename=random_read_write.fio --bs=4k --iodepth=64 --size=4G --readwrite=randrw --rwmixread=75 - - ``` -Below is the outout we get from the command above. +下面的内容是我们从上面的命令得到的输出: ``` - fio-2.2.10 Starting 1 process Jobs: 1 (f=1): [m(1)] [100.0% done] [217.8MB/74452KB/0KB /s] [55.8K/18.7K/0 iops] [eta 00m:00s] @@ -233,19 +211,19 @@ Run status group 0 (all jobs): Disk stats (read/write): sda: ios=774141/258944, merge=1463/899, ticks=748800/150316, in_queue=900720, util=99.35% - - ``` We hope you enjoyed this tutorial and enjoyed following along, Fio is a very useful tool and we hope you can use it in your next debugging activity. If you enjoyed reading this post feel free to leave a comment of questions. Go ahead and clone the repo and play around with the code. +我们希望你能喜欢这个教程并且享受接下来的内容,Fio 是一个非常有用的工具,并且我们希望你能在你下一次 Debugging 活动中使用到它。如果你喜欢这个文章,欢迎留下评论和问题。 + -------------------------------------------------------------------------------- via: https://wpmojo.com/how-to-use-fio-to-measure-disk-performance-in-linux/ 作者:[Alex Pearson][a] -译者:[译者ID](https://github.com/译者ID) +译者:[Bestony](https://github.com/bestony) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20171003 Streams a new general purpose data structure in Redis.md b/translated/tech/20171003 Streams a new general purpose data structure in Redis.md deleted file mode 100644 index 39da54d0cf..0000000000 --- a/translated/tech/20171003 Streams a new general purpose data structure in Redis.md +++ /dev/null @@ -1,165 +0,0 @@ -streams:一个新的 Redis 通用数据结构 -================================== - -直到几个月以前,对于我来说,在消息传递的环境中,streams 只是一个有趣且相对简单的概念。在 Kafka 流行这个概念之后,我主要研究它们在 Disque 实例中的用途。Disque 是一个将会转化为 Redis 4.2 的模块的消息队列。后来我发现 Disque 全都是 AP 消息,它将在不需要客户端过多参与的情况下实现容错和保证送达,因此,我认为 streams 的概念在那种情况下并不适用。 - -但是,在 Redis 中有一个问题,那就是缺省情况下导出数据结构并不轻松。它在 Redis 列表、排序集和发布/订阅(Pub/Sub)能力上有某些缺陷。你可以合适地使用这些工具去模拟一个消息或事件的序列,而有所权衡。排序集是大量耗费内存的,不能自然的模拟一次又一次的相同消息的传递,客户端不能阻塞新消息。因为一个排序集并不是一个序列化的数据结构,它是一个根据它们量的变化而移动的元素集:它不是很像时间系列一样的东西。列表有另外的问题,它在某些特定的用例中产生类似的适用性问题:你无法浏览列表中部是什么,因为在那种情况下,访问时间是线性的。此外,没有任何的指定输出功能,列表上的阻塞操作仅为单个客户端提供单个元素。列表中没有固定的元素标识,也就是说,不能指定从哪个元素开始给我提供内容。对于一到多的工作负载,这里有发布/订阅,它在大多数情况下是非常好的,但是,对于某些不想“即发即弃”的东西:保留一个历史是很重要的,而不是断开之后重新获得消息,也因为某些消息列表,像时间系列,在用范围查询浏览时,是非常重要的:在这 10 秒范围内我的温度读数是多少? - -这有一种方法可以尝试处理上面的问题,我计划对排序集进行通用化,并列入一个唯一的、更灵活的数据结构,然而,我的设计尝试最终以生成一个比当前的数据结构更加矫揉造作的结果而结束。一个关于 Redis 数据结构导出的更好的想法是,让它更像天然的计算机科学的数据结构,而不是,“Salvatore 发明的 API”。因此,在最后我停止了我的尝试,并且说,“ok,这是我们目前能提供的”,或许,我将为发布/订阅增加一些历史信息,或者将来对列表访问增加一些更灵活的方式。然而,每次在会议上有用户对我说“你如何在 Redis 中模拟时间系列” 或者类似的问题时,我的脸就绿了。 - -### 起源 - -在将 Redis 4.0 中的模块介绍完之后,用户开始去看他们自己怎么去修复这些问题。他们之一,Timothy Downs,通过 IRC 写信给我: - - 这个模块,我计划去增加一个事务日志式的数据类型 - 这意味着大量的订阅者可以在没有大量的内存增加的情况下做一些像发布/订阅那样的事情 - 订阅者保持他在消息队列中的位置,而不是在 Redis 上维护每个客户和复制消息的每个订阅者 - -这激发了我的想像力。我想了几天,并且意识到这可能是我们立刻同时解决上面的问题的契机。我需要去重新想像 “日志” 的概念是什么。它是个基本的编程元素,每个人都使用到它,因为它是非常简单地在追加模式中打开一个文件并以一定的格式写入数据,数据结构必须是抽象的。然而 Redis ,它们在内存中,并且我们使用 RAM 并不是因为我们懒,但是,因为使用一些指针,我们可以概念化数据结构并让他们抽象,并允许他们去摆脱明显的限制。对于实例,正常的日志有几个问题:偏移不是逻辑的,但是,它是一个真实的字节偏移,如果你想逻辑偏移是什么,那是与条目插入的时间相关的,我们有范围查询可用。同样的,一个日志通常很难收集:在一个只追加的数据结构中怎么去删除旧的元素?好吧,在我们理想的日志中,我们只是说,我想要最大的条目数,而旧的元素一个也不要,等等。 - -当我从 Timothy 的想法,去尝试着写一个规范的时候,我使用了 radix 树去实现,它是用于 Redis 集群的,去优化它内部的某些部分。这为实现一个有效的空间日志提供了基础。它在对数的时间(logarithmic time)内得到范围是仍然可访问的。同时,我开始去读关于 Kafka 流,去得到另外的创意,它也非常适合我的设计,并且产生了一个 Kafka 客户组的概念,并且,将它理想化用于 Redis 和内存中(in-memory)使用的案例。然而,该规范仅保留了几个月,在一段时间后,我积累了与别人讨论的即将增加到 Redis 中的内容,为了升级它,使用了许多提示(hint)几乎从头到尾重写了一遍。我想 Redis 流尤其对于时间系列是非常有用的,而不仅是用于事件和消息类的应用程序。 - -让我们写一些代码 -===================== - -从 Redis 会议回来后,在整个夏天,我实现了一个称为 “listpack” 的库。这个库是 ziplist.c 的继承者,那是一个表示在单个分配中字符串元素的列表的数据结构。它是一个非常专业的序列化格式,有在相反的顺序中可解析的特性,从右到左: 在所有的用户案例中用于替代 ziplists 中所需的某些东西。 - -结合 radix 树 + listpacks,它可以很容易地去构建一个日志,它同时也是非常高效的,并且是索引化的,意味着,允许通过 IDs 和时间进行随机访问。自从实现这个方法后,为了实现流数据结构,我开始去写一些代码。我直到完成实现,不管怎样,在这个时候,在 Github 上的 Redis 内部的 “streams” 分支,去启动共同开发并接受订阅已经足够了。我并没有声称那个 API 是最终版本,但是,这有两个有趣的事实:一是,在那时,仅客户组是缺失的,加上一些不那么重要的命令去操作流,但是,所有的大的方面都已经实现了。二是,一旦各个方面比较稳定了之后 ,决定将所有的流的工作移植到 4.0 分支,它大约两个月后发布。这意味着 Redis 用户为了使用流,不用等待 Redis 4.2,它们将对生产使用的 ASAP 可用。这是可能的,因为有一个新的数据结构,几乎所有的代码改变都是独立于新代码的。除了阻塞列表操作之外 :代码都重构了,因此,我们和流共享了相同的代码,并且,列表阻塞操作在 Redis 内部进行了大量的简化。 - -教程:欢迎使用 Redis 流 -================================== - -在某种程序上,你应该感谢流作为 Redis 列表的一个增强版本。流元素不再是一个单一的字符串,它们更多是一个域(fields)和值(values)组成的对象。范围查询更适用而且更快。流中的每个条目都有一个 ID,它是一个逻辑偏移量。不同的客户端可以阻塞等待(blocking-wait)比指定的 IDs 更大的元素。Redis 流的一个基本的命令是 XADD。是的,所有的 Redis 命令都是以一个“X”为前缀的。 - -> XADD mystream * sensor-id 1234 temperature 10.5 -1506871964177.0 - -这个 XADD 命令将追加指定的条目作为一个新元素到一个指定的流 “mystream” 中。在上面的示例中的这个条目有两个域:sensor-id 和 temperature,然而,每个条目在同一个流中可以有不同的域。使用相同的域名字将导致更多的内存使用。一个有趣的事情是,域的排序是保证保存的。XADD 仅返回插入的条目的 ID,因为在第三个参数中有星号(*),我们请求命令去自动生成 ID。这几乎总是你想要的,但是,它也可能去强制指定一个 ID,实例为了去复制这个命令到被动服务器和 AOF 文件。 - -这个 ID 是由两部分组成的:一个毫秒时间和一个序列号。1506871964177 是毫秒时间,它仅是一个使用毫秒解决方案的 UNIX 时间。圆点(.)后面的数字 0,是一个序列号,它是为了区分相同毫秒数的条目增加上去的。所有的数字都是 64 位的无符号整数。这意味着在流中,我们可以增加所有我们想要的条目,在相同毫秒数中的事件。ID 的毫秒部分使用 Redis 服务器的当前本地时间生成的 ID 和流中的最后一个条目之间的最大值来获取。因此,对实例来说,即使是计算机时间向后跳,这个 IDs 仍然是增加的。在某些情况下,你可能想流条目的 IDs 作为完整的 128 位数字。然而,现实是,它们与被添加的实例的本地时间有关,意味着我们有毫秒级的精确的范围查询。 - -如你想像的那样,以一个快速的方式去添加两个条目,结果是仅序列号增加。我可以使用一个 MULTI/EXEC 块去简单模拟“快速插入”,如下: - -> MULTI -OK -> XADD mystream * foo 10 -QUEUED -> XADD mystream * bar 20 -QUEUED -> EXEC -1) 1506872463535.0 -2) 1506872463535.1 - -在上面的示例中,也展示了无需在开始时指定任何模式(schema)的情况下,对不同的条目,使用不同的域。会发生什么呢?每个块(它通常包含 50 - 150 个消息范围的内容)的每一个信息被用作参考。并且,有相同域的连续条目被使用一个标志进行压缩,这个标志表明“这个块中的第一个条目的相同域”。因此,对于连续消息使用相同域可以节省许多内存,即使是域的集合随着时间发生缓慢变化。 - -为了从流中检索数据,这里有两种方法:范围查询,它是通过 XRANGE 命令实现的,并且对于正在变化的流,通过 XREAD 命令去实现。XRANGE 命令仅取得包括从开始到停止范围内的条目。因此,对于实例,如果我知道它的 ID,我可以取得单个条目,像这样: - -> XRANGE mystream 1506871964177.0 1506871964177.0 -1) 1) 1506871964177.0 - 2) 1) "sensor-id" - 2) "1234" - 3) "temperature" - 4) "10.5" - -然而,你可以使用指定的开始符号 “-” 和停止符号 “+” 去表示可能的最小和最大 ID。为了限制返回条目的数量,它也可以使用 COUNT 选项。下面是一个更复杂的 XRANGE 示例: - -> XRANGE mystream - + COUNT 2 -1) 1) 1506871964177.0 - 2) 1) "sensor-id" - 2) "1234" - 3) "temperature" - 4) "10.5" -2) 1) 1506872463535.0 - 2) 1) "foo" - 2) "10" - -这里我们讲的是 IDs 的范围,然后,为了在一个给定时间范围内取得特定元素的范围,你可以使用 XRANGE,因为你可以省略 IDs 的“序列” 部分。因此,你可以做的仅是指定“毫秒”时间,下面的命令的意思是: “从 UNIX 时间 1506872463 开始给我 10 个条目”: - -127.0.0.1:6379> XRANGE mystream 1506872463000 + COUNT 10 -1) 1) 1506872463535.0 - 2) 1) "foo" - 2) "10" -2) 1) 1506872463535.1 - 2) 1) "bar" - 2) "20" - -关于 XRANGE 注意的最重要的事情是,由于我们在回复中收到了 IDs,并且连续 ID 是无法直接获得的,因为 ID 的序列部分是增加的,它可以使用 XRANGE 去遍历整个流,接收每个调用的元素的特定个数。在 Redis 中的*SCAN*系列命令之后,那是允许 Redis 数据结构迭代的,尽管事实上它们不是为迭代设计的,我以免再次产生相同的错误。 - -使用 XREAD 处理变化的流:阻塞新的数据 -=========================================== - -XRANGE 用于,当我们想通过 ID 或时间去访问流中的一个范围或者是通过 ID 去得到单个元素时,是非常完美的。然而,在当数据到达时,不同的客户端必须同时使用流的情况下,它就不是一个很好的解决方案,并且它是需要某种形式的“池”的。(对于*某些*应用程序来说,这可能是个好主意,因为它们仅是偶尔连接取数的)。 - -XREAD 命令是为读设计的,同时从多个流中仅指定我们得到的流中的最后条目的 ID。此外,如果没有数据可用,我们可以要求阻塞,当数据到达时,去解除阻塞。类似于阻塞列表操作产生的效果,但是,这里的数据是从流中得到的。并且多个客户端可以在同时访问相同的数据。 - -这里有一个关于 XREAD 调用的规范示例: - -> XREAD BLOCK 5000 STREAMS mystream otherstream $ $ - -它的意思是:从 “mystream” 和 “otherstream” 取得数据。如果没有数据可用,阻塞客户端 5000 毫秒。之后我们用关键字 STREAMS 指定我们想要监听的流,和最后的 ID,指定的 ID “$” 意思是:假设我现在已经有了流中的所有元素,因此,从下一个到达的元素开始给我。 - -如果,从另外一个客户端,我发出这样的命令: - -> XADD otherstream * message “Hi There” - -在 XREAD 侧会出现什么情况呢? - -1) 1) "otherstream" - 2) 1) 1) 1506935385635.0 - 2) 1) "message" - 2) "Hi There" - -和到过的数据一起,我们得到了最新到达的数据的 key,在下次的调用中,我们将使用接收到的最新消息的 ID: - -> XREAD BLOCK 5000 STREAMS mystream otherstream $ 1506935385635.0 - -依次类推。然而需要注意的是使用方式,有可能客户端在一个非常大的延迟(因为它处理消息需要时间,或者其它什么原因)之后再次连接。在这种情况下,同时会有很多消息堆积,为了确保客户端不被消息淹没,并且服务器不会丢失太多时间的提供给单个客户端的大量消息,所以,总是使用 XREAD 的 COUNT 选项是明智的。 - -流封顶 -============== - -到现在为止,一直还都不错… 然而,有些时候,流需要去删除一些旧的消息。幸运的是,这可以使用 XADD 命令的 MAXLEN 选项去做: - -> XADD mystream MAXLEN 1000000 * field1 value1 field2 value2 - -它是基本意思是,如果流添加的新元素被发现超过 1000000 个消息,那么,删除旧的消息,以便于长度回到 1000000 个元素以内。它很像是使用 RPUSH + LTRIM 的列表,但是,这是我们使用了一个内置机制去完成的。然而,需要注意的是,上面的意思是每次我们增加一个新的消息时,我们还需要另外的工作去从流中删除旧的消息。这将使用一些 CPU 资源,所以,在计算 MAXLEN 的之前,尽可能使用 “~” 符号,为了表明我们不是要求非常*精确*的 1000000 个消息。但是,这里有很多,它还不是一个大的问题: - -> XADD mystream MAXLEN ~ 1000000 * foo bar - -这种方式的 XADD 删除消息,仅用于当它可以删除整个节点的时候。相比 vanilla XADD,这种方式几乎可以自由地对流进行封顶。 - -(进程内工作的)客户组 -================================== - -这是不在 Redis 中实现的第一个特性,但是,它是在进程内工作的。它也是来自 Kafka 的灵感,尽管在这里以不同的方式去实现的。重点是使用了 XREAD,客户端也可以增加一个 “GROUP ” 选项。 在相同组的所有客户端自动调用,以得到*不同的*消息。当然,这里不能从同一个流中被多个组读。在这种情况下,所有的组将收到流中到达的消息的相同副本。但是,在不同的组,消息是不会重复的。 - -当指定组时,尽可能指定一个 “RETRY ” 选项去扩展组:在这种情况下,如果消息没有使用 XACK 去进行确认,它将在指定的毫秒数后进行再次投递。这种情况下,客户端没有私有的方法去标记已处理的消息,这也是一项正在进行中的工作。 - -内存使用和节省的加载时间 -===================================== - -因为被设计用来模拟 Redis 流,所以,根据它们的域的数量、值和长度,内存使用是显著降低的。但对于简单的消息,每 100 MB 内存使用可以有几百万条消息,此外,设想中的格式去需要极少的系列化:是存储为 radix 树节点的 listpack 块,在磁盘上和内存中是用同一个来表示的,因此,它们被琐碎地存储和读取。在一个实例中,Redis 能在 0.3 秒内可以从 RDB 文件中读取 500 万个条目。这使的流的复制和持久存储是非常高效的。 - -它也被计划允许从条目中间删除。现在仅部分实现,策略是整个条目标记中删除的条目被标记为已删除条目,并且,当达到设置的已删除条目占全部条目的比例时,这个块将被回收重写,并且,如果需要,它将被连到相邻的另一个块上,以避免碎片化。 - -最终发布时间的结论 -=================== - -Redis 流将包含在年底前推出的 Redis 4.0 系列的稳定版中。我认为这个通用的数据结构将为 Redis 提供一个巨大的补丁,为了用于解决很多现在很难去解决的情况:那意味着你需要创造性地滥用当前提供的数据结构去解决那些问题。一个非常重要的使用情况是时间系列,但是,我的感觉是,对于其它案例来说,通过 TREAD 来传递消息将是非常有趣的,因为它可以替代那些需要更高可靠性的发布/订阅的应用程序,而不是“即用即弃”,以及全新的使用案例。现在,如果你想在你的有问题的环境中,去评估新的数据结构的能力,可以在 GitHub 上去获得 “streams” 分支,开始去玩吧。欢迎向我们报告所有的 bug 。 :-) - -如果你喜欢这个视频,展示这个 streams 的实时会话在这里: https://www.youtube.com/watch?v=ELDzy9lCFHQ - - --------------------------------------------------------------------------------- - -via: http://antirez.com/news/114 - -作者:[antirez ][a] -译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://antirez.com/ -[1]:http://antirez.com/news/114 -[2]:http://antirez.com/user/antirez -[3]:https://www.youtube.com/watch?v=ELDzy9lCFHQ diff --git a/translated/tech/20171009 Considering Pythons Target Audience.md b/translated/tech/20171009 Considering Pythons Target Audience.md index 60cf84ca5e..b7eed6ff8f 100644 --- a/translated/tech/20171009 Considering Pythons Target Audience.md +++ b/translated/tech/20171009 Considering Pythons Target Audience.md @@ -1,242 +1,186 @@ -[谁是 Python 的目标受众?][40] +盘点 Python 的目标受众 ============================================================ Python 是为谁设计的? -* [Python 使用情况的参考][8] - +* [Python 的参考解析器使用情况][8] * [CPython 主要服务于哪些受众?][9] - * [这些相关问题的原因是什么?][10] - * [适合进入 PyPI 规划的方面有哪些?][11] - -* [当增加它到标准库中时,为什么一些 APIs 会被改变?][12] - -* [为什么一些 API 是以临时(provisional)的形式被增加的?][13] - -* [为什么只有一些标准库 APIs 被升级?][14] - +* [当添加它们到标准库中时,为什么一些 API 会被改变?][12] +* [为什么一些 API 是以临时provisional的形式被添加的?][13] +* [为什么只有一些标准库 API 被升级?][14] * [标准库任何部分都有独立的版本吗?][15] - * [这些注意事项为什么很重要?][16] -几年前, 我在 python-dev 邮件列表中、活跃的 CPython 核心开发人员、以及决定参与该过程的人员中[强调][38]说,“CPython 的动作太快了也太慢了”,作为这种冲突的一个主要原因是,它们不能有效地使用他们的个人时间和精力。 +几年前,我在 python-dev 邮件列表中,以及在活跃的 CPython 核心开发人员和认为参与这一过程不是有效利用他们个人时间和精力的人中[强调][38]说,“CPython 的发展太快了也太慢了”是很多冲突的原因之一。 -我一直在考虑这种情况,在参与的这几年,我也花费了一些时间去思考这一点,在我写那篇文章的时候,我还在波音防务澳大利亚公司(Boeing Defence Australia)工作。下个月,我将离开波音进入红帽亚太(Red Hat Asia-Pacific),并且开始在大企业的[开源供应链管理][39]上获得重分发者(redistributor)级别的观点。 +我一直认为事实确实如此,但这也是一个要点,在这几年中我也花费了一些时间去反思它。在我写那篇文章的时候,我还在波音防务澳大利亚公司Boeing Defence Australia工作。下个月,我将离开波音进入红帽亚太Red Hat Asia-Pacific,并且开始在大企业的[开源供应链管理][39]上获得再分发者redistributor层面的视角。 -### [Python 使用情况的参考][17] +### Python 的参考解析器使用情况 -我将分解 CPython 的使用情况如下,它虽然有些过于简化(注意,这些分类并不是很清晰,他们仅关注影响新软件特性和版本的部署不同因素): +我尝试将 CPython 的使用情况分解如下,它虽然有些过于简化(注意,这些分类的界线并不是很清晰,他们仅关注于思考新软件特性和版本发布后不同因素的影响): -* 教育类:教育工作者的主要兴趣在于建模方法的教学和计算操作方面,_不_ 写或维护软件产品。例如: +* 教育类:教育工作者的主要兴趣在于建模方法的教学和计算操作方面,_不会去_ 写或维护生产级别的软件。例如: * 澳大利亚的 [数字课程][1] - * Lorena A. Barba 的 [AeroPython][2] - -* 个人的自动化爱好者的项目:主要的是软件,经常是只有软件,而且用户通常是写它的人。例如: - * my Digital Blasphemy [image download notebook][3] - - * Paul Fenwick's (Inter)National [Rick Astley Hotline][4] - -* 组织(organisational)过程的自动化:主要是软件,经常是只有软件,用户是为了利益而编写它的组织。例如: - * CPython 的 [核发工作流工具][5] - - * Linux 发行版的开发、构建&发行工具 - -* “一劳永逸(Set-and-forget)” 的基础设施中:这里是软件,(这种说法有时候有些争议),在生命周期中软件几乎不会升级,但是,在底层平台可能会升级。例如: - * 大多数的自我管理的企业或机构的基础设施(在那些资金充足的可持续工程计划中,这是让人非常不安的) - +* 个人级的自动化和爱好者的项目:主要的是软件,而且经常是只有软件,用户通常是写它的人。例如: + * my Digital Blasphemy [图片下载器][3] + * Paul Fenwick 的 (Inter)National [Rick Astley Hotline][4] +* 组织organisational过程自动化:主要是软件,而且经常是只有软件,用户是为了利益而编写它的组织。例如: + * CPython 的 [核心工作流工具][5] + * Linux 发行版的开发、构建 & 发行管理工具 +* “一劳永逸Set-and-forget” 的基础设施中:这里是软件,(这种说法有时候有些争议),在生命周期中该软件几乎不会升级,但是,在底层平台可能会升级。例如: + * 大多数的自我管理的企业或机构的基础设施(在那些资金充足的可持续工程计划中,这种情况是让人非常不安的) * 拨款资助的软件(当最初的拨款耗尽时,维护通常会终止) - * 有严格认证要求的软件(如果没有绝对必要的话,从经济性考虑,重新认证比常规更新来说要昂贵很多) - * 没有自动升级功能的嵌入式软件系统 - -* 持续升级的基础设施:具有健壮的持续工程化模型的软件,对于依赖和平台升级被认为是例行的,而不去关心其它的代码改变。例如: +* 持续升级的基础设施:具有健壮支撑的工程学模型的软件,对于依赖和平台升级通常是例行的,而不去关心其它的代码改变。例如: * Facebook 的 Python 服务基础设施 - * 滚动发布的 Linux 分发版 - * 大多数的公共 PaaS 无服务器环境(Heroku、OpenShift、AWS Lambda、Google Cloud Functions、Azure Cloud Functions等等) - -* 间歇性升级的标准的操作环境:对其核心组件进行常规升级,但这些升级以年为单位进行,而不是周或月。例如: +* 间隔性升级的标准的操作环境:对其核心组件进行常规升级,但这些升级以年为单位进行,而不是周或月。例如: * [VFX 平台][6] - * 长周期支持的 Linux 分发版 - * CPython 和 Python 标准库 - - * 基础设施管理 & 业务流程工具(比如 OpenStack、 Ansible) - + * 基础设施管理 & 编排工具(比如 OpenStack、 Ansible) * 硬件控制系统 - * 短生命周期的软件:软件仅被使用一次,然后就丢弃或忽略,而不是随后接着升级。例如: - * 临时(Ad hoc)自动脚本 - + * 临时Ad hoc自动脚本 * 被确定为 “终止” 的单用户游戏(你玩它们一次后,甚至都忘了去卸载它,或许在一个新的设备上都不打算再去安装它) - * 短暂的或非持久状态的单用户游戏(如果你卸载并重安装它们,你的游戏体验也不会有什么大的变化) - * 特定事件的应用程序(这些应用程序与特定的物理事件捆绑,一旦事件结束,这些应用程序就不再有用了) - -* 定期使用的应用程序:部署后定期升级的软件。例如: +* 频繁使用的应用程序:部署后定期升级的软件。例如: * 业务管理软件 - * 个人 & 专业的生产力应用程序(比如,Blender) - * 开发工具 & 服务(比如,Mercurial、 Buildbot、 Roundup) - * 多用户游戏,和其它明显的处于持续状态的还没有被定义为 “终止” 的游戏 - * 有自动升级功能的嵌入式软件系统 - -* 共享的抽象层:软件组件的设计使它能够在特定的问题域有效地工作,即使你没有亲自掌握该领域的所有错综复杂的东西。例如: +* 共享的抽象层:在一个特定的问题领域中,设计用于让工作更高效的软件组件。即便是你没有亲自掌握该领域的所有错综复杂的东西。例如: * 大多数的运行时库和归入这一类的框架(比如,Django、Flask、Pyramid、SQL Alchemy、NumPy、SciPy、requests) - - * 也适合归入这里的许多测试和类型引用工具(比如,pytest、Hypothesis、vcrpy、behave、mypy) - + * 适合归入这一类的许多测试和类型推断工具(比如,pytest、Hypothesis、vcrpy、behave、mypy) * 其它应用程序的插件(比如,Blender plugins、OpenStack hardware adapters) + * 本身就代表了 “Python 世界” 基准的标准库(那是一个 [难以置信的复杂][7] 的世界观) - * 本身就代表了 “Python 世界” 的基准的标准库(那是一个 [难以置信的复杂][7] 的世界观) +### CPython 主要服务于哪些受众? -### [CPython 主要服务于哪些受众?][18] +从根本上说,CPython 和标准库的主要受众是哪些呢,是那些不管出于什么原因,将有限的标准库和从 PyPI 显式声明安装的第三方库组合起来所提供的服务,还不能够满足需求的那些人。 -最终,CPython 和标准库的主要受众是哪些,不论什么原因,一个更多的有限的标准库和从 PyPI 安装的显式声明的第三方库的组合,提供的服务是不够的。 +为了更进一步简化上面回顾的不同用法和部署模型,尽可能的总结,将最大的 Python 用户群体分开来看,一种是,在一些感兴趣的环境中将 Python 作为一种_脚本语言_使用的那些人;另外一种是将它用作一个_应用程序开发语言_的那些人,他们最终发布的是一种产品而不是他们的脚本。 -为了更一步简化上面回顾的不同用法和部署模式,为了尽可能的总结,将最大的 Python 用户群体分开来看,一种是,在一些环境中将 Python 作为一种_脚本语言_使用的,另外一种是将它用作一个_应用程序开发语言_,最终发布的是一种产品而不是他们的脚本。 - -当把 Python 作为一种脚本语言来使用时,它们典型的开发者特性包括: - -* 主要的处理单元是由一个 Python 文件组成的(或 Jupyter notebook !),而不是一个 Python 目录和元数据文件 - -* 没有任何形式的单独的构建步骤 - 是_作为_一个脚本分发的,类似于分发一个单独的 shell 脚本的方法。 - -* 没有单独的安装步骤(除了下载这个文件到一个合适的位置),除了在目标系统上要求预配置运行时环境 +把 Python 作为一种脚本语言来使用的开发者的典型特性包括: +* 主要的工作单元是由一个 Python 文件组成的(或 Jupyter notebook !),而不是一个 Python 和元数据文件的目录 +* 没有任何形式的单独的构建步骤 —— 是_作为_一个脚本分发的,类似于分发一个独立的 shell 脚本的方式 +* 没有单独的安装步骤(除了下载这个文件到一个合适的位置),除了在目标系统上要求预配置运行时环境外 * 没有显式的规定依赖关系,除了最低的 Python 版本,或一个预期的运行环境声明。如果需要一个标准库以外的依赖项,他们会通过一个环境脚本去提供(无论是操作系统、数据分析平台、还是嵌入 Python 运行时的应用程序) - -* 没有单独的测试套件,使用 "通过你给定的输入,这个脚本是否给出了你期望的结果?" 这种方式来进行测试 - -* 如果在执行前需要测试,它将以 “dry run” 和 “预览” 模式来向用户展示软件_将_怎样运行 - +* 没有单独的测试套件,使用“通过你给定的输入,这个脚本是否给出了你期望的结果?” 这种方式来进行测试 +* 如果在执行前需要测试,它将以 “试运行” 和 “预览” 模式来向用户展示软件_将_怎样运行 * 如果可以完全使用静态代码分析工具,它是通过集成进用户的软件开发环境的,而不是为个别的脚本单独设置的。 相比之下,使用 Python 作为一个应用程序开发语言的开发者特征包括: -* 主要的工作单元是由 Python 的目录和元数据文件组成的,而不是单个 Python 文件 - -* 在发布之前有一个单独的构建步骤去预处理应用程序,即使是把它的这些文件一起打包进一个 Python sdist、wheel 或 zipapp 文档 - +* 主要的工作单元是由 Python 和元数据文件组成的目录,而不是单个 Python 文件 +* 在发布之前有一个单独的构建步骤去预处理应用程序,哪怕是把它的这些文件一起打包进一个 Python sdist、wheel 或 zipapp 文档中 * 是否有独立的安装步骤去预处理将要使用的应用程序,取决于应用程序是如何打包的,和支持的目标环境 +* 外部的依赖明确表示为项目目录中的一个元数据文件中,要么是直接在项目的目录中(比如,`pyproject.toml`、`requirements.txt`、`Pipfile`),要么是作为生成的发行包的一部分(比如,`setup.py`、`flit.ini`) +* 存在一个独立的测试套件,或者作为一个 Python API 的一个单元测试,或者作为功能接口的集成测试,或者是两者的一个结合 +* 静态分析工具的使用是在项目级配置的,并作为测试管理的一部分,而不是取决于环境 -* 外部的依赖直接在项目目录中的一个元数据文件中表示(比如,`pyproject.toml`、`requirements.txt`、`Pipfile`),或作为生成的发行包的一部分(比如,`setup.py`、`flit.ini`) +作为以上分类的一个结果,CPython 和标准库的主要用途是,在相应的 CPython 特性发布后,为教育和临时ad hoc的 Python 脚本环境,最终提供的是定义重分发者假定功能的独立基准 3- 5 年。 -* 存在一个独立的测试套件,或者作为一个 Python API 的一个测试单元、功能接口的集成测试、或者是两者的一个结合 +对于临时ad hoc脚本使用的情况,这个 3 - 5 年的延迟是由于重分发者给用户制作新版本的延迟造成的,以及那些重分发版本的用户们花在修改他们的标准操作环境上的时间。 -* 静态分析工具的使用是在项目级配置的,作为测试管理的一部分,而不是依赖 +在教育环境中的情况是,教育工作者需要一些时间去评估新特性,和决定是否将它们包含进提供给他们的学生的课程中。 -作为以上分类的一个结果,CPython 和标准库最终提供的主要用途是,在合适的 CPython 特性发布后3 - 5年,为教育和临时(ad hoc)的 Python 脚本环境的呈现的功能,定义重新分发的独立基准。 +### 这些相关问题的原因是什么? -对于临时(ad hoc)脚本使用的情况,这个 3-5 年的延迟是由于新版本重分发给用户的延迟组成的,以及那些重分发版的用户花在修改他们的标准操作环境上的时间。 +这篇文章很大程度上是受 Twitter 上对 [我的这个评论][20] 的讨论鼓舞的,它援引了定义在 [PEP 411][21] 中临时Provisional API 的情形,作为一个开源项目的例子,对用户发出事实上的邀请,请其作为共同开发者去积极参与设计和开发过程,而不是仅被动使用已准备好的最终设计。 -在教育环境中的情况,教育工作者需要一些时间去评估新特性,和决定是否将它们包含进提供给他们的学生的课程中。 +这些回复包括一些在更高级别的库中支持临时 API 的困难程度的一些沮丧性表述、没有这些库做临时状态的传递、以及因此而被限制为只有临时 API 的最新版本才支持这些相关特性,而不是任何早期版本的迭代。 -### [这些相关问题的原因是什么?][19] +我的 [主要回应][22] 是,建议开源提供者应该强制实施有限支持,通过这种强制的有限支持可以让个人的维护努力变得可持续。这意味着,如果对临时 API 的老版本提供迭代支持是非常痛苦的,到那时,只有在项目开发人员自己需要、或有人为此支付费用时,他们才会去提供支持。这与我的这个观点是类似的,那就是,志愿者提供的项目是否应该免费支持老的、商业性质的、长周期的 Python 版本,这对他们来说是非常麻烦的事,我[不认为他们应该去做][23],正如我所期望的那样,大多数这样的需求都来自于管理差劲的、习以为常的惯性,而不是真正的需求(真正的需求,应该去支付费用来解决问题)。 -这篇文章很大程序上是受 Twitter 上 [我的评论][20] 的讨论鼓舞的,定义在 [PEP 411][21] 中引用临时(Provisional)的 API 的情形,作为一个开源项目发行的例子,一个真实的被邀请用户,作为共同开发者去积极参与设计和开发过程,而不是仅被动使用已准备好的最终设计。 +而我的[第二个回应][24]是去实现这一点,尽管多年来一直在讨论这个问题(比如,在上面链接中最早在 2011 年的一篇的文章中,以及在 Python 3 问答的回复中的 [这里][25]、[这里][26]、和[这里][27],以及去年的这篇文章 [Python 包生态系统][28] 中也提到了一些),但我从来没有真实地尝试直接去解释它在标准库设计过程中的影响。 -这些回复包括一些在更高级别的库中支持的临时(Provisional) API 的一些相关的沮丧的表述,这些库没有临时(Provisional)状态的传递,以及因此而被限制为只有最新版本的临时(Provisional) API 支持这些相关特性,而不是任何的早期迭代版本。 +如果没有这些背景,设计过程中的一部分,比如临时 API 的引入,或者是受启发而不同于它inspired-by-not-the-same-as的引入,看起来似乎是完全没有意义的,因为他们看起来似乎是在尝试对 API 进行标准化,而实际上并没有。 -我的 [主要反应][22] 是去建议,开源提供者应该努力加强他们需要的有限支持,以加强他们的维护工作的可持续性。这意味着,如果支持老版本的临时(Provisional) API 是非常痛苦的,然后,只有项目开发人员自己需要时,或者,有人为此支付费用时,他们才会去提供支持。这类似于我的观点,志愿者提供的项目是否应该免费支持老的商业的长周期支持的 Python 发行版,这对他们来说是非常麻烦的事,我[不认他们应该去做][23],正如我所期望的那样,大多数这样的需求都来自于管理差劲的习以为常的惯性,而不是真正的需求(真正的需求,它应该去支付费用来解决问题) +### 适合进入 PyPI 规划的方面有哪些? -然而,我的[第二个反应][24]是,去认识到这一点,尽管多年来一直在讨论这个问题(比如,在上面链接中 2011 的一篇年的文章中,以及在 Python 3 问答的回答中 [在这里][25]、[这里][26]、和[这里][27],和在去年的 [Python 包生态系统][28]上的一篇文章中的一小部分),我从来没有真实尝试直接去解释过它对标准库设计过程中的影响。 - -如果没有这些背景,设计过程中的一些方面,如临时(Provisional) API 的介绍,或者是受到不同的启发(inspired-by-not-the-same-as)的介绍,看起来似乎是很荒谬的,因为它们似乎是在试图标准化 API,而实际上并没有对 API 进行标准化。 - -### [适合进入 PyPI 规划的方面有哪些?][29] - -提交给 python-ideas 或 python-dev 的_任何_建议的第一个门槛就是,清楚地回答这个问题,“为什么 PyPI 上的一个模块不够好?”。绝大多数的建议都在这一步失败了,但通过他们得到了几个共同的主题: - -* 大多数新手可能经常是从互联网上去 “复制粘贴” 错误的建议,而不是去下载一个合适的第三方库。(比如,这就是为什么存在 `secrets` 库的原因:使得很少的人去使用 `random` 模块,因为安全敏感的原因,这是用于游戏和统计模拟的) - -* 这个模块是用于提供一个实现的参考,并去允许与其它的相互竞争的实现之间提供互操作性,而不是对所有人的所有事物都是必要的。(比如,`asyncio`、`wsgiref`、`unittest`、和 `logging` 全部都是这种情况) - -* 这个模块是用于标准库的其它部分(比如,`enum` 就是这种情况,像`unittest`一样) +提交给 python-ideas 或 python-dev 的_任何_建议所面临的第一个门槛就是清楚地回答这个问题:“为什么 PyPI 上的一个模块不够好?”。绝大多数的建议都在这一步失败了,为了通过这一步,这里有几个常见的话题: +* 与其去下载一个合适的第三方库,新手一般可能更倾向于从互联网上 “复制粘贴” 错误的指导。(比如,这就是为什么存在 `secrets` 库的原因:它使得人们很少去使用 `random` 模块,由于安全敏感的原因,它预期用于游戏和统计模拟的) +* 这个模块是打算去提供一个实现的参考,并允许与其它的相互竞争的实现之间提供互操作性,而不是对所有人的所有事物都是必要的。(比如,`asyncio`、`wsgiref`、`unittest`、和 `logging` 全部都是这种情况) +* 这个模块是预期用于标准库的其它部分(比如,`enum` 就是这种情况,像`unittest`一样) * 这个模块是被设计去支持语言之外的一些语法(比如,`contextlib`、`asyncio` 和 `typing` 模块,就是这种情况) +* 这个模块只是普通的临时的脚本用途(比如,`pathlib` 和 `ipaddress` 就是这种情况) +* 这个模块被用于一个教育环境(比如,`statistics` 模块允许进行交互式地探索统计的概念,尽管你可能根本就不会用它来做全部的统计分析) -* 这个模块只是普通的临时(ad hoc)脚本用途(比如,`pathlib` 和 `ipaddress` 就是这种情况) +通过前面的 “PyPI 是不是明显不够好” 的检查,一个模块还不足以确保被接收到标准库中,但它已经足以转变问题为 “在接下来的几年中,你所推荐的要包含的库能否对一般的入门级 Python 开发人员的经验有所提升?” -* 这个模块被用于一个教育环境(比如,`statistics` 模块允许进行交互式地探索统计的概念,尽管你不会用它来做全部的统计分析) +标准库中的 `ensurepip` 和 `venv` 模块的引入也明确地告诉再分发者,我们期望的 Python 级别的打包和安装工具在任何平台的特定分发机制中都予以支持。 -通过前面的 “PyPI 是不是明显不够好” 的检查,一个模块还不足以确保被接收到标准库中,但它已经足够转变问题为 “在接下来的几年中,你所推荐的要包含的库能否对一般的 Python 开发人员的经验有所改提升?” +### 当添加它们到标准库中时,为什么一些 API 会被改变? -标准库中的 `ensurepip` 和 `venv` 模块的介绍也明确地告诉分发者,我们期望的 Python 级别的打包和安装工具在任何平台的特定分发机制中都予以支持。 +现在已经存在的第三方模块有时候会被批量地采用到标准库中,在其它情况下,实际上添加的是吸收了用户对现有 API 体验之后,进行重新设计和重新实现的 API,但是,会根据另外的设计考虑和已经成为其中一部分的语言实现参考来进行一些删除或细节修改。 -### [当增加它到标准库中时,为什么一些 APIs 会被改变?][30] +例如,不像广受欢迎的第三方库的前身 `path.py`,`pathlib` 并_没有_定义字符串子类,而是以独立的类型替代。作为解决文件互操作性问题的结果,定义了文件系统路径协议,它允许使用文件系统路径的接口去使用更多的对象。 -现在已经存在的第三方模块有时候会被批量地采用到标准库中,在其它情况下,实际上增加进行的是重新设计和重新实现的 API,只是它参照了现有 API 的用户体验,但是,根据另外的设计参考,删除或修改了一些细节,和附属于语言参考实现部分的权限。 +为了在“IP 地址” 这个概念的教学上提供一个更好的工具,为 `ipaddress` 模块设计的 API,将地址和网络的定义调整为显式的、独立定义的主机接口(IP 地址被关联到特定的 IP 网络),而最原始的 `ipaddr` 模块中,在网络术语的使用方式上不那么严格。 -例如,不像广受欢迎的第三方库的前身 `path.py`,`pathlib` 并_不_规定字符串子类,而是独立的类型。作为解决文件互操作性问题的结果,是定义了文件系统路径协议,它允许与文件系统路径一起使用的接口,去使用更大范围的对象。 +另外的情况是,标准库将综合多种现有的方法的来构建,以及为早已存在的库定义 API 时,还有可能依靠不存在的语法特性。比如,`asyncio` 和 `typing` 模块就全部考虑了这些因素,虽然在 PEP 557 中正在考虑将后者所考虑的因素应用到 `dataclasses` API 上。(它可以被总结为 “像属性一样,但是使用可变注释作为字段声明”)。 -为 `ipaddress` 模块设计的 API 是为教学 IP 地址概念,从定义的地址和网络中,为显式的单独主机接口调整的(IP 地址关联到特定的 IP 网络),为了提供一个最佳的教学工具,而最原始的 “ipaddr” 模块中,使用网络术语的方式不那么严谨。 +这类改变的原理是,这类库不会消失,并且它们的维护者对标准库维护相关的那些限制通常并不感兴趣(特别是,相对缓慢的发行节奏)。在这种情况下,在标准库文档的更新版本中,很常见的做法是使用 “See Also” 链接指向原始模块,尤其是在第三方版本提供了额外的特性以及标准库模块中忽略的那些特性时。 -在其它情况下,标准库被构建为多种现有方法的一个综合,而且,还有可能依赖于定义现有库的 API 时不存在的特性。应用于 `asyncio` 和 `typing` 模块的所有的这些考虑,虽然后来考虑适用于 `dataclasses` 的 API 被认为是 PEP 557 (它可以被总结为 “像属性一样,但是使用变量注释作为字段声明”)。 +### 为什么一些 API 是以临时的形式被添加的? -这类改变的工作原理是,这类库不会消失,而且,它们的维护者经常并不关心与标准库相关的限制(特别是,相对缓慢的发行节奏)。在这种情况下,对于标准库版本的文档来说,使用 “See Also” 链接指向原始模块是很常见的,特别是,如果第三方版本提供了标准库模块中忽略的其他特性和灵活性时。 +虽然 CPython 维护了 API 的弃用策略,但在没有正当理由的情况下,我们通常不会去使用该策略(在其他项目试图与 Python 2.7 保持兼容性时,尤其如此)。 -### [为什么一些 API 是以临时(provisional)的形式被增加的?][31] +然而在实践中,当添加这种受已有的第三方启发而不是直接精确拷贝第三方设计的新 API 时,所承担的风险要高于一些正常设计决定可能出现问题的风险。 -虽然 CPython 确实设置了 API 的弃用策略,但我们通常不希望在没有令人信服的理由的情况下去使用它(在其他项目试图与 Python 2.7 保持兼容性时,尤其如此)。 +当我们考虑这种改变的风险比平常要高,我们将相关的 API 标记为临时,表示保守的终端用户要避免完全依赖它们,而共享抽象层的开发者可能希望,对他们准备去支持的那个临时 API 的版本,考虑实施比平时更严格的限制。 -然而,当增加一个受已有的第三方启发去设计的而不是去拷贝的新的 API 时,在设计实践中,有些设计实践可能会出现问题,这比平常的风险要高。 +### 为什么只有一些标准库 API 被升级? -当我们考虑这种改变的风险比平常要高,我们将相关的 API 标记为临时(provisional),表示保守的终端用户可以希望避免完全依赖他们,并且,共享抽象层的开发者可能希望考虑,对他们准备支持的临时(provisional) API 的版本实施比平时更严格的限制。 - -### [为什么只有一些标准库 APIs 被升级?][32] - -这里简短的回答升级的主要 APIs 有哪些?: - -* 不适合外部因素驱动的补充更新 - -* 无论是临时(ad hoc)脚本使用情况,还是为促进将来的多个第三方解决方案之间的互操作性,都有明显好外的 +这里简短的回答得到升级的主要 API 有哪些?: +* 不太可能有大量的外部因素干扰的附加更新 +* 无论是对临时脚本使用案例还是对促进将来多个第三方解决方案之间的互操作性,都有明显好处的 * 对这方面感兴趣的人提交了一个可接受的建议 -如果一个用于应用程序开发的模块存在一个非常明显的限制(limitations),比如,`datetime`,如果重分发版通过替代一个现成的第三方模块有所改善,比如,`requests`,或者,如果标准库的发布节奏与需要的有问题的包之间有真正的冲突,比如,`certifi`,那么,计划对标准库版本进行改变的因素将显著减少。 +如果一个用于应用程序开发的模块存在一个非常明显的限制,比如,`datetime`,如果重分发者通过可供替代的第三方选择很容易地实现了改善,比如,`requests`,或者,如果标准库的发布节奏与所需要的包之间真的存在冲突,比如,`certifi`,那么,建议对标准库版本进行改变的因素将显著减少。 -从本质上说,这和关于 PyPI 上面的问题是相反的:因为,PyPI 分发机制对增强应用程序开发人员经验来说,通常_是_足够好的,这样的改进是有意义的,允许重分发者和平台提供者自行决定将哪些内容作为缺省提供的一部分。 +从本质上说,这和上面的关于 PyPI 问题正好相反:因为,从应用程序开发人员体验改善的角度来说,PyPI 分发机制通常_是_足够好的,这种分发方式的改进是有意义的,允许重分发者和平台提供者自行决定将哪些内容作为他们缺省提供的一部分。 -当改变后的能力(capabilities)假设在 3-5 年内缺省出现时被认为是有价值的,才会将这些改变进入到 CPython 和标准库中。 +假设在 3-5 年时间内,缺省出现了被认为是改变带来的可感知的价值时,才会将这些改变纳入到 CPython 和标准库中。 -### [标准库任何部分都有独立的版本吗?][33] +### 标准库任何部分都有独立的版本吗? -是的,它就像是 `ensurepip` 使用的捆绑模式( CPython 发行了一个 `pip` 的最新捆绑版本,而并没有把它放进标准库中),将来可能被应用到其它模块中。 +是的,它就像是 `ensurepip` 使用的捆绑模式(CPython 发行了一个 `pip` 的最新捆绑版本,而并没有把它放进标准库中),将来可能被应用到其它模块中。 最有可能的第一个候选者是 `distutils` 构建系统,因为切换到这种模式将允许构建系统在多个发行版本之间保持一致。 -这种处理方式的其它可能的候选对象是 Tcl/Tk graphics 捆绑和 IDLE 编辑器,它们已经被拆分,并且通过一些重分发程序转换成安装可选项。 +这种处理方式的其它的可能候选者是 Tcl/Tk 图形捆绑和 IDLE 编辑器,它们已经被拆分,并且通过一些重分发程序转换成可选安装项。 -### [这些注意事项为什么很重要?][34] +### 这些注意事项为什么很重要? 从本质上说,那些积极参与开源开发的人就是那些致力于开源应用程序和共享抽象层的人。 -写一些临时(ad hoc)脚本和为学生设计一些教学习题的人,通常不会认为他们是软件开发人员 —— 他们是教师、系统管理员、数据分析人员、金融工程师、流行病学家、物理学家、生物学家、商业分析师、动画师、架构设计师、等等。 +那些写一些临时脚本或为学生设计一些教学习题的人,通常不认为他们是软件开发人员 —— 他们是教师、系统管理员、数据分析人员、金融工程师、流行病学家、物理学家、生物学家、商业分析师、动画师、架构设计师等等。 -当所有我们的担心是,语言是开发人员的经验时,那么,我们可以简单假设人们知道一些什么,他们使用的工具,所遵循的开发流程,以及构建和部署他们软件的方法。 +对于一种语言,当我们全部的担心都是开发人员的经验时,那么我们就可以根据人们所知道的内容、他们使用的工具种类、他们所遵循的开发流程种类、构建和部署他们软件的方法等假定,来做大量的简化。 -当一个应用程序运行时(runtime),_也_作为一个脚本引擎广为流行时,事情将变的更加复杂。在一个项目中去平衡两种需求,就会导致双方的不理解和怀疑,做任何一件事都将变得很困难。 +当一个应用程序运行时(runtime),_也_作为一个脚本引擎广为流行时,事情将变的更加复杂。在同一个项目中去平衡两种受众的需求,将就会导致双方的不理解和怀疑,做任何一件事都将变得很困难。 -这篇文章不是为了说,我们在开发 CPython 过程中从来没有做出过不正确的决定 —— 它只是指出添加到 Python 标准库中的看上去很荒谬的特性的最合理的反应(reaction),它将是 “我不是那个特性的预期目标受众的一部分”,而不是 “我对它没有兴趣,因此,它对所有人都是毫无用处和没有价值的,添加它纯属骚扰我”。 +这篇文章不是为了说,我们在开发 CPython 过程中从来没有做出过不正确的决定 —— 它只是去合理地回应那些对添加到 Python 标准库中的看上去很荒谬的特性的质疑,它将是 “我不是那个特性的预期目标受众的一部分”,而不是 “我对它没有兴趣,因此它对所有人都是毫无用处和没有价值的,添加它纯属骚扰我”。 -------------------------------------------------------------------------------- via: http://www.curiousefficiency.org/posts/2017/10/considering-pythons-target-audience.html -作者:[Nick Coghlan ][a] +作者:[Nick Coghlan][a] 译者:[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/) 荣誉推出 diff --git a/translated/tech/20171130 Google launches TensorFlow-based vision recognition kit for RPi Zero W.md b/translated/tech/20171130 Google launches TensorFlow-based vision recognition kit for RPi Zero W.md new file mode 100644 index 0000000000..d95961e949 --- /dev/null +++ b/translated/tech/20171130 Google launches TensorFlow-based vision recognition kit for RPi Zero W.md @@ -0,0 +1,85 @@ +# [Google 为树莓派 Zero W 发布了基于TensorFlow 的视觉识别套件][26] + + +![](http://linuxgizmos.com/files/google_aiyvisionkit-thm.jpg) +Google 发行了一个 45 美元的 “AIY Vision Kit”,它是运行在树莓派 Zero W 上的基于 TensorFlow 的视觉识别开发套件,它使用了一个带 Movidius 芯片的 “VisionBonnet” 板。 + +为加速设备上的神经网络,Google 的 AIY 视频套件继承了早期树莓派上运行的 [AIY 项目][7] 的语音/AI 套件,这个型号的树莓派随五月份的 MagPi 杂志一起赠送。与语音套件和老的 Google 硬纸板 VR 查看器一样,这个新的 AIY 视觉套件也使用一个硬纸板包装。这个套件和 [Cloud Vision API][8] 是不一样的,它使用了一个在 2015 年演示过的基于树莓派的 GoPiGo 机器人,它完全在本地的处理能力上运行,而不需要使用一个云端连接。这个 AIY 视觉套件现在可以 45 美元的价格去预订,将在 12 月份发货。 + + + [![](http://linuxgizmos.com/files/google_aiyvisionkit-sm.jpg)][9]   [![](http://linuxgizmos.com/files/rpi_zerow-sm.jpg)][10] +**AIY 视觉套件,完整包装(左)和树莓派 Zero W** +(点击图片放大) + + +这个套件的主要处理部分除了所需要的 [树莓派 Zero W][21] 单片机之外 —— 一个基于 ARM11 的 1 GHz 的 Broadcom BCM2836 片上系统,另外的就是 Google 最新的 VisionBonnet RPi 附件板。这个 VisionBonnet pHAT 附件板使用了一个 Movidius MA2450,它是 [Movidius Myriad 2 VPU][22] 版的处理器。在 VisionBonnet 上,处理器为神经网络运行了 Google 的开源机器学习库 [TensorFlow][23]。因为这个芯片,便得视觉处理的速度最高达每秒 30 帧。 + +这个 AIY 视觉套件要求用户提供一个树莓派 Zero W、一个 [树莓派摄像机 v2][11]、以及一个 16GB 的 micro SD 卡,它用来下载基于 Linux 的 OS 镜像。这个套件包含了 VisionBonnet、一个 RGB 街机风格的按钮、一个压电扬声器、一个广角镜头套件、以及一个包裹它们的硬纸板。还有一些就是线缆、支架、安装螺母、以及连接部件。 + + + [![](http://linuxgizmos.com/files/google_aiyvisionkit_pieces-sm.jpg)][12]   [![](http://linuxgizmos.com/files/google_visionbonnet-sm.jpg)][13] +**AIY 视觉套件组件(左)和 VisonBonnet 附件板** +(点击图片放大) + + +有三个可用的神经网络模型。一个是通用的模型,它可以识别常见的 1,000 个东西,一个是面部检测模型,它可以对 “快乐程度” 进行评分,从 “悲伤” 到 “大笑”,还有一个模型可以用来辨别图像内容是狗、猫、还是人。这个 1,000-image 模型源自 Google 的开源 [MobileNets][24],它是基于 TensorFlow 家族的计算机视觉模型,它设计用于资源受限的移动或者嵌入式设备。 + +MobileNet 模型是低延时、低功耗,和参数化的,以满足资源受限的不同使用案例。Google 说,这个模型可以用于构建分类、检测、嵌入、以及分隔。在本月的早些时候,Google 发布了一个开发者预览版,它是一个对 Android 和 iOS 移动设备友好的 [TensorFlow Lite][14] 库,它与 MobileNets 和 Android 神经网络 API 是兼容的。 + + + [![](http://linuxgizmos.com/files/google_aiyvisionkit_assembly-sm.jpg)][15] +**AIY 视觉套件包装图** +(点击图像放大) + + +除了提供这三个模型之外,AIY 视觉套件还提供了基本的 TensorFlow 代码和一个编译器,因此用户可以去开发自己的模型。另外,Python 开发者可以写一些新软件去定制 RGB 按钮颜色、压电元素声音、以及在 VisionBonnet 上的 4x GPIO 针脚,它可以添加另外的指示灯、按钮、或者伺服机构。Potential 模型包括识别食物、基于可视化输入来打开一个狗门、当你的汽车偏离车道时发出文本信息、或者根据识别到的人的面部表情来播放特定的音乐。 + + + [![](http://linuxgizmos.com/files/movidius_myriad2vpu_block-sm.jpg)][16]   [![](http://linuxgizmos.com/files/movidius_myriad2_reference_board-sm.jpg)][17] +**Myriad 2 VPU 结构图(左)和参考板** +(点击图像放大) + + +Movidius Myriad 2 处理器在一个标称 1W 的功耗下提供每秒万亿次浮点运算的性能。在被 Intel 收购之前,这个芯片最早出现在 Tango 项目的参考平台上,并内置在 2016 年 5 月由 Movidius 首次亮相的、Ubuntu 驱动的 USB 的 [Fathom][25] 神经网络处理棒中。根据 Movidius 的说法,Myriad 2 目前已经在 “市场上数百万的设备上使用”。 + +**更多信息** + +AIY 视觉套件可以在 Micro Center 上预订,价格为 $44.99,预计在 12 月初发货。更多信息请参考 AIY 视觉套件的 [公告][18]、[Google 博客][19]、以及 [Micro Center 购物页面][20]。 + +-------------------------------------------------------------------------------- + +via: http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ + +作者:[ Eric Brown][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ +[1]:http://twitter.com/share?url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/&text=Google%20launches%20TensorFlow-based%20vision%20recognition%20kit%20for%20RPi%20Zero%20W%20 +[2]:https://plus.google.com/share?url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ +[3]:http://www.facebook.com/sharer.php?u=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ +[4]:http://www.linkedin.com/shareArticle?mini=true&url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ +[5]:http://reddit.com/submit?url=http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/&title=Google%20launches%20TensorFlow-based%20vision%20recognition%20kit%20for%20RPi%20Zero%20W +[6]:mailto:?subject=Google%20launches%20TensorFlow-based%20vision%20recognition%20kit%20for%20RPi%20Zero%20W&body=%20http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ +[7]:http://linuxgizmos.com/free-raspberry-pi-voice-kit-taps-google-assistant-sdk/ +[8]:http://linuxgizmos.com/google-releases-cloud-vision-api-with-demo-for-pi-based-robot/ +[9]:http://linuxgizmos.com/files/google_aiyvisionkit.jpg +[10]:http://linuxgizmos.com/files/rpi_zerow.jpg +[11]:http://linuxgizmos.com/raspberry-pi-cameras-jump-to-8mp-keep-25-dollar-price/ +[12]:http://linuxgizmos.com/files/google_aiyvisionkit_pieces.jpg +[13]:http://linuxgizmos.com/files/google_visionbonnet.jpg +[14]:https://developers.googleblog.com/2017/11/announcing-tensorflow-lite.html +[15]:http://linuxgizmos.com/files/google_aiyvisionkit_assembly.jpg +[16]:http://linuxgizmos.com/files/movidius_myriad2vpu_block.jpg +[17]:http://linuxgizmos.com/files/movidius_myriad2_reference_board.jpg +[18]:https://blog.google/topics/machine-learning/introducing-aiy-vision-kit-make-devices-see/ +[19]:https://developers.googleblog.com/2017/11/introducing-aiy-vision-kit-add-computer.html +[20]:http://www.microcenter.com/site/content/Google_AIY.aspx?ekw=aiy&rd=1 +[21]:http://linuxgizmos.com/raspberry-pi-zero-w-adds-wifi-and-bluetooth-for-only-5-more/ +[22]:https://www.movidius.com/solutions/vision-processing-unit +[23]:https://www.tensorflow.org/ +[24]:https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html +[25]:http://linuxgizmos.com/usb-stick-brings-neural-computing-functions-to-devices/ +[26]:http://linuxgizmos.com/google-launches-tensorflow-based-vision-recognition-kit-for-rpi-zero-w/ diff --git a/translated/tech/20180226 Linux Virtual Machines vs Linux Live Images.md b/translated/tech/20180226 Linux Virtual Machines vs Linux Live Images.md new file mode 100644 index 0000000000..9b927bb348 --- /dev/null +++ b/translated/tech/20180226 Linux Virtual Machines vs Linux Live Images.md @@ -0,0 +1,66 @@ +## sober-wang 翻译中 + +Linux Virtual Machines vs Linux Live Images +Linxu 虚拟机 vs Linux 实体机 +====== +I'll be the first to admit(认可) that I tend(照顾) to try out new [Linux distros(发行版本)][1] on a far(远) too frequent(频繁) basis. Yet the method(方法) I use to test them, does vary depending(依赖) on my goals(目标) for each instance(每一个). In this article(文章), we're going to look at both(两个) running Linux virtual machines and running Linux live images. There are advantages(优势/促进/有利于) to each method(方法), but there are some hurdles(障碍) with each method(方法/函数) as well(同样的). + +首先我得承认,我非常倾向于频繁尝试新的[ linux 发行版本 ][1],我的目标是为了解决每一个 Linux 发行版的依赖,所以我用一些方法来测试它们。在一些文章中,我们将会看到两种运行 Linux 的模式,虚拟机或实体机。每一种方式都存在优势,但是有一些障碍会伴随着这两种方式。 + +### Testing out a new Linux distro for the first time +### 第一时间测试一个新的 Linux 发行版 + +When I test out a brand new Linux distro for the first time, the method I use depends heavily(沉重的) on the resources(资源) of the PC I'm currently(目前的) on. If I have access to my desktop PC, I'm going to run the distro to be tested in a virtual machine. The reason(理由) for this approach(靠近) is that I can download and test the distro in not only a live environment(环境), but also(也) as an installed product with persistent(稳定的) storage abilities(能力). + +为了第一时间去做 Linux 发型版本的依赖测试,我把它们运行在我目前所拥有的所有类型的 PC 上。如果我用我的台式机,我将运行一个 Linux 虚拟机做测试。 + +On the other hand, if I am working with much less robust hardware on a PC, then testing out a distro with a virtual machine installation of Linux is counter-productive. I'd be pushing that PC to its limits and honestly would be better off using a live Linux image instead running from a flash drive. + +### Touring software on a new Linux distro + +If you're interested in checking out a distro's desktop environment or the available software, you can't go wrong with a live image of the distro. A live environment provides you with a birds eye view of what to expect in terms of overall layout, applications provided and how the user experience flows overall. + +To be fair, you could do the same thing with a virtual machine installation, but it may be a bit overkill if you would rather avoid filling up hard drive space with yet more data. After all, this is a simple tour of the distro. Remember what I said in the first section – I like to run Linux in a virtual machine to test it. This means I'm going to see how it installs, what the partition options look like and other elements you wouldn't see from using a live image of any given distro. + +Touring usually indicates that you're only looking to take a quick look at a distro, so in this case the method that can be done with the least amount of resistance and time investment is a good course of action. + +### Taking a Linux distro with you + +While it's not as common as it was a few years ago, the ability to take a Linux distro with you may be a consideration for some users. Obviously, virtual machine installations don't necessarily lend themselves favorably to portability. However a live image of a Linux distro is actually quite portable. A live image can be written to a DVD or copied onto a flash drive for easy traveling. + +Expanding on this concept of Linux portability, it's also beneficial to have a live image on a flash drive when showing off how Linux works on a friend's computer. This empowers you to demonstrate how Linux can enrich their life while not relying on running a virtual machine on their PC. It's a bit of a win-win in favor of using a live image. + +### Alternative to dual-booting Linux + +This next item is a huge one. Consider this – perhaps you're a Windows user. You like playing with Linux, but would rather not take the plunge. Dual-booting is out of the question in case something goes wrong or perhaps you're not comfortable identifying individual partitions. Whatever the case may be, both using Linux in a virtual machine or from a live image might be a great option for you. + +Now I'm going to take a rather odd stance on something. I think you'll get far more value in the long term running Linux on a flash drive using a live image than with a virtual machine. There are two reasons for this. First of all, you'll get used to truly running Linux vs running it inside of a virtual machine on top of Windows. Second, you can setup your flash drive to contain user data with persistent storage. + +I'll grant you the same could be said with a virtual machine running Linux, however you will never have an update break anything using the live image approach. Why? Because you're not updating a host OS or the guest OS. Remember there are entire distros that are designed to be nothing more than persistent storage Linux distros. Puppy Linux is one great example. Not only can it run on PCs that would otherwise be recycled or thrown away, it allows you to never be bothered again with tedious system updates thanks to the way the distro handles security. It's not a normal Linux distro and it's walled off in such a way that the persistent live image is free from anything scary. + +### When a Linux virtual machine is absolutely the best option + +As I bring this article to a close, let me leave you with this. There is one instance where using a virtual machine such as Virtual Box is absolutely better than using a live image – recording the desktop environment of any Linux distro. + +For example, I make videos that provide a tour and review of a variety of Linux distros. Doing this with live images would require me to capture the screen with a hardware device or install a software capture device from the live image's repositories. Clearly, a virtual machine is better suited for this job than a live image of a Linux distro. + +Once you toss audio capture into the mix, there is no question that if you're going to use software to capture your review, you really want to have a host OS that has all the basic needs covered for a reasonably decent capture environment. Again, you could do all of this with a hardware device...but that might be cost prohibitive if you're only do video/audio capturing as a part time endeavor. + +### A Linux virtual machine vs a Linux live image + +What is your preferred method of trying out new distros? Perhaps you're someone who is fine with formatting their hard drive and throwing caution to the wind, thus, making the idea of any of this unneeded? + +Most people I've interacted with online tend to follow much of the methodology I've touched on above, but I'd love to hear what approach works best for you. Hit the comments, let me know which method you prefer when checking out the greatest and latest from the Linux distro world. + +-------------------------------------------------------------------------------- + +via: https://www.datamation.com/open-source/linux-virtual-machines-vs-linux-live-images.html + +作者:[Matt Hartley][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.datamation.com/author/Matt-Hartley-3080.html +[1]:https://www.datamation.com/open-source/best-linux-distro.html diff --git a/translated/tech/20180306 How to apply Machine Learning to IoT using Android Things and TensorFlow.md b/translated/tech/20180306 How to apply Machine Learning to IoT using Android Things and TensorFlow.md index 6905e64f39..0e31bc266b 100644 --- a/translated/tech/20180306 How to apply Machine Learning to IoT using Android Things and TensorFlow.md +++ b/translated/tech/20180306 How to apply Machine Learning to IoT using Android Things and TensorFlow.md @@ -1,30 +1,32 @@ 如何使用 Android Things 和 TensorFlow 在物联网上应用机器学习 ============================================================  +![](https://www.survivingwithandroid.com/wp-content/uploads/2018/03/Apply_Machine_Learning_to_IoT.png) + +> 探索如何将 Android Things 与 Tensorflow 集成起来,以及如何应用机器学习到物联网系统上。学习如何在装有 Android Things 的树莓派上使用 Tensorflow 进行图片分类。 + 这个项目探索了如何将机器学习应用到物联网上。具体来说,物联网平台我们将使用 **Android Things**,而机器学习引擎我们将使用 **Google TensorFlow**。 -![Machine Learning with Android Things](https://www.survivingwithandroid.com/wp-content/uploads/2018/03/machine_learning_android_things.png) +现如今,Android Things 处于名为 Android Things 1.0 的稳定版本,已经可以用在生产系统中了。如你可能已经知道的,树莓派是一个可以支持 Android Things 1.0 做开发和原型设计的平台。本教程将使用 Android Things 1.0 和树莓派,当然,你可以无需修改代码就能换到其它所支持的平台上。这个教程是关于如何将机器学习应用到物联网的,这个物联网平台就是 Android Things Raspberry Pi。 -现如今,机器学习是物联网上使用的最热门的主题之一。给机器学习的最简单的定义,可能就是 [维基百科上的定义][13]:机器学习是计算机科学中,让计算机不需要显式编程就能去“学习”(即,逐步提升在特定任务上的性能)使用数据的一个领域。 +物联网上的机器学习是最热门的话题之一。要给机器学习一个最简单的定义,可能就是 [维基百科上的定义][13]: -换句话说就是,经过训练之后,那怕是它没有针对它们进行特定的编程,这个系统也能够预测结果。另一方面,我们都知道物联网和联网设备的概念。其中一个前景看好的领域就是如何在物联网上应用机器学习,构建专业的系统,这样就能够去开发一个能够“学习”的系统。此外,还可以使用这些知识去控制和管理物理对象。 +> 机器学习是计算机科学中,让计算机不需要显式编程就能去“学习”(即,逐步提升在特定任务上的性能)使用数据的一个领域。 -这里有几个应用机器学习和物联网产生重要价值的领域,以下仅提到了几个感兴趣的领域,它们是: +换句话说就是,经过训练之后,那怕是它没有针对它们进行特定的编程,这个系统也能够预测结果。另一方面,我们都知道物联网和联网设备的概念。其中前景最看好的领域之一就是如何在物联网上应用机器学习,构建专家系统,这样就能够去开发一个能够“学习”的系统。此外,还可以使用这些知识去控制和管理物理对象。在深入了解 Android Things 的细节之前,你应该先将其安装在你的设备上。如果你是第一次使用 Android Things,你可以阅读一下这篇[如何在你的设备上安装 Android Things][14] 的教程。 + +这里有几个应用机器学习和物联网产生重要价值的领域,以下仅提到了几个有趣的领域,它们是: * 在工业物联网(IIoT)中的预见性维护 - * 消费物联网中,机器学习可以让设备更智能,它通过调整使设备更适应我们的习惯 -在本教程中,我们希望去探索如何使用 Android Things 和 TensorFlow 在物联网上应用机器学习。这个 Adnroid Things 物联网项目的基本想法是,探索如何去*构建一个能够识别前方道路上基本形状(比如箭头)的无人驾驶汽车*。我们已经介绍了 [如何使用 Android Things 去构建一个无人驾驶汽车][5],因此,在开始这个项目之前,我们建议你去阅读那个教程。 +在本教程中,我们希望去探索如何使用 Android Things 和 TensorFlow 在物联网上应用机器学习。这个 Adnroid Things 物联网项目的基本想法是,探索如何去*构建一个能够识别前方道路上基本形状(比如箭头)并控制其道路方向的无人驾驶汽车*。我们已经介绍了 [如何使用 Android Things 去构建一个无人驾驶汽车][5],因此,在开始这个项目之前,我们建议你去阅读那个教程。 这个机器学习和物联网项目包含如下的主题: * 如何使用 Docker 配置 TensorFlow 环境 - * 如何训练 TensorFlow 系统 - * 如何使用 Android Things 去集成 TensorFlow - * 如何使用 TensorFlow 的成果去控制无人驾驶汽车 这个项目起源于 [Android Things TensorFlow 图像分类器][6]。 @@ -33,59 +35,55 @@ ### 如何使用 Tensorflow 图像识别 -在开始之前,需要安装和配置 TensorFlow 环境。我不是机器学习方面的专家,因此,我需要快速找到并且准备去使用一些东西,因此,我们可以构建 TensorFlow 图像识别器。为此,我们使用 Docker 去运行一个 TensorFlow 镜像。以下是操作步骤: +在开始之前,需要安装和配置 TensorFlow 环境。我不是机器学习方面的专家,因此,我需要找到一些快速而能用的东西,以便我们可以构建 TensorFlow 图像识别器。为此,我们使用 Docker 去运行一个 TensorFlow 镜像。以下是操作步骤: -1. 克隆 TensorFlow 仓库: - ``` - git clone https://github.com/tensorflow/tensorflow.git - cd /tensorflow - git checkout v1.5.0 - ``` +1、 克隆 TensorFlow 仓库: -2. 创建一个目录(`/tf-data`),它将用于保存这个项目中使用的所有文件。 +``` +git clone https://github.com/tensorflow/tensorflow.git +cd /tensorflow +git checkout v1.5.0 +``` -3. 运行 Docker: - ``` - docker run -it \ - --volume /tf-data:/tf-data \ - --volume /tensorflow:/tensorflow \ - --workdir /tensorflow tensorflow/tensorflow:1.5.0 bash - ``` +2、 创建一个目录(`/tf-data`),它将用于保存这个项目中使用的所有文件。 - 使用这个命令,我们运行一个交互式 TensorFlow 环境,可以在使用项目期间挂载一些目录。 +3、 运行 Docker: + +``` +docker run -it \ +--volume /tf-data:/tf-data \ +--volume /tensorflow:/tensorflow \ +--workdir /tensorflow tensorflow/tensorflow:1.5.0 bash +``` + +使用这个命令,我们运行一个交互式 TensorFlow 环境,可以挂载一些在使用项目期间使用的目录。 ### 如何训练 TensorFlow 去识别图像 在 Android Things 系统能够识别图像之前,我们需要去训练 TensorFlow 引擎,以使它能够构建它的模型。为此,我们需要去收集一些图像。正如前面所言,我们需要使用箭头来控制 Android Things 无人驾驶汽车,因此,我们至少要收集四种类型的箭头: * 向上的箭头 - * 向下的箭头 - * 向左的箭头 - * 向右的箭头 为训练这个系统,需要使用这四类不同的图像去创建一个“知识库”。在 `/tf-data` 目录下创建一个名为 `images` 的目录,然后在它下面创建如下名字的四个子目录: -* up-arrow - -* down-arrow - -* left-arrow - -* right-arrow +* `up-arrow` +* `down-arrow` +* `left-arrow` +* `right-arrow` 现在,我们去找图片。我使用的是 Google 图片搜索,你也可以使用其它的方法。为了简化图片下载过程,你可以安装一个 Chrome 下载插件,这样你只需要点击就可以下载选定的图片。别忘了多下载一些图片,这样训练效果更好,当然,这样创建模型的时间也会相应增加。 **扩展阅读** -[如何使用 API 去集成 Android Things][2] -[如何与 Firebase 一起使用 Android Things][3] + +- [如何使用 API 去集成 Android Things][2] +- [如何与 Firebase 一起使用 Android Things][3] 打开浏览器,开始去查找四种箭头的图片: ![TensorFlow image classifier](https://www.survivingwithandroid.com/wp-content/uploads/2018/03/TensorFlow-image-classifier.png) -[Save][7] 每个类别我下载了 80 张图片。不用管图片文件的扩展名。 @@ -102,9 +100,8 @@ python /tensorflow/examples/image_retraining/retrain.py \ 这个过程你需要耐心等待,它需要花费很长时间。结束之后,你将在 `/tf-data` 目录下发现如下的两个文件: -1. retrained_graph.pb - -2. retrained_labels.txt +1. `retrained_graph.pb` +2. `retrained_labels.txt` 第一个文件包含了 TensorFlow 训练过程产生的结果模型,而第二个文件包含了我们的四个图片类相关的标签。 @@ -139,7 +136,6 @@ python /tensorflow/python/tools/optimize_for_inference.py \ TensorFlow 的数据模型准备就绪之后,我们继续下一步:如何将 Android Things 与 TensorFlow 集成到一起。为此,我们将这个任务分为两步来完成: 1. 硬件部分,我们将把电机和其它部件连接到 Android Things 开发板上 - 2. 实现这个应用程序 ### Android Things 示意图 @@ -147,13 +143,9 @@ TensorFlow 的数据模型准备就绪之后,我们继续下一步:如何将 在深入到如何连接外围部件之前,先列出在这个 Android Things 项目中使用到的组件清单: 1. Android Things 开发板(树莓派 3) - 2. 树莓派摄像头 - 3. 一个 LED 灯 - 4. LN298N 双 H 桥电机驱动模块(连接控制电机) - 5. 一个带两个轮子的无人驾驶汽车底盘 我不再重复 [如何使用 Android Things 去控制电机][9] 了,因为在以前的文章中已经讲过了。 @@ -161,12 +153,10 @@ TensorFlow 的数据模型准备就绪之后,我们继续下一步:如何将 下面是示意图: ![Integrating Android Things with IoT](https://www.survivingwithandroid.com/wp-content/uploads/2018/03/tensor_bb.png) -[Save][10] 上图中没有展示摄像头。最终成果如下图: ![Integrating Android Things with TensorFlow](https://www.survivingwithandroid.com/wp-content/uploads/2018/03/android_things_with_tensorflow-min.jpg) -[Save][11] ### 使用 TensorFlow 实现 Android Things 应用程序 @@ -175,11 +165,8 @@ TensorFlow 的数据模型准备就绪之后,我们继续下一步:如何将 这个 Android Things 应用程序与原始的应用程序是不一样的,因为: 1. 它不使用按钮去开启摄像头图像捕获 - 2. 它使用了不同的模型 - 3. 它使用一个闪烁的 LED 灯来提示,摄像头将在 LED 停止闪烁后拍照 - 4. 当 TensorFlow 检测到图像时(箭头)它将控制电机。此外,在第 3 步的循环开始之前,它将打开电机 5 秒钟。 为了让 LED 闪烁,使用如下的代码: @@ -264,7 +251,7 @@ public void onImageAvailable(ImageReader reader) { 在这个方法中,当 TensorFlow 返回捕获的图片匹配到的可能的标签之后,应用程序将比较这个结果与可能的方向,并因此来控制电机。 -最后,将去使用前面创建的模型了。拷贝 _assets_ 文件夹下的 `opt_graph.pb` 和 `reatrained_labels.txt` 去替换现在的文件。 +最后,将去使用前面创建的模型了。拷贝 `assets` 文件夹下的 `opt_graph.pb` 和 `reatrained_labels.txt` 去替换现在的文件。 打开 `Helper.java` 并修改如下的行: @@ -289,9 +276,9 @@ public static final String OUTPUT_NAME = "final_result"; via: https://www.survivingwithandroid.com/2018/03/apply-machine-learning-iot-using-android-things-tensorflow.html -作者:[Francesco Azzola ][a] +作者:[Francesco Azzola][a] 译者:[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/) 荣誉推出 @@ -309,3 +296,4 @@ via: https://www.survivingwithandroid.com/2018/03/apply-machine-learning-iot-usi [11]:http://pinterest.com/pin/create/bookmarklet/?media=data:image/gif;base64,R0lGODdhAQABAPAAAP///wAAACwAAAAAAQABAEACAkQBADs=&url=https://www.survivingwithandroid.com/2018/03/apply-machine-learning-iot-using-android-things-tensorflow.html&is_video=false&description=Integrating%20Android%20Things%20with%20TensorFlow [12]:https://github.com/androidthings/sample-tensorflow-imageclassifier [13]:https://en.wikipedia.org/wiki/Machine_learning +[14]:https://www.survivingwithandroid.com/2017/01/android-things-android-internet-of-things.html \ No newline at end of file diff --git a/translated/tech/20180320 Migrating to Linux- Installing Software.md b/translated/tech/20180320 Migrating to Linux- Installing Software.md deleted file mode 100644 index 68a9939a9d..0000000000 --- a/translated/tech/20180320 Migrating to Linux- Installing Software.md +++ /dev/null @@ -1,85 +0,0 @@ -迁移到 Linux 之安装软件 -===== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/birds-1835510_1920.jpg?itok=8i6mBStG) -你看到的所有有关 Linux 的关注,以及它在互联网,以及 Arduino, Beagle 和 Raspberry Pi boards(树莓派板)等设备上的使用,或许你正在考虑是时候尝试一下 Linux 了。本系列将帮助你成功过渡到 Linux。如果你错过了本系列的早期文章,可以在这里找到它们: - -[Part 1 - 介绍][1] - -[Part 2 - 磁盘、文件和文件系统][2] - -[Part 3 - 图形界面][3] - -[Part 4 - 命令行][4] - -[Part 5 - 使用 sudo][5] - -### 安装软件 - -要在你的计算机上获得新软件,通常的方法是从供应商处获得软件产品,然后运行一个安装程序。过去,软件产品会像 CD-ROM 或 DVD 一样出现在物理媒介上。而现在我们经常从网上下载软件产品。 - -使用 Linux,安装软件就像在你的智能手机上安装一样。就像去你的手机应用商店一样,在 Linux 上有个开源软件工具和程序的中央仓库,几乎任何你可能想要的程序都会在你可安装的可用软件包列表中。 - -没有为每个程序运行的单独安装程序。相反,你可以使用 Linux 发行版附带的软件包管理工具。(请记住,Linux 发行版是你安装的 Linux,例如 Ubuntu, Fedora, Debian 等)每个发行版在 Internet 上都有自己的集中位置(称为仓库),用于存储数千个预先安装的应用程序。 - -你可能会注意到,在 Linux 上安装软件有几个例外。有时候,你仍然需要去供应商处获取他们的软件,因为该程序不存在于你发行版的中央仓库中。当软件不是开源和/或免费(自由)的时候,通常就是这种情况。 - -另外请记住,如果你最终想要安装一个不在发行版仓库中的程序,事情就不是那么简单了,即使你正在安装免费(自由)和开源程序。这篇文章没有涉及到这些更复杂的情况,最好遵循在线引导。 - -有了所有的 Linux 包管理系统和工具,接下来干什么可能仍然令人困惑。本文应该有助于澄清一些事情。 - -### 包管理 - -一些用于管理、安装和删除软件的包管理系统在 Linux 发行版中竞争。那个发行版背后的人都选择一个包管理系统来使用。Red Hat, Fedora, CentOS, Scientific Linux, SUSE 等使用 Red Hat 包管理(RPM)。Debian, Ubuntu, Linux Mint 等等都使用 Debian 包管理系统,简称 DPKG。其他包管理系统也存在,但 RPM 和 DPKG 是最常见的。 - -![](https://www.linux.com/sites/lcom/files/styles/floated_images/public/package-installer.png?itok=V9OU1Q0u) -图 1: Package installers - -无论你使用的软件包管理是什么,它们通常都附带一组工具,它们是分层的(图 1)。最底层是一个命令行工具,它可以让你做任何事情以及与安装软件相关的一切。你可以列出已安装的程序,删除程序,安装软件包文件等等。 - -这个底层工具并不总是最方便使用的,所以通常会有一个命令行工具,它可以在发行版的中央仓库中找到软件包,并使用单个命令下载和安装它以及任何依赖项。最后,通常会有一个图形应用程序,让你使用鼠标选择任何想要的内容,然后单击 “install” 按钮。 -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/package-kit.png?itok=YimOq2Je) -图 2: PackageKit - -对于基于 Red Hat 的发行版,包括 Fedora, CentOS, Scientific Linux 等。它们的底层工具是 rpm,高级工具叫做 dnf(在旧系统上是 yum)。图形安装程序称为 PackageKit(图 2),它可能在系统管理下显示为 “Add/Remove Software(添加/删除软件)”。 -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu-software.png?itok=5QSctLEW) -图 3: Ubuntu Software - -对于基于 Debian 的发行版,包括 Debian, Ubuntu, Linux Mint, Elementary OS 等。它们的底层命令行工具是 dpkg,高级工具称为 apt。在 Ubuntu 上管理已安装软件的图形工具是 Ubuntu Software(图 3)。对于 Debian 和 Linux Mint,图形工具称为 Synaptic,它也可以安装在 Ubuntu 上。 - -你也可以在 Debian 相关发行版上安装基于文本的图形工具 aptitude。它比 Synaptic(新立得)更强大,并且即使你只能访问命令行也能工作。如果你想获得所有花里胡哨的东西,(to 校正者:这句话仔细考虑一下)你可以试试那个,尽管有更多的选择,但使用起来比 Synaptic(新立得)更复杂。其他发行版可能有自己独特的工具。 - -### 命令行工具 - -在 Linux 上安装软件的在线说明通常描述在命令行中键入的命令。这些指令通常更容易理解,并且可以在不出错的情况下,将命令复制粘贴到命令行窗口中。这与下面的说明相反:“打开这个菜单,选择这个程序,输入这个搜索模式,点击这个标签,选择这个程序,然后点击这个按钮”,这经常在翻译中丢失。 - -有时你正在使用的 Linux 没有图形环境,因此熟悉从命令行安装软件包是件好事。表 1 和表 2 列出了基于 RPM 和 DPKG 系统的一下常见操作及其相关命令。 - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table_1_0.png?itok=hQ_o5Oh2) - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table_2.png?itok=yl3UPQDw) - -请注意 SUSE,它像 RedHat 和 Fedora 一样使用 RPM,却没有 dnf 或 yum。相反,它使用一个名为 zypper 的程序作为高级命令行工具。其他发行版也可能有不同的工具,例如 Arch Linux 上的 pacman 或 Gentoo 上的 emerge。有很多包工具,所以你可能需要查找哪个适用于你的发行版。 - -这些技巧应该能让你更好地了解如何在新的 Linux 中安装程序,以及更好地了解 Linux 中各种软件包方法如何相互关联。 - -通过 Linux 基金会和 edX 的免费 [“Linux 入门”][6]课程了解有关 Linux 的更多信息。 - - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/learn/2018/3/migrating-linux-installing-software - -作者:[JOHN BONESIO][a] -译者:[MjSeven](https://github.com/MjSeven) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.linux.com/users/johnbonesio -[1]:https://www.linux.com/blog/learn/intro-to-linux/2017/10/migrating-linux-introduction -[2]:https://www.linux.com/blog/learn/intro-to-linux/2017/11/migrating-linux-disks-files-and-filesystems -[3]:https://www.linux.com/blog/learn/2017/12/migrating-linux-graphical-environments -[4]:https://www.linux.com/blog/learn/2018/1/migrating-linux-command-line -[5]:https://www.linux.com/blog/learn/2018/3/migrating-linux-using-sudo -[6]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/sources/tech/20180429 Asynchronous Processing with Go using Kafka and MongoDB.md b/translated/tech/20180429 Asynchronous Processing with Go using Kafka and MongoDB.md similarity index 58% rename from sources/tech/20180429 Asynchronous Processing with Go using Kafka and MongoDB.md rename to translated/tech/20180429 Asynchronous Processing with Go using Kafka and MongoDB.md index ba57e40be3..baa4e1fa3e 100644 --- a/sources/tech/20180429 Asynchronous Processing with Go using Kafka and MongoDB.md +++ b/translated/tech/20180429 Asynchronous Processing with Go using Kafka and MongoDB.md @@ -1,33 +1,33 @@ -Asynchronous Processing with Go using Kafka and MongoDB +使用 Kafka 和 MongoDB 进行 Go 异步处理 ============================================================ -In my previous blog post ["My First Go Microservice using MongoDB and Docker Multi-Stage Builds"][9], I created a Go microservice sample which exposes a REST http endpoint and saves the data received from an HTTP POST to a MongoDB database. +在我前面的博客文章 ["使用 MongoDB 和 Docker 多阶段构建我的第一个 Go 微服务][9] 中,我创建了一个 Go 微服务示例,它发布一个 REST 式的 http 端点,并将从 HTTP POST 中接收到的数据保存到 MongoDB 数据库。 -In this example, I decoupled the saving of data to MongoDB and created another microservice to handle this. I also added Kafka to serve as the messaging layer so the microservices can work on its own concerns asynchronously. +在这个示例中,我将保存数据到 MongoDB 和创建另一个微服务去处理它解耦了。我还添加了 Kafka 为消息层服务,这样微服务就可以异步地处理它自己关心的东西了。 -> In case you have time to watch, I recorded a walkthrough of this blog post in the [video below][1] :) +> 如果你有时间去看,我将这个博客文章的整个过程录制到 [这个视频中了][1] :) -Here is the high-level architecture of this simple asynchronous processing example wtih 2 microservices. +下面是这个使用了两个微服务的简单的异步处理示例的高级架构。 ![rest-kafka-mongo-microservice-draw-io](https://www.melvinvivas.com/content/images/2018/04/rest-kafka-mongo-microservice-draw-io.jpg) -Microservice 1 - is a REST microservice which receives data from a /POST http call to it. After receiving the request, it retrieves the data from the http request and saves it to Kafka. After saving, it responds to the caller with the same data sent via /POST +微服务 1 —— 是一个 REST 式微服务,它从一个 /POST http 调用中接收数据。接收到请求之后,它从 http 请求中检索数据,并将它保存到 Kafka。保存之后,它通过 /POST 发送相同的数据去响应调用者。 -Microservice 2 - is a microservice which subscribes to a topic in Kafka where Microservice 1 saves the data. Once a message is consumed by the microservice, it then saves the data to MongoDB. +微服务 2 —— 是一个在 Kafka 中订阅一个主题的微服务,在这里就是微服务 1 保存的数据。一旦消息被微服务消费之后,它接着保存数据到 MongoDB 中。 -Before you proceed, we need a few things to be able to run these microservices: +在你继续之前,我们需要能够去运行这些微服务的几件东西: -1. [Download Kafka][2] - I used version kafka_2.11-1.1.0 +1. [下载 Kafka][2] —— 我使用的版本是 kafka_2.11-1.1.0 -2. Install [librdkafka][3] - Unfortunately, this library should be present in the target system +2. 安装 [librdkafka][3] —— 不幸的是,这个库应该在目标系统中 -3. Install the [Kafka Go Client by Confluent][4] +3. 安装 [Kafka Go 客户端][4] -4. Run MongoDB. You can check my [previous blog post][5] about this where I used a MongoDB docker image. +4. 运行 MongoDB。你可以去看我的 [以前的文章][5] 中关于这一块的内容,那篇文章中我使用了一个 MongoDB docker 镜像。 -Let's get rolling! +我们开始吧! -Start Kafka first, you need Zookeeper running before you run the Kafka server. Here's how +首先,启动 Kafka,在你运行 Kafka 服务器之前,你需要运行 Zookeeper。下面是示例: ``` $ cd //kafka_2.11-1.1.0 @@ -35,14 +35,14 @@ $ bin/zookeeper-server-start.sh config/zookeeper.properties ``` -Then run Kafka - I am using port 9092 to connect to Kafka. If you need to change the port, just configure it in config/server.properties. If you are just a beginner like me, I suggest to just use default ports for now. +接着运行 Kafka —— 我使用 9092 端口连接到 Kafka。如果你需要改变端口,只需要在 `config/server.properties` 中配置即可。如果你像我一样是个新手,我建议你现在还是使用默认端口。 ``` $ bin/kafka-server-start.sh config/server.properties ``` -After running Kafka, we need MongoDB. To make it simple, just use this docker-compose.yml. +Kafka 跑起来之后,我们需要 MongoDB。它很简单,只需要使用这个 `docker-compose.yml` 即可。 ``` version: '3' @@ -64,14 +64,14 @@ networks: ``` -Run the MongoDB docker container using Docker Compose +使用 Docker Compose 去运行 MongoDB docker 容器。 ``` docker-compose up ``` -Here is the relevant code of Microservice 1. I just modified my previous example to save to Kafka rather than MongoDB. +这里是微服务 1 的相关代码。我只是修改了我前面的示例去保存到 Kafka 而不是 MongoDB。 [rest-to-kafka/rest-kafka-sample.go][10] @@ -136,7 +136,7 @@ func saveJobToKafka(job Job) { ``` -Here is the code of Microservice 2. What is important in this code is the consumption from Kafka, the saving part I already discussed in my previous blog post. Here are the important parts of the code which consumes the data from Kafka. +这里是微服务 2 的代码。在这个代码中最重要的东西是从 Kafka 中消耗数据,保存部分我已经在前面的博客文章中讨论过了。这里代码的重点部分是从 Kafka 中消费数据。 [kafka-to-mongo/kafka-mongo-sample.go][11] @@ -209,51 +209,51 @@ func saveJobToMongo(jobString string) { ``` -Let's get down to the demo, run Microservice 1\. Make sure Kafka is running. + 我们来演示一下,运行微服务 1。确保 Kafka 已经运行了。 ``` $ go run rest-kafka-sample.go ``` -I used Postman to send data to Microservice 1 +我使用 Postman 向微服务 1 发送数据。 ![Screenshot-2018-04-29-22.20.33](https://www.melvinvivas.com/content/images/2018/04/Screenshot-2018-04-29-22.20.33.png) -Here is the log you will see in Microservice 1\. Once you see this, it means data has been received from Postman and saved to Kafka +这里是日志,你可以在微服务 1 中看到。当你看到这些的时候,说明已经接收到了来自 Postman 发送的数据,并且已经保存到了 Kafka。 ![Screenshot-2018-04-29-22.22.00](https://www.melvinvivas.com/content/images/2018/04/Screenshot-2018-04-29-22.22.00.png) -Since we are not running Microservice 2 yet, the data saved by Microservice 1 will just be in Kafka. Let's consume it and save to MongoDB by running Microservice 2. +因为我们尚未运行微服务 2,数据被微服务 1 只保存在了 Kafka。我们来消费它并通过运行的微服务 2 来将它保存到 MongoDB。 ``` $ go run kafka-mongo-sample.go ``` -Now you'll see that Microservice 2 consumes the data and saves it to MongoDB +现在,你将在微服务 2 上看到消费的数据,并将它保存到了 MongoDB。 ![Screenshot-2018-04-29-22.24.15](https://www.melvinvivas.com/content/images/2018/04/Screenshot-2018-04-29-22.24.15.png) -Check if data is saved in MongoDB. If it is there, we're good! +检查一下数据是否保存到了 MongoDB。如果有数据,我们成功了! ![Screenshot-2018-04-29-22.26.39](https://www.melvinvivas.com/content/images/2018/04/Screenshot-2018-04-29-22.26.39.png) -Complete source code can be found here +完整的源代码可以在这里找到 [https://github.com/donvito/learngo/tree/master/rest-kafka-mongo-microservice][12] -Shameless plug! If you like this blog post, please follow me in Twitter [@donvito][6]. I tweet about Docker, Kubernetes, GoLang, Cloud, DevOps, Agile and Startups. Would love to connect in [GitHub][7] and [LinkedIn][8] +现在是广告时间:如果你喜欢这篇文章,请在 Twitter [@donvito][6] 上关注我。我的 Twitter 上有关于 Docker、Kubernetes、GoLang、Cloud、DevOps、Agile 和 Startups 的内容。欢迎你们在 [GitHub][7] 和 [LinkedIn][8] 关注我。 -[VIDEO](https://youtu.be/xa0Yia1jdu8) +[视频](https://youtu.be/xa0Yia1jdu8) -Enjoy! +开心地玩吧! -------------------------------------------------------------------------------- via: https://www.melvinvivas.com/developing-microservices-using-kafka-and-mongodb/ 作者:[Melvin Vivas ][a] -译者:[译者ID](https://github.com/译者ID) +译者:[qhwdw](https://github.com/qhwdw) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180429 Passwordless Auth- Client.md b/translated/tech/20180429 Passwordless Auth- Client.md deleted file mode 100644 index e2faf2cb6e..0000000000 --- a/translated/tech/20180429 Passwordless Auth- Client.md +++ /dev/null @@ -1,338 +0,0 @@ -无密码验证:客户端 -====== -我们继续 [无密码验证][1] 的文章。上一篇文章中,我们用 Go 写了一个 HTTP 服务,用这个服务来做无密码验证 API。今天,我们为它再写一个 JavaScript 客户端。 - -我们将使用 [这里的][2] 这个单页面应用程序(SPA)来展示使用的技术。如果你还没有读过它,请先读它。 - -我们将根据验证的状态分别使用两个不同的根 URL(`/`):一个是访问状态的页面或者是欢迎已验证用户的页面。另一个页面是验证失败后重定向到验证页面。 - -### Serving - -我们将使用相同的 Go 服务器来为客户端提供服务,因此,在我们前面的 `main.go` 中添加一些路由: -``` -router.Handle("GET", "/js/", http.FileServer(http.Dir("static"))) -router.HandleFunc("GET", "/...", serveFile("static/index.html")) - -``` - -这个伺服文件在 `static/js` 下,而 `static/index.html` 文件是为所有的访问提供服务的。 - -你可以使用你自己的服务器,但是你得在服务器上启用 [CORS][3]。 - -### HTML - -我们来看一下那个 `static/index.html` 文件。 -``` - - - - - - Passwordless Demo - - - - - - -``` - -单页面应用程序剩余的渲染由 JavaScript 来完成,因此,我们使用了一个空的 body 部分和一个 `main.js` 文件。 - -我们将使用 [上篇文章][2] 中的 Router。 - -### Rendering - -现在,我们使用下面的内容来创建一个 `static/js/main.js` 文件: -``` -import Router from 'https://unpkg.com/@nicolasparada/router' -import { isAuthenticated } from './auth.js' - -const router = new Router() - -router.handle('/', guard(view('home'))) -router.handle('/callback', view('callback')) -router.handle(/^\//, view('not-found')) - -router.install(async resultPromise => { - document.body.innerHTML = '' - document.body.appendChild(await resultPromise) -}) - -function view(name) { - return (...args) => import(`/js/pages/${name}-page.js`) - .then(m => m.default(...args)) -} - -function guard(fn1, fn2 = view('welcome')) { - return (...args) => isAuthenticated() - ? fn1(...args) - : fn2(...args) -} - -``` - -与上篇文章不同的是,我们实现了一个 `isAuthenticated()` 函数和一个 `guard()` 函数,使用它去渲染两种验证状态的页面。因此,当用户访问 `/` 时,它将根据用户是否通过了验证来展示 home 页面或者是欢迎页面。 - -### Auth - -现在,我们来编写 `isAuthenticated()` 函数。使用下面的内容来创建一个 `static/js/auth.js` 文件: -``` -export function getAuthUser() { - const authUserItem = localStorage.getItem('auth_user') - const expiresAtItem = localStorage.getItem('expires_at') - - if (authUserItem !== null && expiresAtItem !== null) { - const expiresAt = new Date(expiresAtItem) - - if (!isNaN(expiresAt.valueOf()) && expiresAt > new Date()) { - try { - return JSON.parse(authUserItem) - } catch (_) { } - } - } - - return null -} - -export function isAuthenticated() { - return localStorage.getItem('jwt') !== null && getAuthUser() !== null -} - -``` - -当有人登入时,我们将保存 JSON 格式的 web 令牌、过期日期、以及在 `localStorage` 上的当前已验证用户。这个模块就是这个用处。 - - * `getAuthUser()` 用于从 `localStorage` 获取已认证的用户,以确认 JSON 格式的 Web 令牌没有过期。 - * `isAuthenticated()` 在前面的函数中用于去检查它是否返回了 `null`。 - - - -### Fetch - -在继续这个页面之前,我将写一些与服务器 API 一起使用的 HTTP 工具。 - -我们使用以下的内容去创建一个 `static/js/http.js` 文件: -``` -import { isAuthenticated } from './auth.js' - -function get(url, headers) { - return fetch(url, { - headers: Object.assign(getAuthHeader(), headers), - }).then(handleResponse) -} - -function post(url, body, headers) { - return fetch(url, { - method: 'POST', - headers: Object.assign(getAuthHeader(), { 'content-type': 'application/json' }, headers), - body: JSON.stringify(body), - }).then(handleResponse) -} - -function getAuthHeader() { - return isAuthenticated() - ? { authorization: `Bearer ${localStorage.getItem('jwt')}` } - : {} -} - -export async function handleResponse(res) { - const body = await res.clone().json().catch(() => res.text()) - const response = { - url: res.url, - statusCode: res.status, - statusText: res.statusText, - headers: res.headers, - body, - } - if (!res.ok) throw Object.assign( - new Error(body.message || body || res.statusText), - response - ) - return response -} - -export default { - get, - post, -} - -``` - -这个模块导出了 `get()` 和 `post()` 函数。它们是 `fetch` API 的封装。当用户是已验证的,这二个函数注入一个 `Authorization: Bearer ` 头到请求中;这样服务器就能对我们进行身份验证。 - -### Welcome Page - -我们现在来到欢迎页面。用如下的内容创建一个 `static/js/pages/welcome-page.js` 文件: -``` -const template = document.createElement('template') -template.innerHTML = ` -

Passwordless Demo

-

Access

-
- - -
-` - -export default function welcomePage() { - const page = template.content.cloneNode(true) - - page.getElementById('access-form') - .addEventListener('submit', onAccessFormSubmit) - - return page -} - -``` - -正如你所见,这个页面使用一个 `HTMLTemplateElement`。这是一个只输入用户 email 的简单表格。 - -为了不让代码太乏味,我将跳过错误处理部分,只是将它们输出到控制台上。 - -现在,我们来写 `onAccessFormSubmit()` 函数。 -``` -import http from '../http.js' - -function onAccessFormSubmit(ev) { - ev.preventDefault() - - const form = ev.currentTarget - const input = form.querySelector('input') - const email = input.value - - sendMagicLink(email).catch(err => { - console.error(err) - if (err.statusCode === 404 && wantToCreateAccount()) { - runCreateUserProgram(email) - } - }) -} - -function sendMagicLink(email) { - return http.post('/api/passwordless/start', { - email, - redirectUri: location.origin + '/callback', - }).then(() => { - alert('Magic link sent. Go check your email inbox.') - }) -} - -function wantToCreateAccount() { - return prompt('No user found. Do you want to create an account?') -} - -``` - -它使用 email 做了一个 `POST` 请求到 `/api/passwordless/start`,然后在 body 中做了 URI 转向。在本例中使用 `404 Not Found` 状态码返回,我们将创建一个用户。 -``` -function runCreateUserProgram(email) { - const username = prompt("Enter username") - if (username === null) return - - http.post('/api/users', { email, username }) - .then(res => res.body) - .then(user => sendMagicLink(user.email)) - .catch(console.error) -} - -``` - -这个用户创建程序,首先询问用户名,然后使用 email 和用户名,在 body 中做一个 `POST` 请求到 `/api/users`。成功之后,给创建的用户发送一个魔法链接。 - -### Callback Page - -这就是访问表格的所有功能,现在我们来做回调页面。使用如下的内容来创建一个 `static/js/pages/callback-page.js` 文件: -``` -import http from '../http.js' - -const template = document.createElement('template') -template.innerHTML = ` -

Authenticating you 👀

-` - -export default function callbackPage() { - const page = template.content.cloneNode(true) - - const hash = location.hash.substr(1) - const fragment = new URLSearchParams(hash) - for (const [k, v] of fragment.entries()) { - fragment.set(decodeURIComponent(k), decodeURIComponent(v)) - } - const jwt = fragment.get('jwt') - const expiresAt = fragment.get('expires_at') - - http.get('/api/auth_user', { authorization: `Bearer ${jwt}` }) - .then(res => res.body) - .then(authUser => { - localStorage.setItem('jwt', jwt) - localStorage.setItem('auth_user', JSON.stringify(authUser)) - localStorage.setItem('expires_at', expiresAt) - - location.replace('/') - }) - .catch(console.error) - - return page -} - -``` - -请记住 … 当点击魔法链接时,我们来到 `/api/passwordless/verify_redirect`,我们通过 (`/callback`)在 URL 的哈希中传递 JWT 和过期日期,将我们转向到重定向 URI。 - -回调页面解码 URL 中的哈希,提取这些参数去做一个 `GET` 请求到 `/api/auth_user`,用 JWT 保存所有数据到 `localStorage` 中。最后,重定向到主页面。 - -### Home Page - -创建如下内容的 `static/pages/home-page.js` 文件: -``` -import { getAuthUser } from '../auth.js' - -export default function homePage() { - const authUser = getAuthUser() - - const template = document.createElement('template') - template.innerHTML = ` -

Passwordless Demo

-

Welcome back, ${authUser.username} 👋

- - ` - - const page = template.content - - page.getElementById('logout-button') - .addEventListener('click', logout) - - return page -} - -function logout() { - localStorage.clear() - location.reload() -} - -``` - -这个页面欢迎已验证用户,同时也有一个登出按钮。`logout()` 函数的功能只是清理掉 `localStorage` 并重载这个页面。 - -这就是全部内容了。我敢说你在此之前已经看过这个 [demo][4] 了。当然,这些源代码也在同一个 [仓库][5] 中。 - -👋👋👋 - --------------------------------------------------------------------------------- - -via: https://nicolasparada.netlify.com/posts/passwordless-auth-client/ - -作者:[Nicolás Parada][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://nicolasparada.netlify.com/ -[1]:https://nicolasparada.netlify.com/posts/passwordless-auth-server/ -[2]:https://nicolasparada.netlify.com/posts/javascript-client-router/ -[3]:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS -[4]:https://go-passwordless-demo.herokuapp.com/ -[5]:https://github.com/nicolasparada/go-passwordless-demo diff --git a/translated/tech/20180508 Everything old is new again- Microservices - DXC Blogs.md b/translated/tech/20180508 Everything old is new again- Microservices - DXC Blogs.md new file mode 100644 index 0000000000..bc8c557339 --- /dev/null +++ b/translated/tech/20180508 Everything old is new again- Microservices - DXC Blogs.md @@ -0,0 +1,57 @@ +老树发新芽:微服务 – DXC Blogs +====== +![](https://csccommunity.files.wordpress.com/2018/05/old-building-with-modern-addition.jpg?w=610) + +如果我告诉你有这样一种软件架构,一个应用程序的组件通过基于网络的通讯协议为其它组件提供服务,我估计你可能会说它是 … + +是的,确实是。如果你从上世纪九十年代就开始了你的编程生涯,那么你肯定会说它是 [面向服务的架构 (SOA)][1]。但是,如果你是个年青人,并且在云上获得初步的经验,那么,你将会说:“哦,你说的是 [微服务][2]。” + +你们都没错。如果想真正地了解它们的差别,你需要深入地研究这两种架构。 + +在 SOA 中,一个服务是一个功能,它是定义好的、自包含的、并且是不依赖上下文和其它服务的状态的功能。总共有两种服务。一种是消费者服务,它从另外类型的服务 —— 提供者服务 —— 中请求一个服务。一个 SOA 服务可以同时扮演这两种角色。 + +SOA 服务可以与其它服务交换数据。两个或多个服务也可以彼此之间相互协调。这些服务执行基本的任务,比如创建一个用户帐户、提供登陆功能、或验证支付。 + +与其说 SOA 是模块化一个应用程序,还不如说它是把分布式的、独立维护和部署的组件,组合成一个应用程序。然后在服务器上运行这些组件。 + +早期版本的 SOA 使用面向对象的协议进行组件间通讯。例如,微软的 [分布式组件对象模型 (DCOM)][3] 和使用 [通用对象请求代理架构 (CORBA)][5] 规范的 [对象请求代理 (ORBs)][4]。 + +用于消息服务的最新版本,比如 [Java 消息服务 (JMS)][6] 或者 [高级消息队列协议 (AMQP)][7]。这些服务通过企业服务总线 (ESB) 进行连接。基于这些总线,来传递和接收可扩展标记语言(XML)格式的数据。 + +[微服务][2] 是一个架构样式,其中的应用程序以松散耦合的服务或模块组成。它适用于开发大型的、复杂的应用程序的持续集成/持续部署(CI/CD)模型。一个应用程序就是一堆模块的汇总。 + +每个微服务提供一个应用程序编程接口(API)端点。它们通过轻量级协议连接,比如,[表述性状态转移 (REST)][8],或 [gRPC][9]。数据倾向于使用 [JavaScript 对象标记 (JSON)][10] 或 [Protobuf][11] 来表示。 + +这两种架构都可以用于去替代以前老的整体式架构,整体式架构的应用程序被构建为单个自治的单元。例如,在一个客户机 - 服务器模式中,一个典型的 Linux、Apache、MySQL、PHP/Python/Perl (LAMP) 服务器端应用程序将去处理 HTTP 请求、运行子程序、以及从底层的 MySQL 数据库中检索/更新数据。所有这些应用程序”绑“在一起提供服务。当你改变了任何一个东西,你都必须去构建和部署一个新版本。 + +使用 SOA,你可以只改变需要的几个组件,而不是整个应用程序。使用微服务,你可以做到一次只改变一个服务。使用微服务,你才能真正做到一个解耦架构。 + +微服务也比 SOA 更轻量级。不过 SOA 服务是部署到服务器和虚拟机上,而微服务是部署在容器中。协议也更轻量级。这使得微服务比 SOA 更灵活。因此,它更适合于要求敏捷性的电商网站。 + +说了这么多,到底意味着什么呢?微服务就是 SOA 在容器和云计算上的变种。 + +老式的 SOA 并没有离我们远去,但是,因为我们持续将应用程序搬迁到容器中,所以微服务架构将越来越流行。 + +-------------------------------------------------------------------------------- + +via: https://blogs.dxc.technology/2018/05/08/everything-old-is-new-again-microservices/ + +作者:[Cloudy Weather][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blogs.dxc.technology/author/steven-vaughan-nichols/ +[1]:https://www.service-architecture.com/articles/web-services/service-oriented_architecture_soa_definition.html +[2]:http://microservices.io/ +[3]:https://technet.microsoft.com/en-us/library/cc958799.aspx +[4]:https://searchmicroservices.techtarget.com/definition/Object-Request-Broker-ORB +[5]:http://www.corba.org/ +[6]:https://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html +[7]:https://www.amqp.org/ +[8]:https://www.service-architecture.com/articles/web-services/representational_state_transfer_rest.html +[9]:https://grpc.io/ +[10]:https://www.json.org/ +[11]:https://github.com/google/protobuf/ diff --git a/translated/tech/20180606 6 Open Source AI Tools to Know.md b/translated/tech/20180606 6 Open Source AI Tools to Know.md deleted file mode 100644 index c687342d31..0000000000 --- a/translated/tech/20180606 6 Open Source AI Tools to Know.md +++ /dev/null @@ -1,55 +0,0 @@ -应该知道的 6 个开源 AI 工具 -====== - -![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/artificial-intelligence-3382507_1920.jpg?itok=HarDnwVX) - -在开源领域,不管你的想法是多少的新颖独到,先去看一下别人是否已经做成了这个概念,总是一个很明智的做法。对于有兴趣借助不断成长的人工智能(AI)的力量的组织和个人来说,许多非常好的工具不仅是免费和开源的,而且在很多的情况下,它们都已经过测试和久经考验的。 - -在领先的公司和非盈利组织中,AI 的优先级都非常高,并且这些公司和组织都开源了很有价值的工具。下面的样本是任何人都可以使用的免费的、开源的 AI 工具。 - -**Acumos.** [Acumos AI][1] 是一个平台和开源框架,使用它可以很容易地去构建、共享和分发 AI 应用。它规范了需要的基础设施栈和组件,使其可以在一个“开箱即用的”通用 AI 环境中运行。这使得数据科学家和模型训练者可以专注于它们的核心竞争力,而不用在无止境的定制、建模、以及训练一个 AI 实现上浪费时间。 - -Acumos 是 [LF 深度学习基金会][2] 的一部分,它是 Linux 基金会中的一个组织,它支持在人工智能、机器学习、以及深度学习方面的开源创新。它的目标是让这些重大的新技术可用于开发者和数据科学家,包括那些在深度学习和 AI 上经验有限的人。LF 深度学习基金会 [最近批准了一个项目生命周期和贡献流程][3],并且它现在正接受项目贡献的建议。 - -**Facebook 的框架.** Facebook 它自己 [有开源的][4] 中央机器学习系统,它设计用于做一些大规模的人工智能任务,以及一系列其它的 AI 技术。这个工具是经过他们公司验证的平台的一部分。Facebook 也开源了一个叫 [Caffe2][5] 的深度学习和人工智能的框架。 - -**说到 Caffe.** Yahoo 也在开源许可证下发布了它自己的关键的 AI 软件。[CaffeOnSpark 工具][6] 是基于深度学习的,它是人工智能的一个分支,在帮助机器识别人类语言、或者照片、视频的内容方面非常有用。同样地,IBM 的机器学习程序 [SystemML][7] 可以通过 Apache 软件基金会免费共享和修改。 - -**Google 的工具.** Google 花费了几年的时间开发了它自己的 [TensorFlow][8] 软件框架,用于去支持它的 AI 软件和其它预测和分析程序。TensorFlow 是你可能都已经在使用的一些 Google 工具背后的引擎,包括 Google Photos 和在 Google app 中使用的语言识别。 - -Google 开源了两个 [AIY kits][9],它可以让个人很容易地使用人工智能,它们专注于计算机视觉和语音助理。这两个工具包将用到的所有组件封装到一个盒子中。这个工具包目前在美国的 Target 中有售,并且它是基于开源的树莓派平台的 —— 有越来越多的证据表明,在开源和 AI 交集中将发生非常多的事情。 - -**H2O.ai.** **** 我 [以前介绍过][10] H2O.ai,它在机器学习和人工智能领域中占有一席之地,因为它的主要工具是免费和开源的。你可以获取主要的 H2O 平台和 Sparkling Water,它与 Apache Spark 一起工作,只需要去 [下载][11] 它们即可。这些工具遵循 Apache 2.0 许可证,它是一个非常灵活的开源许可证,你甚至可以在 Amazon Web 服务(AWS)和其它的集群上运行它们,而这仅需要几百美元而已。 - -**Microsoft Onboard.** “我们的目标是让 AI 大众化,让每个人和组织获得更大的成就,“ Microsoft CEO Satya Nadella [说][12]。因此,微软持续迭代它的 [Microsoft Cognitive Toolkit][13]。它是一个能够与 TensorFlow 和 Caffe 去竞争的一个开源软件框架。Cognitive 工具套件可以工作在 64 位的 Windows 和 Linux 平台上。 - -Cognitive 工具套件团队的报告称,“Cognitive 工具套件通过允许用户去创建、训练、以及评估他们自己的神经网络,以使企业级的、生产系统级的 AI 成为可能,这些神经网络可能跨多个 GPU 以及多个机器在大量的数据集中高效伸缩。” - -从来自 Linux 基金会的新电子书中学习更多的有关 AI 知识。Ibrahim Haddad 的 [开源 AI:项目、洞察、和趋势][14] 调查了 16 个流行的开源 AI 项目—— 深入研究了他们的历史、代码库、以及 GitHub 的贡献。 [现在可以免费下载这个电子书][14]。 - --------------------------------------------------------------------------------- - -via: https://www.linux.com/blog/2018/6/6-open-source-ai-tools-know - -作者:[Sam Dean][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.linux.com/users/sam-dean -[1]:https://www.acumos.org/ -[2]:https://www.linuxfoundation.org/projects/deep-learning/ -[3]:https://www.linuxfoundation.org/blog/lf-deep-learning-foundation-announces-project-contribution-process/ -[4]:https://code.facebook.com/posts/1687861518126048/facebook-to-open-source-ai-hardware-design/ -[5]:https://venturebeat.com/2017/04/18/facebook-open-sources-caffe2-a-new-deep-learning-framework/ -[6]:http://yahoohadoop.tumblr.com/post/139916563586/caffeonspark-open-sourced-for-distributed-deep -[7]:https://systemml.apache.org/ -[8]:https://www.tensorflow.org/ -[9]:https://www.techradar.com/news/google-assistant-sweetens-raspberry-pi-with-ai-voice-control -[10]:https://www.linux.com/news/sparkling-water-bridging-open-source-machine-learning-and-apache-spark -[11]:http://www.h2o.ai/download -[12]:https://blogs.msdn.microsoft.com/uk_faculty_connection/2017/02/10/microsoft-cognitive-toolkit-cntk/ -[13]:https://www.microsoft.com/en-us/cognitive-toolkit/ -[14]:https://www.linuxfoundation.org/publications/open-source-ai-projects-insights-and-trends/ diff --git a/translated/tech/20180607 Using MQTT to send and receive data for your next project.md b/translated/tech/20180607 Using MQTT to send and receive data for your next project.md new file mode 100644 index 0000000000..59e9e92ac9 --- /dev/null +++ b/translated/tech/20180607 Using MQTT to send and receive data for your next project.md @@ -0,0 +1,256 @@ +使用 MQTT 实现项目数据收发 +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/toolbox-learn-draw-container-yearbook.png?itok=xDbwz1pP) + +去年 11 月我们购买了一辆电动汽车,同时也引发了有趣的思考:我们应该什么时候为电动汽车充电?对于电动汽车充电所用的电,我希望能够对应最小的二氧化碳排放,归结为一个特定的问题:对于任意给定时刻,每千瓦时对应的二氧化碳排放量是多少,一天中什么时间这个值最低? + + +### 寻找数据 + +我住在纽约州,大约 80% 的电力消耗可以自给自足,主要来自天然气、水坝(大部分来自于尼亚加拉Niagara大瀑布)、核能发电,少部分来自风力、太阳能和其它化石燃料发电。非盈利性组织 [纽约独立电网运营商New York Independent System Operator][1] (NYISO) 负责整个系统的运作,实现发电机组发电与用电之间的平衡,同时也是纽约路灯系统的监管部门。 + +尽管没有为公众提供公开 API,NYISO 还是尽责提供了[不少公开数据][2]供公众使用。每隔 5 分钟汇报全州各个发电机组消耗的燃料数据。数据以 CSV 文件的形式发布于公开的档案库中,全天更新。如果你了解不同燃料对发电瓦数的贡献比例,你可以比较准确的估计任意时刻的二氧化碳排放情况。 + +在构建收集处理公开数据的工具时,我们应该时刻避免过度使用这些资源。相比将这些数据打包并发送给所有人,我们有更好的方案。我们可以创建一个低开销的事件流event stream,人们可以订阅并第一时间得到消息。我们可以使用 [MQTT][3] 实现该方案。我的 ([ny-power.org][4]) 项目目标是收录到 [Home Assistant][5] 项目中;后者是一个开源的家庭自动化home automation平台,拥有数十万用户。如果所有用户同时访问 CSV 文件服务器,估计 NYISO 不得不增加访问限制。 + +### MQTT 是什么? + +MQTT 是一个发布订阅线协议publish/subscription wire protocol,为小规模设备设计。发布订阅系统工作原理类似于消息总线。你将一条消息发布到一个主题topic上,那么所有订阅了该主题的客户端都可以获得该消息的一份拷贝。对于消息发送者而言,无需知道哪些人在订阅消息;你只需将消息发布到一系列主题,同时订阅一些你感兴趣的主题。就像参加了一场聚会,你选取并加入感兴趣的对话。 + +MQTT 可应用构建极为高效的应用。客户端订阅有限的几个主题,也只收到他们感兴趣的内容。不仅节省了处理时间,还降低了网络带宽使用。 + +作为一个开放标准,MQTT 有很多开源的客户端和服务端实现。对于你能想到的每种编程语言,都有对应的客户端库;甚至有嵌入到 Arduino 的库,可以构建传感器网络。服务端可供选择的也很多,我的选择是 Eclipse 项目提供的 [Mosquitto][6] 服务端,这是因为它体积小、用 C 编写,可以承载数以万计的订阅者。 + +### 为何我喜爱 MQTT + +在过去二十年间,我们为软件应用设计了可靠且准确的模型,用于解决服务遇到的问题。我还有其它邮件吗?当前的天气情况如何?我应该此刻购买这种产品吗?在绝大多数情况下,这种问答式ask/receive的模型工作良好;但对于一个数据爆炸的世界,我们需要其它的模型。MQTT 的发布订阅模型十分强大,可以将大量数据发送到系统中。客户可以订阅数据中的一小部分并在订阅数据发布的第一时间收到更新。 + +MQTT 还有一些有趣的特性,其中之一是遗嘱last-will-and-testament消息,可以用于区分两种不同的静默,一种是没有主题相关数据推送,另一种是你的数据接收器出现故障。MQTT 还包括保留消息retained message,当客户端初次连接时会提供相关主题的最后一条消息。这对那些更新缓慢的主题来说很有必要。 + +我在 Home Assistant 项目开发过程中,发现这种消息总线模型对异构系统heterogeneous systems尤为适合。如果你深入物联网Internet of Things领域,你会发现 MQTT 无处不在。 + +### 我们的第一个 MQTT 流 + +NYSO 公布的 CSV 文件中有一个是实时的燃料混合使用情况。每 5 分钟,NYSO 发布这 5 分钟内发电使用的燃料类型和相应的发电量(以兆瓦为单位)。 + +The CSV file looks something like this: + +| 时间戳 | 时区 | 燃料类型 | 兆瓦为单位的发电量 | +| --- | --- | --- | --- | +| 05/09/2018 00:05:00 | EDT | 混合燃料 | 1400 | +| 05/09/2018 00:05:00 | EDT | 天然气 | 2144 | +| 05/09/2018 00:05:00 | EDT | 核能 | 4114 | +| 05/09/2018 00:05:00 | EDT | 其它化石燃料 | 4 | +| 05/09/2018 00:05:00 | EDT | 其它可再生资源 | 226 | +| 05/09/2018 00:05:00 | EDT | 风力 | 1 | +| 05/09/2018 00:05:00 | EDT | 水力 | 3229 | +| 05/09/2018 00:10:00 | EDT | 混合燃料 | 1307 | +| 05/09/2018 00:10:00 | EDT | 天然气 | 2092 | +| 05/09/2018 00:10:00 | EDT | 核能 | 4115 | +| 05/09/2018 00:10:00 | EDT | 其它化石燃料 | 4 | +| 05/09/2018 00:10:00 | EDT | 其它可再生资源 | 224 | +| 05/09/2018 00:10:00 | EDT | 风力 | 40 | +| 05/09/2018 00:10:00 | EDT | 水力 | 3166 | + +表中唯一令人不解就是燃料类别中的混合燃料。纽约的大多数天然气工厂也通过燃烧其它类型的化石燃料发电。在冬季寒潮到来之际,家庭供暖的优先级高于发电;但这种情况出现的次数不多,(在我们计算中)可以将混合燃料类型看作天然气类型。 + +CSV 文件全天更新。我编写了一个简单的数据泵,每隔 1 分钟检查是否有数据更新,并将新条目发布到 MQTT 服务器的一系列主题上,主题名称基本与 CSV 文件有一定的对应关系。数据内容被转换为 JSON 对象,方便各种编程语言处理。 + +``` +ny-power/upstream/fuel-mix/Hydro {"units": "MW", "value": 3229, "ts": "05/09/2018 00:05:00"} +ny-power/upstream/fuel-mix/Dual Fuel {"units": "MW", "value": 1400, "ts": "05/09/2018 00:05:00"} +ny-power/upstream/fuel-mix/Natural Gas {"units": "MW", "value": 2144, "ts": "05/09/2018 00:05:00"} +ny-power/upstream/fuel-mix/Other Fossil Fuels {"units": "MW", "value": 4, "ts": "05/09/2018 00:05:00"} +ny-power/upstream/fuel-mix/Wind {"units": "MW", "value": 41, "ts": "05/09/2018 00:05:00"} +ny-power/upstream/fuel-mix/Other Renewables {"units": "MW", "value": 226, "ts": "05/09/2018 00:05:00"} +ny-power/upstream/fuel-mix/Nuclear {"units": "MW", "value": 4114, "ts": "05/09/2018 00:05:00"} + +``` + +这种直接的转换是种不错的尝试,可将公开数据转换为公开事件。我们后续会继续将数据转换为二氧化碳排放强度,但这些原始数据还可被其它应用使用,用于其它计算用途。 + +### MQTT 主题 + +主题和主题结构topic structure是 MQTT 的一个主要特色。与其它标准的企业级消息总线不同,MQTT 的主题无需事先注册。发送者可以凭空创建主题,唯一的限制是主题的长度,不超过 220 字符。其中 `/` 字符有特殊含义,用于创建主题的层次结构。我们即将看到,你可以订阅这些层次中的一些分片。 + +基于开箱即用的 Mosquitto,任何一个客户端都可以向任何主题发布消息。在原型设计过程中,这种方式十分便利;但一旦部署到生产环境,你需要增加访问控制列表access control list, ACL只允许授权的应用发布消息。例如,任何人都能以只读的方式访问我的应用的主题层级,但只有那些具有特定凭证credentials的客户端可以发布内容。 + +主题中不包含自动样式automatic schema,也没有方法查找客户端可以发布的全部主题。因此,对于那些从 MQTT 总线消费数据的应用,你需要让其直接使用已知的主题和消息格式样式。 + +那么应该如何设计主题呢?最佳实践包括使用应用相关的根名称,例如在我的应用中使用 `ny-power`。接着,为提高订阅效率,构建足够深的层次结构。`upstream` 层次结构包含了直接从数据源获取的、不经处理的原始数据,而 `fuel-mix` 层次结构包含特定类型的数据;我们后续还可以增加其它的层次结构。 + +### 订阅主题 + +在 MQTT 中,订阅仅仅是简单的字符串匹配。为提高处理效率,只允许如下两种通配符: + + * `#` 以递归方式匹配,直到字符串结束 + * `+` 匹配下一个 `/` 之前的内容 + + +为便于理解,下面给出几个例子: +``` +ny-power/#  - 匹配 ny-power 应用发布的全部主题 +ny-power/upstream/#  - 匹配全部原始数据的主题 +ny-power/upstream/fuel-mix/+  - 匹配全部燃料类型的主题 +ny-power/+/+/Hydro - 匹配全部两次层级之后为 Hydro 类型的主题(即使不位于 upstream 层次结构下) +``` + +类似 `ny-power/#` 的大范围订阅适用于低数据量low-volume的应用,应用从网络获取全部数据并处理。但对高数据量high-volume应用而言则是一个灾难,由于绝大多数消息并不会被使用,大部分的网络带宽被白白浪费了。 + +在大数据量情况下,为确保性能,应用需要使用恰当的主题筛选(如 `ny-power/+/+/Hydro`)尽量准确获取业务所需的数据。 + +### 增加我们自己的数据层次 + +接下来,应用中的一切都依赖于已有的 MQTT 流并构建新流。第一个额外的数据层用于计算发电对应的二氧化碳排放。 + +利用[美国能源情报署U.S. Energy Information Administration][7] 给出的 2016 年纽约各类燃料发电及排放情况,我们可以给出各类燃料的[平均排放率][8],单位为克/兆瓦时。 + +上述结果被封装到一个专用的微服务中。该微服务订阅 `ny-power/upstream/fuel-mix/+`,即数据泵中燃料组成情况的原始数据,接着完成计算并将结果(单位为克/千瓦时)发布到新的主题层次结构上: +``` +ny-power/computed/co2 {"units": "g / kWh", "value": 152.9486, "ts": "05/09/2018 00:05:00"} +``` + +接着,另一个服务会订阅该主题层次结构并将数据打包到 [InfluxDB][9] 进程中;同时,发布 24 小时内的时间序列数据到 `ny-power/archive/co2/24h` 主题,这样可以大大简化当前变化数据的绘制。 + +这种层次结构的主题模型效果不错,可以将上述程序之间的逻辑解耦合。在复杂系统中,各个组件可能使用不同的编程语言,但这并不重要,因为交换格式都是 MQTT 消息,即主题和 JSON 格式的消息内容。 + +### 从终端消费数据 + +为了更好的了解 MQTT 完成了什么工作,将其绑定到一个消息总线并查看消息流是个不错的方法。`mosquitto-clients` 包中的 `mosquitto_sub` 可以让我们轻松实现该目标。 + +安装程序后,你需要提供服务器名称以及你要订阅的主题。如果有需要,使用参数 `-v` 可以让你看到有新消息发布的那些主题;否则,你只能看到主题内的消息数据。 + +``` +mosquitto_sub -h mqtt.ny-power.org -t ny-power/# -v + +``` + +只要我编写或调试 MQTT 应用,我总会在一个终端中运行 `mosquitto_sub`。 + +### 从网页直接访问 MQTT + +到目前为止,我们已经有提供公开事件流的应用,可以用微服务或命令行工具访问该应用。但考虑到互联网仍占据主导地位,因此让用户可以从浏览器直接获取事件流是很重要。 + +MQTT 的设计者已经考虑到了这一点。协议标准支持三种不同的传输协议:[TCP][10],[UDP][11] 和 [WebSockets][12]。主流浏览器都支持 WebSockets,可以维持持久连接,用于实时应用。 + +Eclipse 项目提供了 MQTT 的一个 JavaScript 实现,叫做 [Paho][13],可包含在你的应用中。工作模式为与服务器建立连接、建立一些订阅,然后根据接收到的消息进行响应。 + +``` +// ny-power web console application + +var client = new Paho.MQTT.Client(mqttHost, Number("80"), "client-" + Math.random()); + +// set callback handlers +client.onMessageArrived = onMessageArrived; + +// connect the client +client.reconnect = true; +client.connect({onSuccess: onConnect}); + +// called when the client connects +function onConnect() { +    // Once a connection has been made, make a subscription and send a message. +    console.log("onConnect"); +    client.subscribe("ny-power/computed/co2"); +    client.subscribe("ny-power/archive/co2/24h"); +    client.subscribe("ny-power/upstream/fuel-mix/#"); +} + +// called when a message arrives +function onMessageArrived(message) { +    console.log("onMessageArrived:"+message.destinationName + message.payloadString); +    if (message.destinationName == "ny-power/computed/co2") { +        var data = JSON.parse(message.payloadString); +        $("#co2-per-kwh").html(Math.round(data.value)); +        $("#co2-units").html(data.units); +        $("#co2-updated").html(data.ts); +    } + +    if (message.destinationName.startsWith("ny-power/upstream/fuel-mix")) { +        fuel_mix_graph(message); +    } + +    if (message.destinationName == "ny-power/archive/co2/24h") { +        var data = JSON.parse(message.payloadString); +        var plot = [ +            { +                x: data.ts, +                y: data.values, +                type: 'scatter' +            } +        ]; +        var layout = { +            yaxis: { +                title: "g CO2 / kWh", +            } +        }; +        Plotly.newPlot('co2_graph', plot, layout); +    } + +``` + +上述应用订阅了不少主题,因为我们将要呈现若干种不同类型的数据;其中 `ny-power/computed/co2` 主题为我们提供当前二氧化碳排放的参考值。一旦收到该主题的新消息,网站上的相应内容会被相应替换。 + + +![NYISO 二氧化碳排放图][15] + +[ny-power.org][4] 网站提供的 NYISO 二氧化碳排放图。 + +`ny-power/archive/co2/24h` 主题提供了时间序列数据,用于为 [Plotly][16] 线表提供数据。`ny-power/upstream/fuel-mix` 主题提供当前燃料组成情况,为漂亮的柱状图提供数据。 + +![NYISO 燃料组成情况][18] + +[ny-power.org][4] 网站提供的燃料组成情况。 + +这是一个动态网站,数据不从服务器拉取,而是结合 MQTT 消息总线,监听对外开放的 WebSocket。就像数据泵和打包器程序那样,网站页面也是一个发布订阅客户端,只不过是在你的浏览器中执行,而不是在公有云的微服务上。 + +你可以在 站点点看到动态变更,包括图像和可以看到消息到达的实时 MQTT 终端。 + +### 继续深入 + +ny-power.org 应用的完整内容开源在 [GitHub][19] 中。你也可以查阅 [架构简介][20],学习如何使用 [Helm][21] 部署一系列 Kubernetes 微服务构建应用。另一个有趣的 MQTT 示例使用 MQTT 和 OpenWhisk 进行实时文本消息翻译,代码模式code pattern参考[链接][22]。 + +MQTT 被广泛应用于物联网领域,更多关于 MQTT 用途的例子可以在 [Home Assistant][23] 项目中找到。 + +如果你希望深入了解协议内容,可以从 [mqtt.org][3] 获得该公开标准的全部细节。 + +想了解更多,可以参加 Sean Dague 在 [OSCON][25] 上的演讲,主题为 [将 MQTT 加入到你的工具箱][24],会议将于 7 月 16-19 日在奥尔良州波特兰举办。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/6/mqtt + +作者:[Sean Dague][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[译者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/sdague +[1]:http://www.nyiso.com/public/index.jsp +[2]:http://www.nyiso.com/public/markets_operations/market_data/reports_info/index.jsp +[3]:http://mqtt.org/ +[4]:http://ny-power.org/# +[5]:https://www.home-assistant.io +[6]:https://mosquitto.org/ +[7]:https://www.eia.gov/ +[8]:https://github.com/IBM/ny-power/blob/master/src/nypower/calc.py#L1-L60 +[9]:https://www.influxdata.com/ +[10]:https://en.wikipedia.org/wiki/Transmission_Control_Protocol +[11]:https://en.wikipedia.org/wiki/User_Datagram_Protocol +[12]:https://en.wikipedia.org/wiki/WebSocket +[13]:https://www.eclipse.org/paho/ +[14]:/file/400041 +[15]:https://opensource.com/sites/default/files/uploads/mqtt_nyiso-co2intensity.png (NY ISO Grid CO2 Intensity) +[16]:https://plot.ly/ +[17]:/file/400046 +[18]:https://opensource.com/sites/default/files/uploads/mqtt_nyiso_fuel-mix.png (Fuel mix on NYISO grid) +[19]:https://github.com/IBM/ny-power +[20]:https://developer.ibm.com/code/patterns/use-mqtt-stream-real-time-data/ +[21]:https://helm.sh/ +[22]:https://developer.ibm.com/code/patterns/deploy-serverless-multilingual-conference-room/ +[23]:https://www.home-assistant.io/ +[24]:https://conferences.oreilly.com/oscon/oscon-or/public/schedule/speaker/77317 +[25]:https://conferences.oreilly.com/oscon/oscon-or diff --git a/translated/tech/20180615 5 Commands for Checking Memory Usage in Linux.md b/translated/tech/20180615 5 Commands for Checking Memory Usage in Linux.md new file mode 100644 index 0000000000..08cabe84c7 --- /dev/null +++ b/translated/tech/20180615 5 Commands for Checking Memory Usage in Linux.md @@ -0,0 +1,190 @@ +用以检查 Linux 内存使用的 5 个命令 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/top-main.jpg?itok=WYAw6yJ1) +Linux 操作系统包含大量工具,所有这些工具都可以帮助你管理系统。从简单的文件和目录工具到非常复杂的安全命令,在 Linux 中没有多少是你做不了的。而且,尽管普通桌面用户可能不需要在命令行熟悉这些工具,但对于 Linux 管理员来说,它们是必需的。为什么?首先,你在某些时候不得不使用没有 GUI 的 Linux 服务器。其次,命令行工具通常比 GUI 替代工具提供更多的功能和灵活性。 + +确定内存使用情况是你可能需要的技能,尤其是特定应用程序变为流氓和占用系统内存时。当发生这种情况时,知道有多种工具可以帮助你进行故障排除十分方便的。或者,你可能需要收集有关 Linux 交换分区的信息,或者有关安装的 RAM 的详细信息?对于这些也有相应的命令。让我们深入了解各种 Linux 命令行工具,以帮助你检查系统内存使用情况。这些工具并不是非常难以使用,在本文中,我将向你展示五种不同的方法来解决这个问题。 + +我将在 [Ubuntu 18.04 服务器平台][1]上进行演示,但是你应该在你选择的发行版中找到对应的所有命令。更妙的是,你不需要安装任何东西(因为大多数这些工具都包含 Linux 系统中)。 + +话虽如此,让我们开始工作吧。 + +### top + +我想从最明显的工具开始。top 命令提供正在运行的系统的动态实时视图,它检查每个进程的内存使用情况。这非常重要,因为你可以轻松地对同一命令的多次迭代消耗不同的内存量。虽然你无法在没有外设的服务器上找到它,但是你已经注意到打开 Chrome 使你的系统速度变慢了。发出 top 命令以查看 Chrome 有多个进程在运行(每个选项卡一个 - 图 1)。 + +![top][3] + +图1:top 命令中出现多个 Chrome 进程。 + +(to 校正者:不知道这句话什么意思,难道是是否允许转载的?) +[Used with permission][4] + +Chrome 并不是唯一显示多个进程的应用。你看到图 1 中的 Firefox 了吗?那是 Firefox 的主进程,而 Web Content 进程是其打开的选项卡。在输出的顶部,你将看到系统统计信息。在我的机器上([System76 Leopard Extreme][5]),我总共有 16GB 可用 RAM,其中只有超过 10GB 的 RAM 正在使用中。然后,你可以整理列表,查看每个进程使用的内存百分比。 + +top 最好的事情之一就是发现可能已经失控的进程 ID(PID)服务数量。有了这些 PID,你可以对有问题的任务进行故障排除(或 kill)。 + +如果你想让 top 显示更友好的内存信息,使用命令 top -o%MEM,这会使 top 按进程所用内存对所有进程进行排序(图 2)。 + + +![top][7] + +图 2:在 top 命令中按使用内存对进程排序 + +[Used with permission][4] + +top 命令还为你提供有关使用了多少交换空间的实时更新。 + +### free + +然而有时候,top 命令可能不会满足你的需求。你可能只需要查看系统的可用和已用内存。对此,Linux 还有 free 命令。free 命令显示: +(to 校正者:以下这种可能翻译得不太准确,望纠正) +* 可用和已使用的物理内存总量 + +* 系统中交换内存的总量 + +* 内核使用的缓冲区和缓存 + +在终端窗口中,输入 free 命令。它的输出不是实时的,相反,你将获得的是当前空闲和已用内存的即时快照(图 3)。 + +![free][9] + +图 3 :free 命令的输出简单明了。 + +[Used with permission][4] + +当然,你可以通过添加 -m 选项来让 free 显示得更友好一点,就像这样:free -m。这将显示内存的使用情况,以 MB 为单位(图 4)。 + +![free][11] + +图 4:free 命令以一种更易于阅读的形式输出。 + +[Used with permission][4] + +当然,如果你的系统是远程的,你将希望使用 -g 选项(以 GB 为单位),比如 free -g。 + +如果你需要内存总量,你可以添加 t 选项,比如:free -mt。这将简单地计算每列中的内存总量(图 5)。 + +![total][13] + +图 5:为你提供空闲的内存列。 + +[Used with permission][4] + +### vmstat + +另一个非常方便的工具是 vmstat。这个特殊的命令是一个报告虚拟内存统计信息的小技巧。vmstat 命令将报告关于: + +* 进程 + +* 内存 + +* 页 + +* 阻塞 IO + +* traps + +* 磁盘 + +* CPU + +使用 vmstat 的最佳方法是使用 -s 选项,如 vmstat -s。这将在单列中报告统计信息(这比默认报告更容易阅读)。vmstat 命令将提供比你需要的更多的信息(图 6),但更多的总是更好的(在这种情况下)。 + +![vmstat][15] + +图 6:使用 vmstat 命令来检查内存使用情况。 + +[Used with permission][4] + +### dmidecode + +如果你想找到关于已安装的系统 RAM 的详细信息,该怎么办?为此,你可以使用 dmidecode 命令。这个特殊的工具是 DMI 表解码器,它将系统的 DMI 表内容转储成人类可读的格式。如果你不清楚 DMI 表是什么,那么可以这样说,(to 校正者:这句话可以不加)它是可以用来描述系统的构成(以及系统的演变)。 + +要运行 dmidecode 命令,你需要 sudo 权限。因此输入命令 sudo dmidecode -t 17。该命令的输出(图 7)可能很长,因为它显示所有内存类型设备的信息。因此,如果你无法上下滚动,则可能需要将该命令的输出发送到一个文件中,比如:sudo dmidecode -t 17> dmi_infoI,或将其传递给 less 命令,如 sudo dmidecode | less。 + +![dmidecode][17] + +图 7:dmidecode 命令的输出。 + +[Used with permission][4] + +### /proc/meminfo + +你可能会问自己:“这些命令从哪里获取这些信息?”在某些情况下,它们从 /proc/meminfo 文件中获取。你猜猜?你可以使用命令 less /proc/meminfo 直接读取该文件。通过使用 less 命令,你可以在长长的输出中向上和向下滚动,以准确找到你需要的内容(图 8)。 + +![/proc/meminfo][19] + +图 8:less /proc/meminfo 命令的输出。 + +[Used with permission][4] + +关于 /proc/meminfo 你应该知道:这不是一个真实的文件。相反 /pro/meminfo 是一个虚拟文件,包含有关系统的实时动态信息。特别是,你需要检查以下值: + + * 全部内存 + + * 空闲内存 + + * 可用内存 + + * 缓冲区 + + * 文件缓存 + + * 交换缓存 + + * 全部交换区 + + * 空闲交换区 + +如果你想使用 /proc/meminfo,你可以用连词像 egrep 命令一样使用它:egrep --color'Mem | Cache | Swap'/proc/meminfo。这将生成一个易于阅读的列表,其中包含 Mem, Cache 和 Swap 等所有包含颜色的条目(图 9)。 + +![/proc/meminfo][21] + +图 9:让 /proc/meminfo 更容易阅读。 + +[Used with permission][4] + +### 继续学习 + +你要做的第一件事就是阅读每个命令的手册页(例如 man top, man free, man vmstat, man dmidecode)。从命令的手册页开始,对于如何在 Linux 上使用一个工具,它总是一个很好的学习方法。 + +通过 Linux 基金会和 edX 的免费 [“Linux 简介”][22]课程了解有关 Linux 的更多知识。 + + + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/learn/5-commands-checking-memory-usage-linux + +作者:[Jack Wallen][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[MjSeven](https://github.com/MjSeven) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/jlwallen +[1]:https://www.ubuntu.com/download/server +[2]:/files/images/memory1jpg +[3]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_1.jpg?itok=fhhhUL_l (top) +[4]:/licenses/category/used-permission +[5]:https://system76.com/desktops/leopard +[6]:/files/images/memory2jpg +[7]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_2.jpg?itok=zuVkQfvv (top) +[8]:/files/images/memory3jpg +[9]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_3.jpg?itok=rvuQp3t0 (free) +[10]:/files/images/memory4jpg +[11]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_4.jpg?itok=K_luLLPt (free) +[12]:/files/images/memory5jpg +[13]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_5.jpg?itok=q50atcsX (total) +[14]:/files/images/memory6jpg +[15]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_6.jpg?itok=bwFnUVmy (vmstat) +[16]:/files/images/memory7jpg +[17]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_7.jpg?itok=UNHIT_P6 (dmidecode) +[18]:/files/images/memory8jpg +[19]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_8.jpg?itok=t87jvmJJ (/proc/meminfo) +[20]:/files/images/memory9jpg +[21]:https://www.linux.com/sites/lcom/files/styles/rendered_file/public/memory_9.jpg?itok=t-iSMEKq (/proc/meminfo) +[22]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/translated/tech/20180615 BLUI- An easy way to create game UI.md b/translated/tech/20180615 BLUI- An easy way to create game UI.md deleted file mode 100644 index 5fdb1e5094..0000000000 --- a/translated/tech/20180615 BLUI- An easy way to create game UI.md +++ /dev/null @@ -1,57 +0,0 @@ -BLUI:创建游戏 UI 的简单方法 -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/gaming_plugin_blui_screenshot.jpg?itok=91nnYCt_) - -游戏开发引擎在过去几年中变得越来越易于​​使用。像 Unity 这样一直免费使用的引擎,以及最近从基于订阅的服务切换到免费服务的 Unreal,允许独立开发者使用 AAA 发布商使用的相同行业标准工具。虽然这些引擎都不是开源的,但每个引擎都能够促进其周围的开源生态系统的发展。 - -这些引擎中包含的插件允许开发人员通过添加特定程序来增强引擎的基本功能。这些程序的范围可以从简单的资源包到更复杂的事物,如人工智能 (AI) 集成。这些插件来自不同的创作者。有些是由引擎开发工作室和有些是个人提供的。后者中的很多是开源插件。 - -### 什么是 BLUI? - -作为独立游戏开发工作室的一部分,我体验到了在专有游戏引擎上使用开源插件的好处。Aaron Shea 开发的一个开源插件 [BLUI][1] 对我们团队的开发过程起到了重要作用。它允许我们使用基于 Web 的编程(如 HTML/CSS 和 JavaScript)创建用户界面 (UI) 组件。尽管虚幻引擎(我们选择的引擎)有一个内置的 UI 编辑器实现了类似目的,我们也选择使用这个开源插件。我们选择使用开源替代品有三个主要原因:它们的可访问性、易于实现以及伴随的开源程序活跃的、支持性好的在线社区。 - -在虚幻引擎的最早版本中,我们在游戏中创建 UI 的唯一方法是通过引擎的原生 UI 集成,使用 Autodesk 的 Scaleform 程序,或通过在虚幻社区中传播的一些选定的基于订阅的 Unreal 集成。在这些情况下,这些解决方案要么不能为独立开发者提供有竞争力的 UI 解决方案,要么对于小型团队来说太昂贵,要么只能为大型团队和 AAA 开发者提供。 - -在商业产品和 Unreal 的原生整合失败后,我们向独立社区寻求解决方案。我们在那里发现了 BLUI。它不仅与虚幻引擎无缝集成,而且还保持了一个强大且活跃的社区,经常推出更新并确保独立开发人员可以轻松访问文档。BLUI 使开发人员能够将 HTML 文件导入虚幻引擎,并在程序内部对其进行编程。这使得通过网络语言创建的 UI 能够集成到游戏的代码、资源和其他元素中,并拥有所有 HTML、CSS、Javascript 和其他网络语言的能力。它还为开源 [Chromium Embedded Framework][2] 提供全面支持。 - -### 安装和使用 BLUI - -使用 BLUI 的基本过程包括首先通过 HTML 创建 UI。开发人员可以使用任何工具来实现此目的,包括自举 JavaScript 代码,外部 API 或任何数据库代码。一旦这个 HTML 页面完成,你可以像安装任何 Unreal 插件那样安装它并加载或创建一个项目。项目加载后,你可以将 BLUI 函数放在 Unreal UI 图纸中的任何位置,或者通过 C++ 进行硬编码。开发人员可以通过其 HTML 页面调用函数,或使用 BLUI 的内部函数轻松更改变量。 - -![Integrating BLUI into Unreal Engine 4 blueprints][4] - -将 BLUI 集成到虚幻 4 图纸中。 - -在我们当前的项目中,我们使用 BLUI 将 UI 元素与游戏中的音轨同步,为游戏机制的节奏方面提供视觉反馈。将定制引擎编程与 BLUI 插件集成很容易。 - -![Using BLUI to sync UI elements with the soundtrack.][6] - -使用 BLUI 将 UI 元素与音轨同步。 - -通过 BLUI GitHub 页面上的[文档][7],将 BLUI 集成到虚幻 4 中是一个微不足道的过程。还有一个由支援虚幻引擎开发人员组成的[论坛][8],他们乐于询问和回答关于插件以及实现该工具时出现的任何问题。 - -### 开源优势 - -开源插件可以在专有游戏引擎的范围内扩展创意。他们继续降低进入游戏开发的障碍,并且可以产生前所未有的游戏内机制和资源。随着对专有游戏开发引擎的访问持续增长,开源插件社区将变得更加重要。不断增长的创造力必将超过专有软件,开源代码将会填补这些空白,并促进开发真正独特的游戏。而这种新颖性正是让独立游戏如此美好的原因! - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/6/blui-game-development-plugin - -作者:[Uwana lkaiddi][a] -选题:[lujun9972](https://github.com/lujun9972) -译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/uwikaiddi -[1]:https://github.com/AaronShea/BLUI -[2]:https://bitbucket.org/chromiumembedded/cef -[3]:/file/400616 -[4]:https://opensource.com/sites/default/files/uploads/blui_gaming_plugin-integratingblui.png (Integrating BLUI into Unreal Engine 4 blueprints) -[5]:/file/400621 -[6]:https://opensource.com/sites/default/files/uploads/blui_gaming_plugin-syncui.png (Using BLUI to sync UI elements with the soundtrack.) -[7]:https://github.com/AaronShea/BLUI/wiki -[8]:https://forums.unrealengine.com/community/released-projects/29036-blui-open-source-html5-js-css-hud-ui diff --git a/translated/tech/20180622 How to Check Disk Space on Linux from the Command line.md b/translated/tech/20180622 How to Check Disk Space on Linux from the Command line.md new file mode 100644 index 0000000000..a872fb15cd --- /dev/null +++ b/translated/tech/20180622 How to Check Disk Space on Linux from the Command line.md @@ -0,0 +1,138 @@ +如何使用命令行检查 Linux 上的磁盘空间 +======== + +>通过使用 `df` 命令和 `du` 命令查看 Linux 系统上挂载的驱动器的空间使用情况 + +![](https://camo.githubusercontent.com/9e87938753101d1aad089c55f3793b6f0ce8158f/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163652d6d61696e2e6a70673f69746f6b3d74394f7878633958) + +----------------------------- + +*** 快速提问: ***你的驱动器剩余多少剩余空间?一点点还是很多?接下来的提问是:你知道如何找出这些剩余空间吗?如果你使用的是 GUI 桌面( 例如 GNOME,KDE,Mate,Pantheon 等 ),则任务可能非常简单。但是,当你要在一个没有 GUI 桌面的服务器上查询剩余空间,你该如何去做呢?你是否要为这个任务安装相应的软件工具?答案是绝对不是。在 Linux 中,具备查找驱动器上的剩余磁盘空间的所有工具。事实上,有两个非常容易使用的工具。 + +在本文中,我将演示这些工具。我将使用 Elementary OS( LCTT译注:Elementary OS 是基于 Ubuntu 精心打磨美化的桌面 Linux 发行版 ),它还包括一个 GUI 选项,但我们将限制自己仅使用命令行。好消息是这些命令行工具随时可用于每个 Linux 发行版。在我的测试系统中,连接了许多的驱动器( 内部的和外部的 )。使用的命令与连接驱动器的位置无关,仅仅与驱动器是否已经挂载好并且对操作系统可见。 + +话虽如此,让我们来试试这些工具。 + +### df + +`df` 命令是我第一次用于在 Linux 上查询驱动器空间的工具,时间可以追溯到20世纪90年代。它的使用和报告结果非常简单。直到今天,`df` 还是我执行此任务的首选命令。此命令有几个选项开关,对于基本的报告,你实际上只需要一个选项。该命令是 `df -H` 。`-H` 选项开关用于将df的报告结果以人类可读的格式进行显示。`df -H` 的输出包括:已经使用了的空间量,可用空间,空间使用的百分比,以及每个磁盘连接到系统的挂载点( 图 1 )。 + +![](https://camo.githubusercontent.com/3e52d8b2ba349ecc8517b32080f18ec8216ca63c/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f312e6a70673f69746f6b3d614a6138415a414d) + +图 1:Elementary OS 系统上 `df -H` 命令的输出结果 + +如果你的驱动器列表非常长并且你只想查看单个驱动器上使用的空间,该怎么办?有了 `df`,就可以做到。我们来看一下位于 `/dev/sda1` 的主驱动器已经使用了多少空间。为此,执行如下命令: +``` + df -H /dev/sda1 +``` +输出将限于该驱动器( 图 2 )。 +![](https://camo.githubusercontent.com/4bb588e30a52dff9b588b14e489eb5ffaae98862/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f322e6a70673f69746f6b3d5f504171336b7843) + +图 2:一个单独驱动器空间情况 + +你还可以限制 `df` 命令结果报告中显示指定的字段。可用的字段包括: + +- source — 文件系统的来源( LCTT译注:通常为一个设备,如 `/dev/sda1` ) +- size — 块总数 +- used — 驱动器已使用的空间 +- avail — 可以使用的剩余空间 +- pcent — 驱动器已经使用的空间占驱动器总空间的百分比 +- target —驱动器的挂载点 + +让我们显示所有驱动器的输出,仅显示 `size` ,`used` ,`avail` 字段。对此的命令是: +``` + df -H --output=size,used,avail +``` +该命令的输出非常简单( 图 3 )。 +![](https://camo.githubusercontent.com/57dc803d72d6927b31e02b16e9cf695fec6b3a13/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f332e6a70673f69746f6b3d35316d38492d5675) + +图 3:显示我们驱动器的指定输出 + +这里唯一需要注意的是我们不知道输出的来源,因此,我们要把来源加入命令中: +``` + df -H --output=source,size,used,avail +``` +现在输出的信息更加全面有意义( 图 4 )。 +![](https://camo.githubusercontent.com/e30919f4cce4655d1eee89c635b83fcf7e73e44e/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f342e6a70673f69746f6b3d5375776775654e33) + +图 4:我们现在知道了磁盘使用情况的来源 + + +### du + +我们的下一个命令是 `du` 。 正如您所料,这代表磁盘使用情况( disk usage )。 `du` 命令与 `df` 命令完全不同,因为它报告目录而不是驱动器的空间使用情况。 因此,您需要知道要检查的目录的名称。 假设我的计算机上有一个包含虚拟机文件的目录。 那个目录是 `/media/jack/HALEY/VIRTUALBOX` 。 如果我想知道该特定目录使用了多少空间,我将运行如下命令: +``` + du -h /media/jack/HALEY/VIRTUALBOX +``` +上面命令的输出将显示目录中每个文件占用的空间( 图 5 )。 +![](https://camo.githubusercontent.com/7f7cc19851dfe98abaa782431c924e5a3d2061f7/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f352e6a70673f69746f6b3d5866533473375a71) + +图 5 在特定目录上运行 `du` 命令的输出 + +到目前为止,这个命令并没有那么有用。如果我们想知道特定目录的总使用量怎么办?幸运的是,`du` 可以处理这项任务。对于同一目录,命令将是: +``` + du -sh /media/jack/HALEY/VIRTUALBOX/ +``` +现在我们知道了上述目录使用存储空间的总和( 图 6 )。 +![](https://camo.githubusercontent.com/13cc1575d0612367b86ada9250cc03adb84272c7/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f362e6a70673f69746f6b3d7237317149437947) + +图 6:我的虚拟机文件使用存储空间的总和是 559GB + +您还可以使用此命令查看父项的所有子目录使用了多少空间,如下所示: +``` + du -h /media/jack/HALEY +``` +此命令的输出见( 图 7 ),是一个用于查看各子目录占用的驱动器空间的好方法。 +![](https://camo.githubusercontent.com/a59213db964bdeb8680e1b91f03fb6e631a58d8f/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f372e6a70673f69746f6b3d5074446534713579) + +图 7:子目录的存储空间使用情况 + +`du` 命令也是一个很好的工具,用于查看使用系统磁盘空间最多的目录列表。执行此任务的方法是将 `du` 命令的输出通过管道传递给另外两个命令:`sort` 和 `head` 。下面的命令用于找出驱动器上占用存储空间最大的前10各目录: +``` + du -a /media/jack | sort -n -r |head -n 10 +``` +输出将以从大到小的顺序列出这些目录( 图 8 )。 +![](https://camo.githubusercontent.com/4ddae52f2bd56f9a9c161e82f095e0671133855e/68747470733a2f2f7777772e6c696e75782e636f6d2f73697465732f6c636f6d2f66696c65732f7374796c65732f72656e64657265645f66696c652f7075626c69632f6469736b73706163655f382e6a70673f69746f6b3d7639453153466343) + +图 8:使用驱动器空间最多的 10 个目录 + +### 没有你想像的那么难 + +查看 Linux 系统上挂载的驱动器的空间使用情况非常简单。只要你将你的驱动器挂载在 Linux 系统上,使用 `df` 命令或 `du` 命令在报告必要信息方面都会非常出色。使用 `df` 命令,您可以快速查看磁盘上总的空间使用量,使用 `du` 命令,可以查看特定目录的空间使用情况。对于每一个 Linux 系统的管理员来说,这两个命令的结合使用是必须掌握的。 + +而且,如果你不需要使用 `du` 或 `df` 命令查看驱动器空间的使用情况,我最近介绍了查看 Linux 上内存使用情况的方法。总之,这些技巧将大力帮助你成功管理 Linux 服务器。 + +通过 Linux Foundation 和 edX 免费提供的 “ Linux 简介 ” 课程,了解更多有关 Linux 的信息。 + +-------- + +via: https://www.linux.com/learn/intro-to-linux/2018/6how-check-disk-space-linux-command-line + +作者:Jack Wallen 选题:lujun9972 译者:SunWave 校对:校对者ID + +本文由 LCTT 原创编译,Linux中国 荣誉推出 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/translated/tech/20180623 Intercepting and Emulating Linux System Calls with Ptrace - null program.md b/translated/tech/20180623 Intercepting and Emulating Linux System Calls with Ptrace - null program.md new file mode 100644 index 0000000000..dca23047e8 --- /dev/null +++ b/translated/tech/20180623 Intercepting and Emulating Linux System Calls with Ptrace - null program.md @@ -0,0 +1,293 @@ +使用 Ptrace 去监听和仿真 Linux 系统调用 « null program +====== + +`ptrace(2)`(”进程跟踪“)系统调用通常都与调试有关。它是类 Unix 系统上通过原生调试器监测调试进程的主要机制。它也是实现 [strace][1](系统调用跟踪)的常见方法。使用 Ptrace,跟踪器可以暂停跟踪过程,[检查和设置寄存器和内存][2],监视系统调用,甚至可以监听系统调用。 + +通过监听功能,意味着跟踪器可以修改系统调用参数,修改系统调用的返回值,甚至监听某些系统调用。言外之意就是,一个跟踪器可以完全服务于系统调用本身。这是件非常有趣的事,因为这意味着**一个跟踪器可以仿真一个完整的外部操作系统**,而这些都是在没有得到内核任何帮助的情况下由 Ptrace 实现的。 + +问题是,在同一时间一个进程只能被一个跟踪器附着,因此在那个进程的调试期间,不可能再使用诸如 GDB 这样的工具去仿真一个外部操作系统。另外的问题是,仿真系统调用的开销非常高。 + +在本文中,我们将专注于 x86-64 [Linux 的 Ptrace][3],并将使用一些 Linux 专用的扩展。同时,在本文中,我们将忽略掉一些错误检查,但是完整的源代码仍然会包含这些错误检查。 + +本文中的可直接运行的示例代码在这里: + +**** + +### strace + +在进入到最有趣的部分之前,我们先从回顾 strace 的基本实现来开始。它不是 [DTrace][4],但 strace 仍然非常有用。 + +Ptrace 还没有被标准化。它的界面在不同的操作系统上非常类似,尤其是在核心功能方面,但是在不同的系统之间仍然存在细微的差别。`ptrace(2)` 的样子看起来应该像下面这样,但特定的类型可能有些差别。 +``` +long ptrace(int request, pid_t pid, void *addr, void *data); + +``` + +`pid` 是跟踪的进程 ID。虽然**同一个时间**只有一个跟踪器可以附着到进程上,但是一个跟踪器可以附着跟踪多个进程。 + +`request` 字段选择一个具体的 Ptrace 函数,比如 `ioctl(2)` 接口。对于 strace,只需要两个: + + * `PTRACE_TRACEME`:这个进程被它的父进程跟踪。 + * `PTRACE_SYSCALL`:继续跟踪,但是在下一下系统调用入口或出口时停止。 + * `PTRACE_GETREGS`:取得被跟踪进程的寄存器内容副本。 + + + +另外两个字段,`addr` 和 `data`,作为所选的 Ptrace 函数的一般参数。一般情况下,可以忽略一个或全部忽略,在那种情况下,传递零个参数。 + +strace 接口实质上是另一个命令的前缀。 +``` +$ strace [strace options] program [arguments] + +``` + +最小化的 strace 不需要任何选项,因此需要做的第一件事情是 — 假设它至少有一个参数 — 在 `argv` 尾部的 `fork(2)` 和 `exec(2)` 被跟踪进程。但是在加载目标程序之前,新的进程将告知内核,目标程序将被它的父进程继续跟踪。被跟踪进程将被这个 Ptrace 系统调用暂停。 +``` +pid_t pid = fork(); +switch (pid) { + case -1: /* error */ + FATAL("%s", strerror(errno)); + case 0: /* child */ + ptrace(PTRACE_TRACEME, 0, 0, 0); + execvp(argv[1], argv + 1); + FATAL("%s", strerror(errno)); +} + +``` + +父进程使用 `wait(2)` 等待子进程的 `PTRACE_TRACEME`,当 `wait(2)` 返回后,子进程将被暂停。 +``` +waitpid(pid, 0, 0); + +``` + +在允许子进程继续运行之前,我们告诉操作系统,被跟踪进程被它的父进程的跟踪应该被终止。一个真实的 strace 实现可能会设置其它的选择,比如: `PTRACE_O_TRACEFORK`。 +``` +ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_EXITKILL); + +``` + +剩余部分就是一个简单的、无休止的循环了,每循环一次捕获一个系统调用。循环体总共有四步: + + 1. 等待进程进入下一个系统调用。 + 2. 输出一个系统调用的描述。 + 3. 允许系统调用去运行和等待返回。 + 4. 输出系统调用返回值。 + + + +`PTRACE_SYSCALL` 要求用于等待下一个系统调用时开始,和等待那个系统调用去退出。和前面一样,需要一个 `wait(2)` 去等待跟踪进入期望的状态。 +``` +ptrace(PTRACE_SYSCALL, pid, 0, 0); +waitpid(pid, 0, 0); + +``` + +当 `wait(2)` 返回时,线程寄存器中写入了被系统调用所产生的系统调用号和它的参数。尽管如此,操作系统将不再为这个系统调用提供服务。线程寄存器中的详细内容对后续操作很重要。 + +接下来的一步是采集系统调用信息。这是得到特定系统架构的地方。在 x86-64 上,[系统调用号是在 `rax` 中传递的][5],而参数(最多 6 个)是在 `rdi`、`rsi`、`rdx`、`r10`、`r8`、和 `r9` 中传递的。另外的 Ptrace 调用将读取这些寄存器,不过这里再也不需要 `wait(2)` 了,因为跟踪状态再也不会发生变化了。 +``` +struct user_regs_struct regs; +ptrace(PTRACE_GETREGS, pid, 0, ®s); +long syscall = regs.orig_rax; + +fprintf(stderr, "%ld(%ld, %ld, %ld, %ld, %ld, %ld)", + syscall, + (long)regs.rdi, (long)regs.rsi, (long)regs.rdx, + (long)regs.r10, (long)regs.r8, (long)regs.r9); + +``` + +这里有一个敬告。由于 [内核的内部用途][6],系统调用号是保存在 `orig_rax` 中而不是 `rax` 中。而所有的其它系统调用参数都是非常简单明了的。 + +接下来是它的另一个 `PTRACE_SYSCALL` 和 `wait(2)`,然后是另一个 `PTRACE_GETREGS` 去获取结果。结果保存在 `rax` 中。 +``` +ptrace(PTRACE_GETREGS, pid, 0, ®s); +fprintf(stderr, " = %ld\n", (long)regs.rax); + +``` + +这个简单程序的输出也是非常粗糙的。这里的系统调用都没有符号名,并且所有的参数都是以数字形式输出,甚至是一个指向缓冲区的指针。更完整的 strace 输出将能知道哪个参数是指针,以及 `process_vm_readv(2)` 为了从跟踪中正确输出内容而读取了哪些缓冲区。 + +然后,这些仅仅是系统调用监听的基础工作。 + +### 系统调用监听 + +假设我们想使用 Ptrace 去实现如 OpenBSD 的 [`pledge(2)`][7] 这样的功能,它是 [一个进程承诺只使用一套受限的系统调用][8]。初步想法是,许多程序一般都有一个初始化阶段,这个阶段它们都需要进行许多的系统访问(比如,打开文件、绑定套接字、等等)。初始化完成以后,它们进行一个主循环,在主循环中它们处理输入,并且仅使用所需的、很少的一套系统调用。 + +在进入主循环之前,可以限制一个进程只能运行它自己所需要的几个操作。如果 [程序有 Bug][9],允许通过恶意的输入去利用这个 Bug,这个承诺可以有效地限制漏洞利用的实现。 + +使用与 strace 相同的模型,但不是输出所有的系统调用,我们既能够拦截某些系统调用,也可以在它的行为异常时简单地终止被跟踪进程。终止它很容易:只需要在跟踪器中调用 `exit(2)`。因此,它也可以被设置为去终止被跟踪进程。拦截系统调用和允许子进程继续运行都只是些雕虫小技而已。 + +最棘手的部分是**当系统调用启动后没有办法去中断它**。进入系统调用之后,当跟踪器从 `wait(2)` 中返回,停止一个系统调用的仅有方式是,发生被跟踪进程终止的情况。 + +然而,我们不仅可以“搞乱”系统调用的参数,也可以改变系统调用号本身,将它修改为一个不存在的系统调用。返回时,在 `errno` 中 [通过正常的内部信号][10],我们就可以报告一个“友好的”错误信息。 +``` +for (;;) { + /* Enter next system call */ + ptrace(PTRACE_SYSCALL, pid, 0, 0); + waitpid(pid, 0, 0); + + struct user_regs_struct regs; + ptrace(PTRACE_GETREGS, pid, 0, ®s); + + /* Is this system call permitted? */ + int blocked = 0; + if (is_syscall_blocked(regs.orig_rax)) { + blocked = 1; + regs.orig_rax = -1; // set to invalid syscall + ptrace(PTRACE_SETREGS, pid, 0, ®s); + } + + /* Run system call and stop on exit */ + ptrace(PTRACE_SYSCALL, pid, 0, 0); + waitpid(pid, 0, 0); + + if (blocked) { + /* errno = EPERM */ + regs.rax = -EPERM; // Operation not permitted + ptrace(PTRACE_SETREGS, pid, 0, ®s); + } +} + +``` + +这个简单的示例只是检查了系统调用是否违反白名单或黑名单。而它们在这里并没有差别,比如,允许文件以只读而不是读写方式打开(`open(2)`),允许匿名内存映射但不允许非匿名映射等等。但是这里仍然没有办法去动态撤销被跟踪进程的权限。 + +跟踪器与被跟踪进程如何沟通?使用人为的系统调用! + +### 创建一个人为的系统调用 + +对于我的这个类似于 pledge 的系统调用 — 我可以通过调用 `xpledge()` 将它与真实的系统调用区分开 — 我设置 10000 作为它的系统调用号,这是一个非常大的数字,真实的系统调用中从来不会用到它。 +``` +#define SYS_xpledge 10000 + +``` + +为演示需要,我同时构建了一个非常小的界面,这在实践中并不是个好主意。它与 OpenBSD 的 `pledge(2)` 稍有一些相似之处,它使用了一个 [字符串界面][11]。事实上,设计一个健壮且安全的权限集是非常复杂的,正如在 `pledge(2)` 的手册页面上所显示的那样。下面是对被跟踪进程的完整界面和系统调用的实现: +``` +#define _GNU_SOURCE +#include + +#define XPLEDGE_RDWR (1 << 0) +#define XPLEDGE_OPEN (1 << 1) + +#define xpledge(arg) syscall(SYS_xpledge, arg) + +``` + +如果给它传递零个参数,仅允许一些基本的系统调用,包括那些用于去分配内存的系统调用(比如 `brk(2)`)。 `PLEDGE_RDWR` 位允许 [各种][12] 读和写的系统调用(`read(2)`、`readv(2)`、`pread(2)`、`preadv(2)` 等等)。`PLEDGE_OPEN` 位允许 `open(2)`。 + +为防止发生提升权限的行为,`pledge()` 会拦截它自己 — 但这样也防止了权限撤销,以后再细说这方面内容。 + +在 xpledge 跟踪器中,我需要去检查这个系统调用: +``` +/* Handle entrance */ +switch (regs.orig_rax) { + case SYS_pledge: + register_pledge(regs.rdi); + break; +} + +``` + +操作系统将返回 `ENOSYS`(因为函数还没有实现),因此它不是一个真实的系统调用。为此在退出时我用一个 `success (0)` 去覆写它。 +``` +/* Handle exit */ +switch (regs.orig_rax) { + case SYS_pledge: + ptrace(PTRACE_POKEUSER, pid, RAX * 8, 0); + break; +} + +``` + +我写了一小段测试程序去打开 `/dev/urandom`,做一个读操作,尝试去承诺后,我第二次打开 `/dev/urandom`,然后确认它能够读取原始的 `/dev/urandom` 文件描述符。在没有承诺跟踪器的情况下运行,输出如下: +``` +$ ./example +fread("/dev/urandom")[1] = 0xcd2508c7 +XPledging... +XPledge failed: Function not implemented +fread("/dev/urandom")[2] = 0x0be4a986 +fread("/dev/urandom")[1] = 0x03147604 + +``` + +做一个无效的系统调用并不会让应用程序崩溃。它只是失败,这是一个很方便的返回方式。当它在跟踪器下运行时,它的输出如下: +``` +$ ./xpledge ./example +fread("/dev/urandom")[1] = 0xb2ac39c4 +XPledging... +fopen("/dev/urandom")[2]: Operation not permitted +fread("/dev/urandom")[1] = 0x2e1bd1c4 + +``` + +这个承诺很成功,第二次的 `fopen(3)` 并没有实现,因为跟踪器用一个 `EPERM` 拦截了它。 + +可以将这种思路进一步发扬光大,比如,改变文件路径或返回一个假的结果。一个跟踪器可以很高效地 chroot 它的被跟踪进程,通过一个系统调用将任意路径传递给 root 从而实现 chroot 路径。它甚至可以对用户进行欺骗,告诉用户它以 root 运行。事实上,这些就是 [Fakeroot NG][13] 程序所做的事情。 + +### 仿真外部系统 + +假设你不满足于仅监听一些系统调用,而是想监听全部系统调用。你收到 [一个打算在其它操作系统上运行的二进制程序][14],因为没有系统调用,这个二进制程序将无法正常运行。 + +使用我在前面所描述的这些内容你就可以管理这一切。跟踪器可以使用一个假冒的东西去代替系统调用号,允许它去失败,以及为系统调用本身提供服务。但那样做的效率很低。其实质上是对每个系统调用做了三个上下文切换:一个是在入口上停止,一个是让系统调用总是以失败告终,还有一个是在系统调用退出时停止。 + +从 2005 年以后,对于这个技术,PTrace 的 Linux 版本有更高效的操作:`PTRACE_SYSEMU`。PTrace 仅在每个系统调用发出时停止一次,在允许被跟踪进程继续运行之前,由跟踪器为系统调用提供服务。 +``` +for (;;) { + ptrace(PTRACE_SYSEMU, pid, 0, 0); + waitpid(pid, 0, 0); + + struct user_regs_struct regs; + ptrace(PTRACE_GETREGS, pid, 0, ®s); + + switch (regs.orig_rax) { + case OS_read: + /* ... */ + + case OS_write: + /* ... */ + + case OS_open: + /* ... */ + + case OS_exit: + /* ... */ + + /* ... and so on ... */ + } +} + +``` + +从任何使用(足够)稳定的系统调用 ABI(译注:应用程序二进制接口),在相同架构的机器上运行一个二进制程序时,你只需要 `PTRACE_SYSEMU` 跟踪器,一个加载器(用于代替 `exec(2)`),和这个二进制程序所需要(或仅运行静态的二进制程序)的任何系统库即可。 + +事实上,这听起来有点像一个有趣的周末项目。 + +-------------------------------------------------------------------------------- + +via: http://nullprogram.com/blog/2018/06/23/ + +作者:[Chris Wellons][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://nullprogram.com +[1]:https://blog.plover.com/Unix/strace-groff.html +[2]:http://nullprogram.com/blog/2016/09/03/ +[3]:http://man7.org/linux/man-pages/man2/ptrace.2.html +[4]:http://nullprogram.com/blog/2018/01/17/ +[5]:http://nullprogram.com/blog/2015/05/15/ +[6]:https://stackoverflow.com/a/6469069 +[7]:https://man.openbsd.org/pledge.2 +[8]:http://www.openbsd.org/papers/hackfest2015-pledge/mgp00001.html +[9]:http://nullprogram.com/blog/2017/07/19/ +[10]:http://nullprogram.com/blog/2016/09/23/ +[11]:https://www.tedunangst.com/flak/post/string-interfaces +[12]:http://nullprogram.com/blog/2017/03/01/ +[13]:https://fakeroot-ng.lingnu.com/index.php/Home_Page +[14]:http://nullprogram.com/blog/2017/11/30/ diff --git a/translated/tech/20180703 Understanding Python Dataclasses — Part 1.md b/translated/tech/20180703 Understanding Python Dataclasses — Part 1.md new file mode 100644 index 0000000000..d038a4d5bf --- /dev/null +++ b/translated/tech/20180703 Understanding Python Dataclasses — Part 1.md @@ -0,0 +1,513 @@ +理解 Python 的 Dataclasses -- 第一部分 +====== + +![](https://cdn-images-1.medium.com/max/900/1*7pr8EL8EDsP296pxL7Wz_g.png) + +如果你正在阅读本文,那么你已经意识到了 Python 3.7 以及它所包含的新特性。就我个人而言,我对 `Dataclasses` 感到非常兴奋,因为我有一段时间在等待它了。 + +本系列包含两部分: +1\. Dataclass 特点概述 +2\. 在下一篇文章概述 Dataclass 的 `fields` + +### 介绍 + +`Dataclasses` 是 Python 的类(译注:更准确的说,它是一个模块),适用于存储数据对象。你可能会问什么是数据对象?下面是定义数据对象的一个不太详细的特性列表: + + * 它们存储数据并代表某种数据类型。例如:一个数字。对于熟悉 ORM 的人来说,模型实例是一个数据对象。它代表一种特定的实体。它包含那些定义或表示实体的属性。 + + * 它们可以与同一类型的其他对象进行比较。例如:一个数字可以是 `greater than(大于)`, `less than(小于)` 或 `equal(等于)` 另一个数字。 + +当然还有更多的特性,但是这个列表足以帮助你理解问题的关键。 + +为了理解 `Dataclasses`,我们将实现一个包含数字的简单类,并允许我们执行上面提到的操作。 +首先,我们将使用普通类,然后我们再使用 `Dataclasses` 来实现相同的结果。 + +但在我们开始之前,先来谈谈 `dataclasses` 的用法。 + +Python 3.7 提供了一个装饰器 [dataclass][2],用于将类转换为 `dataclass`。 + +你所要做的就是将类包在装饰器中: + +``` +from dataclasses import dataclass + +@dataclass +class A: + … +``` + +现在,让我们深入了解一下 `dataclass` 带给我们的变化和用途。 + +### 初始化 + +通常是这样: + +``` +class Number: + + def __init__(self, val): + self.val = val + +>>> one = Number(1) +>>> one.val +>>> 1 +``` + +用 `dataclass` 是这样: + +``` +@dataclass +class Number: + val:int + +>>> one = Number(1) +>>> one.val +>>> 1 +``` + +以下是 dataclass 装饰器带来的变化: + +1\. 无需定义 `__init__`,然后将值赋给 `self.d` 负责处理它(to 校正:这里真不知道 d 在哪里) +2\. 我们以更加易读的方式预先定义了成员属性,以及[类型提示][3]。我们现在立即能知道 `val` 是 `int` 类型。这无疑比一般定义类成员的方式更具可读性。 + +> Python 之禅: 可读性很重要 + +它也可以定义默认值: + +``` +@dataclass +class Number: + val:int = 0 +``` + +### 表示 + +对象表示指的是对象的一个有意义的字符串表示,它在调试时非常有用。 + +默认的 Python 对象表示不是很直观: + +``` +class Number: + def __init__(self, val = 0): + self.val = val + +>>> a = Number(1) +>>> a +>>> <__main__.Number object at 0x7ff395b2ccc0> +``` + +这让我们无法知悉对象的作用,并且会导致糟糕的调试体验。 + +一个有意义的表示可以通过在类中定义一个 `__repr__` 方法来实现。 + +``` +def __repr__(self): + return self.val +``` + +现在我们得到这个对象有意义的表示: + +``` +>>> a = Number(1) +>>> a +>>> 1 +``` + +`dataclass` 会自动添加一个 `__repr__ ` 函数,这样我们就不必手动实现它了。 + +``` +@dataclass +class Number: + val: int = 0 +``` + +``` +>>> a = Number(1) +>>> a +>>> Number(val = 1) +``` + +### 数据比较 + +通常,数据对象之间需要相互比较。 + +两个对象 `a` 和 `b` 之间的比较通常包括以下操作: + +* a < b + +* a > b + +* a == b + +* a >= b + +* a <= b + +在 Python 中,能够在可以执行上述操作的类中定义[方法][4]。为了简单起见,不让这篇文章过于冗长,我将只展示 `==` 和 `<` 的实现。 + +通常这样写: + +``` +class Number: + def __init__( self, val = 0): + self.val = val + + def __eq__(self, other): + return self.val == other.val + + def __lt__(self, other): + return self.val < other.val +``` + +使用 `dataclass`: + +``` +@dataclass(order = True) +class Number: + val: int = 0 +``` + +是的,就是这样简单。 + +我们不需要定义 `__eq__` 和 `__lt__` 方法,因为当 `order = True` 被调用时,`dataclass` 装饰器会自动将它们添加到我们的类定义中。 + +那么,它是如何做到的呢? + +当你使用 `dataclass` 时,它会在类定义中添加函数 `__eq__` 和 `__lt__` 。我们已经知道这点了。那么,这些函数是怎样知道如何检查相等并进行比较呢? + +生成 `__eq__` 函数的 `dataclass` 类会比较两个属性构成的元组,一个由自己属性构成的,另一个由同类的其他实例的属性构成。在我们的例子中,`自动`生成的 `__eq__` 函数相当于: + +``` +def __eq__(self, other): + return (self.val,) == (other.val,) +``` + +让我们来看一个更详细的例子: + +我们会编写一个 `dataclass` 类 `Person` 来保存 `name` 和 `age`。 + +``` +@dataclass(order = True) +class Person: + name: str + age:int = 0 +``` + +自动生成的 `__eq__` 方法等同于: + +``` +def __eq__(self, other): + return (self.name, self.age) == ( other.name, other.age) +``` + +请注意属性的顺序。它们总是按照你在 dataclass 类中定义的顺序生成。 + +同样,等效的 `__le__` 函数类似于: + +``` +def __le__(self, other): + return (self.name, self.age) <= (other.name, other.age) +``` + +当你需要对数据对象列表进行排序时,通常会出现像 `__le__` 这样的函数的定义。Python 内置的 [sorted][5] 函数依赖于比较两个对象。 + +``` +>>> import random + +>>> a = [Number(random.randint(1,10)) for _ in range(10)] #generate list of random numbers + +>>> a + +>>> [Number(val=2), Number(val=7), Number(val=6), Number(val=5), Number(val=10), Number(val=9), Number(val=1), Number(val=10), Number(val=1), Number(val=7)] + +>>> sorted_a = sorted(a) #Sort Numbers in ascending order + +>>> [Number(val=1), Number(val=1), Number(val=2), Number(val=5), Number(val=6), Number(val=7), Number(val=7), Number(val=9), Number(val=10), Number(val=10)] + +>>> reverse_sorted_a = sorted(a, reverse = True) #Sort Numbers in descending order + +>>> reverse_sorted_a + +>>> [Number(val=10), Number(val=10), Number(val=9), Number(val=7), Number(val=7), Number(val=6), Number(val=5), Number(val=2), Number(val=1), Number(val=1)] + +``` + +### `dataclass` 作为一个可调用的装饰器 + +定义所有的 `dunder`(译注:这是指双下划线方法,即魔法方法)方法并不总是值得的。你的用例可能只包括存储值和检查相等性。因此,你只需定义 `__init__` 和 `__eq__` 方法。如果我们可以告诉装饰器不生成其他方法,那么它会减少一些开销,并且我们将在数据对象上有正确的操作。 + +幸运的是,这可以通过将 `dataclass` 装饰器作为可调用对象来实现。 + +从官方[文档][6]来看,装饰器可以用作具有如下参数的可调用对象: + +``` +@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False) +class C: + … +``` + +1. `init`:默认将生成 `__init__` 方法。如果传入 `False`,那么该类将不会有 `__init__` 方法。 + +2. `repr`:`__repr__` 方法默认生成。如果传入 `False`,那么该类将不会有 `__repr__` 方法。 + +3. `eq`:默认将生成 `__eq__` 方法。如果传入 `False`,那么 `__eq__` 方法将不会被 `dataclass` 添加,但默认为 `object.__eq__`。 + +4. `order`:默认将生成 `__gt__`、`__ge__`、`__lt__`、`__le__` 方法。如果传入 `False`,则省略它们。 + +我们在接下来会讨论 `frozen`。由于 `unsafe_hash` 参数复杂的用例,它值得单独发布一篇文章。 + +现在回到我们的用例,以下是我们需要的: + +1. `__init__` +2. `__eq__` + +默认会生成这些函数,因此我们需要的是不生成其他函数。那么我们该怎么做呢?很简单,只需将相关参数作为 false 传入给生成器即可。 + +``` +@dataclass(repr = False) # order, unsafe_hash and frozen are False +class Number: + val: int = 0 + + +>>> a = Number(1) + +>>> a + +>>> <__main__.Number object at 0x7ff395afe898> + +>>> b = Number(2) + +>>> c = Number(1) + +>>> a == b + +>>> False + +>>> a < b + +>>> Traceback (most recent call last): + File “”, line 1, in +TypeError: ‘<’ not supported between instances of ‘Number’ and ‘Number’ +``` + +### Frozen(不可变) 实例 + +Frozen 实例是在初始化对象后无法修改其属性的对象。 + +> 无法创建真正不可变的 Python 对象 + +在 Python 中创建对象的不可变属性是一项艰巨的任务,我将不会在本篇文章中深入探讨。 + +以下是我们期望不可变对象能够做到的: + +``` +>>> a = Number(10) #Assuming Number class is immutable + +>>> a.val = 10 # Raises Error +``` + +有了 `dataclass`,就可以通过使用 `dataclass` 装饰器作为可调用对象配合参数 `frozen=True` 来定义一个 `frozen` 对象。 + +当实例化一个 `frozen` 对象时,任何企图修改对象属性的行为都会引发 `FrozenInstanceError`。 + +``` +@dataclass(frozen = True) +class Number: + val: int = 0 + +>>> a = Number(1) + +>>> a.val + +>>> 1 + +>>> a.val = 2 + +>>> Traceback (most recent call last): + File “”, line 1, in + File “”, line 3, in __setattr__ +dataclasses.FrozenInstanceError: cannot assign to field ‘val’ +``` + +因此,一个 `frozen` 实例是一种很好方式来存储: + +* 常数 + +* 设置 + +这些通常不会在应用程序的生命周期内发生变化,任何企图修改它们的行为都应该被禁止。 + +### 后期初始化处理 + +有了 `dataclass`,需要定义一个 `__init__` 方法来将变量赋给 `self` 这种初始化操作已经得到了处理。但是我们失去了在变量被赋值之后立即需要的函数调用或处理的灵活性。 + +让我们来讨论一个用例,在这个用例中,我们定义一个 `Float` 类来包含浮点数,然后在初始化之后立即计算整数和小数部分。 + +通常是这样: + +``` +import math + +class Float: + def __init__(self, val = 0): + self.val = val + self.process() + + def process(self): + self.decimal, self.integer = math.modf(self.val) + +>>> a = Float( 2.2) + +>>> a.decimal + +>>> 0.2000 + +>>> a.integer + +>>> 2.0 +``` + +幸运的是,使用 [__post_init__][9]  方法已经能够处理后期初始化操作。 + +生成的 `__init__`  方法在返回之前调用 `__post_init__` 返回。因此,可以在函数中进行任何处理。 + +``` +import math + +@dataclass +class FloatNumber: + val: float = 0.0 + + def __post_init__(self): + self.decimal, self.integer = math.modf(self.val) + +>>> a = Number(2.2) + +>>> a.val + +>>> 2.2 + +>>> a.integer + +>>> 2.0 + +>>> a.decimal + +>>> 0.2 +``` + +多么方便! + +### 继承 + +`Dataclasses` 支持继承,就像普通的 Python 类一样。 + +因此,父类中定义的属性将在子类中可用。 + +``` +@dataclass +class Person: + age: int = 0 + name: str + +@dataclass +class Student(Person): + grade: int + +>>> s = Student(20, "John Doe", 12) + +>>> s.age + +>>> 20 + +>>> s.name + +>>> "John Doe" + +>>> s.grade + +>>> 12 +``` + +请注意,`Student` 的参数是在类中定义的字段的顺序。 + +继承过程中 `__post_init__` 的行为是怎样的? + +由于 `__post_init__` 只是另一个函数,因此必须以传统方式调用它: + +``` +@dataclass +class A: + a: int + + def __post_init__(self): + print("A") + +@dataclass +class B(A): + b: int + + def __post_init__(self): + print("B") + +>>> a = B(1,2) + +>>> B +``` + +在上面的例子中,只有 `B` 的 `__post_init__` 被调用,那么我们如何调用 `A` 的 `__post_init__` 呢? + +因为它是父类的函数,所以可以用 `super` 来调用它。 + +``` +@dataclass +class B(A): + b: int + + def __post_init__(self): + super().__post_init__() # 调用 A 的 post init + print("B") + +>>> a = B(1,2) + +>>> A + B +``` + +### 结论 + +因此,以上是 dataclasses 使 Python 开发人员变得更轻松的几种方法。 + +我试着彻底覆盖大部分的用例,但是,没有人是完美的。如果你发现了错误,或者想让我注意相关的用例,请联系我。 + +我将在另一篇文章中介绍 [dataclasses.field][10] 和 `unsafe_hash`。 + +在 [Github][11] 和 [Twitter][12] 关注我。 + +更新:`dataclasses.field` 的文章可以在[这里][13]找到。 + + +-------------------------------------------------------------------------------- + +via: https://medium.com/mindorks/understanding-python-dataclasses-part-1-c3ccd4355c34 + +作者:[Shikhar Chauhan][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://medium.com/@xsschauhan?source=post_header_lockup +[1]:https://medium.com/@xsschauhan/understanding-python-dataclasses-part-2-660ecc11c9b8 +[2]:https://docs.python.org/3.7/library/dataclasses.html#dataclasses.dataclass +[3]:https://stackoverflow.com/q/32557920/4333721 +[4]:https://docs.python.org/3/reference/datamodel.html#object.__lt__ +[5]:https://docs.python.org/3.7/library/functions.html#sorted +[6]:https://docs.python.org/3/library/dataclasses.html#dataclasses.dataclass +[7]:http://twitter.com/dataclass +[8]:http://twitter.com/dataclass +[9]:https://docs.python.org/3/library/dataclasses.html#post-init-processing +[10]:https://docs.python.org/3/library/dataclasses.html#dataclasses.field +[11]:http://github.com/xssChauhan/ +[12]:https://twitter.com/xssChauhan +[13]:https://medium.com/@xsschauhan/understanding-python-dataclasses-part-2-660ecc11c9b8 diff --git a/translated/tech/20180709 A sysadmin-s guide to network management.md b/translated/tech/20180709 A sysadmin-s guide to network management.md new file mode 100644 index 0000000000..68a85ecac3 --- /dev/null +++ b/translated/tech/20180709 A sysadmin-s guide to network management.md @@ -0,0 +1,200 @@ +系统管理员的一个网络管理指南 +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openwires_fromRHT_520_0612LL.png?itok=PqZi55Ab) + +如果你是一位系统管理员,那么你的日常工作应该包括管理服务器和数据中心的网络。以下的 Linux 实用工具和命令 —— 从基础的到高级的 —— 将帮你更轻松地管理你的网络。 + +在几个命令中,你将会看到 ``,它是“完全合格域名”的全称。当你看到它时,你应该用你的网站 URL 或你的服务器来代替它(比如,`server-name.company.com`),具体要视情况而定。 + +### Ping + +正如它的名字所表示的那样,`ping` 是用于去检查从你的系统到你想去连接的系统之间端到端的连通性。当一个 ping 成功时,它使用的 [ICMP][1] 的 echo 包将会返回到你的系统中。它是检查系统/网络连通性的一个良好开端。你可以在 IPv4 和 IPv6 地址上使用 `ping` 命令。(阅读我的文章 "[如何在 Linux 系统上找到你的 IP 地址][2]" 去学习更多关于 IP 地址的知识) + +**语法:** + + * IPv4: `ping /` + * IPv6: `ping6 /` + + + +你也可以使用 `ping` 去解析出网站所对应的 IP 地址,如下图所示: + +![](https://opensource.com/sites/default/files/uploads/ping-screen-0.png) + +### Traceroute + +`ping` 是用于检查端到端的连通性,`traceroute` 实用工具将告诉你到达对端系统、网站、或服务器所经过的路径上所有路由器的 IP 地址。`traceroute` 在网络连接调试中经常用于在 `ping` 之后的第二步。 + +这是一个跟踪从你的系统到其它对端的全部网络路径的非常好的工具。在检查端到端的连通性时,这个实用工具将告诉你到达对端系统、网站、或服务器上所经历的路径上的全部路由器的 IP 地址。通常用于网络连通性调试的第二步。 + +**语法:** + + * `traceroute /` + + + +### Telnet + +**语法:** + + * `telnet /` 是用于 [telnet][3] 进入任何支持该协议的服务器。 + + + +### Netstat + +这个网络统计(`netstat`)实用工具是用于去分析解决网络连接问题和检查接口/端口统计数据、路由表、协议状态等等的。它是任何管理员都应该必须掌握的工具。 + +**语法:** + + * `netstat -l` 显示所有处于监听状态的端口列表。 + * `netstat -a` 显示所有端口;如果去指定仅显示 TCP 端口,使用 `-at`(指定信显示 UDP 端口,使用 `-au`)。 + * `netstat -r` 显示路由表。 + + ![](https://opensource.com/sites/default/files/uploads/netstat-r.png) + + * `netstat -s` 显示每个协议的状态总结。 + + ![](https://opensource.com/sites/default/files/uploads/netstat-s.png) + + * `netstat -i` 显示每个接口传输/接收(TX/RX)包的统计数据。 + + ![](https://opensource.com/sites/default/files/uploads/netstat-i.png) + +### Nmcli + +`nmcli` 是一个管理网络连接、配置等工作的非常好的实用工具。它能够去管理网络管理程序和修改任何设备的网络配置详情。 + +**语法:** + + * `nmcli device` 列出网络上的所有设备。 + + * `nmcli device show ` 显示指定接口的网络相关的详细情况。 + + * `nmcli connection` 检查设备的连接情况。 + + * `nmcli connection down ` 关闭指定接口。 + + * `nmcli connection up ` 打开指定接口。 + + * `nmcli con add type vlan con-name dev id ipv4 gw4 ` 在特定的接口上使用指定的 VLAN 号添加一个虚拟局域网(VLAN)接口、IP 地址、和网关。 + + ![](https://opensource.com/sites/default/files/uploads/nmcli.png) + + +### 路由 + +检查和配置路由的命令很多。下面是其中一些比较有用的: + +**语法:** + + * `ip route` 显示各自接口上所有当前的路由配置。 + + ![](https://opensource.com/sites/default/files/uploads/ip-route.png) + + * `route add default gw ` 在路由表中添加一个默认的网关。 + * `route add -net gw ` 在路由表中添加一个新的网络路由。还有许多其它的路由参数,比如,添加一个默认路由,默认网关等等。 + * `route del -net ` 从路由表中删除一个指定的路由条目。 + + ![](https://opensource.com/sites/default/files/uploads/route-add-del.png) + + * `ip neighbor` 显示当前的邻接表和用于去添加、改变、或删除新的邻居。 + +![](https://opensource.com/sites/default/files/uploads/ip-neighbor.png) + +![](https://opensource.com/sites/default/files/uploads/ip-neigh-help.png) + + * `arp` (它的全称是 “地址解析协议”)类似于 `ip neighbor`。`arp` 映射一个系统的 IP 地址到它相应的 MAC(介质访问控制)地址。 + +![](https://opensource.com/sites/default/files/uploads/arp.png) + +### Tcpdump 和 Wireshark + +Linux 提供了许多包捕获工具,比如 `tcpdump`、`wireshark`、`tshark` 等等。它们被用于去捕获传输/接收的网络流量中的数据包,因此它们对于系统管理员去诊断丢包或相关问题时非常有用。对于热衷于命令行操作的人来说,`tcpdump` 是一个非常好的工具,而对于喜欢 GUI 操作的用户来说,`wireshark` 是捕获和分析数据包的不二选择。`tcpdump` 是一个 Linux 内置的用于去捕获网络流量的实用工具。它能够用于去捕获/显示特定端口、协议等上的流量。 + +**语法:** + + * `tcpdump -i ` 显示指定接口上实时通过的数据包。通过在命令中添加一个 `-w` 标志和输出文件的名字,可以将数据包保存到一个文件中。例如:`tcpdump -w -i `。 + +![](https://opensource.com/sites/default/files/uploads/tcpdump-i.png) + + * `tcpdump -i src ` 从指定的源 IP 地址上捕获数据包。 + * `tcpdump -i dst ` 从指定的目标 IP 地址上捕获数据包。 + * `tcpdump -i port ` 从一个指定的端口号(比如,53、80、8080 等等)上捕获数据包。 + * `tcpdump -i ` 捕获指定协议的数据包,比如:TCP、UDP、等等。 + + + +### Iptables + +`iptables` 是一个包过滤防火墙工具,它能够允许或阻止某些流量。这个实用工具的应用范围非常广泛;下面是它的其中一些最常用的使用命令。 + +**语法:** + + * `iptables -L` 列出所有已存在的 `iptables` 规则。 + * `iptables -F` 删除所有已存在的规则。 + + + +下列命令允许流量从指定端口到指定接口: + + * `iptables -A INPUT -i -p tcp –dport -m state –state NEW,ESTABLISHED -j ACCEPT` + * `iptables -A OUTPUT -o -p tcp -sport -m state – state ESTABLISHED -j ACCEPT` + + + +下列命令允许环回loopback接口访问系统: + + * `iptables -A INPUT -i lo -j ACCEPT` + * `iptables -A OUTPUT -o lo -j ACCEPT` + + + +### Nslookup + +`nslookup` 工具是用于去获得一个网站或域名所映射的 IP 地址。它也能用于去获得你的 DNS 服务器的信息,比如,一个网站的所有 DNS 记录(具体看下面的示例)。与 `nslookup` 类似的一个工具是 `dig`(Domain Information Groper)实用工具。 + +**语法:** + + * `nslookup ` 显示你的服务器组中 DNS 服务器的 IP 地址,它后面就是你想去访问网站的 IP 地址。 + * `nslookup -type=any ` 显示指定网站/域中所有可用记录。 + + + +### 网络/接口调试 + +下面是用于接口连通性或相关网络问题调试所需的命令和文件的汇总。 + +**语法:** + + * `ss` 是一个转储套接字统计数据的实用工具。 + * `nmap `,它的全称是 “Network Mapper”,它用于扫描网络端口、发现主机、检测 MAC 地址,等等。 + * `ip addr/ifconfig -a` 提供一个系统上所有接口的 IP 地址和相关信息。 + * `ssh -vvv user@` 允许你使用指定的 IP/域名和用户名通过 SSH 协议登入到其它服务器。`-vvv` 标志提供 SSH 登入到服务器过程中的 "最详细的" 信息。 + * `ethtool -S ` 检查指定接口上的统计数据。 + * `ifup ` 启动指定的接口。 + * `ifdown ` 关闭指定的接口 + * `systemctl restart network` 重启动系统上的一个网络服务。 + * `/etc/sysconfig/network-scripts/` 是一个对指定的接口设置 IP 地址、网络、网关等等的接口配置文件。DHCP 模式也可以在这里设置。 + * `/etc/hosts` 这个文件包含自定义的主机/域名到 IP 地址的映射。 + * `/etc/resolv.conf` 指定系统上的 DNS 服务器的 IP 地址。 + * `/etc/ntp.conf` 指定 NTP 服务器域名。 + + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/sysadmin-guide-networking-commands + +作者:[Archit Modi][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[qhwdw](https://github.com/qhwdw) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/architmodi +[1]:https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol +[2]:https://opensource.com/article/18/5/how-find-ip-address-linux +[3]:https://en.wikipedia.org/wiki/Telnet diff --git a/translated/tech/20180711 Javascript Framework Comparison with Examples React Vue Hyperapp.md b/translated/tech/20180711 Javascript Framework Comparison with Examples React Vue Hyperapp.md new file mode 100644 index 0000000000..c069ca1785 --- /dev/null +++ b/translated/tech/20180711 Javascript Framework Comparison with Examples React Vue Hyperapp.md @@ -0,0 +1,214 @@ +Javascript 框架对比及案例(React、Vue 及 Hyperapp) +============================================================ +在[我的上一片文章中][5],我试图解释为什么我认为[Hyperapp][6]是一个可用的 [React][7] 或 [Vue][8] 的替代品,我发现当我开始用它时,会容易的找到这个原因。许多人批评这篇文章,认为它自以为是,并没有给其他框架一个展示自己的机会。因此,在这篇文章中,我将尽可能客观的通过提供一些最小化的例子来比较这三个框架,以展示他们的能力。 + +#### 臭名昭著计时器例子 + +计时器可能是响应式编程中最常用最容易理解的例子之一: + +* 你需要一个变量 `count` 保持对计数器的追踪。 + +* 你需要两个方法来增加或减少 `count` 变量的值。 + +* 你需要一种方法来渲染 `count` 变量,并将其呈现给用户。 + +* 你需要两个挂载到两个方法上的按钮,以便在用户和它们产生交互时变更 `count` 变量。 + +下述代码是上述所有三个框架的实现: + + +![](https://cdn-images-1.medium.com/max/2000/1*SqyC-DRj22wZRBiI-NOiwA.png) +使用 React、Vue 和 Hyperapp 实现的计数器 + + +这里或许会有很多要做的事情,特别是当你并不熟悉其中的一个或多个的时候,因此,我们来一步一步解构这些代码: + +* 这三个框架的顶部都有一些 `import` 语句 + +* React 更推崇面向对象的范式,就是创建一个 `Counter` 组件的 `class`,Vue 遵循类似的范式,并通过创建一个新的 `Vue` 类的实例并将信息传递给它来实现。 最后,Hyperapp 坚持函数范式,同时完全分离 `view`、`state`和`action` 。 + +* 就 `count` 变量而言, React 在组件的构造函数内对其进行实例化,而 Vue 和 Hyperapp 则分别是在它们的 `data` 和 `state` 中设置这些属性。 + +* 继续看,你可能注意到 React 和 Vue 有相同的方法来于 `count` 变量进行交互。 React 使用继承自 `React.Component` 的 `setState` 方法来修改它的状态,而 Vue 直接修改 `this.count`。 Hyperapp 使用 ES6 的双箭头语法来实现这个方法,并且,据我所知,这是唯一一个更推荐使用这种语法的框架,React 和 Vue 需要在它们的方法内使用 `this`。另一方面,Hyperapp 的方法需要将状态作为参数,这意味着可以在不同的上下文中重用它们。 + +* 这三个框架的渲染部分实际上是相同的。唯一的细微差别是 Vue 需要一个函数 `h` 作为参数传递给渲染器,事实上 Hyperapp 使用 `onclick` 替代 `onClick` 以及基于每个框架中实现状态的方式引用 `count` 变量的方式。 + +* 最后,所有的三个框架都被挂载到了 `#app` 元素上。每个框架都有稍微不同的语法,Vue 则使用了最直接的语法,通过使用元素选择器而不是使用元素来提供最大的通用性。 + +#### 计数器案例对比意见 + + +同时比较所有的三个框架,Hyperapp 需要最少的代码来实现计数器,并且他是唯一一个使用函数范式的框架。然而,Vue 的代码在绝对长度上似乎更短一些,元素选择器的安装是一个很好的补充。React 的代码看起来最多,但是并不意味着代码不好理解。 + +* * * + +#### 使用异步代码 + +偶尔你可能要不得不处理异步代码。最常见的异步操作之一是发送请求给一个 API。为了这个例子的目的,我将使用一个[占位 API]以及一些假数据来渲染一个文章的列表。必须做的事情如下: + +* 在状态里保存一个 `posts` 的数组 + +* 使用一个方法和正确的 URL 来调用 `fetch()` ,等待返回数据,转化为 JSON,最终使用接收到的数据更新 `posts` 变量。 + +* 渲染一个按钮,这个按钮将调用抓取文章的方法。 + +* 渲染有主键的 `posts` 列表。 + + +![](https://cdn-images-1.medium.com/max/2000/1*aubSG-bpe4g20EOJ_99CFA.png) +从一个 RESTFul API 抓取数据 + +让我们分解上面的代码,并比较三个框架: + +* 与上面的技术里例子类似,这三个框架之间的存储状态、渲染试图和挂载非常相似。这些差异与上面的讨论相同。 + +* 在三个框架中使用 `fetch()` 抓取数据都非常简单并且可以像预期一样工作。然而其中的关键在于, Hyperapp 处理异步操作和其他两种框架有些不同。当数据被接收到并转换为JSON 时,该操作将调用不同的同步动作以取代直接在异步操作中修改状态。 + +* 就代码长度而言, Hyperapp 依然需要最少的代码行数来实现相同的结果,但是 Vue 的代码看起来不那么的冗长,同时拥有最少的绝对字符长度。 + +#### 异步代码对比意见 + +无论你选择哪种框架,异步操作都非常简单。在应用异步操作时, Hyperapp 可能会迫使你去遵循编写更加函数化和模块化的代码的路径。但是另外两个框架也确实可以做到这一点,并且在这一方面给你提供更多的选择。 + +* * * + +#### To-Do List 组件案例 + +在响应式编程中,最出名的例子可能是使用每一个框架里来实现 To-Do List。我不打算在这里实现整个部分,我只实现一个无状态的组件,来展示三个框架如何帮助创建更小的可复用的块来协助构建应用程序。 + +![](https://cdn-images-1.medium.com/max/1600/1*3-v6XHigZe_5VfPvcR6nyQ.png) +演示 TodoItem 实现 + +上面的图片展示了每一个框架一个例子,并为 React 提供了一个额外的例子。接下来是我们从它们四个中看到的: + +* React 在编程范式上最为灵活。它支持函数组件以及类组件。它还支持你在右下角看到的 Hyperapp 组件,无需任何修改。 + +* Hyperapp 还支持 React 的函数组件实现,这意味着两个框架之间还有实验的空间。 + +* 最后出现的 Vue 有着其合理而又奇怪的语法,即使是对另外两个很有经验的人,也不能马上理解其含义。 + +* 在长度方面,所有的案例代码长度非常相似,在 React 的一些方法中稍微冗长一些。 + +#### To-Do List 项目对比意见 + +Vue 需要花费一些时间来熟悉,因为它的模板和其他两个框架有一些不同。React 非常的灵活,支持多种不同的方法来创建组件,而 HyperApp 保持一切简单,并提供与 React 的兼容性,以免你希望在某些时刻进行切换。 + +* * * + +#### 生命周期方法比较 + + +另一个关键对比是组件的生命周期事件,每一个框架允许你根据你的需要来订阅和处理这些时间。下面是我根据各框架的 API 参考手册创建的表格: + +![](https://cdn-images-1.medium.com/max/1600/1*yj4H9pYnagZ7b1pyRE-wmQ.png) +Lifecycle method comparison + +* Vue 提供了最多的生命周期钩子,提供了处理生命周期时间之前或之后发生任何时间的机会。这能有效帮助管理复杂的组件。 + +* React 和 Hyperapp 的生命周期钩子非常类似,React 将 `unmount` 和 `destory` 绑定在了一切,而 Hyperapp 则将 `create` 和 `mount` 绑定在了一起。两者在处理生命周期事件方面都提供了相当数量的控制。 + +* Vue 根本没有处理 `unmount` (据我所理解),而是依赖于 `destroy` 事件在组件稍后的生命周期进行处理。 React 不处理 `destory` 事件,而是选择只处理 `unmount` 事件。最终,HyperApp 不处理 `create` 事件,取而代之的是只依赖 `mount` 事件。 + +#### 生命周期对比意见 + +总的来说,每个框架都提供了生命周期组件,它们帮助你处理组件生命周期中的许多事情。这三个框架都为它们的生命周期提供了钩子,其之间的细微差别,可能源自于实现和方案上的根本差异。通过提供更细粒度的时间处理,Vue 可以更进一步的允许你在开始或结束之后处理生命周期事件。 + +* * * + +#### 性能比较 + +除了易用性和编码技术以外,性能也是大多数开发人员考虑的关键因素,尤其是在进行更复杂的应用程序时。[js-framework-benchmark][10]是一个很好的用于比较框架的工具,所以让我们看看每一组测评数据数组都说了些什么: + + +![](https://cdn-images-1.medium.com/max/1600/1*ojtkwrkY4NETUmPsfQYDYA.png) +测评操作表 + +* 与三个框架的有主键操作相比,无主键操作更快。 + +* 无主键的 React 在所有六种对比中拥有最强的性能,他在所有测试上都有令人深刻的表现。 + +* 有主键的 Vue 只比有主键的 React 性能稍强,而无主键的 Vue 要比无主键的 React 性能差。 + +* Vue 和 Hyperapp 在进行局部更新性能测试时遇见了一些问题,与此同时,React 似乎对该问题进行很好的优化。 + + +![](https://cdn-images-1.medium.com/max/1600/1*YFIM2Rd93jDnEZmqw_k3cw.png) + +启动测试 + +* Hyperapp 是三个框架中最轻量的,而 React 和 Vue 有非常小尺度的差异。 + +* Hyperapp 具有最快的启动时间,这得益于他极小的大小和极简的API + +* Vue 在启动上比 React 好一些,但是非常小。 + + +![](https://cdn-images-1.medium.com/max/1600/1*WVtufoJUvyjkaeEl2hz2sQ.png) +内存分配测试 + +* Hyperapp 是三者中对资源依赖最小的一个,与其他两者相比,任何一个操作都需要更少的内存。 + +* 资源消耗不是跟高,三者应该在现代硬件上进行类似的操作。 + +#### 性能对比意见 + +如果性能是一个问题,你应该考虑你正在使用什么样的应用程序以及你的需求是什么。看起来 Vue 和 React 用于更复杂的应用程序更好,而 Hyperapp 更适合于更小的应用程序、更少的数据处理和需要快速启动的应用程序,以及需要在低端硬件上工作的应用程序。 + +但是,要记住,这些测试远不能代表一般用例,所以在现实场景中可能会看到不同的结果。 + +* * * + +#### 额外备注 + +Comparing React, Vue and Hyperapp might feel like comparing apples and oranges in many ways. There are some additional considerations concerning these frameworks that could very well help you decide on one over the other two: + +比较 React、Vue 和 Hyperapp 可能像在许多方面比较苹果、橘子。关于这些框架还有一些其他的考虑,它们可以帮助你决定使用另一个框架。 + +* React 通过引入片段,避免了相邻的JSX元素必须封装在父元素中的问题,这些元素允许你将子元素列表分组,而无需向DOM添加额外的节点。 + +* Read还为你提供更高级别的组件,而VUE为你提供重用组件功能的MIXIN。 + +* Vue 允许使用[模板][4]来分离结构和功能,从而更好的分离关注点。 + +* 与其他两个相比,Hyperapp 感觉像是一个较低级别的API,它的代码短得多,如果你愿意调整它并学习它的工作原理,那么它可以提供更多的通用性。 + +* * * + +#### 结论 + +我认为如果你已经阅读了这么多,你已经知道哪种工具更适合你的需求。毕竟,这不是讨论哪一个更好,而是讨论哪一个更适合每种情况。总而言之: + + +* React 是一个非常强大的工具,他的周围有大量的开发者,可能会帮助你找到一个工作。入门并不难,但是掌握它肯定需要很多时间。然而,这是非常值得去花费你的时间全面掌握的。 + +* 如果你过去曾使用过另外一个 JavaScript 框架,Vue 可能看起来有点奇怪,但它也是一个非常有趣的工具。如果 React 不是你所喜欢的 ,那么它可能是一个可行的值得学习的选择。 + +* 最后,Hyperapp 是一个为小型项目而生的很酷的小框架,也是初学者入门的好地方。它提供比 React 或 Vue 更少的工具,但是它能帮助你快速构建原型并理解许多基本原理。你编写的许多代码都和其他两个框架兼容,或者是稍做更改,你可以在对它们中另外一个有信心时切换框架。 + +-------------------------------------------------------------------------------- + +作者简介: + +Web developer who loves to code, creator of 30 seconds of code (https://30secondsofcode.org/) and the mini.css framework (http://minicss.org). + +-------------------------------------------------------------------------------- + +via: https://hackernoon.com/javascript-framework-comparison-with-examples-react-vue-hyperapp-97f064fb468d + +作者:[Angelos Chalaris ][a] +译者:[Bestony](https://github.com/bestony) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://hackernoon.com/@chalarangelo?source=post_header_lockup +[1]:https://reactjs.org/docs/fragments.html +[2]:https://reactjs.org/docs/higher-order-components.html +[3]:https://vuejs.org/v2/guide/mixins.html +[4]:https://vuejs.org/v2/guide/syntax.html +[5]:https://hackernoon.com/i-abandonded-react-in-favor-of-hyperapp-heres-why-df65638f8a79 +[6]:https://hyperapp.js.org/ +[7]:https://reactjs.org/ +[8]:https://vuejs.org/ +[9]:https://jsonplaceholder.typicode.com/ +[10]:https://github.com/krausest/js-framework-benchmark diff --git a/translated/tech/20180712 Slices from the ground up.md b/translated/tech/20180712 Slices from the ground up.md new file mode 100644 index 0000000000..1e76eb515b --- /dev/null +++ b/translated/tech/20180712 Slices from the ground up.md @@ -0,0 +1,260 @@ +Slices from the ground up +============================================================ + +这篇文章最初的灵感来源于我与一个使用切片作栈的同事的一次聊天。那次聊天,话题最后拓展到了 Go 语言中的切片是如何工作的。我认为把这些知识记录下来会帮到别人。 + +### 数组 + +任何关于 Go 语言的切片的讨论都要从另一个数据结构,也就是 Go 语言的数组开始。Go 语言的数组有两个特性: + +1. 数组的长度是固定的;`[5]int` 是由 5 个 `unt` 构成的数组,和`[3]int` 不同。 + +2. 数组是值类型。考虑如下示例: + ``` + package main + + import "fmt" + + func main() { + var a [5]int + b := a + b[2] = 7 + fmt.Println(a, b) // prints [0 0 0 0 0] [0 0 7 0 0] + } + ``` + + 语句 `b := a` 定义了一个新的变量 `b`,类型是 `[5]int`,然后把 `a` 中的内容_复制_到 `b` 中。改变 `b` 中的值对 `a` 中的内容没有影响,因为 `a` 和 `b` 是相互独立的值。 [1][1] + +### 切片 + +Go 语言的切片和数组的主要有如下两个区别: + +1. 切片没有一个固定的长度。切片的长度不是它类型定义的一部分,而是由切片内部自己维护的。我们可以使用内置的 `len` 函数知道他的长度。 + +2. 将一个切片赋值给另一个切片时 _不会_ 将切片进行复制操作。这是因为切片没有直接保存它的内部数据,而是保留了一个指向 _底层数组_ [3][3]的指针。数据都保留在底层数组里。 + +基于第二个特性,两个切片可以享有共同的底层数组。考虑如下示例: + +1. 对切片取切片 + ``` + package main + + import "fmt" + + func main() { + var a = []int{1,2,3,4,5} + b := a[2:] + b[0] = 0 + fmt.Println(a, b) // prints [1 2 0 4 5] [0 4 5] + } + ``` + + 在这个例子里,`a` 和 `b` 享有共同的底层数组 —— 尽管 `b` 的起始值在数组里的偏移不同,两者的长度也不同。通过 `b` 修改底层数组的值也会导致 `a` 里的值的改变。 + +2. 将切片传进函数 + ``` + package main + + import "fmt" + + func negate(s []int) { + for i := range s { + s[i] = -s[i] + } + } + + func main() { + var a = []int{1, 2, 3, 4, 5} + negate(a) + fmt.Println(a) // prints [-1 -2 -3 -4 -5] + } + ``` + + 在这个例子里,`a` 作为形参 `s` 的实参传进了 `negate` 函数,这个函数遍历 `s` 内的元素并改变其符号。尽管 `nagate` 没有返回值,且没有接触到 `main` 函数里的 `a`。但是当将之传进 `negate` 函数内时,`a` 里面的值却被改变了。 + +大多数程序员都能直观地了解 Go 语言切片的底层数组是如何工作的,因为它与其他语言中类似数组的工作方式类似。比如下面就是使用 Python 重写的这一小节的第一个示例: + +``` +Python 2.7.10 (default, Feb 7 2017, 00:08:15) +[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin +Type "help", "copyright", "credits" or "license" for more information. +>>> a = [1,2,3,4,5] +>>> b = a +>>> b[2] = 0 +>>> a +[1, 2, 0, 4, 5] +``` + +以及使用 Ruby 重写的版本: + +``` +irb(main):001:0> a = [1,2,3,4,5] +=> [1, 2, 3, 4, 5] +irb(main):002:0> b = a +=> [1, 2, 3, 4, 5] +irb(main):003:0> b[2] = 0 +=> 0 +irb(main):004:0> a +=> [1, 2, 0, 4, 5] +``` + +在大多数将数组视为对象或者是引用类型的语言也是如此。[4][8] + +### 切片头 + +让切片得以同时拥有值和指针的特性的魔法来源于切片实际上是一个结构体类型。这个结构体通常叫做 _切片头_,这里是 [反射包内的相关定义][20]。且片头的定义大致如下: + +![](https://dave.cheney.net/wp-content/uploads/2018/07/slice.001-300x257.png) + +``` +package runtime + +type slice struct { + ptr unsafe.Pointer + len int + cap int +} +``` + +这个头很重要,因为和[ `map` 以及 `chan` 这两个类型不同][21],切片是值类型,当被赋值或者被作为函数的参数时候会被复制过去。 + +程序员们都能理解 `square` 的形参 `v` 和 `main` 中声明的 `v` 的是相互独立的,我们一次为例。 + +``` +package main + +import "fmt" + +func square(v int) { + v = v * v +} + +func main() { + v := 3 + square(v) + fmt.Println(v) // prints 3, not 9 +} +``` + +因此 `square` 对自己的形参 `v` 的操作没有影响到 `main` 中的 `v`。下面这个示例中的 `s` 也是 `main` 中声明的切片 `s` 的独立副本,_而不是_指向 `main` 的 `s` 的指针。 + +``` +package main + +import "fmt" + +func double(s []int) { + s = append(s, s...) +} + +func main() { + s := []int{1, 2, 3} + double(s) + fmt.Println(s, len(s)) // prints [1 2 3] 3 +} +``` + +Go 语言的切片是作为值传递的这一点很是不寻常。当你在 Go 语言内定义一个结构体时,90% 的时间里传递的都是这个结构体的指针。[5][9] 切片的传递方式真的很不寻常,我能想到的唯一与之相同的例子只有 `time.Time`。 + +切片作为值传递而不是作为指针传递这一点会让很多想要理解切片的工作原理的 Go 程序员感到困惑,这是可以理解的。你只需要记住,当你对切片进行赋值,取切片,传参或者作为返回值等操作时,你是在复制结构体内的三个位域:指针,长度,以及容量。 + +### 总结 + +我们来用我们引出这一话题的切片作为栈的例子来总结下本文的内容: + +``` +package main + +import "fmt" + +func f(s []string, level int) { + if level > 5 { + return + } + s = append(s, fmt.Sprint(level)) + f(s, level+1) + fmt.Println("level:", level, "slice:", s) +} + +func main() { + f(nil, 0) +} +``` + +在 `main` 函数的最开始我们把一个 `nil` 切片以及 `level` 0传给了函数 `f`。在函数 `f` 里我们把当前的 `level` 添加到切片的后面,之后增加 `level` 的值并进行递归。一旦 `level` 大于 5,函数返回,打印出当前的 `level` 以及他们复制到的 `s` 的内容。 + +``` +level: 5 slice: [0 1 2 3 4 5] +level: 4 slice: [0 1 2 3 4] +level: 3 slice: [0 1 2 3] +level: 2 slice: [0 1 2] +level: 1 slice: [0 1] +level: 0 slice: [0] +``` + +你可以注意到在每一个 `level` 内 `s` 的值没有被别的 `f` 的调用影响,尽管当计算更高阶的 `level` 时作为 `append` 的副产品,调用栈内的四个 `f` 函数创建了四个底层数组,但是没有影响到当前各自的切片。 + +### 了解更多 + +如果你想要了解更多 Go 语言内切片运行的原理,我建议看看 Go 博客里的这些文章: + +* [Go Slices: usage and internals][11] (blog.golang.org) + +* [Arrays, slices (and strings): The mechanics of ‘append’][12] (blog.golang.org) + +### 注释 + +1. 这不是数组才有的特性,在 Go 语言里,_一切_ 赋值都是复制过去的, + +2. 你可以在对数组使用 `len` 函数,但是得到的结果是多少人尽皆知。[][14] + +3. 也叫做后台数组,以及更不严谨的说法是后台切片。[][15] + +4. Go 语言里我们倾向于说值类型以及指针类型,因为 C++ 的引用会使使用引用类型这个词产生误会。但是在这里我说引用类型是没有问题的。[][16] + +5. 如果你的结构体有[定义在其上的方法或者实现了什么接口][17],那么这个比率可以飙升到接近 100%。[][18] + +6. 证明留做习题。 + +### 相关文章: + +1. [If a map isn’t a reference variable, what is it?][4] + +2. [What is the zero value, and why is it useful ?][5] + +3. [The empty struct][6] + +4. [Should methods be declared on T or *T][7] + +-------------------------------------------------------------------------------- + +via: https://dave.cheney.net/2018/07/12/slices-from-the-ground-up + +作者:[Dave Cheney][a] +译者:[name1e5s](https://github.com/name1e5s) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://dave.cheney.net/ +[1]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-bottom-1-3265 +[2]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-bottom-2-3265 +[3]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-bottom-3-3265 +[4]:https://dave.cheney.net/2017/04/30/if-a-map-isnt-a-reference-variable-what-is-it +[5]:https://dave.cheney.net/2013/01/19/what-is-the-zero-value-and-why-is-it-useful +[6]:https://dave.cheney.net/2014/03/25/the-empty-struct +[7]:https://dave.cheney.net/2016/03/19/should-methods-be-declared-on-t-or-t +[8]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-bottom-4-3265 +[9]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-bottom-5-3265 +[10]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-bottom-6-3265 +[11]:https://blog.golang.org/go-slices-usage-and-internals +[12]:https://blog.golang.org/slices +[13]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-1-3265 +[14]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-2-3265 +[15]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-3-3265 +[16]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-4-3265 +[17]:https://dave.cheney.net/2016/03/19/should-methods-be-declared-on-t-or-t +[18]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-5-3265 +[19]:https://dave.cheney.net/2018/07/12/slices-from-the-ground-up#easy-footnote-6-3265 +[20]:https://golang.org/pkg/reflect/#SliceHeader +[21]:https://dave.cheney.net/2017/04/30/if-a-map-isnt-a-reference-variable-what-is-it diff --git a/translated/tech/20180719 Incomplete Path Expansion (Completion) For Bash.md b/translated/tech/20180719 Incomplete Path Expansion (Completion) For Bash.md new file mode 100644 index 0000000000..446bb9e497 --- /dev/null +++ b/translated/tech/20180719 Incomplete Path Expansion (Completion) For Bash.md @@ -0,0 +1,82 @@ +针对 Bash 的不完整路径展开(补全) +====== + +![](https://4.bp.blogspot.com/-k2pRIKTzcBU/W1BpFtzzWuI/AAAAAAAABOE/pqX4XcOX8T4NWkKOmzD0T0OioqxzCmhLgCLcBGAs/s1600/Gnu-bash-logo.png) + +[bash-complete-partial-path][1] 通过添加不完整的路径展开(类似于 Zsh)来增强 Bash(它在 Linux 上,macOS 使用 gnu-sed,Windows 使用 MSYS)中的路径补全。如果你想在 Bash 中使用这个省时特性,而不必切换到 Zsh,它将非常有用。 + +这是它如何工作的。当按下 `Tab` 键时,bash-complete-partial-path 假定每个部分都不完整并尝试展开它。假设你要进入 `/usr/share/applications` 。你可以输入 `cd /u/s/app`,按下 `Tab`,bash-complete-partial-path 应该把它展开成 `cd /usr/share/applications` 。如果存在冲突,那么按 `Tab` 仅补全没有冲突的路径。例如,Ubuntu 用户在 `/usr/share` 中应该有很多以 “app” 开头的文件夹,在这种情况下,输入 `cd /u/s/app` 只会展开 `/usr/share/` 部分。 + +这是更深层不完整文件路径展开的另一个例子。在Ubuntu系统上输入 `cd /u/s/f/t/u`,按下 `Tab`,它应该自动展开为 `cd /usr/share/fonts/truetype/ubuntu`。 + +功能包括: + +* 转义特殊字符 + +* 如果用户路径开头使用引号,则不转义字符转义,而是在展开路径后使用匹配字符结束引号 + +* 正确展开 ~ 表达式 + +* 如果 bash-completion 包正在使用,则此代码将安全地覆盖其 _filedir 函数。无需额外配置,只需确保在主 bash-completion 后 source 此项目。 + +查看[项目页面][2]以获取更多信息和演示截图。 + +### 安装 bash-complete-partial-path + +bash-complete-partial-path 安装说明指定直接下载 bash_completion 脚本。我更喜欢从 Git 仓库获取,这样我可以用一个简单的 `git pull` 来更新它,因此下面的说明将使用这种安装 bash-complete-partial-path。如果你喜欢,可以使用[官方][3]说明。 + +1. 安装 Git(需要克隆 bash-complete-partial-path 的 Git 仓库)。 + +在 Debian、Ubuntu、Linux Mint 等中,使用此命令安装 Git: + +``` +sudo apt install git +``` + +2. 在 `~/.config/` 中克隆 bash-complete-partial-path 的 Git 仓库: + +``` +cd ~/.config && git clone https://github.com/sio/bash-complete-partial-path +``` + +3. 在 `~/.bashrc` 文件中 source `~/.config/bash-complete-partial-path/bash_completion`, + +用文本编辑器打开 ~/.bashrc。例如你可以使用 Gedit: + +``` +gedit ~/.bashrc +``` + +在 `~/.bashrc` 的末尾添加以下内容(在一行中): + +``` +[ -s "$HOME/.config/bash-complete-partial-path/bash_completion" ] && source "$HOME/.config/bash-complete-partial-path/bash_completion" +``` + +我提到在文件的末尾添加它,因为这需要包含在你的 `~/.bashrc` 文件的主 bash-completion 下面(之后)。因此,请确保不要将其添加到原始 bash-completion 之上,因为它会导致问题。 + +4\. Source `~/.bashrc`: + +``` +source ~/.bashrc +``` + +这样就好了,现在应该安装完 bash-complete-partial-path 并可以使用了。 + + + +-------------------------------------------------------------------------------- + +via: https://www.linuxuprising.com/2018/07/incomplete-path-expansion-completion.html + +作者:[Logix][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://plus.google.com/118280394805678839070 +[1]:https://github.com/sio/bash-complete-partial-path +[2]:https://github.com/sio/bash-complete-partial-path +[3]:https://github.com/sio/bash-complete-partial-path#installation-and-updating diff --git a/translated/tech/20180720 3 Methods to List All The Users in Linux System.md b/translated/tech/20180720 3 Methods to List All The Users in Linux System.md new file mode 100644 index 0000000000..b6974bfbd7 --- /dev/null +++ b/translated/tech/20180720 3 Methods to List All The Users in Linux System.md @@ -0,0 +1,234 @@ +列出 Linux 系统上所有用户的 3 种方法 +======= + +> 通过使用 `/etc/passwd` 文件,`getent` 命令,`compgen` 命令这三种方法查看系统中用户的信息 + +---------------- +大家都知道,Linux 系统中用户信息存放在 `/etc/passwd` 文件中。 + +这是一个包含每个用户基本信息的文本文件。 + +当我们在系统中创建一个用户,新用户的详细信息就会被添加到这个文件中。 + +`/etc/passwd` 文件将每个用户的基本信息记录为文件中的一行,一行中包含7个字段。 + +`/etc/passwd` 文件的一行代表一个单独的用户。该文件将用户的信息分为 3 个部分。 + + * 第 1 部分:`root` 用户信息 + * 第 2 部分:系统定义的账号信息 + * 第 3 部分:真实用户的账户信息 + +** 建议阅读 : ** +**( # )** [ 如何在 Linux 上查看创建用户的日期 ][1] +**( # )** [ 如何在 Linux 上查看 A 用户所属的群组 ][2] +**( # )** [ 如何强制用户在下一次登录 Linux 系统时修改密码 ][3] + +第一部分是 `root` 账户,这代表管理员账户,对系统的每个方面都有完全的权力。 + +第二部分是系统定义的群组和账户,这些群组和账号是正确安装和更新系统软件所必需的。 + +第三部分在最后,代表一个使用系统的真实用户。 + +在创建新用户时,将修改以下 4 个文件。 + + * `/etc/passwd:` 用户账户的详细信息在此文件中更新。 + * `/etc/shadow:` 用户账户密码在此文件中更新。 + * `/etc/group:` 新用户群组的详细信息在此文件中更新。 + * `/etc/gshadow:` 新用户群组密码在此文件中更新。 + +### 方法 1 :使用 `/etc/passwd` 文件 + +使用任何一个像 `cat`,`more`,`less` 等文件操作命令来打印 Linux 系统上创建的用户列表。 + +`/etc/passwd` 是一个文本文件,其中包含了登录 Linux 系统所必需的每个用户的信息。它保存用户的有用信息,如用户名,密码,用户 ID,群组 ID,用户 ID 信息,用户的家目录和 Shell 。 + +`/etc/passwd` 文件将每个用户的详细信息写为一行,其中包含七个字段,每个字段之间用冒号 “ :” 分隔: + +``` +# cat /etc/passwd +root:x:0:0:root:/root:/bin/bash +bin:x:1:1:bin:/bin:/sbin/nologin +daemon:x:2:2:daemon:/sbin:/sbin/nologin +adm:x:3:4:adm:/var/adm:/sbin/nologin +lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin +sync:x:5:0:sync:/sbin:/bin/sync +shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown +halt:x:7:0:halt:/sbin:/sbin/halt +mail:x:8:12:mail:/var/spool/mail:/sbin/nologin +ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin +postfix:x:89:89::/var/spool/postfix:/sbin/nologin +sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin +tcpdump:x:72:72::/:/sbin/nologin +2gadmin:x:500:10::/home/viadmin:/bin/bash +apache:x:48:48:Apache:/var/www:/sbin/nologin +zabbix:x:498:499:Zabbix Monitoring System:/var/lib/zabbix:/sbin/nologin +mysql:x:497:502::/home/mysql:/bin/bash +zend:x:502:503::/u01/zend/zend/gui/lighttpd:/sbin/nologin +rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin +2daygeek:x:503:504::/home/2daygeek:/bin/bash +named:x:25:25:Named:/var/named:/sbin/nologin +mageshm:x:506:507:2g Admin - Magesh M:/home/mageshm:/bin/bash + +``` +7 个字段的详细信息如下。 + +* **`Username ( magesh ):`** 已创建用户的用户名,字符长度 1 个到 12 个字符。 +* **`Password ( x ):`** 代表加密密码保存在 `/etc/shadow 文件中。 +* **`User ID ( UID-506 ):`** 代表用户 ID ,每个用户都要有一个唯一的 ID 。UID 号为 0 的是为 `root` 用户保留的,UID 号 1 到 99 是为系统用户保留的,UID 号100-999 是为系统账户和群组保留的。 +* **`Group ID ( GID-507 ):`** 代表组 ID ,每个群组都要有一个唯一的 GID ,保存在 `/etc/group` 文件中。 +* **`User ID Info ( 2g Admin - Magesh M):`** 代表命名字段,可以用来描述用户的信息。 +* **`Home Directory ( /home/mageshm ):`** 代表用户的家目录。 +* **`shell ( /bin/bash ):`** 代表用户使用的 shell种类。 + +你可以使用 **`awk`** 或 **`cut`** 命令仅打印出 Linux 系统中所有用户的用户名列表。显示的结果是相同的。 + +``` +# awk -F':' '{ print $1}' /etc/passwd +or +# cut -d: -f1 /etc/passwd +root +bin +daemon +adm +lp +sync +shutdown +halt +mail +ftp +postfix +sshd +tcpdump +2gadmin +apache +zabbix +mysql +zend +rpc +2daygeek +named +mageshm + +``` +### 方法 2 :使用 `getent` 命令 + +`getent` 命令显示 `Name Service Switch` 库支持的数据库中的条目。这些库的配置文件为 `/etc/nsswitch.conf`。 + +`getent` 命令显示类似于 `/etc/passwd` 文件的用户详细信息,它将每个用户详细信息显示为包含七个字段的单行。 + +``` +# getent passwd +root:x:0:0:root:/root:/bin/bash +bin:x:1:1:bin:/bin:/sbin/nologin +daemon:x:2:2:daemon:/sbin:/sbin/nologin +adm:x:3:4:adm:/var/adm:/sbin/nologin +lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin +sync:x:5:0:sync:/sbin:/bin/sync +shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown +halt:x:7:0:halt:/sbin:/sbin/halt +mail:x:8:12:mail:/var/spool/mail:/sbin/nologin +ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin +postfix:x:89:89::/var/spool/postfix:/sbin/nologin +sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin +tcpdump:x:72:72::/:/sbin/nologin +2gadmin:x:500:10::/home/viadmin:/bin/bash +apache:x:48:48:Apache:/var/www:/sbin/nologin +zabbix:x:498:499:Zabbix Monitoring System:/var/lib/zabbix:/sbin/nologin +mysql:x:497:502::/home/mysql:/bin/bash +zend:x:502:503::/u01/zend/zend/gui/lighttpd:/sbin/nologin +rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin +2daygeek:x:503:504::/home/2daygeek:/bin/bash +named:x:25:25:Named:/var/named:/sbin/nologin +mageshm:x:506:507:2g Admin - Magesh M:/home/mageshm:/bin/bash + +``` + +7 个字段的详细信息如下。 + +* **`Username ( magesh ):`** 已创建用户的用户名,字符长度 1 个到 12 个字符。 +* **`Password ( x ):` 代表加密密码保存在 `/etc/shadow 文件中。 +* **`User ID ( UID-506 ):`** 代表用户 ID ,每个用户都要有一个唯一的 ID 。UID 号为 0 的是为 `root` 用户保留的,UID 号 1 到 99 是为系统用户保留的,UID 号100-999 是为系统账户和群组保留的。 +* **`Group ID ( GID-507 ):`** 代表组 ID ,每个群组都要有一个唯一的 GID ,保存在 `/etc/group` 文件中。 +* **`User ID Info ( 2g Admin - Magesh M):`** 代表命名字段,可以用来描述用户的信息。 +* **`Home Directory ( /home/mageshm ):`** 代表用户的家目录。 +* **`shell ( /bin/bash ):`** 代表用户使用的 shell种类。 + +你可以使用 **`awk`** 或 **`cut`** 命令仅打印出 Linux 系统中所有用户的用户名列表。显示的结果是相同的。 + +``` +# getent passwd | awk -F':' '{ print $1}' +or +# getent passwd | cut -d: -f1 +root +bin +daemon +adm +lp +sync +shutdown +halt +mail +ftp +postfix +sshd +tcpdump +2gadmin +apache +zabbix +mysql +zend +rpc +2daygeek +named +mageshm + +``` + +### 方法 3 :使用 `compgen` 命令 + +`compgen` 是 `bash` 的内置命令,它将显示所有可用的命令,别名和函数。 + +``` +# compgen -u +root +bin +daemon +adm +lp +sync +shutdown +halt +mail +ftp +postfix +sshd +tcpdump +2gadmin +apache +zabbix +mysql +zend +rpc +2daygeek +named +mageshm + +``` + +------------------------ + +via: https://www.2daygeek.com/3-methods-to-list-all-the-users-in-linux-system/ + +作者:[Magesh Maruthamuthu][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[SunWave](https://github.com/SunWave) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/magesh/ +[1]:https://www.2daygeek.com/how-to-check-user-created-date-on-linux/ +[2]:https://www.2daygeek.com/how-to-check-which-groups-a-user-belongs-to-on-linux/ +[3]:https://www.2daygeek.com/how-to-force-user-to-change-password-on-next-login-in-linux/ + + diff --git a/translated/tech/20180720 Convert video using Handbrake.md b/translated/tech/20180720 Convert video using Handbrake.md new file mode 100644 index 0000000000..422226261a --- /dev/null +++ b/translated/tech/20180720 Convert video using Handbrake.md @@ -0,0 +1,56 @@ +使用 Handbrake 转换视频 +====== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OpenVideo.png?itok=jec9ibU5) + +最近,当我的儿子让我数字化他的高中篮球比赛的一些旧 DVD 时,我立刻知道我会使用 [Handbrake][1]。它是一个开源软件包,可轻松将视频转换为可在 MacOS、Windows、Linux、iOS、Android 和其他平台上播放的格式所需的所有工具。 + +Handbrake 是开源的,并在[ GPLv2 许可证][2]下分发。它很容易在 MacOS、Windows 和 Linux 包括 [Fedora][3] 和 [Ubuntu][4] 上安装。在 Linux 中,安装后就可以从命令行使用 `$ handbrake` 或从图形用户界面中选择它。(在我的例子中,是 GNOME 3) + + +![](https://opensource.com/sites/default/files/uploads/handbrake_1.png) + +Handbrake 的菜单系统易于使用。单击 **Open Source** 选择要转换的视频源。对于我儿子的篮球视频,它是我的 Linux 笔记本中的 DVD 驱动器。将 DVD 插入驱动器后,软件会识别磁盘的内容。 +![](https://opensource.com/sites/default/files/uploads/handbrake_2.png) + +正如你在上面截图中的 Source 旁边看到的那样,Handbrake 将其识别为 720x480 的 DVD,宽高比为 4:3,以每秒 29.97 帧的速度录制,有一个音轨。该软件还能预览视频。 + +如果默认转换设置可以接受,只需按下 **Start Encoding** 按钮(一段时间后,根据处理器的速度),DVD 的内容将被转换并以默认格式 [M4V][5] 保存(可以改变)。 + +如果你不喜欢文件名,很容易改变它。 + +![](https://opensource.com/sites/default/files/uploads/handbrake_3.png) + +Handbrake 有各种格式、大小和配置的输出选项。例如,它可以生成针对 YouTube、Vimeo 和其他网站以及 iPod、iPad、Apple TV、Amazon Fire TV、Roku、PlayStation 等设备优化的视频。 + +![](https://opensource.com/sites/default/files/uploads/handbrake_4.png) + +你可以在 ”Dimensions“ 选项卡中更改视频输出大小。其他选项卡允许你应用过滤器、更改视频质量和编码、添加或修改音轨,包括字幕和修改章节。“Tags” 选项卡可让你识别输出视频文件中的作者、演员、导演、发布日期等。 + +![](https://opensource.com/sites/default/files/uploads/handbrake_5.png) + +如果使用 Handbrake 为特定平台输出,可以使用包含的预设。 + +![](https://opensource.com/sites/default/files/uploads/handbrake_6.png) + +你还可以使用菜单选项创建自己的格式,具体取决于你需要的功能。 + +Handbrake 是一款非常强大的软件,但它并不是唯一的开源视频转换工具。你有其他喜欢的吗?如果有,请分享评论。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/7/handbrake + +作者:[Don Watkins][a] +选题:[lujun9972](https://github.com/lujun9972) +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/don-watkins +[1]:https://handbrake.fr/ +[2]:https://github.com/HandBrake/HandBrake/blob/master/LICENSE +[3]:https://fedora.pkgs.org/28/rpmfusion-free-x86_64/HandBrake-1.1.0-1.fc28.x86_64.rpm.html +[4]:https://launchpad.net/~stebbins/+archive/ubuntu/handbrake-releases +[5]:https://en.wikipedia.org/wiki/M4V