归档 201803

This commit is contained in:
wxy
2018-03-31 23:40:29 +08:00
parent 6819891497
commit 3576983306
91 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
内核如何管理内存
============================================================
在学习了进程的 [虚拟地址布局][1] 之后,让我们回到内核,来学习它管理用户内存的机制。这里再次使用 Gonzo
![Linux kernel mm_struct](http://static.duartes.org/img/blogPosts/mm_struct.png)
Linux 进程在内核中是作为进程描述符 [task_struct][2] LCTT 译注:它是在 Linux 中描述进程完整信息的一种数据结构)的实例来实现的。在 task_struct 中的  [mm][3]  域指向到**内存描述符**[mm_struct][4] 是一个程序在内存中的执行摘要。如上图所示,它保存了起始和结束内存段,进程使用的物理内存页面的 [数量][5]RSS <ruby>常驻内存大小<rt>Resident Set Size</rt></ruby> )、虚拟地址空间使用的 [总数量][6]、以及其它片断。 在内存描述符中,我们可以获悉它有两种管理内存的方式:**虚拟内存区域**集和**页面表**。Gonzo 的内存区域如下所示:
![Kernel memory descriptor and memory areas](http://static.duartes.org/img/blogPosts/memoryDescriptorAndMemoryAreas.png)
每个虚拟内存区域VMA是一个连续的虚拟地址范围这些区域绝对不会重叠。一个 [vm_area_struct][7] 的实例完整地描述了一个内存区域,包括它的起始和结束地址,[flags][8] 决定了访问权限和行为,并且 [vm_file][9] 域指定了映射到这个区域的文件(如果有的话)。(除了内存映射段的例外情况之外,)一个 VMA 是不能**匿名**映射文件的。上面的每个内存段(比如,堆、栈)都对应一个单个的 VMA。虽然它通常都使用在 x86 的机器上但它并不是必需的。VMA 也不关心它们在哪个段中。
一个程序的 VMA 在内存描述符中是作为 [mmap][10] 域的一个链接列表保存的,以起始虚拟地址为序进行排列,并且在 [mm_rb][12] 域中作为一个 [红黑树][11] 的根。红黑树允许内核通过给定的虚拟地址去快速搜索内存区域。在你读取文件 `/proc/pid_of_process/maps` 时,内核只是简单地读取每个进程的 VMA 的链接列表并[显示它们][13]。
在 Windows 中,[EPROCESS][14] 块大致类似于一个 task_struct 和 mm_struct 的结合。在 Windows 中模拟一个 VMA 的是虚拟地址描述符,或称为 [VAD][15];它保存在一个 [AVL 树][16] 中。你知道关于 Windows 和 Linux 之间最有趣的事情是什么吗?其实它们只有一点小差别。
4GB 虚拟地址空间被分配到**页面**中。在 32 位模式中的 x86 处理器中支持 4KB、2MB、以及 4MB 大小的页面。Linux 和 Windows 都使用大小为 4KB 的页面去映射用户的一部分虚拟地址空间。字节 0-4095 在页面 0 中,字节 4096-8191 在页面 1 中依次类推。VMA 的大小 _必须是页面大小的倍数_ 。下图是使用 4KB 大小页面的总数量为 3GB 的用户空间:
![4KB Pages Virtual User Space](http://static.duartes.org/img/blogPosts/pagedVirtualSpace.png)
处理器通过查看**页面表**去转换一个虚拟内存地址到一个真实的物理内存地址。每个进程都有它自己的一组页面表每当发生进程切换时用户空间的页面表也同时切换。Linux 在内存描述符的 [pgd][17] 域中保存了一个指向进程的页面表的指针。对于每个虚拟页面,页面表中都有一个相应的**页面表条目**PTE在常规的 x86 页面表中,它是一个简单的如下所示的大小为 4 字节的记录:
![x86 Page Table Entry (PTE) for 4KB page](http://static.duartes.org/img/blogPosts/x86PageTableEntry4KB.png)
Linux 通过函数去 [读取][18] 和 [设置][19]  PTE 条目中的每个标志位。标志位 P 告诉处理器这个虚拟页面是否**在**物理内存中。如果该位被清除(设置为 0访问这个页面将触发一个页面故障。请记住当这个标志位为 0 时,内核可以在剩余的域上**做任何想做的事**。R/W 标志位是读/写标志如果被清除这个页面将变成只读的。U/S 标志位表示用户/超级用户;如果被清除,这个页面将仅被内核访问。这些标志都是用于实现我们在前面看到的只读内存和内核空间保护。
标志位 D 和 A 用于标识页面是否是“**脏的**”或者是已**被访问过**。一个脏页面表示已经被写入而一个被访问过的页面则表示有一个写入或者读取发生过。这两个标志位都是粘滞位处理器只能设置它们而清除则是由内核来完成的。最终PTE 保存了这个页面相应的起始物理地址,它们按 4KB 进行整齐排列。这个看起来不起眼的域是一些痛苦的根源,因为它限制了物理内存最大为 [4 GB][20]。其它的 PTE 域留到下次再讲,因为它是涉及了物理地址扩展的知识。
由于在一个虚拟页面上的所有字节都共享一个 U/S 和 R/W 标志位,所以内存保护的最小单元是一个虚拟页面。但是,同一个物理内存可能被映射到不同的虚拟页面,这样就有可能会出现相同的物理内存出现不同的保护标志位的情况。请注意,在 PTE 中是看不到运行权限的。这就是为什么经典的 x86 页面上允许代码在栈上被执行的原因,这样会很容易导致挖掘出栈缓冲溢出漏洞(可能会通过使用 [return-to-libc][21] 和其它技术来找出非可执行栈)。由于 PTE 缺少禁止运行标志位说明了一个更广泛的事实:在 VMA 中的权限标志位有可能或可能不完全转换为硬件保护。内核只能做它能做到的,但是,最终的架构限制了它能做的事情。
虚拟内存不保存任何东西,它只是简单地  _映射_  一个程序的地址空间到底层的物理内存上。物理内存被当作一个称之为**物理地址空间**的巨大块而由处理器访问。虽然内存的操作[涉及到某些][22]总线,我们在这里先忽略它,并假设物理地址范围从 0 到可用的最大值按字节递增。物理地址空间被内核进一步分解为**页面帧**。处理器并不会关心帧的具体情况,这一点对内核也是至关重要的,因为,**页面帧是物理内存管理的最小单元**。Linux 和 Windows 在 32 位模式下都使用 4KB 大小的页面帧;下图是一个有 2 GB 内存的机器的例子:
![Physical Address Space](http://static.duartes.org/img/blogPosts/physicalAddressSpace.png)
在 Linux 上每个页面帧是被一个 [描述符][23] 和 [几个标志][24] 来跟踪的。通过这些描述符和标志,实现了对机器上整个物理内存的跟踪;每个页面帧的具体状态是公开的。物理内存是通过使用 [Buddy 内存分配][25] LCTT 译注:一种内存分配算法)技术来管理的,因此,如果一个页面帧可以通过 Buddy 系统分配,那么它是**未分配的**free。一个被分配的页面帧可以是**匿名的**、持有程序数据的、或者它可能处于页面缓存中、持有数据保存在一个文件或者块设备中。还有其它的异形页面帧但是这些异形页面帧现在已经不怎么使用了。Windows 有一个类似的页面帧号Page Frame Number (PFN))数据库去跟踪物理内存。
我们把虚拟内存区域VMA、页面表条目PTE以及页面帧放在一起来理解它们是如何工作的。下面是一个用户堆的示例
![Physical Address Space](http://static.duartes.org/img/blogPosts/heapMapped.png)
蓝色的矩形框表示在 VMA 范围内的页面,而箭头表示页面表条目映射页面到页面帧。一些缺少箭头的虚拟页面,表示它们对应的 PTE 的当前标志位被清除(置为 0。这可能是因为这个页面从来没有被使用过或者是它的内容已经被交换出去了。在这两种情况下即便这些页面在 VMA 中,访问它们也将导致产生一个页面故障。对于这种 VMA 和页面表的不一致的情况,看上去似乎很奇怪,但是这种情况却经常发生。
一个 VMA 像一个在你的程序和内核之间的合约。你请求它做一些事情(分配内存、文件映射、等等),内核会回应“收到”,然后去创建或者更新相应的 VMA。 但是,它 _并不立刻_ 去“兑现”对你的承诺,而是它会等待到发生一个页面故障时才去 _真正_ 做这个工作。内核是个“懒惰的家伙”、“不诚实的人渣”这就是虚拟内存的基本原理。它适用于大多数的情况有一些类似情况和有一些意外的情况但是它是规则是VMA 记录 _约定的_ 内容,而 PTE 才反映这个“懒惰的内核”  _真正做了什么_。通过这两种数据结构共同来管理程序的内存;它们共同来完成解决页面故障、释放内存、从内存中交换出数据、等等。下图是内存分配的一个简单案例:
![Example of demand paging and memory allocation](http://static.duartes.org/img/blogPosts/heapAllocation.png)
当程序通过 [brk()][26] 系统调用来请求一些内存时,内核只是简单地 [更新][27] 堆的 VMA 并给程序回复“已搞定”。而在这个时候并没有真正地分配页面帧,并且新的页面也没有映射到物理内存上。一旦程序尝试去访问这个页面时,处理器将发生页面故障,然后调用 [do_page_fault()][28]。这个函数将使用 [find_vma()][30] 去  [搜索][29] 发生页面故障的 VMA。如果找到了然后在 VMA 上进行权限检查以防范恶意访问(读取或者写入)。如果没有合适的 VMA也没有所尝试访问的内存的“合约”将会给进程返回段故障。
当[找到][31]了一个合适的 VMA内核必须通过查找 PTE 的内容和 VMA 的类型去[处理][32]故障。在我们的案例中PTE 显示这个页面是 [不存在的][33]。事实上,我们的 PTE 是全部空白的(全部都是 0在 Linux 中这表示虚拟内存还没有被映射。由于这是匿名 VMA我们有一个完全的 RAM 事务,它必须被 [do_anonymous_page()][34] 来处理,它分配页面帧,并且用一个 PTE 去映射故障虚拟页面到一个新分配的帧。
有时候,事情可能会有所不同。例如,对于被交换出内存的页面的 PTE在当前Present标志位上是 0但它并不是空白的。而是在交换位置仍有页面内容它必须从磁盘上读取并且通过 [do_swap_page()][35] 来加载到一个被称为 [major fault][36] 的页面帧上。
这是我们通过探查内核的用户内存管理得出的前半部分的结论。在下一篇文章中,我们通过将文件加载到内存中,来构建一个完整的内存框架图,以及对性能的影响。
--------------------------------------------------------------------------------
via: http://duartes.org/gustavo/blog/post/how-the-kernel-manages-your-memory/
作者:[Gustavo Duarte][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://duartes.org/gustavo/blog/about/
[1]:https://linux.cn/article-9255-1.html
[2]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/sched.h#L1075
[3]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/sched.h#L1129
[4]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L173
[5]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L197
[6]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L206
[7]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L99
[8]:http://lxr.linux.no/linux+v2.6.28/include/linux/mm.h#L76
[9]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L150
[10]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L174
[11]:http://en.wikipedia.org/wiki/Red_black_tree
[12]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L175
[13]:http://lxr.linux.no/linux+v2.6.28.1/fs/proc/task_mmu.c#L201
[14]:http://www.nirsoft.net/kernel_struct/vista/EPROCESS.html
[15]:http://www.nirsoft.net/kernel_struct/vista/MMVAD.html
[16]:http://en.wikipedia.org/wiki/AVL_tree
[17]:http://lxr.linux.no/linux+v2.6.28.1/include/linux/mm_types.h#L185
[18]:http://lxr.linux.no/linux+v2.6.28.1/arch/x86/include/asm/pgtable.h#L173
[19]:http://lxr.linux.no/linux+v2.6.28.1/arch/x86/include/asm/pgtable.h#L230
[20]:http://www.google.com/search?hl=en&amp;amp;amp;amp;amp;q=2^20+*+2^12+bytes+in+GB
[21]:http://en.wikipedia.org/wiki/Return-to-libc_attack
[22]:http://duartes.org/gustavo/blog/post/getting-physical-with-memory
[23]:http://lxr.linux.no/linux+v2.6.28/include/linux/mm_types.h#L32
[24]:http://lxr.linux.no/linux+v2.6.28/include/linux/page-flags.h#L14
[25]:http://en.wikipedia.org/wiki/Buddy_memory_allocation
[26]:http://www.kernel.org/doc/man-pages/online/pages/man2/brk.2.html
[27]:http://lxr.linux.no/linux+v2.6.28.1/mm/mmap.c#L2050
[28]:http://lxr.linux.no/linux+v2.6.28/arch/x86/mm/fault.c#L583
[29]:http://lxr.linux.no/linux+v2.6.28/arch/x86/mm/fault.c#L692
[30]:http://lxr.linux.no/linux+v2.6.28/mm/mmap.c#L1466
[31]:http://lxr.linux.no/linux+v2.6.28/arch/x86/mm/fault.c#L711
[32]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2653
[33]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2674
[34]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2681
[35]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2280
[36]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2316

View File

@@ -0,0 +1,146 @@
如何使用 yum-cron 自动更新 RHEL/CentOS Linux
======
`yum` 命令是 RHEL / CentOS Linux 系统中用来安装和更新软件包的一个工具。我知道如何使用 [yum 命令行][1] 更新系统,但是我想用 cron 任务自动更新软件包。该如何配置才能使得 `yum` 使用 [cron 自动更新][2]系统补丁或更新呢?
首先需要安装 yum-cron 软件包。该软件包提供以 cron 命令运行 `yum` 更新所需的文件。如果你想要每晚通过 cron 自动更新可以安装这个软件包。
### CentOS/RHEL 6.x/7.x 上安装 yum cron
输入以下 [yum 命令][3]:
```
$ sudo yum install yum-cron
```
![](https://www.cyberciti.biz/media/new/faq/2009/05/How-to-install-yum-cron-on-CentOS-RHEL-server.jpg)
使用 CentOS/RHEL 7.x 上的 `systemctl` 启动服务:
```
$ sudo systemctl enable yum-cron.service
$ sudo systemctl start yum-cron.service
$ sudo systemctl status yum-cron.service
```
在 CentOS/RHEL 6.x 系统中,运行:
```
$ sudo chkconfig yum-cron on
$ sudo service yum-cron start
```
![](https://www.cyberciti.biz/media/new/faq/2009/05/How-to-turn-on-yum-cron-service-on-CentOS-or-RHEL-server.jpg)
`yum-cron``yum` 的一个替代方式。使得 cron 调用 `yum` 变得非常方便。该软件提供了元数据更新、更新检查、下载和安装等功能。`yum-cron` 的各种功能可以使用配置文件配置,而不是输入一堆复杂的命令行参数。
### 配置 yum-cron 自动更新 RHEL/CentOS Linux
使用 vi 等编辑器编辑文件 `/etc/yum/yum-cron.conf``/etc/yum/yum-cron-hourly.conf`
```
$ sudo vi /etc/yum/yum-cron.conf
```
确保更新可用时自动更新:
```
apply_updates = yes
```
可以设置通知 email 的发件地址。注意: localhost` 将会被 `system_name` 的值代替。
```
email_from = root@localhost
```
列出发送到的 email 地址。
```
email_to = your-it-support@some-domain-name
```
发送 email 信息的主机名。
```
email_host = localhost
```
[CentOS/RHEL 7.x][4] 上不想更新内核的话,添加以下内容:
```
exclude=kernel*
```
RHEL/CentOS 6.x 下[添加以下内容来禁用内核更新][5]
```
YUM_PARAMETER=kernel*
```
[保存并关闭文件][6]。如果想每小时更新系统的话修改文件 `/etc/yum/yum-cron-hourly.conf`,否则文件 `/etc/yum/yum-cron.conf` 将使用以下命令每天运行一次(使用 [cat 命令][7] 查看):
```
$ cat /etc/cron.daily/0yum-daily.cron
```
示例输出:
```
#!/bin/bash
# Only run if this flag is set. The flag is created by the yum-cron init
# script when the service is started -- this allows one to use chkconfig and
# the standard "service stop|start" commands to enable or disable yum-cron.
if [[ ! -f /var/lock/subsys/yum-cron ]]; then
exit 0
fi
# Action!
exec /usr/sbin/yum-cron /etc/yum/yum-cron-hourly.conf
[root@centos7-box yum]# cat /etc/cron.daily/0yum-daily.cron
#!/bin/bash
# Only run if this flag is set. The flag is created by the yum-cron init
# script when the service is started -- this allows one to use chkconfig and
# the standard "service stop|start" commands to enable or disable yum-cron.
if [[ ! -f /var/lock/subsys/yum-cron ]]; then
exit 0
fi
# Action!
exec /usr/sbin/yum-cron
```
完成配置。现在你的系统将每天自动更新一次。更多细节请参照 yum-cron 的说明手册。
```
$ man yum-cron
```
### 关于作者
作者是 nixCraft 的创始人,一个经验丰富的系统管理员和 Linux/Unix 脚本培训师。他曾与全球客户合作领域涉及IT教育国防和空间研究以及非营利部门等多个行业。请在 [Twitter][9]、[Facebook][10]、[Google+][11] 上关注他。获取更多有关系统管理、Linux/Unix 和开源话题请关注[我的 RSS/XML 地址][12]。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/fedora-automatic-update-retrieval-installation-with-cron/
作者:[Vivek Gite][a]
译者:[shipsw](https://github.com/shipsw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz/
[1]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/
[2]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses
[3]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ [4]:https://www.cyberciti.biz/faq/yum-update-except-kernel-package-command/
[5]:https://www.cyberciti.biz/faq/redhat-centos-linux-yum-update-exclude-packages/
[6]:https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/
[7]:https://www.cyberciti.biz/faq/linux-unix-appleosx-bsd-cat-command-examples/
[8]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses
[9]:https://twitter.com/nixcraft
[10]:https://facebook.com/nixcraft
[11]:https://plus.google.com/+CybercitiBiz
[12]:https://www.cyberciti.biz/atom/atom.xml

View File

@@ -0,0 +1,435 @@
使用 sar 和 kSar 来发现 Linux 性能瓶颈
======
`sar` 命令用用收集、报告、或者保存 UNIX / Linux 系统的活动信息。它保存选择的计数器到操作系统的 `/var/log/sa/sadd` 文件中。从收集的数据中,你可以得到许多关于你的服务器的信息:
1. CPU 使用率
2. 内存页面和使用率
3. 网络 I/O 和传输统计
4. 进程创建活动
5. 所有的块设备活动
6. 每秒中断数等等
`sar` 命令的输出能够用于识别服务器瓶颈。但是,分析 `sar` 命令提供的信息可能比较困难,所以要使用 kSar 工具。kSar 工具可以将 `sar` 命令的输出绘制成基于时间周期的、易于理解的图表。
### sysstat 包
`sar``sa1`、和 `sa2` 命令都是 sysstat 包的一部分。它是 Linux 包含的性能监视工具集合。
1. `sar`:显示数据
2. `sa1``sa2`:收集和保存数据用于以后分析。`sa2` shell 脚本在 `/var/log/sa` 目录中每日写入一个报告。`sa1` shell 脚本将每日的系统活动信息以二进制数据的形式写入到文件中。
3. sadc —— 系统活动数据收集器。你可以通过修改 `sa1``sa2` 脚本去配置各种选项。它们位于以下的目录:
* `/usr/lib64/sa/sa1` 64 位)或者 `/usr/lib/sa/sa1` 32 位) —— 它调用 `sadc` 去记录报告到 `/var/log/sa/sadX` 格式。
* `/usr/lib64/sa/sa2` 64 位)或者 `/usr/lib/sa/sa2` 32 位) —— 它调用 `sar` 去记录报告到 `/var/log/sa/sarX` 格式。
#### 如何在我的系统上安装 sar
在一个基于 CentOS/RHEL 的系统上,输入如下的 [yum 命令][1] 去安装 sysstat
```
# yum install sysstat
```
示例输出如下:
```
Loaded plugins: downloadonly, fastestmirror, priorities,
: protectbase, security
Loading mirror speeds from cached hostfile
* addons: mirror.cs.vt.edu
* base: mirror.ash.fastserv.com
* epel: serverbeach1.fedoraproject.org
* extras: mirror.cogentco.com
* updates: centos.mirror.nac.net
0 packages excluded due to repository protections
Setting up Install Process
Resolving Dependencies
--&gt; Running transaction check
---&gt; Package sysstat.x86_64 0:7.0.2-3.el5 set to be updated
--&gt; Finished Dependency Resolution
Dependencies Resolved
====================================================================
Package Arch Version Repository Size
====================================================================
Installing:
sysstat x86_64 7.0.2-3.el5 base 173 k
Transaction Summary
====================================================================
Install 1 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total download size: 173 k
Is this ok [y/N]: y
Downloading Packages:
sysstat-7.0.2-3.el5.x86_64.rpm | 173 kB 00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : sysstat 1/1
Installed:
sysstat.x86_64 0:7.0.2-3.el5
Complete!
```
#### 为 sysstat 配置文件
编辑 `/etc/sysconfig/sysstat` 文件去指定日志文件保存多少天(最长为一个月):
```
# vi /etc/sysconfig/sysstat
```
示例输出如下
```
# keep log for 28 days
# the default is 7
HISTORY=28
```
保存并关闭这个文件。
### 找到 sar 默认的 cron 作业
[默认的 cron 作业位于][2] `/etc/cron.d/sysstat`
```
# cat /etc/cron.d/sysstat
```
示例输出如下:
```
# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 1 1
# generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A
```
#### 告诉 sadc 去报告磁盘的统计数据
使用一个文本编辑器去编辑 `/etc/cron.d/sysstat` 文件,比如使用 `vim` 命令,输入如下:
```
# vi /etc/cron.d/sysstat
```
像下面的示例那样更新这个文件,以记录所有的硬盘统计数据(`-d` 选项强制记录每个块设备的统计数据,而 `-I` 选项强制记录所有系统中断的统计数据):
```
# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 -I -d 1 1
# generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A
```
在 CentOS/RHEL 7.x 系统上你需要传递 `-S DISK` 选项去收集块设备的数据。传递 `-S XALL` 选项去采集如下所列的数据:
1. 磁盘
2. 分区
3. 系统中断
4. SNMP
5. IPv6
```
# Run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 -S DISK 1 1
# 0 * * * * root /usr/lib64/sa/sa1 600 6 &
# Generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A
# Run system activity accounting tool every 10 minutes
```
保存并关闭这个文件。
#### 打开 CentOS/RHEL 版本 5.x/6.x 的服务
输入如下命令:
```
chkconfig sysstat on
service sysstat start
```
示例输出如下:
```
Calling the system activity data collector (sadc):
```
对于 CentOS/RHEL 7.x运行如下的命令
```
# systemctl enable sysstat
# systemctl start sysstat.service
# systemctl status sysstat.service
```
示例输出:
```
● sysstat.service - Resets System Activity Logs
Loaded: loaded (/usr/lib/systemd/system/sysstat.service; enabled; vendor preset: enabled)
Active: active (exited) since Sat 2018-01-06 16:33:19 IST; 3s ago
Process: 28297 ExecStart=/usr/lib64/sa/sa1 --boot (code=exited, status=0/SUCCESS)
Main PID: 28297 (code=exited, status=0/SUCCESS)
Jan 06 16:33:19 centos7-box systemd[1]: Starting Resets System Activity Logs...
Jan 06 16:33:19 centos7-box systemd[1]: Started Resets System Activity Logs.
```
### 如何使用 sar如何查看统计数据
使用 `sar` 命令去显示操作系统中选定的累积活动计数器输出。在这个示例中,运行 `sar` 命令行,去实时获得 CPU 使用率的报告:
```
# sar -u 3 10
```
示例输出:
```
Linux 2.6.18-164.2.1.el5 (www-03.nixcraft.in) 12/14/2009
09:49:47 PM CPU %user %nice %system %iowait %steal %idle
09:49:50 PM all 5.66 0.00 1.22 0.04 0.00 93.08
09:49:53 PM all 12.29 0.00 1.93 0.04 0.00 85.74
09:49:56 PM all 9.30 0.00 1.61 0.00 0.00 89.10
09:49:59 PM all 10.86 0.00 1.51 0.04 0.00 87.58
09:50:02 PM all 14.21 0.00 3.27 0.04 0.00 82.47
09:50:05 PM all 13.98 0.00 4.04 0.04 0.00 81.93
09:50:08 PM all 6.60 6.89 1.26 0.00 0.00 85.25
09:50:11 PM all 7.25 0.00 1.55 0.04 0.00 91.15
09:50:14 PM all 6.61 0.00 1.09 0.00 0.00 92.31
09:50:17 PM all 5.71 0.00 0.96 0.00 0.00 93.33
Average: all 9.24 0.69 1.84 0.03 0.00 88.20
```
其中:
* 3 表示间隔时间
* 10 表示次数
查看进程创建的统计数据,输入:
```
# sar -c 3 10
```
查看 I/O 和传输率统计数据,输入:
```
# sar -b 3 10
```
查看内存页面统计数据,输入:
```
# sar -B 3 10
```
查看块设备统计数据,输入:
```
# sar -d 3 10
```
查看所有中断的统计数据,输入:
```
# sar -I XALL 3 10
```
查看网络设备特定的统计数据,输入:
```
# sar -n DEV 3 10
# sar -n EDEV 3 10
```
查看 CPU 特定的统计数据,输入:
```
# sar -P ALL
# Only 1st CPU stats
# sar -P 1 3 10
```
查看队列长度和平均负载的统计数据,输入:
```
# sar -q 3 10
```
查看内存和交换空间的使用统计数据,输入:
```
# sar -r 3 10
# sar -R 3 10
```
查看 inode、文件、和其它内核表统计数据状态输入
```
# sar -v 3 10
```
查看系统切换活动统计数据,输入:
```
# sar -w 3 10
```
查看交换统计数据,输入:
```
# sar -W 3 10
```
查看一个 PID 为 3256 的 Apache 进程,输入:
```
# sar -x 3256 3 10
```
### kSar 介绍
`sar``sadf` 提供了基于命令行界面的输出。这种输出可能会使新手用户/系统管理员感到无从下手。因此,你需要使用 kSar它是一个图形化显示你的 `sar` 数据的 Java 应用程序。它也允许你以 PDF/JPG/PNG/CSV 格式导出数据。你可以用三种方式去加载数据:本地文件、运行本地命令、以及通过 SSH 远程运行的命令。kSar 可以处理下列操作系统的 `sar` 输出:
1. Solaris 8, 9 和 10
2. Mac OS/X 10.4+
3. Linux (Systat Version >= 5.0.5)
4. AIX (4.3 & 5.3)
5. HPUX 11.00+
#### 下载和安装 kSar
访问 [官方][3] 网站去获得最新版本的源代码。使用 [wget][4] 去下载源代码,输入:
```
$ wget https://github.com/vlsi/ksar/releases/download/v5.2.4-snapshot-652bf16/ksar-5.2.4-SNAPSHOT-all.jar
```
#### 如何运行 kSar
首先要确保你的机器上 [JAVA jdk][5] 已安装并能够正常工作。输入下列命令去启动 kSar
```
$ java -jar ksar-5.2.4-SNAPSHOT-all.jar
```
![Fig.01: kSar welcome screen][6]
接下来你将看到 kSar 的主窗口,和有两个菜单的面板。
![Fig.02: kSar - the main window][7]
左侧有一个列表,是 kSar 根据数据已经解析出的可用图表的列表。右侧窗口将展示你选定的图表。
#### 如何使用 kSar 去生成 sar 图表?
首先,你需要从命名为 server1 的服务器上采集 `sar` 命令的统计数据。输入如下的命令:
```
[ server1 ]# LC_ALL=C sar -A > /tmp/sar.data.txt
```
接下来,使用 `scp` 命令从本地桌面拷贝到远程电脑上:
```
[ desktop ]$ scp user@server1.nixcraft.com:/tmp/sar.data.txt /tmp/
```
切换到 kSar 窗口,点击 “Data” > “Load data from text file” > 从 `/tmp/` 中选择 `sar.data.txt` > 点击 “Open” 按钮。
现在,图表类型树已经出现在左侧面板中并选定了一个图形:
![Fig.03: Processes for server1][8]
![Fig.03: Disk stats (blok device) stats for server1][9]
![Fig.05: Memory stats for server1][10]
##### 放大和缩小
通过移动你可以交互式缩放图像的一部分。在要缩放的图像的左上角点击并按下鼠标,移动到要缩放区域的右下角,可以选定要缩放的区域。返回到未缩放状态,点击并拖动鼠标到除了右下角外的任意位置,你也可以点击并选择 zoom 选项。
##### 了解 kSar 图像和 sar 数据
我强烈建议你去阅读 `sar``sadf` 命令的 man 页面:
```
$ man sar
$ man sadf
```
### 案例学习:识别 Linux 服务器的 CPU 瓶颈
使用 `sar` 命令和 kSar 工具可以得到内存、CPU、以及其它子系统的详细快照。例如如果 CPU 使用率在一个很长的时间内持续高于 80%,有可能就是出现了一个 CPU 瓶颈。使用 `sar -x ALL` 你可以找到大量消耗 CPU 的进程。
[mpstat 命令][11] 的输出sysstat 包的一部分)也会帮你去了解 CPU 的使用率。但你可以使用 kSar 很容易地去分析这些信息。
#### 找出 CPU 瓶颈后 …
对 CPU 执行如下的调整:
1. 确保没有不需要的进程在后台运行。关闭 [Linux 上所有不需要的服务][12]。
2. 使用 [cron][13] 在一个非高峰时刻运行任务(比如,备份)。
3. 使用 [top 和 ps 命令][14] 去找出所有非关键的后台作业/服务。使用 [renice 命令][15] 去调整低优先级作业。
4. 使用 [taskset 命令去设置进程使用的 CPU ][16] (卸载所使用的 CPU绑定进程到不同的 CPU 上。例如,在 2# CPU 上运行 MySQL 数据库,而在 3# CPU 上运行 Apache。
5. 确保你的系统使用了最新的驱动程序和固件。
6. 如有可能在系统上增加额外的 CPU。
7. 为单线程应用程序使用更快的 CPU比如Lighttpd web 服务器应用程序)。
8. 为多线程应用程序使用多个 CPU比如MySQL 数据库服务器应用程序)。
9. 为一个 web 应用程序使用多个计算节点并设置一个 [负载均衡器][17]。
### isag —— 交互式系统活动记录器(替代工具)
`isag` 命令图形化显示了以前运行 `sar` 命令时存储在二进制文件中的系统活动数据。`isag` 命令引用 `sar` 并提取出它的数据来绘制图形。与 kSar 相比,`isag` 的选项比较少。
![Fig.06: isag CPU utilization graphs][18]
### 关于作者
本文作者是 nixCraft 的创始人和一位经验丰富的 Linux 操作系统/Unix shell 脚本培训师。他与包括 IT、教育、国防和空间研究、以及非营利组织等全球各行业客户一起合作。可以在 [Twitter][19]、[Facebook][20]、[Google+][21] 上关注他。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/tips/identifying-linux-bottlenecks-sar-graphs-with-ksar.html
作者:[Vivek Gite][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ "See Linux/Unix yum command examples for more info"
[2]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/
[3]:https://github.com/vlsi/ksar
[4]:https://www.cyberciti.biz/tips/linux-wget-your-ultimate-command-line-downloader.html
[5]:https://www.cyberciti.biz/faq/howto-ubuntu-linux-install-configure-jdk-jre/
[6]:https://www.cyberciti.biz/media/new/tips/2009/12/sar-welcome.png "kSar welcome screen"
[7]:https://www.cyberciti.biz/media/new/tips/2009/12/screenshot-kSar-a-sar-grapher-01.png "kSar - the main window"
[8]:https://www.cyberciti.biz/media/new/tips/2009/12/cpu-ksar.png "Linux kSar Processes for server1 "
[9]:https://www.cyberciti.biz/media/new/tips/2009/12/disk-stats-ksar.png "Linux Disk I/O Stats Using kSar"
[10]:https://www.cyberciti.biz/media/new/tips/2009/12/memory-ksar.png "Linux Memory paging and its utilization stats"
[11]:https://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html
[12]:https://www.cyberciti.biz/faq/check-running-services-in-rhel-redhat-fedora-centoslinux/
[13]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/
[14]:https://www.cyberciti.biz/faq/show-all-running-processes-in-linux/
[15]:https://www.cyberciti.biz/faq/howto-change-unix-linux-process-priority/
[16]:https://www.cyberciti.biz/faq/taskset-cpu-affinity-command/
[17]:https://www.cyberciti.biz/tips/load-balancer-open-source-software.html
[18]:https://www.cyberciti.biz/media/new/tips/2009/12/isag.cpu_.png "Fig.06: isag CPU utilization graphs"
[19]:https://twitter.com/nixcraft
[20]:https://facebook.com/nixcraft
[21]:https://plus.google.com/+CybercitiBiz

View File

@@ -0,0 +1,178 @@
如何在 Web 服务器文档根目录上设置只读文件权限
======
**Q如何对我存放在 `/var/www/html/` 目录中的所有文件设置只读权限?**
你可以使用 `chmod` 命令对 Linux/Unix/macOS/OS X/*BSD 操作系统上的所有文件来设置只读权限。这篇文章介绍如何在 Linux/Unix 的 web 服务器(如 Nginx、 Lighttpd、 Apache 等)上来设置只读文件权限。
[![Proper read-only permissions for Linux/Unix Nginx/Apache web server's directory][1]][1]
### 如何设置文件为只读模式
语法为:
```
### 仅针对文件 ###
chmod 0444 /var/www/html/*
chmod 0444 /var/www/html/*.php
```
### 如何设置目录为只读模式
语法为:
```
### 仅针对目录 ###
chmod 0444 /var/www/html/
chmod 0444 /path/to/your/dir/
# ***************************************************************************
# 假如 web 服务器的用户/用户组是 www-data文件拥有者是 ftp-data 用户/用户组
# ***************************************************************************
# 设置目录所有文件为只读
chmod -R 0444 /var/www/html/
# 设置文件/目录拥有者为 ftp-data
chown -R ftp-data:ftp-data /var/www/html/
# 所有目录和子目录的权限为 0445 (这样 web 服务器的用户或用户组就可以读取我们的文件)
find /var/www/html/ -type d -print0 | xargs -0 -I {} chmod 0445 "{}"
```
找到所有 `/var/www/html` 下的所有文件(包括子目录),键入:
```
### 仅对文件有效 ###
find /var/www/html -type f -iname "*" -print0 | xargs -I {} -0 chmod 0444 {}
```
然而,你需要在 `/var/www/html` 目录及其子目录上设置只读和执行权限,如此才能让 web 服务器能够访问根目录,键入:
```
### 仅对目录有效 ###
find /var/www/html -type d -iname "*" -print0 | xargs -I {} -0 chmod 0544 {}
```
### 警惕写权限
请注意在 `/var/www/html/` 目录上的写权限会允许任何人删除文件或添加新文件。也就是说,你可能需要设置一个只读权限给 `/var/www/html/` 目录本身。
```
### web根目录只读 ###
chmod 0555 /var/www/html
```
在某些情况下,根据你的设置要求,你可以改变文件的属主和属组来设置严格的权限。
```
### 如果 /var/www/html 目录的拥有人是普通用户你可以设置拥有人为root:root 或 httpd:httpd (推荐) ###
chown -R root:root /var/www/html/
### 确保 apache 拥有 /var/www/html/ ###
chown -R apache:apache /var/www/html/
```
### 关于 NFS 导出目录
你可以在 `/etc/exports` 文件中指定哪个目录应该拥有[只读或者读写权限 ][2]。这个文件定义各种各样的共享在 NFS 服务器和他们的权限。如:
```
# 对任何人只读权限
/var/www/html *(ro,sync)
# 对192.168.1.10(upload.example.com)客户端读写权限访问
/var/www/html 192.168.1.10(rw,sync)
```
### 关于用于 MS-Windows客户端的 SambaCIFS只读共享
要以只读共享 `sales`,更新 `smb.conf`,如下:
```
[sales]
comment = Sales Data
path = /export/cifs/sales
read only = Yes
guest ok = Yes
```
### 关于文件系统表fstab
你可以在 Unix/Linux 上的 `/etc/fstab` 文件中配置挂载某些文件为只读模式。
你需要有专用分区,不要设置其他系统分区为只读模式。
如下在 `/etc/fstab` 文件中设置 `/srv/html` 为只读模式。
```
/dev/sda6 /srv/html ext4 ro 1 1
```
你可以使用 `mount` 命令[重新挂载分区为只读模式][3](使用 root 用户)
```
# mount -o remount,ro /dev/sda6 /srv/html
```
或者
```
# mount -o remount,ro /srv/html
```
上面的命令会尝试重新挂载已挂载的文件系统到 `/srv/html`上。这是改变文件系统挂载标志的常用方法,特别是让只读文件改为可写的。这种方式不会改变设备或者挂载点。让文件变得再次可写,键入:
```
# mount -o remount,rw /dev/sda6 /srv/html
```
```
# mount -o remount,rw /srv/html
```
### Linuxchattr 命令
你可以在 Linux 文件系统上使用 `chattr` 命令[改变文件属性为只读][4],如:
```
chattr +i /path/to/file.php
chattr +i /var/www/html/
# 查找任何在/var/www/html下的文件并设置为只读#
find /var/www/html -iname "*" -print0 | xargs -I {} -0 chattr +i {}
```
通过提供 `-i` 选项可删除只读属性:
```
chattr -i /path/to/file.php
```
FreeBSD、Mac OS X 和其他 BSD Unix 用户可使用[`chflags`命令][5]
```
### 设置只读 ##
chflags schg /path/to/file.php
### 删除只读 ##
chflags noschg /path/to/file.php
```
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/howto-set-readonly-file-permission-in-linux-unix/
作者:[Vivek Gite][a]
译者:[yizhuoyan](https://github.com/yizhuoyan)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/media/new/faq/2012/04/linux-unix-set-read-only-file-system-permission-for-apache-nginx.jpg
[2]:https://www.cyberciti.biz//www.cyberciti.biz/faq/centos-fedora-rhel-nfs-v4-configuration/
[3]:https://www.cyberciti.biz/faq/howto-freebsd-remount-partition/
[4]:https://www.cyberciti.biz/tips/linux-password-trick.html
[5]:https://www.cyberciti.biz/tips/howto-write-protect-file-with-immutable-bit.html

View File

@@ -0,0 +1,92 @@
如何安全地生成随机数
======
### 使用 urandom
使用 [urandom][1]!使用 [urandom][2]!使用 [urandom][3]
使用 [urandom][4]!使用 [urandom][5]!使用 [urandom][6]
### 但对于密码学密钥呢?
仍然使用 [urandom][6]。
### 为什么不是 SecureRandom、OpenSSL、havaged 或者 c 语言实现呢?
这些是用户空间的 CSPRNG伪随机数生成器。你应该用内核的 CSPRNG因为
* 内核可以访问原始设备熵。
* 它可以确保不在应用程序之间共享相同的状态。
* 一个好的内核 CSPRNG像 FreeBSD 中的,也可以保证它播种之前不给你随机数据。
研究过去十年中的随机失败案例,你会看到一连串的用户空间的随机失败案例。[Debian 的 OpenSSH 崩溃][7]?用户空间随机!安卓的比特币钱包[重复 ECDSA 随机 k 值][8]?用户空间随机!可预测洗牌的赌博网站?用户空间随机!
用户空间的生成器几乎总是依赖于内核的生成器。即使它们不这样做,整个系统的安全性也会确保如此。**但用户空间的 CSPRNG 不会增加防御深度;相反,它会产生两个单点故障。**
### 手册页不是说使用 /dev/random 嘛?
这个稍后详述,保留你的意见。你应该忽略掉手册页。不要使用 `/dev/random``/dev/random``/dev/urandom` 之间的区别是 Unix 设计缺陷。手册页不想承认这一点,因此它产生了一个并不存在的安全顾虑。把 `random(4)` 中的密码学上的建议当作传说,继续你的生活吧。
### 但是如果我需要的是真随机值,而非伪随机值呢?
urandom 和 `/dev/random` 提供的是同一类型的随机。与流行的观念相反,`/dev/random` 不提供“真正的随机”。从密码学上来说,你通常不需要“真正的随机”。
urandom 和 `/dev/random` 都基于一个简单的想法。它们的设计与流密码的设计密切相关:一个小秘密被延伸到不可预测值的不确定流中。 这里的秘密是“熵”,而流是“输出”。
只在 Linux 上 `/dev/random` 和 urandom 仍然有意义上的不同。Linux 内核的 CSPRNG 定期进行密钥更新(通过收集更多的熵)。但是 `/dev/random` 也试图跟踪内核池中剩余的熵,并且如果它没有足够的剩余熵时,偶尔也会罢工。这种设计和我所说的一样蠢;这与基于“密钥流”中剩下多少“密钥”的 AES-CTR 设计类似。
如果你使用 `/dev/random` 而非 urandom那么当 Linux 对自己的 RNG随机数生成器如何工作感到困惑时你的程序将不可预测地或者如果你是攻击者非常可预测地挂起。使用 `/dev/random` 会使你的程序不太稳定,但这不会让你在密码学上更安全。
### 这是个缺陷,对吗?
不是,但存在一个你可能想要了解的 Linux 内核 bug即使这并不能改变你应该使用哪一个 RNG。
在 Linux 上,如果你的软件在引导时立即运行,或者这个操作系统你刚刚安装好,那么你的代码可能会与 RNG 发生竞争。这很糟糕,因为如果你赢了竞争,那么你可能会在一段时间内从 urandom 获得可预测的输出。这是 Linux 中的一个 bug如果你正在为 Linux 嵌入式设备构建平台级代码,那你需要了解它。
在 Linux 上,这确实是 urandom而不是 `/dev/random`)的问题。这也是 [Linux 内核中的错误][9]。 但它也容易在用户空间中修复:在引导时,明确地为 urandom 提供种子。长期以来,大多数 Linux 发行版都是这么做的。但**不要**切换到不同的 CSPRNG。
### 在其它操作系统上呢?
FreeBSD 和 OS X 消除了 urandom 和 `/dev/random` 之间的区别;这两个设备的行为是相同的。不幸的是,手册页在解释为什么这样做上干的很糟糕,并延续了 Linux 上 urandom 可怕的神话。
无论你使用 `/dev/random` 还是 urandomFreeBSD 的内核加密 RNG 都不会停摆。 除非它没有被提供种子,在这种情况下,这两者都会停摆。与 Linux 不同这种行为是有道理的。Linux 应该采用它。但是如果你是一名应用程序开发人员这对你几乎没有什么影响Linux、FreeBSD、iOS无论什么使用 urandom 吧。
### 太长了,懒得看
直接使用 urandom 吧。
### 结语
[ruby-trunk Feature #9569][10]
> 现在,在尝试检测 `/dev/urandom` 之前SecureRandom.random_bytes 会尝试检测要使用的 OpenSSL。 我认为这应该反过来。在这两种情况下,你只需要将随机字节进行解压,所以 SecureRandom 可以跳过中间人(和第二个故障点),如果可用的话可以直接与 `/dev/urandom` 进行交互。
总结:
> `/dev/urandom` 不适合用来直接生成会话密钥和频繁生成其他应用程序级随机数据。
>
> GNU/Linux 上的 random(4) 手册所述......
感谢 Matthew Green、 Nate Lawson、 Sean Devlin、 Coda Hale 和 Alex Balducci 阅读了本文草稿。公正警告Matthew 只是大多同意我的观点。
--------------------------------------------------------------------------------
via: https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
作者:[Thomas & Erin Ptacek][a]
译者:[kimii](https://github.com/kimii)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://sockpuppet.org/blog
[1]:http://blog.cr.yp.to/20140205-entropy.html
[2]:http://cr.yp.to/talks/2011.09.28/slides.pdf
[3]:http://golang.org/src/pkg/crypto/rand/rand_unix.go
[4]:http://security.stackexchange.com/questions/3936/is-a-rand-from-dev-urandom-secure-for-a-login-key
[5]:http://stackoverflow.com/a/5639631
[6]:https://twitter.com/bramcohen/status/206146075487240194
[7]:http://research.swtch.com/openssl
[8]:http://arstechnica.com/security/2013/08/google-confirms-critical-android-crypto-flaw-used-in-5700-bitcoin-heist/
[9]:https://factorable.net/weakkeys12.extended.pdf
[10]:https://bugs.ruby-lang.org/issues/9569

View File

@@ -0,0 +1,332 @@
让我们做个简单的解释器(一)
======
> “如果你不知道编译器是怎么工作的,那你就不知道电脑是怎么工作的。如果你不能百分百确定,那就是不知道它们是如何工作的。” --Steve Yegge
就是这样。想一想。你是萌新还是一个资深的软件开发者实际上都无关紧要:如果你不知道<ruby>编译器<rt>compiler</rt></ruby>和<ruby>解释器<rt>interpreter</rt></ruby>是怎么工作的,那么你就不知道电脑是怎么工作的。就这么简单。
所以,你知道编译器和解释器是怎么工作的吗?我是说,你百分百确定自己知道他们怎么工作吗?如果不知道。
![][1]
或者如果你不知道但你非常想要了解它。
![][2]
不用担心。如果你能坚持跟着这个系列做下去,和我一起构建一个解释器和编译器,最后你将会知道他们是怎么工作的。并且你会变成一个自信满满的快乐的人。至少我希望如此。
![][3]
为什么要学习编译器和解释器?有三点理由。
1. 要写出一个解释器或编译器,你需要有很多的专业知识,并能融会贯通。写一个解释器或编译器能帮你加强这些能力,成为一个更厉害的软件开发者。而且,你要学的技能对编写软件非常有用,而不是仅仅局限于解释器或编译器。
2. 你确实想要了解电脑是怎么工作的。通常解释器和编译器看上去很魔幻。你或许不习惯这种魔力。你会想去揭开构建解释器和编译器那层神秘的面纱,了解它们的原理,把事情做好。
3. 你想要创建自己的编程语言或者特定领域的语言。如果你创建了一个你还要为它创建一个解释器或者编译器。最近兴起了对新的编程语言的兴趣。你能看到几乎每天都有一门新的编程语言横空出世ElixirGoRust还有很多。
好,但什么是解释器和编译器?
**解释器****编译器** 的任务是把用高级语言写的源程序翻译成其他的格式。很奇怪,是不是?忍一忍,稍后你会在这个系列学到到底把源程序翻译成什么东西。
这时你可能会奇怪解释器和编译器之间有什么区别。为了实现这个系列的目的,我们规定一下,如果有个翻译器把源程序翻译成机器语言,那它就是 **编译器**。如果一个翻译器可以处理并执行源程序,却不用把它翻译器机器语言,那它就是 **解释器**。直观上它看起来像这样:
![][4]
我希望你现在确信你很想学习构建一个编译器和解释器。你期望在这个教程里学习解释器的哪些知识呢?
你看这样如何。你和我一起为 [Pascal][5] 语言的一个大子集做一个简单的解释器。在这个系列结束的时候你能做出一个可以运行的 Pascal 解释器和一个像 Python 的 [pdb][6] 那样的源代码级别的调试器。
你或许会问,为什么是 Pascal一方面它不是我为了这个系列而提出的一个虚构的语言它是真实存在的一门编程语言有很多重要的语言结构。有些陈旧但有用的计算机书籍使用 Pascal 编程语言作为示例(我知道对于选择一门语言来构建解释器,这个理由并不令人信服,但我认为学一门非主流的语言也不错 :))。
这有个 Pascal 中的阶乘函数示例,你将能用自己的解释器解释代码,还能够用可交互的源码级调试器进行调试,你可以这样创造:
```
program factorial;
function factorial(n: integer): longint;
begin
if n = 0 then
factorial := 1
else
factorial := n * factorial(n - 1);
end;
var
n: integer;
begin
for n := 0 to 16 do
writeln(n, '! = ', factorial(n));
end.
```
这个 Pascal 解释器的实现语言会使用 Python但你也可以用其他任何语言因为这里展示的思想不依赖任何特殊的实现语言。好让我们开始干活。准备好了出发
你会从编写一个简单的算术表达式解析器,也就是常说的计算器,开始学习解释器和编译器。今天的目标非常简单:让你的计算器能处理两个个位数相加,比如 `3+5`。下面是你的计算器的源代码——不好意思,是解释器:
```
# 标记类型
#
# EOF end-of-file 文件末尾)标记是用来表示所有输入都解析完成
INTEGER, PLUS, EOF = 'INTEGER', 'PLUS', 'EOF'
class Token(object):
def __init__(self, type, value):
# token 类型: INTEGER, PLUS, MINUS, or EOF
self.type = type
# token 值: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, '+', 或 None
self.value = value
def __str__(self):
"""String representation of the class instance.
Examples:
Token(INTEGER, 3)
Token(PLUS '+')
"""
return 'Token({type}, {value})'.format(
type=self.type,
value=repr(self.value)
)
def __repr__(self):
return self.__str__()
class Interpreter(object):
def __init__(self, text):
# 用户输入字符串, 例如 "3+5"
self.text = text
# self.pos 是 self.text 的索引
self.pos = 0
# 当前标记实例
self.current_token = None
def error(self):
raise Exception('Error parsing input')
def get_next_token(self):
"""词法分析器(也说成扫描器或者标记器)
该方法负责把一个句子分成若干个标记。每次处理一个标记
"""
text = self.text
# self.pos 索引到达了 self.text 的末尾吗?
# 如果到了,就返回 EOF 标记,因为没有更多的
# 能转换成标记的输入了
if self.pos > len(text) - 1:
return Token(EOF, None)
# 从 self.pos 位置获取当前的字符,
# 基于单个字符判断要生成哪种标记
current_char = text[self.pos]
# 如果字符是一个数字,就把他转换成一个整数,生成一个 INTEGER # 标记,累加 self.pos 索引,指向数字后面的下一个字符,
# 并返回 INTEGER 标记
if current_char.isdigit():
token = Token(INTEGER, int(current_char))
self.pos += 1
return token
if current_char == '+':
token = Token(PLUS, current_char)
self.pos += 1
return token
self.error()
def eat(self, token_type):
# 将当前的标记类型与传入的标记类型作比较,如果他们相匹配,就
# “eat” 掉当前的标记并将下一个标记赋给 self.current_token
# 否则抛出一个异常
if self.current_token.type == token_type:
self.current_token = self.get_next_token()
else:
self.error()
def expr(self):
"""expr -> INTEGER PLUS INTEGER"""
# 将输入中的第一个标记设置成当前标记
self.current_token = self.get_next_token()
# 我们期望当前标记是个位数。
left = self.current_token
self.eat(INTEGER)
# 期望当前标记是 +
op = self.current_token
self.eat(PLUS)
# 我们期望当前标记是个位数。
right = self.current_token
self.eat(INTEGER)
# 上述操作完成后self.current_token 被设成 EOF 标记
# 这时成功找到 INTEGER PLUS INTEGER 标记序列
# 这个方法就可以返回两个整数相加的结果了,
# 即高效的解释了用户输入
result = left.value + right.value
return result
def main():
while True:
try:
# 要在 Python3 下运行,请把 raw_input 换成 input
text = raw_input('calc> ')
except EOFError:
break
if not text:
continue
interpreter = Interpreter(text)
result = interpreter.expr()
print(result)
if __name__ == '__main__':
main()
```
把上面的代码保存到 `calc1.py` 文件,或者直接从 [GitHub][7] 上下载。在你深入研究代码前,在命令行里面运行它看看效果。试一试!这是我笔记本上的示例会话(如果你想在 Python3 下运行,你要把 `raw_input` 换成 `input`
```
$ python calc1.py
calc> 3+4
7
calc> 3+5
8
calc> 3+9
12
calc>
```
要让你的简易计算器正常工作,不抛出异常,你的输入要遵守以下几个规则:
* 只允许输入个位数
* 此时支持的唯一一个运算符是加法
* 输入中不允许有任何的空格符号
要让计算器变得简单,这些限制非常必要。不用担心,你很快就会让它变得很复杂。
好,现在让我们深入它,看看解释器是怎么工作,它是怎么评估出算术表达式的。
当你在命令行中输入一个表达式 `3+5`,解释器就获得了字符串 “3+5”。为了让解释器能够真正理解要用这个字符串做什么它首先要把输入 “3+5” 分到叫做 `token`(标记)的容器里。<ruby>标记<rt>token</rt></ruby> 是一个拥有类型和值的对象。比如说,对字符 “3” 而言,标记的类型是 INTEGER 整数,对应的值是 3。
把输入字符串分成标记的过程叫<ruby>词法分析<rt>lexical analysis</rt></ruby>。因此解释器的需要做的第一步是读取输入字符,并将其转换成标记流。解释器中的这一部分叫做<ruby>词法分析器<rt>lexical analyzer</rt></ruby>,或者简短点叫 **lexer**。你也可以给它起别的名字,诸如<ruby>扫描器<rt>scanner</rt></ruby>或者<ruby>标记器<rt>tokenizer</rt></ruby>。它们指的都是同一个东西:解释器或编译器中将输入字符转换成标记流的那部分。
`Interpreter` 类中的 `get_next_token` 方法就是词法分析器。每次调用它的时候,你都能从传入解释器的输入字符中获得创建的下一个标记。仔细看看这个方法,看看它是如何完成把字符转换成标记的任务的。输入被存在可变文本中,它保存了输入的字符串和关于该字符串的索引(把字符串想象成字符数组)。`pos` 开始时设为 0指向字符 3。这个方法一开始检查字符是不是数字如果是就将 `pos` 加 1并返回一个 INTEGER 类型的标记实例,并把字符 3 的值设为整数,也就是整数 3
![][8]
现在 `pos` 指向文本中的 + 号。下次调用这个方法的时候,它会测试 `pos` 位置的字符是不是个数字,然后检测下一个字符是不是个加号,就是这样。结果这个方法把 `pos` 加 1返回一个新创建的标记类型是 PLUS值为 +’。
![][9]
`pos` 现在指向字符 5。当你再调用 `get_next_token` 方法时,该方法会检查这是不是个数字,就是这样,然后它把 `pos` 加 1返回一个新的 INTEGER 标记,该标记的值被设为整数 5
![][10]
因为 `pos` 索引现在到了字符串 “3+5” 的末尾,你每次调用 `get_next_token` 方法时,它将会返回 EOF 标记:
![][11]
自己试一试,看看计算器里的词法分析器的运行:
```
>>> from calc1 import Interpreter
>>>
>>> interpreter = Interpreter('3+5')
>>> interpreter.get_next_token()
Token(INTEGER, 3)
>>>
>>> interpreter.get_next_token()
Token(PLUS, '+')
>>>
>>> interpreter.get_next_token()
Token(INTEGER, 5)
>>>
>>> interpreter.get_next_token()
Token(EOF, None)
>>>
```
既然你的解释器能够从输入字符中获取标记流,解释器需要对它做点什么:它需要在词法分析器 `get_next_token` 中获取的标记流中找出相应的结构。你的解释器应该能够找到流中的结构INTEGER -> PLUS -> INTEGER。就是这样它尝试找出标记的序列整数后面要跟着加号加号后面要跟着整数。
负责找出并解释结构的方法就是 `expr`。该方法检验标记序列确实与期望的标记序列是对应的,比如 INTEGER -> PLUS -> INTEGER。成功确认了这个结构后就会生成加号左右两边的标记的值相加的结果这样就成功解释你输入到解释器中的算术表达式了。
`expr` 方法用了一个助手方法 `eat` 来检验传入的标记类型是否与当前的标记类型相匹配。在匹配到传入的标记类型后,`eat` 方法会获取下一个标记,并将其赋给 `current_token` 变量,然后高效地 “吃掉” 当前匹配的标记,并将标记流的虚拟指针向后移动。如果标记流的结构与期望的 INTEGER -> PLUS -> INTEGER 标记序列不对应,`eat` 方法就抛出一个异常。
让我们回顾下解释器做了什么来对算术表达式进行评估的:
* 解释器接受输入字符串,比如说 “3+5”
* 解释器调用 `expr` 方法,在词法分析器 `get_next_token` 返回的标记流中找出结构。这个结构就是 INTEGER -> PLUS -> INTEGER 这样的格式。在确认了格式后,它就通过把两个整型标记相加来解释输入,因为此时对于解释器来说很清楚,它要做的就是把两个整数 3 和 5 进行相加。
恭喜。你刚刚学习了怎么构建自己的第一个解释器!
现在是时候做练习了。
![][12]
看了这篇文章,你肯定觉得不够,是吗?好,准备好做这些练习:
1. 修改代码,允许输入多位数,比如 “12+3”
2. 添加一个方法忽略空格符,让你的计算器能够处理带有空白的输入,比如 “12 + 3”
3. 修改代码,用 - 号而非 + 号去执行减法比如 “7-5”
**检验你的理解**
1. 什么是解释器?
2. 什么是编译器
3. 解释器和编译器有什么差别?
4. 什么是标记?
5. 将输入分隔成若干个标记的过程叫什么?
6. 解释器中进行词法分析的部分叫什么?
7. 解释器或编译器中进行词法分析的部分有哪些其他的常见名字?
在结束本文前,我衷心希望你能留下学习解释器和编译器的承诺。并且现在就开始做。不要把它留到以后。不要拖延。如果你已经看完了本文,就开始吧。如果已经仔细看完了但是还没做什么练习 —— 现在就开始做吧。如果已经开始做练习了,那就把剩下的做完。你懂得。而且你知道吗?签下承诺书,今天就开始学习解释器和编译器!
> 本人, ______身体健全思想正常在此承诺从今天开始学习解释器和编译器直到我百分百了解它们是怎么工作的
>
> 签字人:
> 日期:
![][13]
签字,写上日期,把它放在你每天都能看到的地方,确保你能坚守承诺。谨记你的承诺:
> “承诺就是,你说自己会去做的事,在你说完就一直陪着你的东西。” —— Darren Hardy
好,今天的就结束了。这个系列的下一篇文章里,你将会扩展自己的计算器,让它能够处理更复杂的算术表达式。敬请期待。
--------------------------------------------------------------------------------
via: https://ruslanspivak.com/lsbasi-part1/
作者:[Ruslan Spivak][a]
译者:[BriFuture](https://github.com/BriFuture)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://ruslanspivak.com
[1]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_i_dont_know.png
[2]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_omg.png
[3]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_i_know.png
[4]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_compiler_interpreter.png
[5]:https://en.wikipedia.org/wiki/Pascal_%28programming_language%29
[6]:https://docs.python.org/2/library/pdb.html
[7]:https://github.com/rspivak/lsbasi/blob/master/part1/calc1.py
[8]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_lexer1.png
[9]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_lexer2.png
[10]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_lexer3.png
[11]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_lexer4.png
[12]:https://ruslanspivak.com/lsbasi-part1/lsbasi_exercises2.png
[13]:https://ruslanspivak.com/lsbasi-part1/lsbasi_part1_commitment_pledge.png
[14]:http://ruslanspivak.com/lsbaws-part1/ (Part 1)
[15]:http://ruslanspivak.com/lsbaws-part2/ (Part 2)
[16]:http://ruslanspivak.com/lsbaws-part3/ (Part 3)

View File

@@ -0,0 +1,189 @@
Linux 跟踪器之选
======
[![][1]][2]
> Linux 跟踪很神奇!
<ruby>跟踪器<rt>tracer</rt></ruby>是一个高级的性能分析和调试工具,如果你使用过 `strace(1)` 或者 `tcpdump(8)`,你不应该被它吓到 ... 你使用的就是跟踪器。系统跟踪器能让你看到很多的东西,而不仅是系统调用或者数据包,因为常见的跟踪器都可以跟踪内核或者应用程序的任何东西。
有大量的 Linux 跟踪器可供你选择。由于它们中的每个都有一个官方的(或者非官方的)的吉祥物,我们有足够多的选择给孩子们展示。
你喜欢使用哪一个呢?
我从两类读者的角度来回答这个问题:大多数人和性能/内核工程师。当然随着时间的推移这也可能会发生变化因此我需要及时去更新本文内容或许是每年一次或者更频繁。LCTT 译注:本文最后更新于 2015 年)
### 对于大多数人
大多数人开发者、系统管理员、运维人员、网络可靠性工程师SRE是不需要去学习系统跟踪器的底层细节的。以下是你需要去了解和做的事情
#### 1. 使用 perf_events 进行 CPU 剖析
可以使用 perf_events 进行 CPU <ruby>剖析<rt>profiling</rt></ruby>。它可以用一个 [火焰图][3] 来形象地表示。比如:
```
git clone --depth 1 https://github.com/brendangregg/FlameGraph
perf record -F 99 -a -g -- sleep 30
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > perf.svg
```
![](http://www.brendangregg.com/blog/images/2015/cpu-bash-flamegraph-500.png)
Linux 的 perf_events`perf`,后者是它的命令)是官方为 Linux 用户准备的跟踪器/分析器。它位于内核源码中,并且维护的非常好(而且现在它的功能还在快速变强)。它一般是通过 linux-tools-common 这个包来添加的。
`perf` 可以做的事情很多,但是,如果我只能建议你学习其中的一个功能的话,那就是 CPU 剖析。虽然从技术角度来说,这并不是事件“跟踪”,而是<ruby>采样<rt>sampling</rt></ruby>。最难的部分是获得完整的栈和符号,这部分在我的 [Linux Profiling at Netflix][4] 中针对 Java 和 Node.js 讨论过。
#### 2. 知道它能干什么
正如一位朋友所说的:“你不需要知道 X 光机是如何工作的但你需要明白的是如果你吞下了一个硬币X 光机是你的一个选择!”你需要知道使用跟踪器能够做什么,因此,如果你在业务上确实需要它,你可以以后再去学习它,或者请会使用它的人来做。
简单地说几乎任何事情都可以通过跟踪来了解它。内部文件系统、TCP/IP 处理过程、设备驱动、应用程序内部情况。阅读我在 lwn.net 上的 [ftrace][5] 的文章,也可以去浏览 [perf_events 页面][6],那里有一些跟踪(和剖析)能力的示例。
#### 3. 需要一个前端工具
如果你要购买一个性能分析工具(有许多公司销售这类产品),并要求支持 Linux 跟踪。想要一个直观的“点击”界面去探查内核的内部,以及包含一个在不同堆栈位置的延迟热力图。就像我在 [Monitorama 演讲][7] 中描述的那样。
我创建并开源了我自己的一些前端工具,虽然它是基于 CLI 的(不是图形界面的)。这样可以使其它人使用跟踪器更快更容易。比如,我的 [perf-tools][8],跟踪新进程是这样的:
```
# ./execsnoop
Tracing exec()s. Ctrl-C to end.
PID PPID ARGS
22898 22004 man ls
22905 22898 preconv -e UTF-8
22908 22898 pager -s
22907 22898 nroff -mandoc -rLL=164n -rLT=164n -Tutf8
[...]
```
在 Netflix 公司,我正在开发 [Vector][9],它是一个实例分析工具,实际上它也是一个 Linux 跟踪器的前端。
### 对于性能或者内核工程师
一般来说,我们的工作都非常难,因为大多数人或许要求我们去搞清楚如何去跟踪某个事件,以及因此需要选择使用哪个跟踪器。为完全理解一个跟踪器,你通常需要花至少一百多个小时去使用它。理解所有的 Linux 跟踪器并能在它们之间做出正确的选择是件很难的事情。(我或许是唯一接近完成这件事的人)
在这里我建议选择如下,要么:
A选择一个全能的跟踪器并以它为标准。这需要在一个测试环境中花大量的时间来搞清楚它的细微差别和安全性。我现在的建议是 SystemTap 的最新版本(例如,从 [源代码][10] 构建)。我知道有的公司选择的是 LTTng ,尽管它并不是很强大(但是它很安全),但他们也用的很好。如果在 `sysdig` 中添加了跟踪点或者是 kprobes它也是另外的一个候选者。
B按我的 [Velocity 教程中][11] 的流程图。这意味着尽可能使用 ftrace 或者 perf_eventseBPF 已经集成到内核中了,然后用其它的跟踪器,如 SystemTap/LTTng 作为对 eBPF 的补充。我目前在 Netflix 的工作中就是这么做的。
![](http://www.brendangregg.com/blog/images/2015/choosing_a_tracer.png)
以下是我对各个跟踪器的评价:
#### 1. ftrace
我爱 [ftrace][12]它是内核黑客最好的朋友。它被构建进内核中它能够利用跟踪点、kprobes、以及 uprobes以提供一些功能使用可选的过滤器和参数进行事件跟踪事件计数和计时内核概览<ruby>函数流步进<rt>function-flow walking</rt></ruby>。关于它的示例可以查看内核源代码树中的 [ftrace.txt][13]。它通过 `/sys` 来管理,是面向单一的 root 用户的(虽然你可以使用缓冲实例以让其支持多用户),它的界面有时很繁琐,但是它比较容易<ruby>调校<rt>hackable</rt></ruby>并且有个前端ftrace 的主要创建者 Steven Rostedt 设计了一个 trace-cmd而且我也创建了 perf-tools 集合。我最诟病的就是它不是<ruby>可编程的<rt>programmable</rt></ruby>,因此,举个例子说,你不能保存和获取时间戳、计算延迟,以及将其保存为直方图。你需要转储事件到用户级以便于进行后期处理,这需要花费一些成本。它也许可以通过 eBPF 实现可编程。
#### 2. perf_events
[perf_events][14] 是 Linux 用户的主要跟踪工具,它的源代码位于 Linux 内核中,一般是通过 linux-tools-common 包来添加的。它又称为 `perf`后者指的是它的前端它相当高效动态缓存一般用于跟踪并转储到一个文件中perf.data然后可以在之后进行后期处理。它可以做大部分 ftrace 能做的事情。它不能进行函数流步进,并且不太容易调校(而它的安全/错误检查做的更好一些。但它可以做剖析采样、CPU 性能计数、用户级的栈转换、以及使用本地变量利用<ruby>调试信息<rt>debuginfo</rt></ruby>进行<ruby>行级跟踪<rt>line tracing</rt></ruby>。它也支持多个并发用户。与 ftrace 一样,它也不是内核可编程的,除非 eBPF 支持(补丁已经在计划中)。如果只学习一个跟踪器,我建议大家去学习 perf它可以解决大量的问题并且它也相当安全。
#### 3. eBPF
<ruby>扩展的伯克利包过滤器<rt>extended Berkeley Packet Filter</rt></ruby>eBPF是一个<ruby>内核内<rt>in-kernel</rt></ruby>的虚拟机可以在事件上运行程序它非常高效JIT。它可能最终为 ftrace 和 perf_events 提供<ruby>内核内编程<rt>in-kernel programming</rt></ruby>,并可以去增强其它跟踪器。它现在是由 Alexei Starovoitov 开发的还没有实现完全的整合但是对于一些令人印象深刻的工具有些内核版本比如4.1)已经支持了:比如,块设备 I/O 的<ruby>延迟热力图<rt>latency heat map</rt></ruby>。更多参考资料,请查阅 Alexei 的 [BPF 演示][15],和它的 [eBPF 示例][16]。
#### 4. SystemTap
[SystemTap][17] 是一个非常强大的跟踪器。它可以做任何事情剖析、跟踪点、kprobes、uprobes它就来自 SystemTap、USDT、内核内编程等等。它将程序编译成内核模块并加载它们 —— 这是一种很难保证安全的方法。它开发是在内核代码树之外进行的,并且在过去出现过很多问题(内核崩溃或冻结)。许多并不是 SystemTap 的过错 —— 它通常是首次对内核使用某些跟踪功能,并率先遇到 bug。最新版本的 SystemTap 是非常好的(你需要从它的源代码编译),但是,许多人仍然没有从早期版本的问题阴影中走出来。如果你想去使用它,花一些时间去测试环境,然后,在 irc.freenode.net 的 #systemtap 频道与开发者进行讨论。Netflix 有一个容错架构,我们使用了 SystemTap但是我们或许比起你来说更少担心它的安全性我最诟病的事情是它似乎假设你有办法得到内核调试信息而我并没有这些信息。没有它我实际上可以做很多事情但是缺少相关的文档和示例我现在自己开始帮着做这些了
#### 5. LTTng
[LTTng][18] 对事件收集进行了优化,性能要好于其它的跟踪器,也支持许多的事件类型,包括 USDT。它的开发是在内核代码树之外进行的。它的核心部分非常简单通过一个很小的固定指令集写入事件到跟踪缓冲区。这样让它既安全又快速。缺点是做内核内编程不太容易。我觉得那不是个大问题由于它优化的很好可以充分的扩展尽管需要后期处理。它也探索了一种不同的分析技术。很多的“黑匣子”记录了所有感兴趣的事件以便可以在 GUI 中以后分析它。我担心该记录会错失之前没有预料的事件,我真的需要花一些时间去看看它在实践中是如何工作的。这个跟踪器上我花的时间最少(没有特别的原因)。
#### 6. ktap
[ktap][19] 是一个很有前途的跟踪器,它在内核中使用了一个 lua 虚拟机,不需要调试信息和在嵌入时设备上可以工作的很好。这使得它进入了人们的视野,在某个时候似乎要成为 Linux 上最好的跟踪器。然而,由于 eBPF 开始集成到了内核,而 ktap 的集成工作被推迟了,直到它能够使用 eBPF 而不是它自己的虚拟机。由于 eBPF 在几个月过去之后仍然在集成过程中ktap 的开发者已经等待了很长的时间。我希望在今年的晚些时间它能够重启开发。
#### 7. dtrace4linux
[dtrace4linux][20] 主要由一个人Paul Fox利用业务时间将 Sun DTrace 移植到 Linux 中的。它令人印象深刻,一些<ruby>供应器<rt>provider</rt></ruby>可以工作,还不是很完美,它最多应该算是实验性的工具(不安全)。我认为对于许可证的担心,使人们对它保持谨慎:它可能永远也进入不了 Linux 内核,因为 Sun 是基于 CDDL 许可证发布的 DTracePaul 的方法是将它作为一个插件。我非常希望看到 Linux 上的 DTrace并且希望这个项目能够完成我想我加入 Netflix 时将花一些时间来帮它完成。但是,我一直在使用内置的跟踪器 ftrace 和 perf_events。
#### 8. OL DTrace
[Oracle Linux DTrace][21] 是将 DTrace 移植到 Linux (尤其是 Oracle Linux的重大努力。过去这些年的许多发布版本都一直稳定的进步开发者甚至谈到了改善 DTrace 测试套件这显示出这个项目很有前途。许多有用的功能已经完成系统调用、剖析、sdt、proc、sched、以及 USDT。我一直在等待着 fbt函数边界跟踪对内核的动态跟踪它将成为 Linux 内核上非常强大的功能。它最终能否成功取决于能否吸引足够多的人去使用 Oracle Linux并为支持付费。另一个羁绊是它并非完全开源的内核组件是开源的但用户级代码我没有看到。
#### 9. sysdig
[sysdig][22] 是一个很新的跟踪器,它可以使用类似 `tcpdump` 的语法来处理<ruby>系统调用<rt>syscall</rt></ruby>事件,并用 lua 做后期处理。它也是令人印象深刻的并且很高兴能看到在系统跟踪领域的创新。它的局限性是它的系统调用只能是在当时并且它转储所有事件到用户级进行后期处理。你可以使用系统调用来做许多事情虽然我希望能看到它去支持跟踪点、kprobes、以及 uprobes。我也希望看到它支持 eBPF 以查看内核内概览。sysdig 的开发者现在正在增加对容器的支持。可以关注它的进一步发展。
### 深入阅读
我自己的工作中使用到的跟踪器包括:
- **ftrace** 我的 [perf-tools][8] 集合(查看示例目录);我的 lwn.net 的 [ftrace 跟踪器的文章][5] 一个 [LISA14][8] 演讲;以及帖子: [函数计数][23]、 [iosnoop][24]、 [opensnoop][25]、 [execsnoop][26]、 [TCP retransmits][27]、 [uprobes][28] 和 [USDT][29]。
- **perf_events** 我的 [perf_events 示例][6] 页面;在 SCALE 的一个 [Linux Profiling at Netflix][4] 演讲;和帖子:[CPU 采样][30]、[静态跟踪点][31]、[热力图][32]、[计数][33]、[内核行级跟踪][34]、[off-CPU 时间火焰图][35]。
- **eBPF** : 帖子 [eBPF一个小的进步][36],和一些 [BPF-tools][37] (我需要发布更多)。
- **SystemTap** 很久以前,我写了一篇 [使用 SystemTap][38] 的文章,它有点过时了。最近我发布了一些 [systemtap-lwtools][39]展示了在没有内核调试信息的情况下SystemTap 是如何使用的。
- **LTTng** 我使用它的时间很短,不足以发布什么文章。
- **ktap** 我的 [ktap 示例][40] 页面包括一行程序和脚本,虽然它是早期的版本。
- **dtrace4linux** 在我的 [系统性能][41] 书中包含了一些示例,并且在过去我为了某些事情开发了一些小的修补,比如, [timestamps][42]。
- **OL DTrace** 因为它是对 DTrace 的直接移植,我早期 DTrace 的工作大多与之相关(链接太多了,可以去 [我的主页][43] 上搜索)。一旦它更加完美,我可以开发很多专用工具。
- **sysdig** 我贡献了 [fileslower][44] 和 [subsecond offset spectrogram][45] 的 chisel。
- **其它** 关于 [strace][46],我写了一些告诫文章。
不好意思,没有更多的跟踪器了! … 如果你想知道为什么 Linux 中的跟踪器不止一个,或者关于 DTrace 的内容,在我的 [从 DTrace 到 Linux][47] 的演讲中有答案,从 [第 28 张幻灯片][48] 开始。
感谢 [Deirdre Straughan][49] 的编辑以及跟踪小马的创建General Zoi 是小马的创建者)。
--------------------------------------------------------------------------------
via: http://www.brendangregg.com/blog/2015-07-08/choosing-a-linux-tracer.html
作者:[Brendan Gregg][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.brendangregg.com
[1]:http://www.brendangregg.com/blog/images/2015/tracing_ponies.png
[2]:http://www.slideshare.net/brendangregg/velocity-2015-linux-perf-tools/105
[3]:http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html
[4]:http://www.brendangregg.com/blog/2015-02-27/linux-profiling-at-netflix.html
[5]:http://lwn.net/Articles/608497/
[6]:http://www.brendangregg.com/perf.html
[7]:http://www.brendangregg.com/blog/2015-06-23/netflix-instance-analysis-requirements.html
[8]:http://www.brendangregg.com/blog/2015-03-17/linux-performance-analysis-perf-tools.html
[9]:http://techblog.netflix.com/2015/04/introducing-vector-netflixs-on-host.html
[10]:https://sourceware.org/git/?p=systemtap.git;a=blob_plain;f=README;hb=HEAD
[11]:http://www.slideshare.net/brendangregg/velocity-2015-linux-perf-tools
[12]:http://lwn.net/Articles/370423/
[13]:https://www.kernel.org/doc/Documentation/trace/ftrace.txt
[14]:https://perf.wiki.kernel.org/index.php/Main_Page
[15]:http://www.phoronix.com/scan.php?page=news_item&amp;px=BPF-Understanding-Kernel-VM
[16]:https://github.com/torvalds/linux/tree/master/samples/bpf
[17]:https://sourceware.org/systemtap/wiki
[18]:http://lttng.org/
[19]:http://ktap.org/
[20]:https://github.com/dtrace4linux/linux
[21]:http://docs.oracle.com/cd/E37670_01/E38608/html/index.html
[22]:http://www.sysdig.org/
[23]:http://www.brendangregg.com/blog/2014-07-13/linux-ftrace-function-counting.html
[24]:http://www.brendangregg.com/blog/2014-07-16/iosnoop-for-linux.html
[25]:http://www.brendangregg.com/blog/2014-07-25/opensnoop-for-linux.html
[26]:http://www.brendangregg.com/blog/2014-07-28/execsnoop-for-linux.html
[27]:http://www.brendangregg.com/blog/2014-09-06/linux-ftrace-tcp-retransmit-tracing.html
[28]:http://www.brendangregg.com/blog/2015-06-28/linux-ftrace-uprobe.html
[29]:http://www.brendangregg.com/blog/2015-07-03/hacking-linux-usdt-ftrace.html
[30]:http://www.brendangregg.com/blog/2014-06-22/perf-cpu-sample.html
[31]:http://www.brendangregg.com/blog/2014-06-29/perf-static-tracepoints.html
[32]:http://www.brendangregg.com/blog/2014-07-01/perf-heat-maps.html
[33]:http://www.brendangregg.com/blog/2014-07-03/perf-counting.html
[34]:http://www.brendangregg.com/blog/2014-09-11/perf-kernel-line-tracing.html
[35]:http://www.brendangregg.com/blog/2015-02-26/linux-perf-off-cpu-flame-graph.html
[36]:http://www.brendangregg.com/blog/2015-05-15/ebpf-one-small-step.html
[37]:https://github.com/brendangregg/BPF-tools
[38]:http://dtrace.org/blogs/brendan/2011/10/15/using-systemtap/
[39]:https://github.com/brendangregg/systemtap-lwtools
[40]:http://www.brendangregg.com/ktap.html
[41]:http://www.brendangregg.com/sysperfbook.html
[42]:https://github.com/dtrace4linux/linux/issues/55
[43]:http://www.brendangregg.com
[44]:https://github.com/brendangregg/sysdig/commit/d0eeac1a32d6749dab24d1dc3fffb2ef0f9d7151
[45]:https://github.com/brendangregg/sysdig/commit/2f21604dce0b561407accb9dba869aa19c365952
[46]:http://www.brendangregg.com/blog/2014-05-11/strace-wow-much-syscall.html
[47]:http://www.brendangregg.com/blog/2015-02-28/from-dtrace-to-linux.html
[48]:http://www.slideshare.net/brendangregg/from-dtrace-to-linux/28
[49]:http://www.beginningwithi.com/

View File

@@ -0,0 +1,208 @@
gdb 如何工作?
============================================================
大家好!今天,我开始进行我的 [ruby 堆栈跟踪项目][1],我发觉我现在了解了一些关于 `gdb` 内部如何工作的内容。
最近,我使用 `gdb` 来查看我的 Ruby 程序,所以,我们将对一个 Ruby 程序运行 `gdb` 。它实际上就是一个 Ruby 解释器。首先,我们需要打印出一个全局变量的地址:`ruby_current_thread`
### 获取全局变量
下面展示了如何获取全局变量 `ruby_current_thread` 的地址:
```
$ sudo gdb -p 2983
(gdb) p & ruby_current_thread
$2 = (rb_thread_t **) 0x5598a9a8f7f0 <ruby_current_thread>
```
变量能够位于的地方有<ruby>堆<rt>heap</rt></ruby>、<ruby>栈<rt>stack</rt></ruby>或者程序的<ruby>文本段<rt>text</rt></ruby>。全局变量是程序的一部分。某种程度上,你可以把它们想象成是在编译的时候分配的。因此,我们可以很容易的找出全局变量的地址。让我们来看看,`gdb` 是如何找出 `0x5598a9a87f0` 这个地址的。
我们可以通过查看位于 `/proc` 目录下一个叫做 `/proc/$pid/maps` 的文件,来找到这个变量所位于的大致区域。
```
$ sudo cat /proc/2983/maps | grep bin/ruby
5598a9605000-5598a9886000 r-xp 00000000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby
5598a9a86000-5598a9a8b000 r--p 00281000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby
5598a9a8b000-5598a9a8d000 rw-p 00286000 00:32 323508 /home/bork/.rbenv/versions/2.1.6/bin/ruby
```
所以,我们看到,起始地址 `5598a9605000``0x5598a9a8f7f0` 很像,但并不一样。哪里不一样呢,我们把两个数相减,看看结果是多少:
```
(gdb) p/x 0x5598a9a8f7f0 - 0x5598a9605000
$4 = 0x48a7f0
```
你可能会问,这个数是什么?让我们使用 `nm` 来查看一下程序的符号表。
```
sudo nm /proc/2983/exe | grep ruby_current_thread
000000000048a7f0 b ruby_current_thread
```
我们看到了什么?能够看到 `0x48a7f0` 吗?是的,没错。所以,如果我们想找到程序中一个全局变量的地址,那么只需在符号表中查找变量的名字,然后再加上在 `/proc/whatever/maps` 中的起始地址,就得到了。
所以现在,我们知道 `gdb` 做了什么。但是,`gdb` 实际做的事情更多,让我们跳过直接转到…
### 解引用指针
```
(gdb) p ruby_current_thread
$1 = (rb_thread_t *) 0x5598ab3235b0
```
我们要做的下一件事就是解引用 `ruby_current_thread` 这一指针。我们想看一下它所指向的地址。为了完成这件事,`gdb` 会运行大量系统调用比如:
```
ptrace(PTRACE_PEEKTEXT, 2983, 0x5598a9a8f7f0, [0x5598ab3235b0]) = 0
```
你是否还记得 `0x5598a9a8f7f0` 这个地址?`gdb` 会问:“嘿,在这个地址中的实际内容是什么?”。`2983` 是我们运行 gdb 这个进程的 ID。gdb 使用 `ptrace` 这一系统调用来完成这一件事。
好极了!因此,我们可以解引用内存并找出内存地址中存储的内容。有一些有用的 `gdb` 命令,比如 `x/40w 变量``x/40b 变量` 分别会显示给定地址的 40 个字/字节。
### 描述结构
一个内存地址中的内容可能看起来像下面这样。可以看到很多字节!
```
(gdb) x/40b ruby_current_thread
0x5598ab3235b0: 16 -90 55 -85 -104 85 0 0
0x5598ab3235b8: 32 47 50 -85 -104 85 0 0
0x5598ab3235c0: 16 -64 -55 115 -97 127 0 0
0x5598ab3235c8: 0 0 2 0 0 0 0 0
0x5598ab3235d0: -96 -83 -39 115 -97 127 0 0
```
这很有用,但也不是非常有用!如果你是一个像我一样的人类并且想知道它代表什么,那么你需要更多内容,比如像这样:
```
(gdb) p *(ruby_current_thread)
$8 = {self = 94114195940880, vm = 0x5598ab322f20, stack = 0x7f9f73c9c010,
stack_size = 131072, cfp = 0x7f9f73d9ada0, safe_level = 0, raised_flag = 0,
last_status = 8, state = 0, waiting_fd = -1, passed_block = 0x0,
passed_bmethod_me = 0x0, passed_ci = 0x0, top_self = 94114195612680,
top_wrapper = 0, base_block = 0x0, root_lep = 0x0, root_svar = 8, thread_id =
140322820187904,
```
太好了。现在就更加有用了。`gdb` 是如何知道这些所有域的,比如 `stack_size` ?是从 `DWARF` 得知的。`DWARF` 是存储额外程序调试数据的一种方式,从而像 `gdb` 这样的调试器能够工作的更好。它通常存储为二进制的一部分。如果我对我的 Ruby 二进制文件运行 `dwarfdump` 命令,那么我将会得到下面的输出:
(我已经重新编排使得它更容易理解)
```
DW_AT_name "rb_thread_struct"
DW_AT_byte_size 0x000003e8
DW_TAG_member
DW_AT_name "self"
DW_AT_type <0x00000579>
DW_AT_data_member_location DW_OP_plus_uconst 0
DW_TAG_member
DW_AT_name "vm"
DW_AT_type <0x0000270c>
DW_AT_data_member_location DW_OP_plus_uconst 8
DW_TAG_member
DW_AT_name "stack"
DW_AT_type <0x000006b3>
DW_AT_data_member_location DW_OP_plus_uconst 16
DW_TAG_member
DW_AT_name "stack_size"
DW_AT_type <0x00000031>
DW_AT_data_member_location DW_OP_plus_uconst 24
DW_TAG_member
DW_AT_name "cfp"
DW_AT_type <0x00002712>
DW_AT_data_member_location DW_OP_plus_uconst 32
DW_TAG_member
DW_AT_name "safe_level"
DW_AT_type <0x00000066>
```
所以,`ruby_current_thread` 的类型名为 `rb_thread_struct`,它的大小为 `0x3e8` (即 1000 字节),它有许多成员项,`stack_size` 是其中之一,在偏移为 `24` 的地方,它有类型 `31``31` 是什么?不用担心,我们也可以在 DWARF 信息中查看。
```
< 1><0x00000031> DW_TAG_typedef
DW_AT_name "size_t"
DW_AT_type <0x0000003c>
< 1><0x0000003c> DW_TAG_base_type
DW_AT_byte_size 0x00000008
DW_AT_encoding DW_ATE_unsigned
DW_AT_name "long unsigned int"
```
所以,`stack_size` 具有类型 `size_t`,即 `long unsigned int`,它是 8 字节的。这意味着我们可以查看该栈的大小。
如果我们有了 DWARF 调试数据,该如何分解:
1. 查看 `ruby_current_thread` 所指向的内存区域
2. 加上 `24` 字节来得到 `stack_size`
3. 读 8 字节(以小端的格式,因为是在 x86 上)
4. 得到答案!
在上面这个例子中是 `131072`(即 128 kb
对我来说,这使得调试信息的用途更加明显。如果我们不知道这些所有变量所表示的额外的元数据,那么我们无法知道存储在 `0x5598ab325b0` 这一地址的字节是什么。
这就是为什么你可以为你的程序单独安装程序的调试信息,因为 `gdb` 并不关心从何处获取这些额外的调试信息。
### DWARF 令人迷惑
我最近阅读了大量的 DWARF 知识。现在,我使用 libdwarf使用体验不是很好这个 API 令人迷惑,你将以一种奇怪的方式初始化所有东西,它真的很慢(需要花费 0.3 秒的时间来读取我的 Ruby 程序的所有调试信息,这真是可笑)。有人告诉我,来自 elfutils 的 libdw 要好一些。
同样,再提及一点,你可以查看 `DW_AT_data_member_location` 来查看结构成员的偏移。我在 Stack Overflow 上查找如何完成这件事,并且得到[这个答案][2]。基本上,以下面这样一个检查开始:
```
dwarf_whatform(attrs[i], &form, &error);
if (form == DW_FORM_data1 || form == DW_FORM_data2
form == DW_FORM_data2 || form == DW_FORM_data4
form == DW_FORM_data8 || form == DW_FORM_udata) {
```
继续往前。为什么会有 800 万种不同的 `DW_FORM_data` 需要检查?发生了什么?我没有头绪。
不管怎么说我的印象是DWARF 是一个庞大而复杂的标准(可能是人们用来生成 DWARF 的库稍微不兼容),但是我们有的就是这些,所以我们只能用它来工作。
我能够编写代码并查看 DWARF ,这就很酷了,并且我的代码实际上大多数能够工作。除了程序崩溃的时候。我就是这样工作的。
### 展开栈路径
在这篇文章的早期版本中,我说过,`gdb` 使用 libunwind 来展开栈路径,这样说并不总是对的。
有一位对 `gdb` 有深入研究的人发了大量邮件告诉我,为了能够做得比 libunwind 更好,他们花费了大量时间来尝试如何展开栈路径。这意味着,如果你在程序的一个奇怪的中间位置停下来了,你所能够获取的调试信息又很少,那么你可以对栈做一些奇怪的事情,`gdb` 会尝试找出你位于何处。
### gdb 能做的其他事
我在这儿所描述的一些事请(查看内存,理解 DWARF 所展示的结构)并不是 `gdb` 能够做的全部事情。阅读 Brendan Gregg 的[昔日 gdb 例子][3],我们可以知道,`gdb` 也能够完成下面这些事情:
* 反汇编
* 查看寄存器内容
在操作程序方面,它可以:
* 设置断点,单步运行程序
* 修改内存(这是一个危险行为)
了解 `gdb` 如何工作使得当我使用它的时候更加自信。我过去经常感到迷惑,因为 `gdb` 有点像 C当你输入 `ruby_current_thread->cfp->iseq`,就好像是在写 C 代码。但是你并不是在写 C 代码。我很容易遇到 `gdb` 的限制,不知道为什么。
知道使用 DWARF 来找出结构内容给了我一个更好的心智模型和更加正确的期望!这真是极好的!
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/2016/08/10/how-does-gdb-work/
作者:[Julia Evans][a]
译者:[ucasFL](https://github.com/ucasFL)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://jvns.ca/
[1]:http://jvns.ca/blog/2016/06/12/a-weird-system-call-process-vm-readv/
[2]:https://stackoverflow.com/questions/25047329/how-to-get-struct-member-offset-from-dwarf-info
[3]:http://www.brendangregg.com/blog/2016-08-09/gdb-example-ncurses.html

View File

@@ -0,0 +1,109 @@
计算机系统进化论
======
纵观现代计算机的历史,从与系统的交互方式方面,可以划分为数个进化阶段。而我更倾向于将之归类为以下几个阶段:
1. 数字系统
2. 专用应用系统
3. 应用中心系统
4. 信息中心系统
5. 无应用系统
下面我们详细聊聊这几种分类。
### 数字系统
在我看来,[早期计算机][1],只被设计用来处理数字。它们能够加、减、乘、除。在它们中有一些能够运行像是微分和积分之类的更复杂的数学操作。
当然,如果你把字符映射成数字,它们也可以计算字符串。但这多少有点“数字的创造性使用”的意思,而不是直接处理各种信息。
### 专用应用系统
对于更高层级的问题,纯粹的数字系统是不够的。专用应用系统被开发用来处理单一任务。它们和数字系统十分相似,但是,它们拥有足够的复杂数字计算能力。这些系统能够完成十分明确的高层级任务,像调度问题的相关计算或者其他优化问题。
这类系统为单一目的而搭建,它们解决的是单一明确的问题。
### 应用中心系统
应用中心系统是第一个真正的通用系统。它们的主要使用风格很像专用应用系统,但是它们拥有以时间片模式(一个接一个)或以多任务模式(多应用同时)运行的多个应用程序。
上世纪 70 年代的 [早期的个人电脑][3]是第一种受人们欢迎的应用中心系统。
如今的现在操作系统 —— Windows 、macOS 、大多数 GNU/Linux 桌面环境 —— 一直遵循相同的法则。
当然,应用中心系统还可以再细分为两种子类:
1. 紧密型应用中心系统
2. 松散型应用中心系统
紧密型应用中心系统像是 [Windows 3.1][4] (拥有程序管理器和文件管理器)或者甚至 [Windows 95][5] 的最初版本都没有预定义的文件夹层次。用户启动文本处理程序(像 [ WinWord ][6])并且把文件保存在 WinWord 的程序文件夹中。在使用表格处理程序的时候,又把文件保存在表格处理工具的程序文件夹中。诸如此类。用户几乎不创建自己的文件层次结构,可能由于此举的不方便、用户单方面的懒惰,或者他们认为根本没有必要。那时,每个用户拥有几十个至多几百个文件。
为了访问文件中的信息,用户常常先打开一个应用程序,然后通过程序中的“文件/打开”功能来获取处理过的数据文件。
在 Windows 平台的 [Windows 95][5] SP2 中,“[我的文档][7]”首次被使用。有了这样一个文件层次结构的样板,应用设计者开始把 “[我的文档][7]” 作为程序的默认的保存 / 打开目录,抛弃了原来将软件产品安装目录作为默认目录的做法。这样一来,用户渐渐适应了这种模式,并且开始自己维护文件夹层次。
松散型应用中心系统(通过文件管理器来提取文件)应运而生。在这种系统下,当打开一个文件的时候,操作系统会自动启动与之相关的应用程序。这是一次小而精妙的用法转变。这种应用中心系统的用法模式一直是个人电脑的主要用法模式。
然而,这种模式有很多的缺点。例如,为了防止数据提取出现问题,需要维护一个包含给定项目的所有相关文件的严格文件夹层次结构。不幸的是,人们并不总能这样做。更进一步说,[这种模式不能很好的扩展][8]。 桌面搜索引擎和高级数据组织工具(像 [tagstore][9])可以起到一点改善作用。正如研究显示的那样,只有一少部分人正在使用那些高级文件提取工具。大多数的用户不使用替代提取工具或者辅助提取技术在文件系统中寻找文件。
### 信息中心系统
解决上述需要将所有文件都放到一个文件夹的问题的可行办法之一就是从应用中心系统转换到信息中心系统。
信息中心系统将项目的所有信息联合起来,放在一个地方,放在同一个应用程序里。因此,我们再也不需要计算项目预算时,打开表格处理程序;写工程报告时,打开文本处理程序;处理图片文件时,又打开另一个工具。
上个月的预算情况在客户会议笔记的右下方,客户会议笔记又在画板的右下方,而画板又在另一些要去完成的任务的右下方。在各个层之间没有文件或者应用程序来回切换的麻烦。
早期IBM [OS/2][10]、 Microsoft [OLE][11] 和 [NeXT][12] 都做过类似的尝试。但都由于种种原因没有取得重大成功。从 [Plan 9][14] 发展而来的 [ACme][13] 是一个非常有趣的信息中心环境。它在一个应用程序中包含了[多种应用程序][15]。但是即时是它移植到了 Windows 和 GNU/Linux也从来没有成为一个引起关注的软件。
信息中心系统的现代形式是高级 [个人维基][16](像 [TheBrain][17] 和 [Microsoft OneNote][18])。
我选择的个人工具是带 [Org 模式][19] 扩展的 [GNU/Emacs][20] 平台。在用电脑的时候,我几乎不能没有 Org 模式 。为了访问外部数据资源,我创建了一个可以将多种数据导入 Org 模式的插件 —— [Memacs][20] 。我喜欢将表格数据计算放到日程任务的右下方,然后是行内图片,内部和外部链接,等等。它是一个真正的用户不用必须操心程序或者严格的层次文件系统文件夹的信息中心系统。同时,用简单的或高级的标签也可以进行多分类。一个命令可以派生多种视图。比如,一个视图有日历,待办事项。另一个视图是租借事宜列表。等等。它对 Org 模式的用户没有限制。只有你想不到,没有它做不到。
进化结束了吗? 当然没有。
### 无应用系统
我能想到这样一类操作系统,我称之为无应用系统。在下一步的发展中,系统将不需要单一领域的应用程序,即使它们能和 Org 模式一样出色。计算机直接提供一个处理信息和使用功能的友好用户接口,而不通过文件和程序。甚至连传统的操作系统也不需要。
无应用系统也可能和 [人工智能][21] 联系起来。把它想象成 [2001 太空漫游][23] 中的 [HAL 9000][22] 和星际迷航中的 [LCARS][24] 一类的东西就可以了。
从基于应用的、基于供应商的软件文化到无应用系统的转化让人很难相信。 或许,缓慢但却不断发展的开源环境,可以使一个由各种各样组织和人们贡献的真正无应用环境成型。
信息和提取、操作信息的功能,这是系统应该具有的,同时也是我们所需要的。其他的东西仅仅是为了使我们不至于分散注意力。
--------------------------------------------------------------------------------
via: http://karl-voit.at/2017/02/10/evolution-of-systems/
作者:[Karl Voit][a]
译者:[lontow](https://github.com/lontow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://karl-voit.at
[1]:https://en.wikipedia.org/wiki/History_of_computing_hardware
[2]:https://en.wikipedia.org/wiki/String_%2528computer_science%2529
[3]:https://en.wikipedia.org/wiki/Xerox_Alto
[4]:https://en.wikipedia.org/wiki/Windows_3.1x
[5]:https://en.wikipedia.org/wiki/Windows_95
[6]:https://en.wikipedia.org/wiki/Microsoft_Word
[7]:https://en.wikipedia.org/wiki/My_Documents
[8]:http://karl-voit.at/tagstore/downloads/Voit2012b.pdf
[9]:http://karl-voit.at/tagstore/
[10]:https://en.wikipedia.org/wiki/OS/2
[11]:https://en.wikipedia.org/wiki/Object_Linking_and_Embedding
[12]:https://en.wikipedia.org/wiki/NeXT
[13]:https://en.wikipedia.org/wiki/Acme_%2528text_editor%2529
[14]:https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs
[15]:https://en.wikipedia.org/wiki/List_of_Plan_9_applications
[16]:https://en.wikipedia.org/wiki/Personal_wiki
[17]:https://en.wikipedia.org/wiki/TheBrain
[18]:https://en.wikipedia.org/wiki/Microsoft_OneNote
[19]:../../../../tags/emacs
[20]:https://github.com/novoid/Memacs
[21]:https://en.wikipedia.org/wiki/Artificial_intelligence
[22]:https://en.wikipedia.org/wiki/HAL_9000
[23]:https://en.wikipedia.org/wiki/2001:_A_Space_Odyssey
[24]:https://en.wikipedia.org/wiki/LCARS

View File

@@ -0,0 +1,210 @@
9 个提高系统运行速度的轻量级 Linux 应用
======
**简介:** [加速 Ubuntu 系统][1]有很多方法,办法之一是使用轻量级应用来替代一些常用应用程序。我们之前之前发布过一篇 [Linux 必备的应用程序][2],如今将分享这些应用程序在 Ubuntu 或其他 Linux 发行版的轻量级替代方案。
![在 ubunt 使用轻量级应用程序替代方案][4]
### 9 个常用 Linux 应用程序的轻量级替代方案
你的 Linux 系统很慢吗?应用程序是不是很久才能打开?你最好的选择是使用[轻量级的 Linux 系统][5]。但是重装系统并非总是可行,不是吗?
所以如果你想坚持使用你现在用的 Linux 发行版,但是想要提高性能,你应该使用更轻量级应用来替代你一些常用的应用。这篇文章会列出各种 Linux 应用程序的轻量级替代方案。
由于我使用的是 Ubuntu因此我只提供了基于 Ubuntu 的 Linux 发行版的安装说明。但是这些应用程序可以用于几乎所有其他 Linux 发行版。你只需去找这些轻量级应用在你的 Linux 发行版中的安装方法就可以了。
### 1. Midori Web 浏览器
[Midori][8] 是与现代互联网环境具有良好兼容性的最轻量级网页浏览器之一。它是开源的,使用与 Google Chrome 最初所基于的相同的渲染引擎 —— WebKit。并且超快速最小化但高度可定制。
![Midori Browser][6]
Midori 浏览器有很多可以定制的扩展和选项。如果你有最高权限,使用这个浏览器也是一个不错的选择。如果在浏览网页的时候遇到了某些问题,请查看其网站上[常见问题][7]部分 -- 这包含了你可能遇到的常见问题及其解决方案。
#### 在基于 Ubuntu 的发行版上安装 Midori
在 Ubuntu 上,可通过官方源找到 Midori 。运行以下指令即可安装它:
```
sudo apt install midori
```
### 2. Trojita电子邮件客户端
[Trojita][11] 是一款开源强大的 IMAP 电子邮件客户端。它速度快,资源利用率高。我可以肯定地称它是 [Linux 最好的电子邮件客户端之一][9]。如果你只需电子邮件客户端提供 IMAP 支持,那么也许你不用再进一步考虑了。
![Trojitá][10]
Trojita 使用各种技术 —— 按需电子邮件加载、离线缓存、带宽节省模式等 —— 以实现其令人印象深刻的性能。
#### 在基于 Ubuntu 的发行版上安装 Trojita
Trojita 目前没有针对 Ubuntu 的官方 PPA 。但这应该不成问题。您可以使用以下命令轻松安装它:
```
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/home:/jkt-gentoo:/trojita/xUbuntu_16.04/ /' > /etc/apt/sources.list.d/trojita.list"
wget http://download.opensuse.org/repositories/home:jkt-gentoo:trojita/xUbuntu_16.04/Release.key
sudo apt-key add - < Release.key
sudo apt update
sudo apt install trojita
```
### 3. GDebi包安装程序
有时您需要快速安装 DEB 软件包。Ubuntu 软件中心是一个消耗资源严重的应用程序,仅用于安装 .deb 文件并不明智。
Gdebi 无疑是一款可以完成同样目的的漂亮工具,而它只有个极简的图形界面。
![GDebi][12]
GDebi 是完全轻量级的,完美无缺地完成了它的工作。你甚至应该[让 Gdebi 成为 DEB 文件的默认安装程序][13]。
#### 在基于 Ubuntu 的发行版上安装 GDebi
只需一行指令,你便可以在 Ubuntu 上安装 GDebi
```
sudo apt install gdebi
```
### 4. App Grid软件中心
如果您经常在 Ubuntu 上使用软件中心搜索、安装和管理应用程序,则 [App Grid][15] 是必备的应用程序。它是默认的 Ubuntu 软件中心最具视觉吸引力且速度最快的替代方案。
![App Grid][14]
App Grid 支持应用程序的评分、评论和屏幕截图。
#### 在基于 Ubuntu 的发行版上安装 App Grid
App Grid 拥有 Ubuntu 的官方 PPA。使用以下指令安装 App Grid
```
sudo add-apt-repository ppa:appgrid/stable
sudo apt update
sudo apt install appgrid
```
### 5. Yarock音乐播放器
[Yarock][17] 是一个优雅的音乐播放器,拥有现代而最轻量级的用户界面。尽管在设计上是轻量级的,但 Yarock 有一个全面的高级功能列表。
![Yarock][16]
Yarock 的主要功能包括多种音乐收藏、评级、智能播放列表、多种后端选项、桌面通知、音乐剪辑、上下文获取等。
### 在基于 Ubuntu 的发行版上安装 Yarock
您得通过 PPA 使用以下指令在 Ubuntu 上安装 Yarock
```
sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt update
sudo apt install yarock
```
### 6. VLC视频播放器
谁不需要视频播放器?谁还从未听说过 [VLC][19]?我想并不需要对它做任何介绍。
![VLC][18]
VLC 能满足你在 Ubuntu 上播放各种媒体文件的全部需求,而且它非常轻便。它甚至可以在非常旧的 PC 上完美运行。
#### 在基于 Ubuntu 的发行版上安装 VLC
VLC 为 Ubuntu 提供官方 PPA。可以输入以下命令来安装它
```
sudo apt install vlc
```
### 7. PCManFM文件管理器
PCManFM 是 LXDE 的标准文件管理器。与 LXDE 的其他应用程序一样,它也是轻量级的。如果您正在为文件管理器寻找更轻量级的替代品,可以尝试使用这个应用。
![PCManFM][20]
尽管来自 LXDEPCManFM 也同样适用于其他桌面环境。
#### 在基于 Ubuntu 的发行版上安装 PCManFM
在 Ubuntu 上安装 PCManFM 只需要一条简单的指令:
```
sudo apt install pcmanfm
```
### 8. Mousepad文本编辑器
在轻量级方面,没有什么可以击败像 nano、vim 等命令行文本编辑器。但是,如果你想要一个图形界面,你可以尝试一下 Mousepad -- 一个最轻量级的文本编辑器。它非常轻巧,速度非常快。带有简单的可定制的用户界面和多个主题。
![Mousepad][21]
Mousepad 支持语法高亮显示。所以,你也可以使用它作为基础的代码编辑器。
#### 在基于 Ubuntu 的发行版上安装 Mousepad
想要安装 Mousepad ,可以使用以下指令:
```
sudo apt install mousepad
```
### 9. GNOME Office办公软件
许多人需要经常使用办公应用程序。通常大多数办公应用程序体积庞大且很耗资源。Gnome Office 在这方面非常轻便。Gnome Office 在技术上不是一个完整的办公套件。它由不同的独立应用程序组成,在这之中 AbiWordGnumeric 脱颖而出。
**AbiWord** 是文字处理器。它比其他替代品轻巧并且快得多。但是这样做是有代价的 —— 你可能会失去宏、语法检查等一些功能。AdiWord 并不完美,但它可以满足你基本的需求。
![AbiWord][22]
**Gnumeric** 是电子表格编辑器。就像 AbiWord 一样Gnumeric 也非常快速提供了精确的计算功能。如果你正在寻找一个简单轻便的电子表格编辑器Gnumeric 已经能满足你的需求了。
![Gnumeric][23]
在 [Gnome Office][24] 下面还有一些其它应用程序。你可以在官方页面找到它们。
#### 在基于 Ubuntu 的发行版上安装 AbiWordGnumeric
要安装 AbiWordGnumeric只需在终端中输入以下指令
```
sudo apt install abiword gnumeric
```
--------------------------------------------------------------------------------
via: https://itsfoss.com/lightweight-alternative-applications-ubuntu/
作者:[Munif Tanjim][a]
译者:[imquanquan](https://github.com/imquanquan)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://itsfoss.com/author/munif/
[1]:https://itsfoss.com/speed-up-ubuntu-1310/
[2]:https://itsfoss.com/essential-linux-applications/
[4]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/Lightweight-alternative-applications-for-Linux-800x450.jpg
[5]:https://itsfoss.com/lightweight-linux-beginners/
[6]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/Midori-800x497.png
[7]:http://midori-browser.org/faqs/
[8]:http://midori-browser.org/
[9]:https://itsfoss.com/best-email-clients-linux/
[10]:http://trojita.flaska.net/img/2016-03-22-trojita-home.png
[11]:http://trojita.flaska.net/
[12]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/GDebi.png
[13]:https://itsfoss.com/gdebi-default-ubuntu-software-center/
[14]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/AppGrid-800x553.png
[15]:http://www.appgrid.org/
[16]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/Yarock-800x529.png
[17]:https://seb-apps.github.io/yarock/
[18]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/VLC-800x526.png
[19]:http://www.videolan.org/index.html
[20]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/PCManFM.png
[21]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/Mousepad.png
[22]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/AbiWord-800x626.png
[23]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/03/Gnumeric-800x470.png
[24]:https://gnome.org/gnome-office/

View File

@@ -0,0 +1,164 @@
如何提供有帮助的回答
=============================
如果你的同事问你一个不太清晰的问题,你会怎么回答?我认为提问题是一种技巧(可以看 [如何提出有意义的问题][1]) 同时,合理地回答问题也是一种技巧,它们都是非常实用的。
一开始 —— 有时向你提问的人不尊重你的时间,这很糟糕。理想情况下,我们假设问你问题的人是一个理性的人并且正在尽力解决问题,而你想帮助他们。和我一起工作的人是这样,我所生活的世界也是这样。当然,现实生活并不是这样。
下面是有助于回答问题的一些方法!
### 如果他们的提问不清楚,帮他们澄清
通常初学者不会提出很清晰的问题,或者问一些对回答问题没有必要信息的问题。你可以尝试以下方法 澄清问题:
* **重述为一个更明确的问题**来回复他们(“你是想问 X 吗?”)
* **向他们了解更具体的他们并没有提供的信息** (“你使用 IPv6 ?”)
* **问是什么导致了他们的问题**。例如,有时有些人会进入我的团队频道,询问我们的<ruby>服务发现<rt>service discovery</rt></ruby>如何工作的。这通常是因为他们试图设置/重新配置服务。在这种情况下,如果问“你正在使用哪种服务?可以给我看看你正在处理的‘拉取请求’吗?”是有帮助的。
这些方法很多来自[如何提出有意义的问题][2]中的要点。(尽管我永远不会对某人说“噢,你得先看完《如何提出有意义的问题》这篇文章后再来向我提问)
### 弄清楚他们已经知道了什么
在回答问题之前,知道对方已经知道什么是非常有用的!
Harold Treen 给了我一个很好的例子:
> 前几天,有人请我解释 “Redux-Sagas”。与其深入解释不如说 “它们就像监听 action 的工人线程,并可以让你更新 Redux store。
> 我开始搞清楚他们对 Redux、action、store 以及其他基本概念了解多少。将这些概念都联系在一起再来解释会容易得多。
弄清楚问你问题的人已经知道什么是非常重要的。因为有时他们可能会对基础概念感到疑惑“Redux 是什么?”),或者他们可能是专家,但是恰巧遇到了微妙的<ruby>极端情况<rt>corner case</rt></ruby>。如果答案建立在他们不知道的概念上会令他们困惑,但如果重述他们已经知道的的又会是乏味的。
这里有一个很实用的技巧来了解他们已经知道什么 - 比如可以尝试用“你对 X 了解多少?”而不是问“你知道 X 吗?”。
### 给他们一个文档
“RTFM” <ruby>“去读那些他妈的手册”<rt>Read The Fucking Manual</rt></ruby>)是一个典型的无用的回答,但事实上如果向他们指明一个特定的文档会是非常有用的!当我提问题的时候,我当然很乐意翻看那些能实际解决我的问题的文档,因为它也可能解决其他我想问的问题。
我认为明确你所给的文档的确能够解决问题是非常重要的,或者至少经过查阅后确认它对解决问题有帮助。否则,你可能将以下面这种情形结束对话(非常常见):
* Ali我应该如何处理 X
* Jada\<文档链接>
* Ali: 这个没有实际解释如何处理 X ,它仅仅解释了如何处理 Y !
如果我所给的文档特别长,我会指明文档中那个我将会谈及的特定部分。[bash 手册][3] 有 44000 个字(真的!),所以如果只说“它在 bash 手册中有说明”是没有帮助的 :)
### 告诉他们一个有用的搜索
在工作中,我经常发现我可以利用我所知道的关键字进行搜索来找到能够解决我的问题的答案。对于初学者来说,这些关键字往往不是那么明显。所以说“这是我用来寻找这个答案的搜索”可能有用些。再次说明,回答时请经检查后以确保搜索能够得到他们所需要的答案 :)
### 写新文档
人们经常一次又一次地问我的团队同样的问题。很显然这并不是他们的错(他们怎么能够知道在他们之前已经有 10 个人问了这个问题,且知道答案是什么呢?)因此,我们会尝试写新文档,而不是直接回答回答问题。
1. 马上写新文档
2. 给他们我们刚刚写好的新文档
3. 公示
写文档有时往往比回答问题需要花很多时间,但这是值得的。写文档尤其重要,如果:
a. 这个问题被问了一遍又一遍
b. 随着时间的推移,这个答案不会变化太大(如果这个答案每一个星期或者一个月就会变化,文档就会过时并且令人受挫)
### 解释你做了什么
对于一个话题,作为初学者来说,这样的交流会真让人沮丧:
* 新人:“嗨!你如何处理 X ?”
* 有经验的人:“我已经处理过了,而且它已经完美解决了”
* 新人:”...... 但是你做了什么?!“
如果问你问题的人想知道事情是如何进行的,这样是有帮助的:
* 让他们去完成任务而不是自己做
* 告诉他们你是如何得到你给他们的答案的。
这可能比你自己做的时间还要长,但对于被问的人来说这是一个学习机会,因为那样做使得他们将来能够更好地解决问题。
这样,你可以进行更好的交流,像这:
* 新人:“这个网站出现了错误,发生了什么?”
* 有经验的人2分钟后“oh 这是因为发生了数据库故障转移”
* 新人: “你是怎么知道的??!?!?”
* 有经验的人:“以下是我所做的!”:
1. 通常这些错误是因为服务器 Y 被关闭了。我查看了一下 `$PLACE` 但它表明服务器 Y 开着。所以,并不是这个原因导致的。
2. 然后我查看 X 的仪表盘 ,仪表盘的这个部分显示这里发生了数据库故障转移。
3. 然后我在日志中找到了相应服务器,并且它显示连接数据库错误,看起来错误就是这里。
如果你正在解释你是如何调试一个问题,解释你是如何发现问题,以及如何找出问题的。尽管看起来你好像已经得到正确答案,但感觉更好的是能够帮助他们提高学习和诊断能力,并了解可用的资源。
### 解决根本问题
这一点有点棘手。有时候人们认为他们依旧找到了解决问题的正确途径,且他们只要再多一点信息就可以解决问题。但他们可能并不是走在正确的道路上!比如:
* George“我在处理 X 的时候遇到了错误,我该如何修复它?”
* Jasminda“你是正在尝试解决 Y 吗?如果是这样,你不应该处理 X ,反而你应该处理 Z 。”
* George“噢你是对的谢谢你我回反过来处理 Z 的。”
Jasminda 一点都没有回答 George 的问题!反而,她猜测 George 并不想处理 X ,并且她是猜对了。这是非常有用的!
如果你这样做可能会产生高高在上的感觉:
* George“我在处理 X 的时候遇到了错误,我该如何修复它?”
* Jasminda“不要这样做如果你想处理 Y ,你应该反过来完成 Z 。”
* George“好吧我并不是想处理 Y 。实际上我想处理 X 因为某些原因REASONS。所以我该如何处理 X 。”
所以不要高高在上,且要记住有时有些提问者可能已经偏离根本问题很远了。同时回答提问者提出的问题以及他们本该提出的问题都是合理的:“嗯,如果你想处理 X ,那么你可能需要这么做,但如果你想用这个解决 Y 问题,可能通过处理其他事情你可以更好地解决这个问题,这就是为什么可以做得更好的原因。”
### 询问“那个回答可以解决您的问题吗?”
我总是喜欢在我回答了问题之后核实是否真的已经解决了问题:“这个回答解决了您的问题吗?您还有其他问题吗?”在问完这个之后最好等待一会,因为人们通常需要一两分钟来知道他们是否已经找到了答案。
我发现尤其是问“这个回答解决了您的问题吗”这个额外的步骤在写完文档后是非常有用的。通常,在写关于我熟悉的东西的文档时,我会忽略掉重要的东西而不会意识到它。
### 结对编程和面对面交谈
我是远程工作的,所以我的很多对话都是基于文本的。我认为这是沟通的默认方式。
今天,我们生活在一个方便进行小视频会议和屏幕共享的世界!在工作时候,在任何时间我都可以点击一个按钮并快速加入与他人的视频对话或者屏幕共享的对话中!
例如,最近有人问如何自动调节他们的服务容量规划。我告诉他们我们有几样东西需要清理,但我还不太确定他们要清理的是什么。然后我们进行了一个简短的视频会话并在 5 分钟后,我们解决了他们问题。
我认为,特别是如果有人真的被困在该如何开始一项任务时,开启视频进行结对编程几分钟真的比电子邮件或者一些即时通信更有效。
### 不要表现得过于惊讶
这是源自 Recurse Center 的一则法则:[不要故作惊讶][4]。这里有一个常见的情景:
* 某甲:“什么是 Linux 内核”
* 某乙:“你竟然不知道什么是 Linux 内核?!!!!?!!!????”
某乙的表现(无论他们是否真的如此惊讶)是没有帮助的。这大部分只会让某甲不好受,因为他们确实不知道什么是 Linux 内核。
我一直在假装不惊讶,即使我事实上确实有点惊讶那个人不知道这种东西。
### 回答问题真的很棒
显然并不是所有方法都是合适的,但希望你能够发现这里有些是有帮助的!我发现花时间去回答问题并教导人们是其实是很有收获的。
特别感谢 Josh Triplett 的一些建议并做了很多有益的补充,以及感谢 Harold Treen、Vaibhav Sagar、Peter Bhat Hatkins、Wesley Aptekar Cassels 和 Paul Gowder 的阅读或评论。
--------------------------------------------------------------------------------
via: https://jvns.ca/blog/answer-questions-well/
作者:[Julia Evans][a]
译者:[HardworkFish](https://github.com/HardworkFish)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://jvns.ca/about
[1]:https://jvns.ca/blog/good-questions/
[2]:https://jvns.ca/blog/good-questions/
[3]:https://linux.die.net/man/1/bash
[4]:https://jvns.ca/blog/2017/04/27/no-feigning-surprise/

View File

@@ -0,0 +1,142 @@
4 种绕过 Linux/Unix 命令别名的方法
======
我在我的 Linux 系统上定义了如下 mount 别名:
```
alias mount='mount | column -t'
```
但是我需要在挂载文件系统和其他用途时绕过这个 bash 别名。我如何在 Linux、*BSD、macOS 或者类 Unix 系统上临时禁用或者绕过 bash shell 呢?
你可以使用 `alias` 命令定义或显示 bash shell 别名。一旦创建了 bash shell 别名,它们将优先于外部或内部命令。本文将展示如何暂时绕过 bash 别名,以便你可以运行实际的内部或外部命令。
[![Bash Bypass Alias Linux BSD macOS Unix Command][1]][1]
### 4 种绕过 bash 别名的方法
尝试以下任意一种方法来运行被 bash shell 别名绕过的命令。让我们[如下定义一个别名][2]
```
alias mount='mount | column -t'
```
运行如下:
```
mount
```
示例输出:
```
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
udev on /dev type devtmpfs (rw,nosuid,relatime,size=8023572k,nr_inodes=2005893,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=1610240k,mode=755)
/dev/mapper/ubuntu--vg-root on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)
/dev/sda1 on /boot type ext4 (rw,relatime,data=ordered)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
lxcfs on /var/lib/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)
```
#### 方法 1 - 使用 `\command`
输入以下命令暂时绕过名为 `mount` 的 bash 别名:
```
\mount
```
#### 方法 2 - 使用 `"command"` 或 `'command'`
如下引用 `mount` 命令调用实际的 `/bin/mount`
```
"mount"
```
或者
```
'mount'
```
#### 方法 3 - 使用命令的完全路径
使用完整的二进制路径,如 `/bin/mount`
```
/bin/mount
/bin/mount /dev/sda1 /mnt/sda
```
#### 方法 4 - 使用内部命令 `command`
语法是:
```
command cmd
command cmd arg1 arg2
```
要覆盖 `.bash_aliases` 中设置的别名,例如 `mount`
```
command mount
command mount /dev/sdc /mnt/pendrive/
```
[“command” 直接运行命令或显示][3]关于命令的信息。它带参数运行命令会抑制 shell 函数查询或者别名,或者显示有关给定命令的信息。
### 关于 unalias 命令的说明
要从当前会话的已定义别名列表中移除别名,请使用 `unalias` 命令:
```
unalias mount
```
要从当前 bash 会话中删除所有别名定义:
```
unalias -a
```
确保你更新你的 `~/.bashrc``$HOME/.bash_aliases`。如果要永久删除定义的别名,则必须删除定义的别名:
```
vi ~/.bashrc
```
或者
```
joe $HOME/.bash_aliases
```
想了解更多信息,参考[这里][4]的在线手册,或者输入下面的命令查看:
```
man bash
help command
help unalias
help alias
```
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/bash-bypass-alias-command-on-linux-macos-unix/
作者:[Vivek Gite][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/media/new/faq/2017/10/Bash-Bypass-Alias-Linux-BSD-macOS-Unix-Command.jpg
[2]:https://bash.cyberciti.biz/guide/Create_and_use_aliases
[3]:https://bash.cyberciti.biz/guide/Command
[4]:https://www.gnu.org/software/bash/manual/bash.html

View File

@@ -0,0 +1,62 @@
使用一个命令重置 Linux 桌面为默认设置
======
![](https://www.ostechnix.com/wp-content/uploads/2017/10/Reset-Linux-Desktop-To-Default-Settings-720x340.jpg)
前段时间,我们分享了一篇关于 [Resetter][1] 的文章 - 这是一个有用的软件,可以在几分钟内将 Ubuntu 重置为出厂默认设置。使用 Resetter任何人都可以轻松地将 Ubuntu 重置为第一次安装时的状态。今天,我偶然发现了一个类似的东西。不,它不是一个应用程序,而是一个单行的命令来重置你的 Linux 桌面设置、调整和定制到默认状态。
### 将 Linux 桌面重置为默认设置
这个命令会将 Ubuntu Unity、Gnome 和 MATE 桌面重置为默认状态。我在我的 Arch Linux MATE 和 Ubuntu 16.04 Unity 上测试了这个命令。它可以在两个系统上工作。我希望它也能在其他桌面上运行。在写这篇文章的时候,我还没有安装 GNOME 的 Linux 桌面,因此我无法确认。但是,我相信它也可以在 Gnome 桌面环境中使用。
**一句忠告:**请注意,此命令将重置你在系统中所做的所有定制和调整,包括 Unity 启动器或 Dock 中固定的应用程序、桌面小程序、桌面指示器、系统字体、GTK主题、图标主题、显示器分辨率、键盘快捷键、窗口按钮位置、菜单和启动器行为等。
好的是它只会重置桌面设置。它不会影响其他不使用 `dconf` 的程序。此外,它不会删除你的个人资料。
现在,让我们开始。要将 Ubuntu Unity 或其他带有 GNOME/MATE 环境的 Linux 桌面重置,运行下面的命令:
```
dconf reset -f /
```
在运行上述命令之前,这是我的 Ubuntu 16.04 LTS 桌面:
[![][2]][3]
如你所见,我已经改变了桌面壁纸和主题。
这是运行该命令后,我的 Ubuntu 16.04 LTS 桌面的样子:
[![][2]][4]
看见了么?现在,我的 Ubuntu 桌面已经回到了出厂设置。
有关 `dconf` 命令的更多详细信息,请参阅手册页。
```
man dconf
```
在重置桌面上我个人更喜欢 “Resetter” 而不是 `dconf` 命令。因为Resetter 给用户提供了更多的选择。用户可以决定删除哪些应用程序、保留哪些应用程序、是保留现有用户帐户还是创建新用户等等。如果你懒得安装 Resetter你可以使用这个 `dconf` 命令在几分钟内将你的 Linux 系统重置为默认设置。
就是这样了。希望这个有帮助。我将很快发布另一篇有用的指导。敬请关注!
干杯!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/reset-linux-desktop-default-settings-single-command/
作者:[Edwin Arteaga][a]
译者:[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
[1]:https://linux.cn/article-9217-1.html
[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[3]:http://www.ostechnix.com/wp-content/uploads/2017/10/Before-resetting-Ubuntu-to-default-1.png
[4]:http://www.ostechnix.com/wp-content/uploads/2017/10/After-resetting-Ubuntu-to-default-1.png

View File

@@ -0,0 +1,137 @@
如何使用 GNU Stow 来管理从源代码安装的程序和点文件
=====
### 目的
使用 GNU Stow 轻松管理从源代码安装的程序和点文件LCTT 译注:<ruby>点文件<rt>dotfile</rt></ruby>,即以 `.` 开头的文件,在 *nix 下默认为隐藏文件,常用于存储程序的配置信息。)
### 要求
* root 权限
### 难度
简单
### 约定
* `#` - 给定的命令要求直接以 root 用户身份或使用 `sudo` 命令以 root 权限执行
* `$` - 给定的命令将作为普通的非特权用户来执行
### 介绍
有时候我们必须从源代码安装程序,因为它们也许不能通过标准渠道获得,或者我们可能需要特定版本的软件。 GNU Stow 是一个非常不错的<ruby>符号链接工厂<rt>symlinks factory</rt></ruby>程序,它可以帮助我们保持文件的整洁,易于维护。
### 获得 stow
你的 Linux 发行版本很可能包含 `stow`,例如在 Fedora你安装它只需要
```
# dnf install stow
```
在 Ubuntu/Debian 中,安装 `stow` 需要执行:
```
# apt install stow
```
在某些 Linux 发行版中,`stow` 在标准库中是不可用的,但是可以通过一些额外的软件源(例如 RHEL 和 CentOS7 中的EPEL )轻松获得,或者,作为最后的手段,你可以从源代码编译它。只需要很少的依赖关系。
### 从源代码编译
最新的可用 stow 版本是 `2.2.2`。源码包可以在这里下载:`https://ftp.gnu.org/gnu/stow/`
一旦你下载了源码包,你就必须解压它。切换到你下载软件包的目录,然后运行:
```
$ tar -xvpzf stow-2.2.2.tar.gz
```
解压源文件后,切换到 `stow-2.2.2` 目录中,然后编译该程序,只需运行:
```
$ ./configure
$ make
```
最后,安装软件包:
```
# make install
```
默认情况下,软件包将安装在 `/usr/local/` 目录中,但是我们可以改变它,通过配置脚本的 `--prefix` 选项指定目录,或者在运行 `make install` 时添加 `prefix="/your/dir"`
此时,如果所有工作都按预期工作,我们应该已经在系统上安装了 `stow`
### stow 是如何工作的?
`stow` 背后主要的概念在程序手册中有很好的解释:
> Stow 使用的方法是将每个软件包安装到自己的目录树中,然后使用符号链接使它看起来像文件一样安装在公共的目录树中
为了更好地理解这个软件的运作,我们来分析一下它的关键概念:
#### stow 文件目录
stow 目录是包含所有 stow 软件包的根目录,每个包都有自己的子目录。典型的 stow 目录是 `/usr/local/stow`:在其中,每个子目录代表一个软件包。
#### stow 软件包
如上所述stow 目录包含多个“软件包”,每个软件包都位于自己单独的子目录中,通常以程序本身命名。包就是与特定软件相关的文件和目录列表,作为一个实体进行管理。
#### stow 目标目录
stow 目标目录解释起来是一个非常简单的概念。它是包文件应该安装到的目录。默认情况下stow 目标目录被视作是调用 stow 的目录。这种行为可以通过使用 `-t` 选项( `--target` 的简写)轻松改变,这使我们可以指定一个替代目录。
### 一个实际的例子
我相信一个好的例子胜过 1000 句话,所以让我来展示 `stow` 如何工作。假设我们想编译并安装 `libx264`,首先我们克隆包含其源代码的仓库:
```
$ git clone git://git.videolan.org/x264.git
```
运行该命令几秒钟后,将创建 `x264` 目录,它将包含准备编译的源代码。我们切换到 `x264` 目录中并运行 `configure` 脚本,将 `--prefix` 指定为 `/usr/local/stow/libx264` 目录。
```
$ cd x264 && ./configure --prefix=/usr/local/stow/libx264
```
然后我们构建该程序并安装它:
```
$ make
# make install
```
`x264` 目录应该创建在 `stow` 目录内:它包含了所有通常直接安装在系统中的东西。 现在,我们所要做的就是调用 `stow`。 我们必须从 `stow` 目录内运行这个命令,通过使用 `-d` 选项来手动指定 `stow` 目录的路径(默认为当前目录),或者通过如前所述用 `-t` 指定目标。我们还应该提供要作为参数存储的软件包的名称。 在这里,我们从 `stow` 目录运行程序,所以我们需要输入的内容是:
```
# stow libx264
```
libx264 软件包中包含的所有文件和目录现在已经在调用 stow 的父目录 (/usr/local) 中进行了符号链接,因此,例如在 `/usr/local/ stow/x264/bin` 中包含的 libx264 二进制文件现在符号链接在 `/usr/local/bin` 之中,`/usr/local/stow/x264/etc` 中的文件现在符号链接在 `/usr/local/etc` 之中等等。通过这种方式,系统将显示文件已正常安装,并且我们可以容易地跟踪我们编译和安装的每个程序。要反转该操作,我们只需使用 `-D` 选项:
```
# stow -d libx264
```
完成了!符号链接不再存在:我们只是“卸载”了一个 stow 包,使我们的系统保持在一个干净且一致的状态。 在这一点上,我们应该清楚为什么 stow 还可以用于管理点文件。 通常的做法是在 git 仓库中包含用户特定的所有配置文件,以便轻松管理它们并使它们在任何地方都可用,然后使用 stow 将它们放在适当位置,如放在用户主目录中。
stow 还会阻止你错误地覆盖文件:如果目标文件已经存在,并且没有指向 stow 目录中的包时,它将拒绝创建符号链接。 这种情况在 stow 术语中称为冲突。
就是这样!有关选项的完整列表,请参阅 stow 帮助页,并且不要忘记在评论中告诉我们你对此的看法。
--------------------------------------------------------------------------------
via: https://linuxconfig.org/how-to-use-gnu-stow-to-manage-programs-installed-from-source-and-dotfiles
作者:[Egidio Docile][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://linuxconfig.org

View File

@@ -0,0 +1,101 @@
你没听过的 10 个免费的 Linux 生产力应用程序
=====
![](https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-00-Featured.jpg)
高效率的应用程序确实可以让你工作变得更轻松。如果你是一位 Linux 用户,这 10 个不太知名的 Linux 桌面应用程序可以帮助到你。事实上Linux 用户可能已经听说过这个列表上的所有应用,但对于那些只用过主流应用的人来说,应该是不知道这些应用的。
### 1. Tomboy/Gnote
![linux-productivity-apps-01-tomboy][1]
[Tomboy][2] 是一个简单的便签应用。它不仅仅适用于 Linux你也可以在 Unix、Windows 和 macOS 上获得它。Tomboy 很容易使用——你写一个便条,选择是否让它粘贴在你的桌面上,当你完成它时删除它。
### 2. MyNotex
![linux-productivity-apps-02-mynotex][3]
如果你想要一个更多功能的便签,但是仍喜欢一个小而简单的应用程序,而不是一个巨大的套件,请看看 [MyNotex][4]。除了简单的笔记和检索之外,它还带有一些不错的功能,例如格式化、键盘快捷键和附件等等。你也可以将其用作图片管理器。
### 3. Trojitá
![linux-productivity-apps-03-trojita][5]
尽管你可以没有桌面电子邮件客户端,但如果你想要一个的话,在几十个的桌面电子邮件客户端里,请尝试下 [Trojita][6]。这有利于生产力,因为它是一个快速而轻量级的电子邮件客户端,但它提供了一个好的电子邮件客户端所必须具备的所有功能(以及更多)。
### 4. Kontact
![linux-productivity-apps-04-kontact][7]
个人信息管理器PIM是一款出色的生产力工具。我的个人喜好是 [Kontact][8]。尽管它已经有几年没有更新,但它仍然是一个非常有用的 PIM 工具用于管理电子邮件、地址簿、日历、任务、新闻源等。Kontact 是一个 KDE 原生程序,但你也可以在其他桌面上使用它。
### 5. Osmo
![linux-productivity-apps-05-osmo][9]
[Osmo][10] 是一款更先进的应用,包括日历、任务、联系人和便签功能。它还附带一些额外的功能,比如加密私有数据备份和地图上的地理位置,以及对便签、任务、联系人等的强大搜索功能。
### 6. Catfish
![linux-productivity-apps-06-catfish][11]
没有好的搜索工具就没有高生产力。[Catfish][12] 是一个必须尝试的搜索工具。它是一个 GTK+ 工具非常快速轻量级。Catfish 会利用 Zeitgeist 的自动完成功能,你还可以按日期和类型过滤搜索结果。
### 7. KOrganizer
![linux-productivity-apps-07-korganizer][13]
[KOrganizer][14] 是我上面提到的 Kontact 应用程序的日历和计划组件。如果你不需要完整的 PIM 应用程序,只需要日历和日程安排,则可以使用 KOrganizer。KOrganizer 提供快速的待办事项和快速事件条目,以及事件和待办事项的附件。
### 8. Evolution
![linux-productivity-apps-08-evolution][15]
如果你不是 KDE 应用程序的粉丝,但你仍然需要一个好的 PIM那么试试 GNOME 的 [Evolution][16]。Evolution 并不是一个你从没听过的少见的应用程序,但因为它有用,所以它出现在这个列表中。也许你已经听说过 Evolution 是一个电子邮件客户端,但它远不止于此——你可以用它来管理日历、邮件、地址簿和任务。
### 9. Freeplane
![linux-productivity-apps-09-freeplane][17]
我不知道你们中的大多数是否每天都使用思维导图软件,但是如果你使用,请选择 [Freeplane][18]。这是一款免费的思维导图和知识管理软件,可用于商业或娱乐。你可以创建笔记,将其排列在云图或图表中,使用日历和提醒设置任务等。
### 10. Calligra Flow
![linux-productivity-apps-10-calligra-flow][19]
最后,如果你需要流程图和图表工具,请尝试 [Calligra Flow][20]。你可以将其视为开放源代码的 [Microsoft Visio][21] 替代品,但 Calligra Flow 不提供 Viso 提供的所有特性。不过,你可以使用它来创建网络图、组织结构图、流程图等等。
生产力工具不仅可以加快工作速度,还可以让你更有条理。我敢打赌,几乎没有人不使用某种形式的生产力工具。尝试这里列出的应用程序可以使你的工作效率更高,还能让你的生活至少轻松一些。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/free-linux-productivity-apps-you-havent-heard-of/
作者:[Ada Ivanova][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.maketecheasier.com/author/adaivanoff/
[1]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-01-Tomboy.png (linux-productivity-apps-01-tomboy)
[2]:https://wiki.gnome.org/Apps/Tomboy
[3]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-02-MyNotex.jpg (linux-productivity-apps-02-mynotex)
[4]:https://sites.google.com/site/mynotex/
[5]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-03-Trojita.jpg (linux-productivity-apps-03-trojita)
[6]:http://trojita.flaska.net/
[7]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-04-Kontact.jpg (linux-productivity-apps-04-kontact)
[8]:https://userbase.kde.org/Kontact
[9]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-05-Osmo.jpg (linux-productivity-apps-05-osmo)
[10]:http://clayo.org/osmo/
[11]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-06-Catfish.png (linux-productivity-apps-06-catfish)
[12]:http://www.twotoasts.de/index.php/catfish/
[13]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-07-KOrganizer.jpg (linux-productivity-apps-07-korganizer)
[14]:https://userbase.kde.org/KOrganizer
[15]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-08-Evolution.jpg (linux-productivity-apps-08-evolution)
[16]:https://help.gnome.org/users/evolution/3.22/intro-main-window.html.en
[17]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-09-Freeplane.jpg (linux-productivity-apps-09-freeplane)
[18]:https://www.freeplane.org/wiki/index.php/Home
[19]:https://www.maketecheasier.com/assets/uploads/2017/09/Linux-productivity-apps-10-Calligra-Flow.jpg (linux-productivity-apps-10-calligra-flow)
[20]:https://www.calligra.org/flow/
[21]:https://www.maketecheasier.com/5-best-free-alternatives-to-microsoft-visio/

View File

@@ -0,0 +1,129 @@
Linux 容器安全的 10 个层面
======
> 应用这些策略来保护容器解决方案的各个层面和容器生命周期的各个阶段的安全。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDU_UnspokenBlockers_1110_A.png?itok=x8A9mqVA)
容器提供了打包应用程序的一种简单方法,它实现了从开发到测试到投入生产系统的无缝传递。它也有助于确保跨不同环境的连贯性,包括物理服务器、虚拟机、以及公有云或私有云。这些好处使得一些组织为了更方便地部署和管理为他们提升业务价值的应用程序,而快速地采用了容器技术。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/what-are-containers.png?itok=dxQfkbF-)
企业需要高度安全,在容器中运行核心服务的任何人都会问,“容器安全吗?”以及“我们能信任运行在容器中的应用程序吗?”
对容器进行安全保护就像是对运行中的进程进行安全保护一样。在你部署和运行你的容器之前,你需要去考虑整个解决方案各个层面的安全。你也需要去考虑贯穿了应用程序和容器整个生命周期的安全。
请尝试从这十个关键的因素去确保容器解决方案栈不同层面、以及容器生命周期的不同阶段的安全。
### 1. 容器宿主机操作系统和多租户环境
由于容器将应用程序和它的依赖作为一个单元来处理,使得开发者构建和升级应用程序变得更加容易,并且,容器可以启用多租户技术将许多应用程序和服务部署到一台共享主机上。在一台单独的主机上以容器方式部署多个应用程序、按需启动和关闭单个容器都是很容易的。为完全实现这种打包和部署技术的优势,运营团队需要运行容器的合适环境。运营者需要一个安全的操作系统,它能够在边界上保护容器安全、从容器中保护主机内核,以及保护容器彼此之间的安全。
容器是隔离而资源受限的 Linux 进程,允许你在一个共享的宿主机内核上运行沙盒化的应用程序。保护容器的方法与保护你的 Linux 中运行的任何进程的方法是一样的。降低权限是非常重要的,也是保护容器安全的最佳实践。最好使用尽可能小的权限去创建容器。容器应该以一个普通用户的权限来运行,而不是 root 权限的用户。在 Linux 中可以使用多个层面的安全加固手段Linux 命名空间、安全强化 Linux[SELinux][1])、[cgroups][2] 、capabilitiesLCTT 译注Linux 内核的一个安全特性,它打破了传统的普通用户与 root 用户的概念,在进程级提供更好的安全控制)、以及安全计算模式( [seccomp][3] ),这五种 Linux 的安全特性可以用于保护容器的安全。
### 2. 容器内容(使用可信来源)
在谈到安全时,首先要考虑你的容器里面有什么?例如 有些时候应用程序和基础设施是由很多可用组件所构成的。它们中的一些是开源的软件包比如Linux 操作系统、Apache Web 服务器、Red Hat JBoss 企业应用平台、PostgreSQL以及 Node.js。这些软件包的容器化版本已经可以使用了因此你没有必要自己去构建它们。但是对于你从一些外部来源下载的任何代码你需要知道这些软件包的原始来源是谁构建的它以及这些包里面是否包含恶意代码。
### 3. 容器注册(安全访问容器镜像)
你的团队的容器构建于下载的公共容器镜像,因此,访问和升级这些下载的容器镜像以及内部构建镜像,与管理和下载其它类型的二进制文件的方式是相同的,这一点至关重要。许多私有的注册库支持容器镜像的存储。选择一个私有的注册库,可以帮你将存储在它的注册中的容器镜像实现策略自动化。
### 4. 安全性与构建过程
在一个容器化环境中,软件构建过程是软件生命周期的一个阶段,它将所需的运行时库和应用程序代码集成到一起。管理这个构建过程对于保护软件栈安全来说是很关键的。遵守“一次构建,到处部署”的原则,可以确保构建过程的结果正是生产系统中需要的。保持容器的恒定不变也很重要 — 换句话说就是,不要对正在运行的容器打补丁,而是,重新构建和部署它们。
不论是因为你处于一个高强度监管的行业中,还是只希望简单地优化你的团队的成果,设计你的容器镜像管理以及构建过程,可以使用容器层的优势来实现控制分离,因此,你应该去这么做:
* 运营团队管理基础镜像
* 架构师管理中间件、运行时、数据库,以及其它解决方案
* 开发者专注于应用程序层面,并且只写代码
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/separation-of-control.png?itok=x2O39kqB)
最后,标记好你的定制构建容器,这样可以确保在构建和部署时不会搞混乱。
### 5. 控制好在同一个集群内部署应用
如果是在构建过程中出现的任何问题,或者在镜像被部署之后发现的任何漏洞,那么,请在基于策略的、自动化工具上添加另外的安全层。
我们来看一下,一个应用程序的构建使用了三个容器镜像层:内核、中间件,以及应用程序。如果在内核镜像中发现了问题,那么只能重新构建镜像。一旦构建完成,镜像就会被发布到容器平台注册库中。这个平台可以自动检测到发生变化的镜像。对于基于这个镜像的其它构建将被触发一个预定义的动作,平台将自己重新构建应用镜像,合并该修复的库。
一旦构建完成镜像将被发布到容器平台的内部注册库中。在它的内部注册库中会立即检测到镜像发生变化应用程序在这里将会被触发一个预定义的动作自动部署更新镜像确保运行在生产系统中的代码总是使用更新后的最新的镜像。所有的这些功能协同工作将安全功能集成到你的持续集成和持续部署CI/CD过程和管道中。
### 6. 容器编配:保护容器平台安全
当然了,应用程序很少会以单一容器分发。甚至,简单的应用程序一般情况下都会有一个前端、一个后端、以及一个数据库。而在容器中以微服务模式部署的应用程序,意味着应用程序将部署在多个容器中,有时它们在同一台宿主机上,有时它们是分布在多个宿主机或者节点上,如下面的图所示:
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/replace-affected-deployments.png?itok=vWneAxPm)
在大规模的容器部署时,你应该考虑:
* 哪个容器应该被部署在哪个宿主机上?
* 那个宿主机应该有什么样的性能?
* 哪个容器需要访问其它容器?它们之间如何发现彼此?
* 你如何控制和管理对共享资源的访问,像网络和存储?
* 如何监视容器健康状况?
* 如何去自动扩展性能以满足应用程序的需要?
* 如何在满足安全需求的同时启用开发者的自助服务?
考虑到开发者和运营者的能力提供基于角色的访问控制是容器平台的关键要素。例如编配管理服务器是中心访问点应该接受最高级别的安全检查。API 是规模化的自动容器平台管理的关键,可以用于为 pod、服务以及复制控制器验证和配置数据在入站请求上执行项目验证以及调用其它主要系统组件上的触发器。
### 7. 网络隔离
在容器中部署现代微服务应用,经常意味着跨多个节点在多个容器上部署。考虑到网络防御,你需要一种在一个集群中的应用之间的相互隔离的方法。一个典型的公有云容器服务,像 Google 容器引擎GKE、Azure 容器服务,或者 Amazon Web 服务AWS容器服务是单租户服务。他们让你在你初始化建立的虚拟机集群上运行你的容器。对于多租户容器的安全你需要容器平台为你启用一个单一集群并且分割流量以隔离不同的用户、团队、应用、以及在这个集群中的环境。
使用网络命名空间,容器内的每个集合(即大家熟知的 “pod”都会得到它自己的 IP 和绑定的端口范围,以此来从一个节点上隔离每个 pod 网络。除使用下面所述的方式之外,默认情况下,来自不同命名空间(项目)的 pod 并不能发送或者接收其它 pod 上的包和不同项目的服务。你可以使用这些特性在同一个集群内隔离开发者环境、测试环境,以及生产环境。但是,这样会导致 IP 地址和端口数量的激增,使得网络管理更加复杂。另外,容器是被设计为反复使用的,你应该在处理这种复杂性的工具上进行投入。在容器平台上比较受欢迎的工具是使用 [软件定义网络][4] (SDN) 提供一个定义的网络集群,它允许跨不同集群的容器进行通讯。
### 8. 存储
容器即可被用于无状态应用也可被用于有状态应用。保护外加的存储是保护有状态服务的一个关键要素。容器平台对多种受欢迎的存储提供了插件包括网络文件系统NFS、AWS 弹性块存储EBS、GCE 持久磁盘、GlusterFS、iSCSI、 RADOSCeph、Cinder 等等。
一个持久卷PV可以通过资源提供者支持的任何方式装载到一个主机上。提供者有不同的性能而每个 PV 的访问模式被设置为特定的卷支持的特定模式。例如NFS 能够支持多路客户端同时读/写,但是,一个特定的 NFS 的 PV 可以在服务器上被发布为只读模式。每个 PV 有它自己的一组反应特定 PV 性能的访问模式的描述比如ReadWriteOnce、ReadOnlyMany、以及 ReadWriteMany。
### 9. API 管理、终端安全、以及单点登录SSO
保护你的应用安全,包括管理应用、以及 API 的认证和授权。
Web SSO 能力是现代应用程序的一个关键部分。在构建它们的应用时,容器平台带来了开发者可以使用的多种容器化服务。
API 是微服务构成的应用程序的关键所在。这些应用程序有多个独立的 API 服务,这导致了终端服务数量的激增,它就需要额外的管理工具。推荐使用 API 管理工具。所有的 API 平台应该提供多种 API 认证和安全所需要的标准选项,这些选项既可以单独使用,也可以组合使用,以用于发布证书或者控制访问。
这些选项包括标准的 API key、应用 ID 和密钥对,以及 OAuth 2.0。
### 10. 在一个联合集群中的角色和访问管理
在 2016 年 7 月份Kubernetes 1.3 引入了 [Kubernetes 联合集群][5]。这是一个令人兴奋的新特性之一,它是在 Kubernetes 上游、当前的 Kubernetes 1.6 beta 中引用的。联合是用于部署和访问跨多集群运行在公有云或企业数据中心的应用程序服务的。多个集群能够用于去实现应用程序的高可用性应用程序可以跨多个可用区域或者去启用部署公共管理或者跨不同的供应商进行迁移比如AWS、Google Cloud、以及 Azure。
当管理联合集群时,你必须确保你的编配工具能够提供你所需要的跨不同部署平台的实例的安全性。一般来说,认证和授权是很关键的 —— 不论你的应用程序运行在什么地方将数据安全可靠地传递给它们以及管理跨集群的多租户应用程序。Kubernetes 扩展了联合集群,包括对联合的秘密数据、联合的命名空间、以及 Ingress objects 的支持。
### 选择一个容器平台
当然,它并不仅关乎安全。你需要提供一个你的开发者团队和运营团队有相关经验的容器平台。他们需要一个安全的、企业级的基于容器的应用平台,它能够同时满足开发者和运营者的需要,而且还能够提高操作效率和基础设施利用率。
想从 Daniel 在 [欧盟开源峰会][7] 上的 [容器安全的十个层面][6] 的演讲中学习更多知识吗?这个峰会已于 10 月 23 - 26 日在 Prague 举行。
### 关于作者
Daniel OhMicroservivesAgileDevopsJava EeContainerOpenshiftJbossEvangelism
--------------------------------------------------------------------------------
via: https://opensource.com/article/17/10/10-layers-container-security
作者:[Daniel Oh][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/daniel-oh
[1]:https://en.wikipedia.org/wiki/Security-Enhanced_Linux
[2]:https://en.wikipedia.org/wiki/Cgroups
[3]:https://en.wikipedia.org/wiki/Seccomp
[4]:https://en.wikipedia.org/wiki/Software-defined_networking
[5]:https://kubernetes.io/docs/concepts/cluster-administration/federation/
[6]:https://osseu17.sched.com/mobile/#session:f2deeabfc1640d002c1d55101ce81223
[7]:http://events.linuxfoundation.org/events/open-source-summit-europe

View File

@@ -0,0 +1,91 @@
给 “rm” 命令添加个“垃圾桶”
============
人类犯错误是因为我们不是一个可编程设备,所以,在使用 `rm` 命令时要额外注意,不要在任何时候使用 `rm -rf *`。当你使用 `rm` 命令时,它会永久删除文件,不会像文件管理器那样将这些文件移动到 “垃圾箱”。
有时我们会将不应该删除的文件删除掉,所以当错误地删除了文件时该怎么办? 你必须看看恢复工具Linux 中有很多数据恢复工具),但我们不知道是否能将它百分之百恢复,所以要如何解决这个问题?
我们最近发表了一篇关于 [Trash-Cli][1] 的文章,在评论部分,我们从用户 Eemil Lgz 那里获得了一个关于 [saferm.sh][2] 脚本的更新,它可以帮助我们将文件移动到“垃圾箱”而不是永久删除它们。
将文件移动到“垃圾桶”是一个好主意,当你无意中运行 `rm` 命令时,可以拯救你;但是很少有人会说这是一个坏习惯,如果你不注意“垃圾桶”,它可能会在一定的时间内被文件和文件夹堆积起来。在这种情况下,我建议你按照你的意愿去做一个定时任务。
这适用于服务器和桌面两种环境。 如果脚本检测到 GNOME 、KDE、Unity 或 LXDE 桌面环境DE则它将文件或文件夹安全地移动到默认垃圾箱 `$HOME/.local/share/Trash/files`,否则会在您的主目录中创建垃圾箱文件夹 `$HOME/Trash`
`saferm.sh` 脚本托管在 Github 中,可以从仓库中克隆,也可以创建一个名为 `saferm.sh` 的文件并复制其上的代码。
```
$ git clone https://github.com/lagerspetz/linux-stuff
$ sudo mv linux-stuff/scripts/saferm.sh /bin
$ rm -Rf linux-stuff
```
`.bashrc` 文件中设置别名,
```
alias rm=saferm.sh
```
执行下面的命令使其生效,
```
$ source ~/.bashrc
```
一切就绪,现在你可以执行 `rm` 命令,自动将文件移动到”垃圾桶”,而不是永久删除它们。
测试一下,我们将删除一个名为 `magi.txt` 的文件,命令行明确的提醒了 `Moving magi.txt to $HOME/.local/share/Trash/file`
```
$ rm -rf magi.txt
Moving magi.txt to /home/magi/.local/share/Trash/files
```
也可以通过 `ls` 命令或 `trash-cli` 进行验证。
```
$ ls -lh /home/magi/.local/share/Trash/files
Permissions Size User Date Modified Name
.rw-r--r-- 32 magi 11 Oct 16:24 magi.txt
```
或者我们可以通过文件管理器界面中查看相同的内容。
![![][3]][4]
LCTT 译注:原文此处混淆了部分 trash-cli 的内容,考虑到文章衔接和逻辑,此处略。)
要了解 `saferm.sh` 的其他选项,请查看帮助。
```
$ saferm.sh -h
This is saferm.sh 1.16. LXDE and Gnome3 detection.
Will ask to unsafe-delete instead of cross-fs move. Allows unsafe (regular rm) delete (ignores trashinfo).
Creates trash and trashinfo directories if they do not exist. Handles symbolic link deletion.
Does not complain about different user any more.
Usage: /path/to/saferm.sh [OPTIONS] [--] files and dirs to safely remove
OPTIONS:
-r allows recursively removing directories.
-f Allow deleting special files (devices, ...).
-u Unsafe mode, bypass trash and delete files permanently.
-v Verbose, prints more messages. Default in this version.
-q Quiet mode. Opposite of verbose.
```
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/rm-command-to-move-files-to-trash-can-rm-alias/
作者:[2DAYGEEK][a]
译者:[amwps290](https://github.com/amwps290)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.2daygeek.com/author/2daygeek/
[1]:https://www.2daygeek.com/trash-cli-command-line-trashcan-linux-system/
[2]:https://github.com/lagerspetz/linux-stuff/blob/master/scripts/saferm.sh
[3]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[4]:https://www.2daygeek.com/wp-content/uploads/2017/10/rm-command-to-move-files-to-trash-can-rm-alias-1.png

View File

@@ -0,0 +1,59 @@
我的 Linux 主目录中的隐藏文件是干什么用的?
======
![](https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-linux-hero.png)
在 Linux 系统中,你可能会在主目录中存储了大量文件和文件夹。但在这些文件之外,你知道你的主目录还附带了很多隐藏的文件和文件夹吗?如果你在主目录中运行 `ls -a`,你会发现一堆带有点前缀的隐藏文件和目录。这些隐藏的文件到底做了什么?
### 在主目录中隐藏的文件是干什么用的?
![hidden-files-liunux-2][1]
通常,主目录中的隐藏文件和目录包含该用户程序访问的设置或数据。它们不打算让用户编辑,只需要应用程序进行编辑。这就是为什么它们被隐藏在用户的正常视图之外。
通常,删除和修改自己主目录中的文件不会损坏操作系统。然而,依赖这些隐藏文件的应用程序可能不那么灵活。从主目录中删除隐藏文件时,通常会丢失与其关联的应用程序的设置。
依赖该隐藏文件的程序通常会重新创建它。 但是,你将从“开箱即用”设置开始,如全新用户一般。如果你在使用应用程序时遇到问题,那实际上可能是一个巨大的帮助。它可以让你删除可能造成麻烦的自定义设置。但如果你不这样做,这意味着你需要把所有的东西都设置成原来的样子。
### 主目录中某些隐藏文件的特定用途是什么?
![hidden-files-linux-3][2]
每个人在他们的主目录中都会有不同的隐藏文件。每个人都有一些。但是,无论应用程序如何,这些文件都有类似的用途。
#### 系统设置
系统设置包括桌面环境和 shell 的配置。
* shell 和命令行程序的**配置文件**:根据你使用的特定 shell 和类似命令的应用程序,特定的文件名称会变化。你会看到 `.bashrc``.vimrc``.zshrc`。这些文件包含你已经更改的有关 shell 的操作环境的任何设置,或者对 `vim` 等命令行实用工具的设置进行的调整。删除这些文件将使关联的应用程序返回到其默认状态。考虑到许多 Linux 用户多年来建立了一系列微妙的调整和设置,删除这个文件可能是一个非常头疼的问题。
* **用户配置文件**:像上面的配置文件一样,这些文件(通常是 `.profile``.bash_profile`)保存 shell 的用户设置。该文件通常包含你的 `PATH` 环境变量。它还包含你设置的[别名][3]。用户也可以在 `.bashrc` 或其他位置放置别名。`PATH` 环境变量控制着 shell 寻找可执行命令的位置。通过添加或修改 `PATH`,可以更改 shell 的命令查找位置。别名更改了原有命令的名称。例如:一个别名可能将 `ls -l` 设置为 `ll`。这为经常使用的命令提供基于文本的快捷方式。如果删除 `.profile` 文件,通常可以在 `/etc/skel` 目录中找到默认版本。
* **桌面环境设置**:这里保存你的桌面环境的任何定制。其中包括桌面背景、屏幕保护程序、快捷键、菜单栏和任务栏图标以及用户针对其桌面环境设置的其他任何内容。当你删除这个文件时,用户的环境会在下一次登录时恢复到新的用户环境。
#### 应用配置文件
你会在 Ubuntu 的 `.config` 文件夹中找到它们。 这些是针对特定应用程序的设置。 它们将包含喜好列表和设置等内容。
* **应用程序的配置文件**:这包括应用程序首选项菜单中的设置、工作区配置等。 你在这里找到的具体取决于应用程序。
* **Web 浏览器数据**:这可能包括书签和浏览历史记录等内容。这些文件大部分是缓存。这是 Web 浏览器临时存储下载文件(如图片)的地方。删除这些内容可能会降低你首次访问某些媒体网站的速度。
* **缓存**:如果用户应用程序缓存仅与该用户相关的数据(如 [Spotify 应用程序存储播放列表的缓存][4]),则主目录是存储该目录的默认地点。 这些缓存可能包含大量数据或仅包含几行代码:这取决于应用程序需要什么。 如果你删除这些文件,则应用程序会根据需要重新创建它们。
* **日志**:一些用户应用程序也可能在这里存储日志。根据开发人员设置应用程序的方式,你可能会发现存储在你的主目录中的日志文件。然而,这不是一个常见的选择。
### 结论
在大多数情况下,你的 Linux 主目录中的隐藏文件用于存储用户设置。 这包括命令行程序以及基于 GUI 的应用程序的设置。删除它们将删除用户设置。 通常情况下,它不会导致程序被破坏。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/hidden-files-linux-home-directory/
作者:[Alexander Fox][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.maketecheasier.com/author/alexfox/
[1]:https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-liunux-2.png (hidden-files-liunux-2)
[2]:https://www.maketecheasier.com/assets/uploads/2017/06/hidden-files-linux-3.png (hidden-files-linux-3)
[3]:https://www.maketecheasier.com/making-the-linux-command-line-a-little-friendlier/#aliases
[4]:https://www.maketecheasier.com/clear-spotify-cache/

View File

@@ -0,0 +1,140 @@
Linux 中的“大内存页”hugepage是个什么
======
> 学习 Linux 中的<ruby>大内存页<rt>hugepage</rt></ruby>。理解什么是“大内存页”,如何进行配置,如何查看当前状态以及如何禁用它。
![Huge Pages in Linux][1]
本文中我们会详细介绍<ruby>大内存页<rt>huge page</rt></ruby>让你能够回答Linux 中的“大内存页”是什么?在 RHEL6、RHEL7、Ubuntu 等 Linux 中,如何启用/禁用“大内存页”?如何查看“大内存页”的当前值?
首先让我们从“大内存页”的基础知识开始讲起。
### Linux 中的“大内存页”是个什么玩意?
“大内存页”有助于 Linux 系统进行虚拟内存管理。顾名思义,除了标准的 4KB 大小的页面外,它们还能帮助管理内存中的巨大的页面。使用“大内存页”,你最大可以定义 1GB 的页面大小。
在系统启动期间,你能用“大内存页”为应用程序预留一部分内存。这部分内存,即被“大内存页”占用的这些存储器永远不会被交换出内存。它会一直保留其中,除非你修改了配置。这会极大地提高像 Oracle 数据库这样的需要海量内存的应用程序的性能。
### 为什么使用“大内存页”?
在虚拟内存管理中,内核维护一个将虚拟内存地址映射到物理地址的表,对于每个页面操作,内核都需要加载相关的映射。如果你的内存页很小,那么你需要加载的页就会很多,导致内核会加载更多的映射表。而这会降低性能。
使用“大内存页”,意味着所需要的页变少了。从而大大减少由内核加载的映射表的数量。这提高了内核级别的性能最终有利于应用程序的性能。
简而言之,通过启用“大内存页”,系统具只需要处理较少的页面映射表,从而减少访问/维护它们的开销!
### 如何配置“大内存页”?
运行下面命令来查看当前“大内存页”的详细内容。
```
root@kerneltalks # grep Huge /proc/meminfo
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
```
从上面输出可以看到,每个页的大小为 2MB`Hugepagesize`),并且系统中目前有 `0` 个“大内存页”(`HugePages_Total`)。这里“大内存页”的大小可以从 `2MB` 增加到 `1GB`
运行下面的脚本可以知道系统当前需要多少个巨大页。该脚本取之于 Oracle。
```
#!/bin/bash
#
# hugepages_settings.sh
#
# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
#
# Note: This script does calculation for all shared memory
# segments available when the script is run, no matter it
# is an Oracle RDBMS shared memory segment or not.
# Check for the kernel version
KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'`
# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}`
# Start from 1 pages to be on the safe side and guarantee 1 free HugePage
NUM_PG=1
# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"`
do
MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
if [ $MIN_PG -gt 0 ]; then
NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q`
fi
done
# Finish with results
case $KERN in
'2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`;
echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;;
'2.6' | '3.8' | '3.10' | '4.1' ) echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
*) echo "Unrecognized kernel version $KERN. Exiting." ;;
esac
# End
```
将它以 `hugepages_settings.sh` 为名保存到 `/tmp` 中,然后运行之:
```
root@kerneltalks # sh /tmp/hugepages_settings.sh
Recommended setting: vm.nr_hugepages = 124
```
你的输出类似如上结果,只是数字会有一些出入。
这意味着,你系统需要 124 个每个 2MB 的“大内存页”!若你设置页面大小为 4MB则结果就变成了 62。你明白了吧
### 配置内核中的“大内存页”
本文最后一部分内容是配置上面提到的 [内核参数 ][2] ,然后重新加载。将下面内容添加到 `/etc/sysctl.conf` 中,然后输入 `sysctl -p` 命令重新加载配置。
```
vm.nr_hugepages=126
```
注意我们这里多加了两个额外的页,因为我们希望在实际需要的页面数量之外多一些额外的空闲页。
现在,内核已经配置好了,但是要让应用能够使用这些“大内存页”还需要提高内存的使用阀值。新的内存阀值应该为 126 个页 x 每个页 2 MB = 252 MB也就是 258048 KB。
你需要编辑 `/etc/security/limits.conf` 中的如下配置:
```
soft memlock 258048
hard memlock 258048
```
某些情况下,这些设置是在指定应用的文件中配置的,比如 Oracle DB 就是在 `/etc/security/limits.d/99-grid-oracle-limits.conf` 中配置的。
这就完成了!你可能还需要重启应用来让应用来使用这些新的巨大页。
### 如何禁用“大内存页”?
“大内存页”默认是开启的。使用下面命令来查看“大内存页”的当前状态。
```
root@kerneltalks# cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
```
输出中的 `[always]` 标志说明系统启用了“大内存页”。
若使用的是基于 RedHat 的系统,则应该要查看的文件路径为 `/sys/kernel/mm/redhat_transparent_hugepage/enabled`
若想禁用“大内存页”,则在 `/etc/grub.conf` 中的 `kernel` 行后面加上 `transparent_hugepage=never`,然后重启系统。
--------------------------------------------------------------------------------
via: https://kerneltalks.com/services/what-is-huge-pages-in-linux/
作者:[Shrikant Lavhate][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://kerneltalks.com
[1]:https://a1.kerneltalks.com/wp-content/uploads/2017/11/hugepages-in-linux.png
[2]:https://kerneltalks.com/linux/how-to-tune-kernel-parameters-in-linux/

View File

@@ -0,0 +1,210 @@
如何使用 GNOME Shell 扩展
=====
> 简介:这是一份详细指南,我将会向你展示如何手动或通过浏览器轻松安装 GNOME Shell <ruby>扩展<rt>Extension</rt></ruby>。
在讨论 [如何在 Ubuntu 17.10 上安装主题][1] 一文时,我简要地提到了 GNOME Shell 扩展,它用来安装用户主题。今天,我们将详细介绍 Ubuntu 17.10 中的 GNOME Shell 扩展。
我可能会使用术语 GNOME 扩展而不是 GNOME Shell 扩展,但是这两者在这里具有相同的含义。
什么是 GNOME Shell 扩展?如何安装 GNOME Shell 扩展,以及如何管理和删除 GNOME Shell 扩展?我会一一解释所有的问题。
在此之前,如果你喜欢视频,我已经在 [FOSS 的 YouTube 频道][2] 上展示了所有的这些操作。我强烈建议你订阅它来获得更多有关 Linux 的视频。
### 什么是 GNOME Shell 扩展?
[GNOME Shell 扩展][3] 根本上来说是增强 GNOME 桌面功能的一小段代码。
把它看作是你的浏览器的一个附加组件。例如,你可以在浏览器中安装附加组件来禁用广告。这个附加组件是由第三方开发者开发的。虽然你的 Web 浏览器默认不提供此项功能,但安装此附加组件可增强你 Web 浏览器的功能。
同样, GNOME Shell 扩展就像那些可以安装在 GNOME 之上的第三方附加组件和插件。这些扩展程序是为执行特定任务而创建的,例如显示天气状况、网速等。大多数情况下,你可以在顶部面板中访问它们。
![GNOME Shell 扩展显示天气信息][5]
也有一些 GNOME 扩展在顶部面板上不可见,但它们仍然可以调整 GNOME 的行为。例如,有一个这样的扩展可以让鼠标中键来关闭应用程序。
### 安装 GNOME Shell 扩展
现在你知道了什么是 GNOME Shell 扩展,那么让我们来看看如何安装它吧。有三种方式可以使用 GNOME 扩展:
* 使用来自 Ubuntu (或你的 Linux 发行版)的最小扩展集
* 在 Web 浏览器中查找并安装扩展程序
* 下载并手动安装扩展
在你学习如何使用 GNOME Shell 扩展之前,你应该安装 GNOME Tweak Tool。你可以在软件中心找到它或者你可以使用以下命令
```
sudo apt install gnome-tweak-tool
```
有时候,你需要知道你正在使用的 GNOME Shell 的版本,这有助于你确定扩展是否与系统兼容。你可以使用下面的命令来找到它:
```
gnome-shell --version
```
#### 1. 使用 gnome-shell-extensions 包 [最简单最安全的方式]
Ubuntu以及其他几个 Linux 发行版,如 Fedora )提供了一个包,这个包有最小集合的 GNOME 扩展。由于 Linux 发行版经过测试,所以你不必担心兼容性问题。
如果你不想费神,你只需获得这个包,你就可以安装 8-10 个 GNOME 扩展。
```
sudo apt install gnome-shell-extensions
```
你将需要重新启动系统(或者重新启动 GNOME Shell我具体忘了是哪个。之后启动 GNOME Tweaks你会发现一些扩展自动安装了你只需切换按钮即可开始使用已安装的扩展程序。
![Change GNOME Shell theme in Ubuntu 17.1][6]
#### 2. 从 Web 浏览器安装 GNOME Shell 扩展
GNOME 项目有一个专门用于扩展的网站,不干别的,你可以在这里找到并安装扩展,并管理它们,甚至不需要 GNOME Tweaks Tool。
- [GNOME Shell Extensions Website][3]
但是为了安装 Web 浏览器扩展,你需要两件东西:浏览器附加组件和本地主机连接器。
**步骤 1 安装 浏览器附加组件**
当你访问 GNOME Shell 扩展网站时,你会看到如下消息:
> “要使用此站点控制 GNOME Shell 扩展,你必须安装由两部分组成的 GNOME Shell 集成:浏览器扩展和本地主机消息应用。”
![Installing GNOME Shell Extensions][7]
你只需在你的 Web 浏览器上点击建议的附加组件链接即可。你也可以从下面的链接安装它们:
- 对于 Google Chrome、Chromium 和 Vivaldi [Chrome Web 商店][21]
- 对于 Firefox [Mozilla Addons][22]
- 对于 Opera [Opera Addons][23]
**步骤 2 安装本地连接器**
仅仅安装浏览器附加组件并没有帮助。你仍然会看到如下错误:
> “尽管 GNOME Shell 集成扩展正在运行,但未检测到本地主机连接器。请参阅文档以获取有关安装连接器的信息。”
![How to install GNOME Shell Extensions][8]
这是因为你尚未安装主机连接器。要做到这一点,请使用以下命令:
```
sudo apt install chrome-gnome-shell
```
不要担心包名中的 “chrome” 前缀,它与 Chrome 无关,你无需再次安装 Firefox 或 Opera 的单独软件包。
**步骤 3 在 Web 浏览器中安装 GNOME Shell 扩展**
一旦你完成了这两个要求,你就可以开始了。现在,你将看不到任何错误消息。
![GNOME Shell Extension][9]
一件好的做法是按照 GNOME Shell 版本对扩展进行排序,但这不是强制性的。这是因为开发人员是为其当前的 GNOME 版本创建的扩展。而在一年之内,会发布两个或更多 GNOME 发行版本,但开发人员没有时间(在新的 GNOME 版本上)测试或更新他/她的扩展。
因此,你不知道该扩展是否与你的系统兼容。尽管扩展已经存在很长一段时间了,但是有可能在最新的 GNOME Shell 版本中,它也能正常工作。同样它也有可能不工作。
你也可以去搜索扩展程序。假设你想要安装有关天气的扩展,只要搜索它并选择一个搜索结果即可。
当你访问扩展页面时,你会看到一个切换按钮。
![Installing GNOME Shell Extension ][10]
点击它,你会被提示是否要安装这个扩展:
![Install GNOME Shell Extensions via web browser][11]
显然,直接安装就好。安装完成后,你会看到切换按钮已打开,旁边有一个设置选项。你也可以使用设置选项配置扩展,也可以禁用扩展。
![Configuring installed GNOME Shell Extensions][12]
你也可以在 GNOME Tweaks Tool 中配置通过 Web 浏览器安装的扩展:
![GNOME Tweaks to handle GNOME Shell Extensions][13]
你可以在 GNOME 网站中 [已安装的扩展部分][14] 下查看所有已安装的扩展。
![Manage your installed GNOME Shell Extensions][15]
使用 GNOME 扩展网站的一个主要优点是你可以查看扩展是否有可用的更新,你不会在 GNOME Tweaks 或系统更新中得到更新(和提示)。
#### 3. 手动安装 GNOME Shell 扩展
你不需要始终在线才能安装 GNOME Shell 扩展,你可以下载文件并稍后安装,这样就不必使用互联网了。
去 GNOME 扩展网站下载最新版本的扩展。
![Download GNOME Shell Extension][16]
解压下载的文件,将该文件夹复制到 `~/.local/share/gnome-shell/extensions` 目录。到主目录下并按 `Ctrl+H` 显示隐藏的文件夹,在这里找到 `.local` 文件夹,你可以找到你的路径,直至 `extensions` 目录。
一旦你将文件复制到正确的目录后,进入它并打开 `metadata.json` 文件,寻找 `uuid` 的值。
确保该扩展的文件夹名称与 `metadata.json` 中的 `uuid` 值相同。如果不相同,请将目录重命名为 `uuid` 的值。
![Manually install GNOME Shell extension][17]
差不多了!现在重新启动 GNOME Shell。 按 `Alt+F2` 并输入 `r` 重新启动 GNOME Shell。
![Restart GNOME Shell][18]
同样重新启动 GNOME Tweaks Tool。你现在应该可以在 Tweaks Tool 中看到手动安装的 GNOME 扩展,你可以在此处配置或启用新安装的扩展。
这就是安装 GNOME Shell 扩展你需要知道的所有内容。
### 移除 GNOME Shell 扩展
你可能想要删除一个已安装的 GNOME Shell 扩展,这是完全可以理解的。
如果你是通过 Web 浏览器安装的,你可以到 [GNOME 网站的以安装的扩展部分][14] 那移除它(如前面的图片所示)。
如果你是手动安装的,可以从 `~/.local/share/gnome-shell/extensions` 目录中删除扩展文件来删除它。
### 特别提示:获得 GNOME Shell 扩展更新的通知
到目前为止,你已经意识到除了访问 GNOME 扩展网站之外,无法知道更新是否可用于 GNOME Shell 扩展。
幸运的是,有一个 GNOME Shell 扩展可以通知你是否有可用于已安装扩展的更新。你可以从下面的链接中获得它:
- [Extension Update Notifier][19]
### 你如何管理 GNOME Shell 扩展?
我觉得很奇怪不能通过系统更新来更新扩展,就好像 GNOME Shell 扩展不是系统的一部分。
如果你正在寻找一些建议,请阅读这篇文章: [关于最佳 GNOME 扩展][20]。同时,你可以分享有关 GNOME Shell 扩展的经验。你经常使用它们吗?如果是,哪些是你最喜欢的?
--------------------------------------------------------------------------------
via: [https://itsfoss.com/gnome-shell-extensions/](https://itsfoss.com/gnome-shell-extensions/)
作者:[Abhishek Prakash][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[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/install-themes-ubuntu/
[2]:https://www.youtube.com/c/itsfoss?sub_confirmation=1
[3]:https://extensions.gnome.org/
[5]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-weather.jpeg
[6]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/enableuser-themes-extension-gnome.jpeg
[7]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-1.jpeg
[8]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-2.jpeg
[9]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-3.jpeg
[10]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-4.jpeg
[11]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-5.jpeg
[12]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-6.jpeg
[13]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-7-800x572.jpeg
[14]:https://extensions.gnome.org/local/
[15]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-8.jpeg
[16]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-9-800x456.jpeg
[17]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/gnome-shell-extension-installation-10-800x450.jpg
[18]:https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/11/restart-gnome-shell-800x299.jpeg
[19]:https://extensions.gnome.org/extension/1166/extension-update-notifier/
[20]:https://itsfoss.com/best-gnome-extensions/
[21]:https://chrome.google.com/webstore/detail/gnome-shell-integration/gphhapmejobijbbhgpjhcjognlahblep
[22]:https://addons.mozilla.org/en/firefox/addon/gnome-shell-integration/
[23]:https://addons.opera.com/en/extensions/details/gnome-shell-integration/

View File

@@ -0,0 +1,481 @@
并发服务器libuv
============================================================
这是并发网络服务器系列文章的第四部分。在这一部分中我们将使用 libuv 再次重写我们的服务器,并且也会讨论关于使用一个线程池在回调中去处理耗时任务。最终,我们去看一下底层的 libuv花一点时间去学习如何用异步 API 对文件系统阻塞操作进行封装。
本系列的所有文章:
* [第一节 - 简介][7]
* [第二节 - 线程][8]
* [第三节 - 事件驱动][9]
* [第四节 - libuv][10]
### 使用 libuv 抽象出事件驱动循环
在 [第三节][11] 中,我们看到了基于 `select``epoll` 的服务器的相似之处,并且,我说过,在它们之间抽象出细微的差别是件很有吸引力的事。许多库已经做到了这些,所以在这一部分中我将去选一个并使用它。我选的这个库是 [libuv][12],它最初设计用于 Node.js 底层的可移植平台层并且后来发现在其它的项目中也有使用。libuv 是用 C 写的,因此,它具有很高的可移植性,非常适用嵌入到像 JavaScript 和 Python 这样的高级语言中。
虽然 libuv 为了抽象出底层平台细节已经变成了一个相当大的框架但它仍然是以 _事件循环_ 思想为中心的。在我们第三部分的事件驱动服务器中,事件循环是显式定义在 `main` 函数中的当使用 libuv 时该循环通常隐藏在库自身中而用户代码仅需要注册事件句柄作为一个回调函数和运行这个循环。此外libuv 会在给定的平台上使用更快的事件循环实现对于 Linux 它是 `epoll`,等等。
![libuv loop](https://eli.thegreenplace.net/images/2017/libuvloop.png)
libuv 支持多路事件循环因此事件循环在库中是非常重要的它有一个句柄 —— `uv_loop_t`,以及创建/杀死/启动/停止循环的函数。也就是说,在这篇文章中,我将仅需要使用 “默认的” 循环libuv 可通过 `uv_default_loop()` 提供它;多路循环大多用于多线程事件驱动的服务器,这是一个更高级别的话题,我将留在这一系列文章的以后部分。
### 使用 libuv 的并发服务器
为了对 libuv 有一个更深的印象,让我们跳转到我们的可靠协议的服务器,它通过我们的这个系列已经有了一个强大的重新实现。这个服务器的结构与第三部分中的基于 `select``epoll` 的服务器有一些相似之处,因为,它也依赖回调。完整的 [示例代码在这里][13];我们开始设置这个服务器的套接字绑定到一个本地端口:
```
int portnum = 9090;
if (argc >= 2) {
portnum = atoi(argv[1]);
}
printf("Serving on port %d\n", portnum);
int rc;
uv_tcp_t server_stream;
if ((rc = uv_tcp_init(uv_default_loop(), &server_stream)) < 0) {
die("uv_tcp_init failed: %s", uv_strerror(rc));
}
struct sockaddr_in server_address;
if ((rc = uv_ip4_addr("0.0.0.0", portnum, &server_address)) < 0) {
die("uv_ip4_addr failed: %s", uv_strerror(rc));
}
if ((rc = uv_tcp_bind(&server_stream, (const struct sockaddr*)&server_address, 0)) < 0) {
die("uv_tcp_bind failed: %s", uv_strerror(rc));
}
```
除了它被封装进 libuv API 中之外,你看到的是一个相当标准的套接字。在它的返回中,我们取得了一个可工作于任何 libuv 支持的平台上的可移植接口。
这些代码也展示了很认真负责的错误处理;多数的 libuv 函数返回一个整数状态返回一个负数意味着出现了一个错误。在我们的服务器中我们把这些错误看做致命问题进行处理但也可以设想一个更优雅的错误恢复。
现在,那个套接字已经绑定,是时候去监听它了。这里我们运行首个回调注册:
```
// Listen on the socket for new peers to connect. When a new peer connects,
// the on_peer_connected callback will be invoked.
if ((rc = uv_listen((uv_stream_t*)&server_stream, N_BACKLOG, on_peer_connected)) < 0) {
die("uv_listen failed: %s", uv_strerror(rc));
}
```
`uv_listen` 注册一个事件回调,当新的对端连接到这个套接字时将会调用事件循环。我们的回调在这里被称为 `on_peer_connected`,我们一会儿将去查看它。
最终,`main` 运行这个 libuv 循环直到它被停止`uv_run` 仅在循环被停止或者发生错误时返回)。
```
// Run the libuv event loop.
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
// If uv_run returned, close the default loop before exiting.
return uv_loop_close(uv_default_loop());
```
注意,在运行事件循环之前,只有一个回调是通过 `main` 注册的;我们稍后将看到怎么去添加更多的回调。在事件循环的整个运行过程中,添加和删除回调并不是一个问题 —— 事实上,大多数服务器就是这么写的。
这是一个 `on_peer_connected`,它处理到服务器的新的客户端连接:
```
void on_peer_connected(uv_stream_t* server_stream, int status) {
if (status < 0) {
fprintf(stderr, "Peer connection error: %s\n", uv_strerror(status));
return;
}
// client will represent this peer; it's allocated on the heap and only
// released when the client disconnects. The client holds a pointer to
// peer_state_t in its data field; this peer state tracks the protocol state
// with this client throughout interaction.
uv_tcp_t* client = (uv_tcp_t*)xmalloc(sizeof(*client));
int rc;
if ((rc = uv_tcp_init(uv_default_loop(), client)) < 0) {
die("uv_tcp_init failed: %s", uv_strerror(rc));
}
client->data = NULL;
if (uv_accept(server_stream, (uv_stream_t*)client) == 0) {
struct sockaddr_storage peername;
int namelen = sizeof(peername);
if ((rc = uv_tcp_getpeername(client, (struct sockaddr*)&peername,
&namelen)) < 0) {
die("uv_tcp_getpeername failed: %s", uv_strerror(rc));
}
report_peer_connected((const struct sockaddr_in*)&peername, namelen);
// Initialize the peer state for a new client: we start by sending the peer
// the initial '*' ack.
peer_state_t* peerstate = (peer_state_t*)xmalloc(sizeof(*peerstate));
peerstate->state = INITIAL_ACK;
peerstate->sendbuf[0] = '*';
peerstate->sendbuf_end = 1;
peerstate->client = client;
client->data = peerstate;
// Enqueue the write request to send the ack; when it's done,
// on_wrote_init_ack will be called. The peer state is passed to the write
// request via the data pointer; the write request does not own this peer
// state - it's owned by the client handle.
uv_buf_t writebuf = uv_buf_init(peerstate->sendbuf, peerstate->sendbuf_end);
uv_write_t* req = (uv_write_t*)xmalloc(sizeof(*req));
req->data = peerstate;
if ((rc = uv_write(req, (uv_stream_t*)client, &writebuf, 1,
on_wrote_init_ack)) < 0) {
die("uv_write failed: %s", uv_strerror(rc));
}
} else {
uv_close((uv_handle_t*)client, on_client_closed);
}
}
```
这些代码都有很好的注释但是这里有一些重要的 libuv 语法我想去强调一下
* 传入自定义数据到回调中:因为 C 语言还没有闭包这可能是个挑战libuv 在它的所有的处理类型中有一个 `void* data` 字段;这些字段可以被用于传递用户数据。例如,注意 `client->data` 是如何指向到一个 `peer_state_t` 结构上,以便于 `uv_write` 和 `uv_read_start` 注册的回调可以知道它们正在处理的是哪个客户端的数据。
* 内存管理在带有垃圾回收的语言中进行事件驱动编程是非常容易的因为回调通常运行在一个与它们注册的地方完全不同的栈帧中使得基于栈的内存管理很困难。它总是需要传递堆分配的数据到 libuv 回调中当所有回调运行时除了 `main`,其它的都运行在栈上),并且,为了避免泄漏,许多情况下都要求这些数据去安全释放(`free()`)。这些都是些需要实践的内容 ^注1 。
这个服务器上对端的状态如下:
```
typedef struct {
ProcessingState state;
char sendbuf[SENDBUF_SIZE];
int sendbuf_end;
uv_tcp_t* client;
} peer_state_t;
```
它与第三部分中的状态非常类似;我们不再需要 `sendptr`,因为,在调用 “done writing” 回调之前,`uv_write` 将确保发送它提供的整个缓冲。我们也为其它的回调使用保持了一个到客户端的指针。这里是 `on_wrote_init_ack`
```
void on_wrote_init_ack(uv_write_t* req, int status) {
if (status) {
die("Write error: %s\n", uv_strerror(status));
}
peer_state_t* peerstate = (peer_state_t*)req->data;
// Flip the peer state to WAIT_FOR_MSG, and start listening for incoming data
// from this peer.
peerstate->state = WAIT_FOR_MSG;
peerstate->sendbuf_end = 0;
int rc;
if ((rc = uv_read_start((uv_stream_t*)peerstate->client, on_alloc_buffer,
on_peer_read)) < 0) {
die("uv_read_start failed: %s", uv_strerror(rc));
}
// Note: the write request doesn't own the peer state, hence we only free the
// request itself, not the state.
free(req);
}
```
然后,我们确信知道了这个初始的 `'*'` 已经被发送到对端,我们通过调用 `uv_read_start` 去监听从这个对端来的入站数据,它注册一个将被事件循环调用的回调(`on_peer_read`),不论什么时候,事件循环都在套接字上接收来自客户端的调用:
```
void on_peer_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) {
if (nread < 0) {
if (nread != uv_eof) {
fprintf(stderr, "read error: %s\n", uv_strerror(nread));
}
uv_close((uv_handle_t*)client, on_client_closed);
} else if (nread == 0) {
// from the documentation of uv_read_cb: nread might be 0, which does not
// indicate an error or eof. this is equivalent to eagain or ewouldblock
// under read(2).
} else {
// nread > 0
assert(buf->len >= nread);
peer_state_t* peerstate = (peer_state_t*)client->data;
if (peerstate->state == initial_ack) {
// if the initial ack hasn't been sent for some reason, ignore whatever
// the client sends in.
free(buf->base);
return;
}
// run the protocol state machine.
for (int i = 0; i < nread; ++i) {
switch (peerstate->state) {
case initial_ack:
assert(0 && "can't reach here");
break;
case wait_for_msg:
if (buf->base[i] == '^') {
peerstate->state = in_msg;
}
break;
case in_msg:
if (buf->base[i] == '$') {
peerstate->state = wait_for_msg;
} else {
assert(peerstate->sendbuf_end < sendbuf_size);
peerstate->sendbuf[peerstate->sendbuf_end++] = buf->base[i] + 1;
}
break;
}
}
if (peerstate->sendbuf_end > 0) {
// we have data to send. the write buffer will point to the buffer stored
// in the peer state for this client.
uv_buf_t writebuf =
uv_buf_init(peerstate->sendbuf, peerstate->sendbuf_end);
uv_write_t* writereq = (uv_write_t*)xmalloc(sizeof(*writereq));
writereq->data = peerstate;
int rc;
if ((rc = uv_write(writereq, (uv_stream_t*)client, &writebuf, 1,
on_wrote_buf)) < 0) {
die("uv_write failed: %s", uv_strerror(rc));
}
}
}
free(buf->base);
}
```
这个服务器的运行时行为非常类似于第三部分的事件驱动服务器:所有的客户端都在一个单个的线程中并发处理。并且类似的,一些特定的行为必须在服务器代码中维护:服务器的逻辑实现为一个集成的回调,并且长周期运行是禁止的,因为它会阻塞事件循环。这一点也很类似。让我们进一步探索这个问题。
### 在事件驱动循环中的长周期运行的操作
单线程的事件驱动代码使它先天就容易受到一些常见问题的影响:长周期运行的代码会阻塞整个循环。参见如下的程序:
```
void on_timer(uv_timer_t* timer) {
uint64_t timestamp = uv_hrtime();
printf("on_timer [%" PRIu64 " ms]\n", (timestamp / 1000000) % 100000);
// "Work"
if (random() % 5 == 0) {
printf("Sleeping...\n");
sleep(3);
}
}
int main(int argc, const char** argv) {
uv_timer_t timer;
uv_timer_init(uv_default_loop(), &timer);
uv_timer_start(&timer, on_timer, 0, 1000);
return uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
```
它用一个单个注册的回调运行一个 libuv 事件循环`on_timer`,它被每秒钟循环调用一次。回调报告一个时间戳,并且,偶尔通过睡眠 3 秒去模拟一个长周期运行。这是运行示例:
```
$ ./uv-timer-sleep-demo
on_timer [4840 ms]
on_timer [5842 ms]
on_timer [6843 ms]
on_timer [7844 ms]
Sleeping...
on_timer [11845 ms]
on_timer [12846 ms]
Sleeping...
on_timer [16847 ms]
on_timer [17849 ms]
on_timer [18850 ms]
...
```
`on_timer` 忠实地每秒执行一次,直到随机出现的睡眠为止。在那个时间点,`on_timer` 不再被调用直到睡眠时间结束事实上_没有其它的回调_  会在这个时间帧中被调用。这个睡眠调用阻塞了当前线程,它正是被调用的线程,并且也是事件循环使用的线程。当这个线程被阻塞后,事件循环也被阻塞。
这个示例演示了在事件驱动的调用中为什么回调不能被阻塞是多少的重要。并且,同样适用于 Node.js 服务器、客户端侧的 Javascript、大多数的 GUI 编程框架、以及许多其它的异步编程模型。
但是,有时候运行耗时的任务是不可避免的。并不是所有任务都有一个异步 API例如我们可能使用一些仅有同步 API 的库去处理,或者,正在执行一个可能的长周期计算。我们如何用事件驱动编程去结合这些代码?线程可以帮到你!
### “转换” 阻塞调用为异步调用的线程
一个线程池可以用于转换阻塞调用为异步调用,通过与事件循环并行运行,并且当任务完成时去由它去公布事件。以阻塞函数 `do_work()` 为例,这里介绍了它是怎么运行的:
1. 不在一个回调中直接调用 `do_work()` ,而是将它打包进一个 “任务”,让线程池去运行这个任务。当任务完成时,我们也为循环去调用它注册一个回调;我们称它为 `on_work_done()`
2. 在这个时间点,我们的回调就可以返回了,而事件循环保持运行;在同一时间点,线程池中的有一个线程运行这个任务。
3. 一旦任务运行完成,通知主线程(指正在运行事件循环的线程),并且事件循环调用 `on_work_done()`
让我们看一下,使用 libuv 的工作调度 API是怎么去解决我们前面的计时器/睡眠示例中展示的问题的:
```
void on_after_work(uv_work_t* req, int status) {
free(req);
}
void on_work(uv_work_t* req) {
// "Work"
if (random() % 5 == 0) {
printf("Sleeping...\n");
sleep(3);
}
}
void on_timer(uv_timer_t* timer) {
uint64_t timestamp = uv_hrtime();
printf("on_timer [%" PRIu64 " ms]\n", (timestamp / 1000000) % 100000);
uv_work_t* work_req = (uv_work_t*)malloc(sizeof(*work_req));
uv_queue_work(uv_default_loop(), work_req, on_work, on_after_work);
}
int main(int argc, const char** argv) {
uv_timer_t timer;
uv_timer_init(uv_default_loop(), &timer);
uv_timer_start(&timer, on_timer, 0, 1000);
return uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
```
通过一个 `work_req` ^注2 类型的句柄,我们进入一个任务队列,代替在 `on_timer` 上直接调用 sleep这个函数在任务中`on_work`)运行,并且,一旦任务完成(`on_after_work`),这个函数被调用一次。`on_work` 是指 “work”阻塞中的/耗时的操作)进行的地方。注意在这两个回调传递到 `uv_queue_work` 时的一个关键区别:`on_work` 运行在线程池中,而 `on_after_work` 运行在事件循环中的主线程上 —— 就好像是其它的回调一样。
让我们看一下这种方式的运行:
```
$ ./uv-timer-work-demo
on_timer [89571 ms]
on_timer [90572 ms]
on_timer [91573 ms]
on_timer [92575 ms]
Sleeping...
on_timer [93576 ms]
on_timer [94577 ms]
Sleeping...
on_timer [95577 ms]
on_timer [96578 ms]
on_timer [97578 ms]
...
```
即便在 sleep 函数被调用时,定时器也每秒钟滴答一下,睡眠现在运行在一个单独的线程中,并且不会阻塞事件循环。
### 一个用于练习的素数测试服务器
因为通过睡眠去模拟工作并不是件让人兴奋的事,我有一个事先准备好的更综合的一个示例 —— 一个基于套接字接受来自客户端的数字的服务器,检查这个数字是否是素数,然后去返回一个 “prime" 或者 “composite”。完整的 [服务器代码在这里][15] —— 我不在这里粘贴了,因为它太长了,更希望读者在一些自己的练习中去体会它。
这个服务器使用了一个原生的素数测试算法,因此,对于大的素数可能花很长时间才返回一个回答。在我的机器中,对于 2305843009213693951它花了 ~5 秒钟去计算,但是,你的方法可能不同。
练习 1服务器有一个设置通过一个名为 `MODE` 的环境变量)要么在套接字回调(意味着在主线程上)中运行素数测试,要么在 libuv 工作队列中。当多个客户端同时连接时,使用这个设置来观察服务器的行为。当它计算一个大的任务时,在阻塞模式中,服务器将不回复其它客户端,而在非阻塞模式中,它会回复。
练习 2libuv 有一个缺省大小的线程池并且线程池的大小可以通过环境变量配置。你可以通过使用多个客户端去实验找出它的缺省值是多少找到线程池缺省值后使用不同的设置去看一下在重负载下怎么去影响服务器的响应能力。
### 在非阻塞文件系统中使用工作队列
对于只是呆板的演示和 CPU 密集型的计算来说将可能的阻塞操作委托给一个线程池并不是明智的libuv 在它的文件系统 API 中本身就大量使用了这种能力。通过这种方式libuv 使用一个异步 API以一个轻便的方式显示出它强大的文件系统的处理能力。
让我们使用 `uv_fs_read()`,例如,这个函数从一个文件中(表示为一个 `uv_fs_t` 句柄)读取一个文件到一个缓冲中 ^注3并且当读取完成后调用一个回调。换句话说`uv_fs_read()` 总是立即返回,即使是文件在一个类似 NFS 的系统上,而数据到达缓冲区可能需要一些时间。换句话说,这个 API 与这种方式中其它的 libuv API 是异步的。这是怎么工作的呢?
在这一点上,我们看一下 libuv 的底层内部实际上非常简单并且它是一个很好的练习。作为一个可移植的库libuv 对于 Windows 和 Unix 系统在它的许多函数上有不同的实现。我们去看一下在 libuv 源树中的 `src/unix/fs.c`
这是 `uv_fs_read` 的代码:
```
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
uv_file file,
const uv_buf_t bufs[],
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
if (bufs == NULL || nbufs == 0)
return -EINVAL;
INIT(READ);
req->file = file;
req->nbufs = nbufs;
req->bufs = req->bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = uv__malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL) {
if (cb != NULL)
uv__req_unregister(loop, req);
return -ENOMEM;
}
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
req->off = off;
POST;
}
```
第一次看可能觉得很困难,因为它延缓真实的工作到 `INIT` 和 `POST` 宏中,以及为 `POST` 设置了一些本地变量。这样做可以避免了文件中的许多重复代码。
这是 `INIT` 宏:
```
#define INIT(subtype) \
do { \
req->type = UV_FS; \
if (cb != NULL) \
uv__req_init(loop, req, UV_FS); \
req->fs_type = UV_FS_ ## subtype; \
req->result = 0; \
req->ptr = NULL; \
req->loop = loop; \
req->path = NULL; \
req->new_path = NULL; \
req->cb = cb; \
} \
while (0)
```
它设置了请求,并且更重要的是,设置 `req->fs_type` 域为真实的 FS 请求类型。因为 `uv_fs_read` 调用 `INIT(READ)`,它意味着 `req->fs_type` 被分配一个常数 `UV_FS_READ`
这是 `POST` 宏:
```
#define POST \
do { \
if (cb != NULL) { \
uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
return 0; \
} \
else { \
uv__fs_work(&req->work_req); \
return req->result; \
} \
} \
while (0)
```
它做什么取决于回调是否为 `NULL`。在 libuv 文件系统 API 中,一个 `NULL` 回调意味着我们真实地希望去执行一个 _同步_ 操作。在这种情况下,`POST` 直接调用 `uv__fs_work`(我们需要了解一下这个函数的功能),而对于一个非 `NULL` 回调,它把 `uv__fs_work` 作为一个工作项提交到工作队列(指的是线程池),然后,注册 `uv__fs_done` 作为回调;该函数执行一些登记并调用用户提供的回调。
如果我们去看 `uv__fs_work` 的代码,我们将看到它使用很多宏按照需求将工作分发到实际的文件系统调用。在我们的案例中,对于 `UV_FS_READ` 这个调用将被 `uv__fs_read` 生成,它(最终)使用普通的 POSIX API 去读取。这个函数可以在一个 _阻塞_ 方式中很安全地实现。因为,它通过异步 API 调用时被置于一个线程池中。
在 Node.js 中,`fs.readFile` 函数是映射到 `uv_fs_read` 上。因此,可以在一个非阻塞模式中读取文件,甚至是当底层文件系统 API 是阻塞方式时。
* * *
- 注1 为确保服务器不泄露内存,我在一个启用泄露检查的 Valgrind 中运行它。因为服务器经常是被设计为永久运行,这是一个挑战;为克服这个问题,我在服务器上添加了一个 “kill 开关” —— 一个从客户端接收的特定序列,以使它可以停止事件循环并退出。这个代码在 `theon_wrote_buf` 句柄中。
- 注2 在这里我们不过多地使用 `work_req`;讨论的素数测试服务器接下来将展示怎么被用于去传递上下文信息到回调中。
- 注3 `uv_fs_read()` 提供了一个类似于 `preadv` Linux 系统调用的通用 API它使用多缓冲区用于排序并且支持一个到文件中的偏移。基于我们讨论的目的可以忽略这些特性。
--------------------------------------------------------------------------------
via: https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/
作者:[Eli Bendersky][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://eli.thegreenplace.net/
[1]:https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/#id1
[2]:https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/#id2
[3]:https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/#id3
[4]:https://eli.thegreenplace.net/tag/concurrency
[5]:https://eli.thegreenplace.net/tag/c-c
[6]:https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/#id4
[7]:https://linux.cn/article-8993-1.html
[8]:https://linux.cn/article-9002-1.html
[9]:https://linux.cn/article-9117-1.html
[10]:http://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/
[11]:https://linux.cn/article-9117-1.html
[12]:http://libuv.org/
[13]:https://github.com/eliben/code-for-blog/blob/master/2017/async-socket-server/uv-server.c
[14]:https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/#id5
[15]:https://github.com/eliben/code-for-blog/blob/master/2017/async-socket-server/uv-isprime-server.c
[16]:https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/#id6
[17]:https://eli.thegreenplace.net/2017/concurrent-servers-part-4-libuv/

View File

@@ -0,0 +1,94 @@
如何在 Linux 中配置 ssh 登录导语
======
> 了解如何在 Linux 中创建登录导语,来向要登录或登录后的用户显示不同的警告或消息。
![Login banners in Linux][1]
无论何时登录公司的某些生产系统,你都会看到一些登录消息、警告或关于你将登录或已登录的服务器的信息,如下所示。这些是<ruby>登录导语<rt>login banner</rt></ruby>。
![Login welcome messages in Linux][2]
在本文中,我们将引导你配置它们。
你可以配置两种类型的导语。
1. 用户登录前显示的导语信息(在你选择的文件中配置,例如 `/etc/login.warn`
2. 用户成功登录后显示的导语信息(在 `/etc/motd` 中配置)
### 如何在用户登录前连接系统时显示消息
当用户连接到服务器并且在登录之前,这个消息将被显示给他。意味着当他输入用户名时,该消息将在密码提示之前显示。
你可以使用任何文件名并在其中输入信息。在这里我们使用 `/etc/login.warn` 并且把我们的消息放在里面。
```
# cat /etc/login.warn
!!!! Welcome to KernelTalks test server !!!!
This server is meant for testing Linux commands and tools. If you are
not associated with kerneltalks.com and not authorized please dis-connect
immediately.
```
现在,需要将此文件和路径告诉 `sshd` 守护进程,以便它可以为每个用户登录请求获取此标语。对于此,打开 `/etc/sshd/sshd_config` 文件并搜索 `#Banner none`
这里你需要编辑该配置文件,并写下你的文件名并删除注释标记(`#`)。它应该看起来像:`Banner /etc/login.warn`
保存文件并重启 `sshd` 守护进程。为避免断开现有的连接用户,请使用 HUP 信号重启 sshd。
```
root@kerneltalks # ps -ef | grep -i sshd
root 14255 1 0 18:42 ? 00:00:00 /usr/sbin/sshd -D
root 19074 14255 0 18:46 ? 00:00:00 sshd: ec2-user [priv]
root 19177 19127 0 18:54 pts/0 00:00:00 grep -i sshd
root@kerneltalks # kill -HUP 14255
```
就是这样了!打开新的会话并尝试登录。你将看待你在上述步骤中配置的消息。
![Login banner in Linux][3]
你可以在用户输入密码登录系统之前看到此消息。
### 如何在用户登录后显示消息
消息用户在成功登录系统后看到的<ruby>当天消息<rt>Message Of The Day</rt></ruby>MOTD`/etc/motd` 控制。编辑这个文件并输入当成功登录后欢迎用户的消息。
```
root@kerneltalks # cat /etc/motd
W E L C O M E
Welcome to the testing environment of kerneltalks.
Feel free to use this system for testing your Linux
skills. In case of any issues reach out to admin at
info@kerneltalks.com. Thank you.
```
你不需要重启 `sshd` 守护进程来使更改生效。只要保存该文件,`sshd` 守护进程就会下一次登录请求时读取和显示。
![motd in linux][4]
你可以在上面的截图中看到:黄色框是由 `/etc/motd` 控制的 MOTD绿色框就是我们之前看到的登录导语。
你可以使用 [cowsay][5]、[banner][6]、[figlet][7]、[lolcat][8] 等工具创建出色的引人注目的登录消息。此方法适用于几乎所有 Linux 发行版,如 RedHat、CentOs、Ubuntu、Fedora 等。
--------------------------------------------------------------------------------
via: https://kerneltalks.com/tips-tricks/how-to-configure-login-banners-in-linux/
作者:[kerneltalks][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://kerneltalks.com
[1]:https://a3.kerneltalks.com/wp-content/uploads/2017/11/login-banner-message-in-linux.png
[2]:https://a3.kerneltalks.com/wp-content/uploads/2017/11/Login-message-in-linux.png
[3]:https://a1.kerneltalks.com/wp-content/uploads/2017/11/login-banner.png
[4]:https://a3.kerneltalks.com/wp-content/uploads/2017/11/motd-message-in-linux.png
[5]:https://kerneltalks.com/tips-tricks/cowsay-fun-in-linux-terminal/
[6]:https://kerneltalks.com/howto/create-nice-text-banner-hpux/
[7]:https://kerneltalks.com/tips-tricks/create-beautiful-ascii-text-banners-linux/
[8]:https://kerneltalks.com/linux/lolcat-tool-to-rainbow-color-linux-terminal/

View File

@@ -0,0 +1,46 @@
如何使用看板kanban创建更好的文档
======
> 通过卡片分类和看板来给用户提供他们想要的信息。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/open%20source_collaboration.png?itok=68kU6BHy)
如果你正在处理文档、网站或其他面向用户的内容,那么了解用户希望找到的内容(包括他们想要的信息以及信息的组织和结构)很有帮助。毕竟,如果人们无法找到他们想要的东西,那么再出色的内容也没有用。
卡片分类是一种简单而有效的方式,可以从用户那里收集有关菜单界面和页面的内容。最简单的实现方式是在计划在网站或文档中的部分分类标注一些索引卡,并要求用户按照查找信息的方式对卡片进行分类。一个变体是让人们编写自己的菜单标题或内容元素。
我们的目标是了解用户的期望以及他们希望在哪里找到它,而不是自己弄清楚菜单和布局。当与用户处于相同的物理位置时,这是相对简单的,但当尝试从多个位置的人员获得反馈时,这会更具挑战性。
我发现[<ruby>看板<rt>kanban</rt></ruby>][1]对于这些情况是一个很好的工具。它允许人们轻松拖动虚拟卡片进行分类和排名,而且与专门卡片分类软件不同,它们是多用途的。
我经常使用 Trello 进行卡片分类,但有几种你可能想尝试的[开源替代品][2]。
### 怎么运行的
我最成功的看板体验是在写 [Gluster][3] 文档的时候 —— 这是一个自由开源的可扩展的网络存储文件系统。我需要携带大量随着时间而增长的文档,并将其分成若干类别以创建导航系统。由于我没有必要的技术知识来分类,我向 Gluster 团队和开发人员社区寻求指导。
首先,我创建了一个共享看板。我列出了一些通用名称,这些名称可以为我计划在文档中涵盖的所有主题排序和创建卡片。我标记了一些不同颜色的卡片,以表明某个主题缺失并需要创建,或者它存在并需要删除。然后,我把所有卡片放入“未排序”一列,并要求人们将它们拖到他们认为这些卡片应该组织到的地方,然后给我一个他们认为是理想状态的截图。
处理所有截图是最棘手的部分。我希望有一个合并或共识功能可以帮助我汇总每个人的数据,而不必检查一堆截图。幸运的是,在第一个人对卡片进行分类之后,人们或多或少地对该结构达成一致,而只做了很小的修改。当对某个主题的位置有不同意见时,我发起一个快速会议,让人们可以解释他们的想法,并且可以排除分歧。
### 使用数据
在这里,很容易将捕捉到的信息转换为菜单并对其进行优化。如果用户认为项目应该成为子菜单,他们通常会在评论中或在电话聊天时告诉我。对菜单组织的看法因人们的工作任务而异,所以从来没有完全达成一致意见,但用户进行测试意味着你不会对人们使用什么以及在哪里查找有很多盲点。
将卡片分类与分析功能配对,可以让你更深入地了解人们在寻找什么。有一次,当我对一些我正在写的培训文档进行分析时,我惊讶地发现搜索量最大的页面是关于资本的。所以我在顶层菜单层面上显示了该页面,即使我的“逻辑”设置将它放在了子菜单中。
我发现看板卡片分类是一种很好的方式,可以帮助我创建用户想要查看的内容,并将其放在希望被找到的位置。你是否发现了另一种对用户友好的组织内容的方法?或者看板的另一种有趣用途是什么?如果有的话,请在评论中分享你的想法。
--------------------------------------------------------------------------------
via: https://opensource.com/article/17/11/kanban-boards-card-sorting
作者:[Heidi Waterhouse][a]
译者:[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/hwaterhouse
[1]:https://en.wikipedia.org/wiki/Kanban
[2]:https://opensource.com/alternatives/trello
[3]:https://www.gluster.org/

View File

@@ -0,0 +1,78 @@
使用 Showterm 录制和分享终端会话
======
![](https://www.maketecheasier.com/assets/uploads/2017/11/record-terminal-session.jpg)
你可以使用几乎所有的屏幕录制程序轻松录制终端会话。但是你很可能会得到超大的视频文件。Linux 中有几种终端录制程序每种录制程序都有自己的优点和缺点。Showterm 是一个可以非常容易地记录终端会话、上传、分享,并将它们嵌入到任何网页中的工具。一个优点是,你不会有巨大的文件来处理。
Showterm 是开源的,该项目可以在这个 [GitHub 页面][1]上找到。
**相关**[2 个简单的将你的终端会话录制为视频的 Linux 程序][2]
### 在 Linux 中安装 Showterm
Showterm 要求你在计算机上安装了 Ruby。以下是如何安装该程序。
```
gem install showterm
```
如果你没有在 Linux 上安装 Ruby可以这样
```
sudo curl showterm.io/showterm > ~/bin/showterm
sudo chmod +x ~/bin/showterm
```
如果你只是想运行程序而不是安装:
```
bash <(curl record.showterm.io)
```
你可以在终端输入 `showterm --help` 得到帮助页面。如果没有出现帮助页面,那么可能是未安装 `showterm`。现在你已安装了 Showterm或正在运行独立版本让我们开始使用该工具进行录制。
**相关**[如何在 Ubuntu 中录制终端会话][3]
### 录制终端会话
![showterm terminal][4]
录制终端会话非常简单。从命令行运行 `showterm`。这会在后台启动终端录制。所有从命令行输入的命令都由 Showterm 记录。完成录制后,请按 `Ctrl + D` 或在命令行中输入`exit` 停止录制。
Showterm 会上传你的视频并输出一个看起来像 `http://showterm.io/<一长串字符>` 的链接的视频。不幸的是,终端会话会立即上传,而没有任何提示。请不要惊慌!你可以通过输入 `showterm --delete <recording URL>` 删除任何已上传的视频。在上传视频之前,你可以通过在 `showterm` 命令中添加 `-e` 选项来改变计时。如果视频无法上传,你可以使用 `showterm --retry <script> <times>` 强制重试。
在查看录制内容时,还可以通过在 URL 中添加 `#slow``#fast``#stop` 来控制视频的计时。`#slow` 让视频以正常速度播放、`#fast` 是速度加倍、`#stop`,如名称所示,停止播放视频。
Showterm 终端录制视频可以通过 iframe 轻松嵌入到网页中。这可以通过将 iframe 源添加到 showterm 视频地址来实现,如下所示。
![showtermio][5]
作为开源工具Showterm 允许进一步定制。例如,要运行你自己的 Showterm 服务器,你需要运行以下命令:
```
export SHOWTERM_SERVER=https://showterm.myorg.local/
```
这样你的客户端可以和它通信。还有额外的功能只需很少的编程知识就可添加。Showterm 服务器项目可在此 [GitHub 页面][1]获得。
### 结论
如果你想与同事分享一些命令行教程,请务必记得 Showterm。Showterm 是基于文本的。因此,与其他屏幕录制机相比,它将产生相对较小的视频。该工具本身尺寸相当小 —— 只有几千字节。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/record-terminal-session-showterm/
作者:[Bruno Edoh][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.maketecheasier.com/author/brunoedoh/
[1]:https://github.com/ConradIrwin/showterm
[2]:https://www.maketecheasier.com/record-terminal-session-as-video/ (2 Simple Applications That Record Your Terminal Session as Video [Linux])
[3]:https://www.maketecheasier.com/record-terminal-session-in-ubuntu/ (How to Record Terminal Session in Ubuntu)
[4]:https://www.maketecheasier.com/assets/uploads/2017/11/showterm-interface.png (showterm terminal)
[5]:https://www.maketecheasier.com/assets/uploads/2017/11/showterm-site.png (showtermio)

View File

@@ -0,0 +1,212 @@
命令行乐趣:嘲讽输错 Bash 命令的用户
======
你可以通过配置 `sudo` 命令去嘲讽输入错误密码的用户。但是现在,当用户在 shell 输错命令时,就能嘲讽他了(滥用?)。
### 你好 bash-insulter
来自 Github 页面:
> 当用户键入错误命令,随机嘲讽。它使用了一个 bash4.x. 版本的全新内置错误处理函数,叫 `command_not_found_handle`。
### 安装
键入下列 git 命令克隆一个仓库:
```
git clone https://github.com/hkbakke/bash-insulter.git bash-insulter
```
示例输出:
```
Cloning into 'bash-insulter'...
remote: Counting objects: 52, done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 52 (delta 12), reused 12 (delta 2), pack-reused 0
Unpacking objects: 100% (52/52), done.
```
用文本编辑器,比如说使用 `vi`,编辑你的 `~/.bashrc` 或者 `/etc/bash.bashrc` 文件:
```
$ vi ~/.bashrc
```
在其后追加这一行(具体了解请查看 [if..else..fi 声明][1] 和 [source 命令][2]
```
if [ -f $HOME/bash-insulter/src/bash.command-not-found ]; then
source $HOME/bash-insulter/src/bash.command-not-found
fi
```
保存并关闭文件。重新登录,如果不想退出账号也可以手动运行它:
```
$ . $HOME/bash-insulter/src/bash.command-not-found
```
### 如何使用它?
尝试键入一些无效命令:
```
$ ifconfigs
$ dates
```
示例输出:
[![一个有趣的 bash 钩子功能,嘲讽输入了错误命令的你。][3]][3]
### 自定义
你需要编辑 `$HOME/bash-insulter/src/bash.command-not-found`
```
$ vi $HOME/bash-insulter/src/bash.command-not-found
```
示例代码:
```
command_not_found_handle () {
local INSULTS=(
"Boooo!"
"Don't you know anything?"
"RTFM!"
"Hahaha, n00b!"
"Wow! That was impressively wrong!"
"What are you doing??"
"Pathetic"
"...and this is the best you can do??"
"The worst one today!"
"n00b alert!"
"Your application for reduced salary has been sent!"
"lol"
"u suk"
"lol... plz"
"plz uninstall"
"And the Darwin Award goes to.... ${USER}!"
"ERROR_INCOMPETENT_USER"
"Incompetence is also competence"
"Bad."
"Fake it till you make it!"
"What is this...? Amateur hour!?"
"Come on! You can do it!"
"Nice try."
"What if... you type an actual command the next time!"
"What if I told you... it is possible to type valid commands."
"Y u no speak computer???"
"This is not Windows"
"Perhaps you should leave the command line alone..."
"Please step away from the keyboard!"
"error code: 1D10T"
"ACHTUNG! ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS! DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN. IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS. ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN."
"Pro tip: type a valid command!"
)
# 设置“随机”种子发生器
RANDOM=$(date +%s%N)
VALUE=$((${RANDOM}%2))
if [[ ${VALUE} -lt 1 ]]; then
printf "\n $(tput bold)$(tput setaf 1)$(shuf -n 1 -e "${INSULTS[@]}")$(tput sgr0)\n\n"
fi
echo "-bash: $1: command not found"
# 无效命令,常规返回已存在的代码
return 127
}
```
### 赠品sudo 嘲讽
编辑 `sudoers` 文件:
```
$ sudo visudo
```
追加下面这一行:
```
Defaults insults
```
或者像下面尾行增加一句嘲讽语:
```
Defaults !lecture,tty_tickets,!fqdn,insults
```
这是我的文件:
```
Defaults env_reset
Defaults mail_badpass
Defaults secure_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
## If set, sudo will insult users when they enter an incorrect password. ##
Defaults insults
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL = (ALL:ALL) ALL
# Members of the admin group may gain root privileges
% admin ALL = (ALL) ALL  
# Allow members of group sudo to execute any command
% sudo ALL = (ALL:ALL) ALL  
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
```
试一试:
```
$ sudo -k # 清除缓存,从头开始
$ sudo ls /root/
$ sudo -i
```
样例对话:
[![当输入错误密码时,你会被一个有趣的的 sudo 嘲讽语戏弄。][4]][4]
### 赠品:你好 sl
[sl 或是 UNIX 经典捣蛋软件][5] 游戏。当你错误的把 `ls` 输入成 `sl`,将会有一辆蒸汽机车穿过你的屏幕。
```
$ sl
```
[![Linux / UNIX 桌面乐趣: 蒸汽机车][6]][5]
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/howto/insult-linux-unix-bash-user-when-typing-wrong-command/
作者:[Vivek Gite][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://bash.cyberciti.biz/guide/If..else..fi
[2]:https://bash.cyberciti.biz/guide/Source_command
[3]:https://www.cyberciti.biz/media/new/cms/2017/11/bash-insulter-Insults-the-user-when-typing-wrong-command.jpg
[4]:https://www.cyberciti.biz/media/new/cms/2017/11/sudo-insults.jpg
[5]:https://www.cyberciti.biz/tips/displays-animations-when-accidentally-you-type-sl-instead-of-ls.html
[6]:https://www.cyberciti.biz/media/new/tips/2011/05/sl_command_steam_locomotive.png

View File

@@ -0,0 +1,160 @@
使用 pass 密码管理器管理你的密码
======
### 目标
学习在 Linux 上使用 pass 密码管理器来管理你的密码
### 条件
* 需要 root 权限来安装需要的包
### 难度
简单
### 约定
* `#` - 执行指定命令需要 root 权限,可以是直接使用 root 用户来执行或者使用 `sudo` 命令来执行
* `$` - 使用普通的非特权用户执行指定命令
### 介绍
如果你有根据不同的意图设置不同密码的好习惯,你可能已经感受到需要一个密码管理器的必要性了。在 Linux 上有很多选择,可以是专有软件(如果你敢用的话)也可以是开源软件。如果你跟我一样喜欢简洁的话,你可能会对 `pass` 感兴趣。
### 第一步
pass 作为一个密码管理器,其实际上是一些你可能早已每天使用的、可信赖且实用的工具的一种封装,比如 `gpg``git` 。虽然它也有图形界面,但它专门设计能成在命令行下工作的:因此它也可以在 headless 机器上工作LCTT 译注:根据 wikipedia 的说法,所谓 headless 是指没有显示器、键盘和鼠标的机器,一般通过网络链接来控制)。
### 安装
pass 在主流的 Linux 发行版中都是可用的,你可以通过包管理器安装:
#### Fedora
```
# dnf install pass
```
#### RHEL 和 CentOS
pass 不在官方仓库中,但你可以从 `epel` 中获取道它。要在 CentOS7 上启用后面这个源,只需要执行:
```
# yum install epel-release
```
然而在 Red Hat 企业版的 Linux 上,这个额外的源是不可用的;你需要从 EPEL 官方网站上下载它。
#### Debian 和 Ubuntu
```
# apt-get install pass
```
#### Arch Linux
```
# pacman -S pass
```
### 初始化密码仓库
安装好 `pass` 后,就可以开始使用和配置它了。首先,由于 `pass` 依赖于 `gpg` 来对我们的密码进行加密并以安全的方式进行存储,我们必须准备好一个 gpg 密钥对。
首先我们要初始化密码仓库:这就是一个用来存放 gpg 加密后的密码的目录。默认情况下它会在你的 `$HOME` 创建一个隐藏目录,不过你也可以通过使用 `PASSWORD_STORE_DIR` 这一环境变量来指定另一个路径。让我们运行:
```
$ pass init
```
然后 `password-store` 目录就创建好了。现在,让我们来存储我们第一个密码:
```
$ pass edit mysite
```
这会打开默认文本编辑器,我么只需要输入密码就可以了。输入的内容会用 gpg 加密并存储为密码仓库目录中的 `mysite.gpg` 文件。
`pass` 以目录树的形式存储加密后的文件,也就是说我们可以在逻辑上将多个文件放在子目录中以实现更好的组织形式,我们只需要在创建文件时指定存在哪个目录下就行了,像这样:
```
$ pass edit foo/bar
```
跟上面的命令一样,它也会让你输入密码,但是创建的文件是放在密码仓库目录下的 `foo` 子目录中的。要查看文件组织结构,只需要不带任何参数运行 `pass` 命令即可:
```
$ pass
Password Store
├── foo
│   └── bar
└── mysite
```
若想修改密码,只需要重复创建密码的操作就行了。
### 获取密码
有两种方法可以获取密码:第一种会显示密码到终端上,方法是运行:
```
pass mysite
```
然而更好的方法是使用 `-c` 选项让 `pass` 将密码直接拷贝到剪切板上:
```
pass -c mysite
```
这种情况下剪切板中的内容会在 `45` 秒后自动清除。两种方法都会要求你输入 gpg 密码。
### 生成密码
`pass` 也可以为我们自动生成(并自动存储)安全密码。假设我们想要生成一个由 15 个字符组成的密码:包含字母,数字和特殊符号,其命令如下:
```
pass generate mysite 15
```
若希望密码只包含字母和数字则可以是使用 `--no-symbols` 选项。生成的密码会显示在屏幕上。也可以通过 `--clip``-c` 选项让 `pass` 把密码直接拷贝到剪切板中。通过使用 `-q``--qrcode` 选项来生成二维码:
![qrcode][1]
从上面的截屏中可看出,生成了一个二维码,不过由于运行该命令时 `mysite` 的密码已经存在了,`pass` 会提示我们确认是否要覆盖原密码。
`pass` 使用 `/dev/urandom` 设备作为(伪)随机数据生成器来生成密码,同时它使用 `xclip` 工具来将密码拷贝到粘帖板中,而使用 `qrencode` 来将密码以二维码的形式显示出来。在我看来,这种模块化的设计正是它最大的优势:它并不重复造轮子,而只是将常用的工具包装起来完成任务。
你也可以使用 `pass mv``pass cp``pass rm` 来重命名、拷贝和删除密码仓库中的文件。
### 将密码仓库变成 git 仓库
`pass` 另一个很棒的功能就是可以将密码仓库当成 git 仓库来用:通过版本管理系统能让我们管理密码更方便。
```
pass git init
```
这会创建 git 仓库,并自动提交所有已存在的文件。下一步就是指定跟踪的远程仓库了:
```
pass git remote add <name> <url>
```
我们可以把这个密码仓库当成普通仓库来用。唯一的不同点在于每次我们新增或修改一个密码,`pass` 都会自动将该文件加入索引并创建一个提交。
`pass` 有一个叫做 `qtpass` 的图形界面,而且也支持 Windows 和 MacOs。通过使用 `PassFF` 插件,它还能获取 firefox 中存储的密码。在它的项目网站上可以查看更多详细信息。试一下 `pass` 吧,你不会失望的!
--------------------------------------------------------------------------------
via: https://linuxconfig.org/how-to-organize-your-passwords-using-pass-password-manager
作者:[Egidio Docile][a]
译者:[lujun9972](https://github.com/lujun9972)
校对:[Locez](https://github.com/locez)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://linuxconfig.org
[1]:https://linuxconfig.org/images/pass-manager-qrcode.png

View File

@@ -0,0 +1,85 @@
Torrents种子你需要知道的一切事情
======
![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrenting-how-torrent-works_orig.jpg)
**Torrents种子** — 每次听到这个词时,在我的脑海里想到的唯一的事情就是免费的电影、游戏、和被破解的软件。但是我们并不知道它们是如何工作的,在“种子”中涉及到各种概念。因此,通过这篇文章我们从技术的角度来了解**种子下载**是什么。
### “种子”是什么?
“种子”是一个到因特网上文件位置的链接。它们不是一个文件,它们仅仅是动态指向到你想去下载的原始文件上。
例如:如果你点击 [Google Chrome][1],你可以从谷歌的服务器上下载 Google Chrome 浏览器。
如果你明天、或者下周、或者下个月再去点击那个链接,这个文件仍然可以从谷歌服务器上去下载。
但是当我们使用“种子”下载时,它并没有固定的服务器。文件是从以前使用“种子”下载的其它人的个人电脑上下载的。
### Torrents 是如何工作的?
[![Peer to peer network](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrent_orig.png)][2]
假设 A 上有一些视频,它希望以“种子”方式去下载。因此,他创建了一个“种子”,并将这个链接发送给 B这个链接包含了那个视频在因特网上的准确 IP 地址的信息。因此,当 B 开始下载那个文件的时候B 连接到 A 的计算机。在 B 下载完成这个视频之后B 将开始做为种子,也就是 B 将允许其它的 C 或者 DB 的计算机上下载它。
因此每个人先下载文件然后会上传,下载的人越多,下载的速度也越快。并且在任何情况下,如果想停止上传,也没有问题,随时可以。这样做并不会成为什么问题,除非很多的人下载而上传的人很少。
### 播种者和索取者
[![kickass torrents website](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/seeders_orig.png)][3]
下载完成特定文件的用户将会即刻做为上传者,因此,可以被新用户下载的已下载者称为播种者。
而一些还没有完成特定文件的下载者,并且还正在下载的用户称为索取者。
### 块
[![qbittorrent software for linux](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/peers_orig.png)][4]
所有的“种子”文件都独立分割成固定大小的数据包,因此,它们可以非线性顺序和随机顺序下载。每个块都有唯一的标识,因此,一旦所有的块下载完成之后,它们会被拼接出原始文件。
正是因为这种机制,如果你正在从某人处下载一个文件,假如这个时候因某些原因他停止了上传,你可以继续从其它的播种者处继续下载,而不需要从头开始重新下载。
### 对端
对端是指当前连接到你的索取者。一个正在上传的索取者,不论它下载了多少块,它就是一个对端。
**例如:**
一个已经下载了文件的前 50 个块的用户就是一个索取者,但是,他又同时上传这些文件,而你只有前 10 个块,因此,你可以从他那里下载最多 50 个块。这时候他就成了你的对端。
### 最佳实践
当你下载一个“种子”时,总是选择最大的播种者。这就是最佳经验。
这里并没有最小的标准,但是只要确保你选择的是最大的那一个播种者就可以了。
### “种子”相关的法律
[![piracy is illegal](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrent-laws_orig.png)][5]
“种子”相关的法律和其它的法律并没有什么区别,对受版权保护的其它任何东西一样,侵权行为会受到法律的制裁。大多数的政府都拦截“种子”站点和协议,但是“种子”下载本身并不是有害的东西。
“种子”对快速分享文件是非常有用的,并且它们被用来共享开源社区的软件,因为它们能节约大量的服务器资源。但是,许多人却因为盗版而使用它们。
### 结束语
Torrenting 是降低服务器上负载的一个非常完美的技术。“种子”下载可以使我们将下载速度提升到网卡的极限,这是非常好的。但是,在这种非中心化的服务器上,盗版成为一种必然发生的事。限制我们分享的内容,从不去下载盗版的东西,这是我们的道德责任。
请在下面的评论中分享你使用“种子”的心得,分享你喜欢的、法律许可下载的“种子”网站。
--------------------------------------------------------------------------------
via: http://www.linuxandubuntu.com/home/torrents-everything-you-need-to-know
作者:[LINUXANDUBUNTU][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxandubuntu.com
[1]:https://www.google.com/chrome/
[2]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrent_orig.png
[3]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/seeders_orig.png
[4]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/peers_orig.png
[5]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/torrent-laws_orig.png

View File

@@ -0,0 +1,46 @@
下一次技术面试时要问的 3 个重要问题
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/os-jobs_0.jpg?itok=nDf5j7xC)
> 面试可能会有压力,但 58 的公司告诉 Dice 和 Linux 基金会,他们需要在未来几个月内聘请开源人才。学习如何提出正确的问题。
Dice 和 Linux 基金会的年度[开源工作报告][1]揭示了开源专业人士的前景以及未来一年的招聘活动。在今年的报告中86 的科技专业人士表示,了解开源推动了他们的职业生涯。然而,当在他们自己的组织内推进或在别处申请新职位的时候,有这些经历会发生什么呢?
面试新工作绝非易事。除了在准备新职位时还要应付复杂的工作,当面试官问“你有什么问题要问吗?”时,适当的回答更增添了压力。
在 Dice我们从事职业、建议并将技术专家与雇主连接起来。但是我们也在公司里雇佣技术人才来开发开源项目。实际上Dice 平台基于许多 Linux 发行版,我们利用开源数据库作为我们搜索功能的基础。总之,如果没有开源软件,我们就无法运行 Dice因此聘请了解和热爱开源软件的专业人士至关重要。
多年来,我在面试中了解到提出好问题的重要性。这是一个了解你的潜在新雇主的机会,以及更好地了解他们是否与你的技能相匹配。
这里有三个要问的重要问题,以及其重要的原因:
### 1、 公司对员工在空闲时间致力于开源项目或编写代码的立场是什么?
这个问题的答案会告诉正在面试的公司的很多信息。一般来说,只要它与你在该公司所从事的工作没有冲突,公司会希望技术专家为网站或项目做出贡献。在公司之外允许这种情况,也会在技术组织中培养出一种创业精神,并教授技术技能,否则在正常的日常工作中你可能无法获得这些技能。
### 2、 项目如何区分优先级?
由于所有的公司都成为了科技公司,所以在创新的客户面对技术项目与改进平台本身之间往往存在着分歧。你会努力保持现有的平台最新么?或者致力于公众开发新产品?根据你的兴趣,答案可以决定公司是否适合你。
### 3、 谁主要决定新产品,开发者在决策过程中有多少投入?
这个问题是了解谁负责公司创新(以及与他/她有多少联系),还有一个是了解你在公司的职业道路。在开发新产品之前,一个好的公司会和开发人员和开源人才交流。这看起来不用多想,但有时会错过这步,意味着在新产品发布之前协作环境的不同或者混乱的过程。
面试可能会有压力,但是 58 的公司告诉 Dice 和 Linux 基金会他们需要在未来几个月内聘用开源人才,所以记住高需求会让像你这样的专业人士成为雇员。以你想要的方向引导你的事业。
现在[下载][2]完整的 2017 年开源工作报告。
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/os-jobs/2017/12/3-essential-questions-ask-your-next-tech-interview
作者:[Brian Hostetter][a]
译者:[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/brianhostetter
[1]:https://www.linuxfoundation.org/blog/2017-jobs-report-highlights-demand-open-source-skills/
[2]:http://bit.ly/2017OSSjobsreport

View File

@@ -0,0 +1,109 @@
并发服务器Redis 案例研究
======
这是我写的并发网络服务器系列文章的第五部分。在前四部分中我们讨论了并发服务器的结构,这篇文章我们将去研究一个在生产系统中大量使用的服务器的案例—— [Redis][10]。
![Redis logo](https://eli.thegreenplace.net/images/2017/redis_logo.png)
Redis 是一个非常有魅力的项目,我关注它很久了。它最让我着迷的一点就是它的 C 源代码非常清晰。它也是一个高性能、大并发的内存数据库服务器的非常好的例子,它是研究网络并发服务器的一个非常好的案例,因此,我们不能错过这个好机会。
我们来看看前四部分讨论的概念在真实世界中的应用程序。
本系列的所有文章有:
* [第一节 - 简介][3]
* [第二节 - 线程][4]
* [第三节 - 事件驱动][5]
* [第四节 - libuv][6]
* [第五节 - Redis 案例研究][7]
### 事件处理库
Redis 最初发布于 2009 年,它最牛逼的一件事情大概就是它的速度 —— 它能够处理大量的并发客户端连接。需要特别指出的是,它是用*一个单线程*来完成的,而且还不对保存在内存中的数据使用任何复杂的锁或者同步机制。
Redis 之所以如此牛逼是因为,它在给定的系统上使用了其可用的最快的事件循环,并将它们封装成由它实现的事件循环库(在 Linux 上是 epoll在 BSD 上是 kqueue等等。这个库的名字叫做 [ae][11]。ae 使得编写一个快速服务器变得很容易,只要在它内部没有阻塞即可,而 Redis 则保证 ^注1 了这一点。
在这里,我们的兴趣点主要是它对*文件事件*的支持 —— 当文件描述符(如网络套接字)有一些有趣的未决事情时将调用注册的回调函数。与 libuv 类似ae 支持多路事件循环(参阅本系列的[第三节][5]和[第四节][6])和不应该感到意外的 `aeCreateFileEvent` 信号:
```
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
aeFileProc *proc, void *clientData);
```
它在 `fd` 上使用一个给定的事件循环,为新的文件事件注册一个回调(`proc`)函数。当使用的是 epoll 时,它将调用 `epoll_ctl` 在文件描述符上添加一个事件(可能是 `EPOLLIN``EPOLLOUT`、也或许两者都有,取决于 `mask` 参数。ae 的 `aeProcessEvents` 功能是 “运行事件循环和发送回调函数”,它在底层调用了 `epoll_wait`
### 处理客户端请求
我们通过跟踪 Redis 服务器代码来看一下ae 如何为客户端事件注册回调函数的。`initServer` 启动时,通过注册一个回调函数来读取正在监听的套接字上的事件,通过使用回调函数 `acceptTcpHandler` 来调用 `aeCreateFileEvent`。当新的连接可用时,这个回调函数被调用。它调用 `accept` ^注2 ,接下来是 `acceptCommonHandler`,它转而去调用 `createClient` 以初始化新客户端连接所需要的数据结构。
`createClient` 的工作是去监听来自客户端的入站数据。它将套接字设置为非阻塞模式(一个异步事件循环中的关键因素)并使用 `aeCreateFileEvent` 去注册另外一个文件事件回调函数以读取事件 —— `readQueryFromClient`。每当客户端发送数据,这个函数将被事件循环调用。
`readQueryFromClient` 就让我们期望的那样 —— 解析客户端命令和动作,并通过查询和/或操作数据来回复。因为客户端套接字是非阻塞的,所以这个函数必须能够处理 `EAGAIN`,以及部分数据;从客户端中读取的数据是累积在客户端专用的缓冲区中,而完整的查询可能被分割在回调函数的多个调用当中。
### 将数据发送回客户端
在前面的内容中,我说到了 `readQueryFromClient` 结束了发送给客户端的回复。这在逻辑上是正确的,因为 `readQueryFromClient` *准备*要发送回复,但它不真正去做实质的发送 —— 因为这里并不能保证客户端套接字已经准备好写入/发送数据。我们必须为此使用事件循环机制。
Redis 是这样做的,它注册一个 `beforeSleep` 函数,每次事件循环即将进入休眠时,调用它去等待套接字变得可以读取/写入。`beforeSleep` 做的其中一件事情就是调用 `handleClientsWithPendingWrites`。它的作用是通过调用 `writeToClient` 去尝试立即发送所有可用的回复;如果一些套接字不可用时,那么*当*套接字可用时,它将注册一个事件循环去调用 `sendReplyToClient`。这可以被看作为一种优化 —— 如果套接字可用于立即发送数据(一般是 TCP 套接字),这时并不需要注册事件 ——直接发送数据。因为套接字是非阻塞的,它从不会去阻塞循环。
### 为什么 Redis 要实现它自己的事件库?
在 [第四节][14] 中我们讨论了使用 libuv 来构建一个异步并发服务器。需要注意的是Redis 并没有使用 libuv或者任何类似的事件库而是它去实现自己的事件库 —— ae用 ae 来封装 epoll、kqueue 和 select。事实上AntirezRedis 的创建者)恰好在 [2011 年的一篇文章][15] 中回答了这个问题。他的回答的要点是ae 只有大约 770 行他理解的非常透彻的代码;而 libuv 代码量非常巨大,也没有提供 Redis 所需的额外功能。
现在ae 的代码大约增长到 1300 多行,比起 libuv 的 26000 行(这是在没有 Windows、测试、示例、文档的情况下的数据来说那是小巫见大巫了。libuv 是一个非常综合的库这使它更复杂并且很难去适应其它项目的特殊需求另一方面ae 是专门为 Redis 设计的,与 Redis 共同演进,只包含 Redis 所需要的东西。
这是我 [前些年在一篇文章中][16] 提到的软件项目依赖关系的另一个很好的示例:
> 依赖的优势与在软件项目上花费的工作量成反比。
在某种程度上Antirez 在他的文章中也提到了这一点。他提到,提供大量附加价值(在我的文章中的“基础” 依赖)的依赖比像 libuv 这样的依赖更有意义(它的例子是 jemalloc 和 Lua对于 Redis 特定需求,其功能的实现相当容易。
### Redis 中的多线程
[在 Redis 的绝大多数历史中][17]它都是一个不折不扣的单线程的东西。一些人觉得这太不可思议了有这种想法完全可以理解。Redis 本质上是受网络束缚的 —— 只要数据库大小合理,对于任何给定的客户端请求,其大部分延时都是浪费在网络等待上,而不是在 Redis 的数据结构上。
然而现在事情已经不再那么简单了。Redis 现在有几个新功能都用到了线程:
1. “惰性” [内存释放][8]。
2. 在后台线程中使用 fsync 调用写一个 [持久化日志][9]。
3. 运行需要执行一个长周期运行的操作的用户定义模块。
对于前两个特性Redis 使用它自己的一个简单的 bio它是 “Background I/O" 的首字母缩写)库。这个库是根据 Redis 的需要进行了硬编码,它不能用到其它的地方 —— 它运行预设数量的线程,每个 Redis 后台作业类型需要一个线程。
而对于第三个特性,[Redis 模块][18] 可以定义新的 Redis 命令,并且遵循与普通 Redis 命令相同的标准,包括不阻塞主线程。如果在模块中自定义的一个 Redis 命令,希望去执行一个长周期运行的操作,这将创建一个线程在后台去运行它。在 Redis 源码树中的 `src/modules/helloblock.c` 提供了这样的一个示例。
有了这些特性Redis 使用线程将一个事件循环结合起来在一般的案例中Redis 具有了更快的速度和弹性,这有点类似于在本系统文章中 [第四节][19] 讨论的工作队列。
- 注1 Redis 的一个核心部分是:它是一个 _内存中_ 数据库;因此,查询从不会运行太长的时间。当然了,这将会带来各种各样的其它问题。在使用分区的情况下,服务器可能最终路由一个请求到另一个实例上;在这种情况下,将使用异步 I/O 来避免阻塞其它客户端。
- 注2 使用 `anetAccept``anet` 是 Redis 对 TCP 套接字代码的封装。
--------------------------------------------------------------------------------
via: https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/
作者:[Eli Bendersky][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://eli.thegreenplace.net/pages/about
[1]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id1
[2]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id2
[3]:https://linux.cn/article-8993-1.html
[4]:https://linux.cn/article-9002-1.html
[5]:https://linux.cn/article-9117-1.html
[6]:https://linux.cn/article-9397-1.html
[7]:http://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/
[8]:http://antirez.com/news/93
[9]:https://redis.io/topics/persistence
[10]:https://redis.io/
[11]:https://redis.io/topics/internals-rediseventlib
[12]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id4
[13]:https://eli.thegreenplace.net/2017/concurrent-servers-part-5-redis-case-study/#id5
[14]:https://linux.cn/article-9397-1.html
[15]:http://oldblog.antirez.com/post/redis-win32-msft-patch.html
[16]:http://eli.thegreenplace.net/2017/benefits-of-dependencies-in-software-projects-as-a-function-of-effort/
[17]:http://antirez.com/news/93
[18]:https://redis.io/topics/modules-intro
[19]:https://linux.cn/article-9397-1.html

View File

@@ -0,0 +1,198 @@
使用 pelican 和 Github pages 来搭建博客
===============================
今天我将谈一下[我这个博客][a]是如何搭建的。在我们开始之前,我希望你熟悉使用 Github 并且可以搭建一个 Python 虚拟环境来进行开发。如果你不能做到这些,我推荐你去学习一下 [Django Girls 教程][2],它包含以上和更多的内容。
这是一篇帮助你发布由 Github 托管的个人博客的教程。为此,你需要一个正常的 Github 用户账户 (而不是一个工程账户)。
你要做的第一件事是创建一个放置代码的 Github 仓库。如果你想要你的博客仅仅指向你的用户名 (比如 rsip22.github.io) 而不是一个子文件夹 (比如 rsip22.github.io/blog),你必须创建一个带有全名的仓库。
![][3]
*Github 截图,打开了创建新仓库的菜单,正在以 'rsip22.github.io' 名字创建一个新的仓库*
我推荐你使用 `README`、用于 Python 的 `.gitignore` 和 [一个自由软件许可证][4] 初始化你的仓库。如果你使用自由软件许可证,你仍然拥有这些代码,但是你使得其他人能从中受益,允许他们学习和复用它,并且更重要的是允许他们享有这些代码。
既然仓库已经创建好了,那我们就克隆到本机中将用来保存代码的文件夹下:
```
$ git clone https://github.com/YOUR_USERNAME/YOUR_USERNAME.github.io.git
```
并且切换到新的目录:
```
$ cd YOUR_USERNAME.github.io
```
因为 Github Pages 偏好运行的方式是从 master 分支提供文件,你必须将你的源代码放到新的分支,防止 Pelican 产生的静态文件输出到 master 分支。为此,你必须创建一个名为 source 的分支。
```
$ git checkout -b source
```
用你的系统所安装的 Pyhton 3 创建该虚拟环境virtualenv
在 GNU/Linux 系统中,命令可能如下:
```
$ python3 -m venv venv
```
或者像这样:
```
$ virtualenv --python=python3.5 venv
```
并且激活它:
```
$ source venv/bin/activate
```
在虚拟环境里,你需要安装 pelican 和它的依赖包。你也应该安装 ghp-import (来帮助我们发布到 Github 上)和 Markdown (为了使用 markdown 语法来写文章)。运行如下命令:
```
(venv)$ pip install pelican markdown ghp-import
```
一旦完成,你就可以使用 `pelican-quickstart` 开始创建你的博客了:
```
(venv)$ pelican-quickstart
```
这将会提示我们一系列的问题。在回答它们之前,请看一下如下我的答案:
```
> Where do you want to create your new web site? [.] ./
> What will be the title of this web site? Renata's blog
> Who will be the author of this web site? Renata
> What will be the default language of this web site? [pt] en
> Do you want to specify a URL prefix? e.g., http://example.com (Y/n) n
> Do you want to enable article pagination? (Y/n) y
> How many articles per page do you want? [10] 10
> What is your time zone? [Europe/Paris] America/Sao_Paulo
> Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) Y **# PAY ATTENTION TO THIS!**
> Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) n
> Do you want to upload your website using FTP? (y/N) n
> Do you want to upload your website using SSH? (y/N) n
> Do you want to upload your website using Dropbox? (y/N) n
> Do you want to upload your website using S3? (y/N) n
> Do you want to upload your website using Rackspace Cloud Files? (y/N) n
> Do you want to upload your website using GitHub Pages? (y/N) y
> Is this your personal page (username.github.io)? (y/N) y
Done. Your new project is available at /home/username/YOUR_USERNAME.github.io
```
关于时区,应该指定为 TZ 时区(这里是全部列表: [tz 数据库时区列表][5])。
现在,继续往下走并开始创建你的第一篇博文!你可能想在你喜爱的代码编辑器里打开工程目录并且找到里面的 `content` 文件夹。然后创建一个新文件,它可以被命名为 `my-first-post.md` (别担心,这只是为了测试,以后你可以改变它)。在文章内容之前,应该以元数据开始,这些元数据标识标题、日期、目录及更多,像下面这样:
```
.lang="markdown" # DON'T COPY this line, it exists just for highlighting purposes
Title: My first post
Date: 2017-11-26 10:01
Modified: 2017-11-27 12:30
Category: misc
Tags: first, misc
Slug: My-first-post
Authors: Your name
Summary: What does your post talk about? Write here.
This is the *first post* from my Pelican blog. **YAY!**
```
让我们看看它长什么样?
进入终端,产生静态文件并且启动服务器。要这么做,使用下面命令:
```
(venv)$ make html && make serve
```
当这条命令正在运行,你应该可以在你喜爱的 web 浏览器地址栏中键入 `localhost:8000` 来访问它。
![][6]
*博客主页的截图。它有一个带有 Renata's blog 标题的头部,第一篇博文在左边,文章的信息在右边,链接和社交在底部*
相当简洁,对吧?
现在,如果你想在文章中放一张图片,该怎么做呢?好,首先你在放置文章的内容目录里创建一个目录。为了引用简单,我们将这个目录命名为 `image`。现在你必须让 Pelican 使用它。找到 `pelicanconf.py` 文件,这个文件是你配置系统的地方,并且添加一个包含你的图片目录的变量:
```
.lang="python" # DON'T COPY this line, it exists just for highlighting purposes
STATIC_PATHS = ['images']
```
保存它。打开文章并且以如下方式添加图片:
```
.lang="markdown" # DON'T COPY this line, it exists just for highlighting purposes
![Write here a good description for people who can't see the image]({filename}/images/IMAGE_NAME.jpg)
```
你可以在终端中随时按下 `CTRL+C` 来中断服务器。但是你应该再次启动它并检查图片是否正确。你能记住怎么样做吗?
```
(venv)$ make html && make serve
```
在你代码完工之前的最后一步:你应该确保任何人都可以使用 ATOM 或 RSS 流来读你的文章。找到 `pelicanconf.py` 文件,这个文件是你配置系统的地方,并且编辑关于 RSS 流产生的部分:
```
.lang="python" # DON'T COPY this line, it exists just for highlighting purposes
FEED_ALL_ATOM = 'feeds/all.atom.xml'
FEED_ALL_RSS = 'feeds/all.rss.xml'
AUTHOR_FEED_RSS = 'feeds/%s.rss.xml'
RSS_FEED_SUMMARY_ONLY = False
```
保存所有,这样你才可以将代码上传到 Github 上。你可以通过添加所有文件使用一个信息“first commit”来提交它并且使用 `git push`。你将会被问起你的 Github 登录名和密码。
```
$ git add -A && git commit -a -m 'first commit' && git push --all
```
还有...记住在最开始的时候,我给你说的怎样防止 Pelican 产生的静态文件输出 master 分支吗。现在对你来说是时候产生它们了:
```
$ make github
```
你将会被再次问及 Github 登录名和密码。好了!你的新博客应该创建在 `https://YOUR_USERNAME.github.io`。
如果你在过程中任何一步遇到一个错误,请重新读一下这篇手册,尝试并看看你是否能发现错误发生的部分,因为这是调试的第一步。有时甚至一些简单的东西比如一个错字或者 Python 中错误的缩进都可以给我们带来麻烦。说出来并向网上或你的社区求助。
对于如何使用 Markdown 来写文章,你可以读一下 [Daring Fireball Markdown 指南][7]。
为了获取其它主题,我建议你访问 [Pelican 主题][8]。
这篇文章改编自 [Adrien Leger 的使用一个 Bottstrap3 主题来搭建由 Github 托管的 Pelican 博客][9]。
-----------------------------------------------------------
via: https://rsip22.github.io/blog/create-a-blog-with-pelican-and-github-pages.html
作者:[rsip22][a]
译者:[liuxinyu123](https://github.com/liuxinyu123)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://rsip22.github.io
[1]:https://rsip22.github.io/blog/category/blog.html
[2]:https://tutorial.djangogirls.org
[3]:https://rsip22.github.io/blog/img/create_github_repository.png
[4]:https://www.gnu.org/licenses/license-list.html
[5]:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
[6]:https://rsip22.github.io/blog/img/blog_screenshot.png
[7]:https://daringfireball.net/projects/markdown/syntax
[8]:http://www.pelicanthemes.com/
[9]:https://a-slide.github.io/blog/github-pelican

View File

@@ -0,0 +1,115 @@
6 个开源的家庭自动化工具
======
> 用这些开源软件解决方案构建一个更智能的家庭。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_520x292_openlightbulbs.png?itok=nrv9hgnH)
[物联网][13] 不仅是一个时髦词,在现实中,自 2016 年我们发布了一篇关于家庭自动化工具的评论文章以来,它也在迅速占领着我们的生活。在 2017[26.5% 的美国家庭][14] 已经使用了一些智能家居技术;预计五年内,这一数字还将翻倍。
随着这些数量持续增加的各种设备的使用,可以帮助你实现对家庭的自动化管理、安保、和监视,在家庭自动化方面,从来没有像现在这样容易和更加吸引人过。不论你是要远程控制你的 HVAC 系统,集成一个家庭影院,保护你的家免受盗窃、火灾、或是其它威胁,还是节省能源或只是控制几盏灯,现在都有无数的设备可以帮到你。
但同时,还有许多用户担心安装在他们家庭中的新设备带来的安全和隐私问题 —— 这是一个很现实也很 [严肃的问题][15]。他们想要去控制有谁可以接触到这个重要的系统,这个系统管理着他们的应用程序,记录了他们生活中的点点滴滴。这种想法是可以理解的:毕竟在一个连你的冰箱都是智能设备的今天,你不想要一个基本的保证吗?甚至是如果你授权了设备可以与外界通讯,它是否是仅被授权的人访问它呢?
[对安全的担心][16] 是为什么开源对我们将来使用的互联设备至关重要的众多理由之一。由于源代码运行在他们自己的设备上,完全可以去搞明白控制你的家庭的程序,也就是说你可以查看它的代码,如果必要的话甚至可以去修改它。
虽然联网设备通常都包含它们专有的组件,但是将开源引入家庭自动化的第一步是确保你的设备和这些设备可以共同工作 —— 它们为你提供一个接口 —— 并且是开源的。幸运的是,现在有许多解决方案可供选择,从 PC 到树莓派,你可以在它们上做任何事情。
这里有几个我比较喜欢的。
### Calaos
[Calaos][17] 是一个设计为全栈的家庭自动化平台包含一个服务器应用程序、触摸屏界面、Web 应用程序、支持 iOS 和 Android 的原生移动应用、以及一个运行在底层的预配置好的 Linux 操作系统。Calaos 项目出自一个法国公司,因此它的支持论坛以法语为主,不过大量的介绍资料和文档都已经翻译为英语了。
Calaos 使用的是 [GPL][18] v3 的许可证,你可以在 [GitHub][19] 上查看它的源代码。
### Domoticz
[Domoticz][20] 是一个有大量设备库支持的家庭自动化系统,在它的项目网站上有大量的文档,从气象站到远程控制的烟雾探测器,以及大量的第三方 [集成软件][21] 。它使用一个 HTML5 前端,可以从桌面浏览器或者大多数现代的智能手机上访问它,它是一个轻量级的应用,可以运行在像树莓派这样的低功耗设备上。
Domoticz 是用 C++ 写的,使用 [GPLv3][22] 许可证。它的 [源代码][23] 在 GitHub 上。
### Home Assistant
[Home Assistant][24] 是一个开源的家庭自动化平台,它可以轻松部署在任何能运行 Python 3 的机器上从树莓派到网络存储NAS甚至可以使用 Docker 容器轻松地部署到其它系统上。它集成了大量的开源和商业的产品允许你去连接它们比如IFTTT、天气信息、或者你的 Amazon Echo 设备,去控制从锁到灯的各种硬件。
Home Assistant 以 [MIT 许可证][25] 发布,它的源代码可以从 [GitHub][26] 上下载。
### MisterHouse
从 2016 年起,[MisterHouse][27] 取得了很多的进展,我们把它作为一个“可以考虑的另外选择”列在这个清单上。它使用 Perl 脚本去监视任何东西,它可以通过一台计算机来查询或者控制任何可以远程控制的东西。它可以响应语音命令,查询当前时间、天气、位置、以及其它事件,比如去打开灯、唤醒你、记下你喜欢的电视节目、通报呼入的来电、开门报警、记录你儿子上了多长时间的网、如果你女儿汽车超速它也可以告诉你等等。它可以运行在 Linux、macOS、以及 Windows 计算机上,它可以读/写很多的设备,包括安全系统、气象站、来电显示、路由器、机动车位置系统等等。
MisterHouse 使用 [GPLv2][28] 许可证,你可以在 [GitHub][29] 上查看它的源代码。
### OpenHAB
[OpenHAB][30](开放家庭自动化总线的简称)是在开源爱好者中所熟知的家庭自动化工具,它拥有大量用户的社区以及支持和集成了大量的设备。它是用 Java 写的OpenHAB 非常轻便可以跨大多数主流操作系统使用它甚至在树莓派上也运行的很好。支持成百上千的设备OpenHAB 被设计为与设备无关的这使开发者在系统中添加他们的设备或者插件很容易。OpenHAB 也支持通过 iOS 和 Android 应用来控制设备以及设计工具,因此,你可以为你的家庭系统创建你自己的 UI。
你可以在 GitHub 上找到 OpenHAB 的 [源代码][31],它使用 [Eclipse 公共许可证][32]。
### OpenMotics
[OpenMotics][33] 是一个开源的硬件和软件家庭自动化系统。它的设计目标是为控制设备提供一个综合的系统而不是从不同的供应商处将各种设备拼接在一起。不像其它的系统主要是为了方便改装而设计的OpenMotics 专注于硬件解决方案。更多资料请查阅来自 OpenMotics 的后端开发者 Frederick Ryckbosch的 [完整文章][34] 。
OpenMotics 使用 [GPLv2][35] 许可证,它的源代码可以从 [GitHub][36] 上下载。
当然了,我们的选择不仅有这些。许多家庭自动化爱好者使用不同的解决方案,甚至是他们自己动手做。其它用户选择使用单独的智能家庭设备而无需集成它们到一个单一的综合系统中。
如果上面的解决方案并不能满足你的需求,下面还有一些潜在的替代者可以去考虑:
* [EventGhost][1] 是一个开源的([GPL v2][2])家庭影院自动化工具,它只能运行在 Microsoft Windows PC 上。它允许用户去控制多媒体电脑和连接的硬件,它通过触发宏指令的插件或者定制的 Python 脚本来使用。
* [ioBroker][3] 是一个基于 JavaScript 的物联网平台,它能够控制灯、锁、空调、多媒体、网络摄像头等等。它可以运行在任何可以运行 Node.js 的硬件上,包括 Windows、Linux、以及 macOS它使用 [MIT 许可证][4]。
* [Jeedom][5] 是一个由开源软件([GPL v2][6]构成的家庭自动化平台它可以控制灯、锁、多媒体等等。它包含一个移动应用程序Android 和 iOS并且可以运行在 Linux PC 上;该公司也销售 hub它为配置家庭自动化提供一个现成的解决方案。
* [LinuxMCE][7] 标称它是你的多媒体与电子设备之间的“数字粘合剂”。它运行在 Linux包括树莓派它基于 Pluto 开源 [许可证][8] 发布它可以用于家庭安全、电话VoIP 和语音信箱、A/V 设备、家庭自动化、以及玩视频游戏。
* [OpenNetHome][9],和这一类中的其它解决方案一样,是一个控制灯、报警、应用程序等等的一个开源软件。它基于 Java 和 Apache Maven可以运行在 Windows、macOS、以及 Linux —— 包括树莓派,它以 [GPLv3][10] 许可证发布。
* [Smarthomatic][11] 是一个专注于硬件设备和软件的开源家庭自动化框架,而不仅是用户界面。它基于 [GPLv3][12] 许可证,它可用于控制灯、电器、以及空调、检测温度、提醒给植物浇水。
现在该轮到你了:你已经准备好家庭自动化系统了吗?或者正在研究去设计一个。你对家庭自动化的新手有什么建议,你会推荐什么样的系统?
--------------------------------------------------------------------------------
via: https://opensource.com/life/17/12/home-automation-tools
作者:[Jason Baker][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/jason-baker
[1]:http://www.eventghost.net/
[2]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[3]:http://iobroker.net/
[4]:https://github.com/ioBroker/ioBroker#license
[5]:https://www.jeedom.com/site/en/index.html
[6]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[7]:http://www.linuxmce.com/
[8]:http://wiki.linuxmce.org/index.php/License
[9]:http://opennethome.org/
[10]:https://github.com/NetHome/NetHomeServer/blob/master/LICENSE
[11]:https://www.smarthomatic.org/
[12]:https://github.com/breaker27/smarthomatic/blob/develop/GPL3.txt
[13]:https://opensource.com/resources/internet-of-things
[14]:https://www.statista.com/outlook/279/109/smart-home/united-states
[15]:http://www.crn.com/slide-shows/internet-of-things/300089496/black-hat-2017-9-iot-security-threats-to-watch.htm
[16]:https://opensource.com/business/15/5/why-open-source-means-stronger-security
[17]:https://calaos.fr/en/
[18]:https://github.com/calaos/calaos-os/blob/master/LICENSE
[19]:https://github.com/calaos
[20]:https://domoticz.com/
[21]:https://www.domoticz.com/wiki/Integrations_and_Protocols
[22]:https://github.com/domoticz/domoticz/blob/master/License.txt
[23]:https://github.com/domoticz/domoticz
[24]:https://home-assistant.io/
[25]:https://github.com/home-assistant/home-assistant/blob/dev/LICENSE.md
[26]:https://github.com/balloob/home-assistant
[27]:http://misterhouse.sourceforge.net/
[28]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
[29]:https://github.com/hollie/misterhouse
[30]:http://www.openhab.org/
[31]:https://github.com/openhab/openhab
[32]:https://github.com/openhab/openhab/blob/master/LICENSE.TXT
[33]:https://www.openmotics.com/
[34]:https://opensource.com/life/14/12/open-source-home-automation-system-opemmotics
[35]:http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
[36]:https://github.com/openmotics

View File

@@ -0,0 +1,110 @@
在 Linux 中自动配置 IPv6 地址
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/banner_5.png?itok=3kN83IjL)
在 [KVM 中测试 IPv6 网络:第 1 部分][1] 一文中,我们学习了关于<ruby>唯一本地地址<rt>unique local addresses</rt></ruby>ULA的相关内容。在本文中我们将学习如何为 ULA 自动配置 IP 地址。
### 何时使用唯一本地地址
<ruby>唯一本地地址<rt>unique local addresses</rt></ruby>ULA使用 `fd00::/8` 地址块,它类似于我们常用的 IPv4 的私有地址:`10.0.0.0/8``172.16.0.0/12`、以及 `192.168.0.0/16`。但它们并不能直接替换。IPv4 的私有地址分类和网络地址转换NAT功能是为了缓解 IPv4 地址短缺的问题,这是个明智的解决方案,它延缓了本该被替换的 IPv4 的生命周期。IPv6 也支持 NAT但是我想不出使用它的理由。IPv6 的地址数量远远大于 IPv4它是不一样的因此需要做不一样的事情。
那么ULA 存在的意义是什么呢?尤其是在我们已经有了<ruby>本地链路地址<rt>link-local addresses</rt></ruby>`fe80::/10`到底需不需要我们去配置它们呢它们之间LCTT 译注指的是唯一本地地址和本地链路地址有两个重要的区别。一是本地链路地址是不可路由的因此你不能跨子网使用它。二是ULA 是你自己管理的;你可以自己选择它用于子网的地址范围,并且它们是可路由的。
使用 ULA 的另一个好处是,如果你只是在局域网中“混日子”的话,你不需要为它们分配全局单播 IPv6 地址。当然了,如果你的 ISP 已经为你分配了 IPv6 的<ruby>全局单播地址<rt>global unicast addresses</rt></ruby>,就不需要使用 ULA 了。你也可以在同一个网络中混合使用全局单播地址和 ULA但是我想不出这样使用的一个好理由并且要一定确保你不使用网络地址转换NAT以使 ULA 可公共访问。在我看来,这是很愚蠢的行为。
ULA 是仅为私有网络使用的,并且应该阻止其流出你的网络,不允许进入因特网。这很简单,在你的边界设备上只要阻止整个 `fd00::/8` 范围的 IPv6 地址即可实现。
### 地址自动配置
ULA 不像本地链路地址那样自动配置的,但是使用 radvd 设置自动配置是非常容易的radva 是路由器公告守护程序。在你开始之前,运行 `ifconfig` 或者 `ip addr show` 去查看你现有的 IP 地址。
在生产系统上使用时,你应该将 radvd 安装在一台单独的路由器上,如果只是测试使用,你可以将它安装在你的网络中的任意 Linux PC 上。在我的小型 KVM 测试实验室中,我使用 `apt-get install radvd` 命令把它安装在 Ubuntu 上。安装完成之后,我先不启动它,因为它还没有配置文件:
```
$ sudo systemctl status radvd
● radvd.service - LSB: Router Advertising Daemon
Loaded: loaded (/etc/init.d/radvd; bad; vendor preset: enabled)
Active: active (exited) since Mon 2017-12-11 20:08:25 PST; 4min 59s ago
Docs: man:systemd-sysv-generator(8)
Dec 11 20:08:25 ubunut1 systemd[1]: Starting LSB: Router Advertising Daemon...
Dec 11 20:08:25 ubunut1 radvd[3541]: Starting radvd:
Dec 11 20:08:25 ubunut1 radvd[3541]: * /etc/radvd.conf does not exist or is empty.
Dec 11 20:08:25 ubunut1 radvd[3541]: * See /usr/share/doc/radvd/README.Debian
Dec 11 20:08:25 ubunut1 radvd[3541]: * radvd will *not* be started.
Dec 11 20:08:25 ubunut1 systemd[1]: Started LSB: Router Advertising Daemon.
```
这些所有的消息有点让人困惑,实际上 radvd 并没有运行,你可以使用经典命令 `ps | grep radvd` 来验证这一点。因此,我们现在需要去创建 `/etc/radvd.conf` 文件。拷贝这个示例,将第一行的网络接口名替换成你自己的接口名字:
```
interface ens7 {
AdvSendAdvert on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
prefix fd7d:844d:3e17:f3ae::/64
{
AdvOnLink on;
AdvAutonomous on;
};
};
```
前缀(`prefix`)定义了你的网络地址,它是地址的前 64 位。前两个字符必须是 `fd`,前缀接下来的剩余部分你自己定义它,最后的 64 位留空,因为 radvd 将去分配最后的 64 位。前缀后面的 16 位用来定义子网,剩余的地址定义为主机地址。你的子网必须总是 `/64`。RFC 4193 要求地址必须随机生成;查看 [在 KVM 中测试 IPv6 Networking第 1 部分][1] 学习创建和管理 ULAs 的更多知识。
### IPv6 转发
IPv6 转发必须要启用。下面的命令去启用它,重启后生效:
```
$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
```
取消注释或者添加如下的行到 `/etc/sysctl.conf` 文件中,以使它永久生效:
```
net.ipv6.conf.all.forwarding = 1
```
启动 radvd 守护程序:
```
$ sudo systemctl stop radvd
$ sudo systemctl start radvd
```
这个示例在我的 Ubuntu 测试系统中遇到了一个怪事radvd 总是停止,我查看它的状态却没有任何问题,做任何改变之后都需要重新启动 radvd。
启动成功后没有任何输出,并且失败也是如此,因此,需要运行 `sudo systemctl status radvd` 去查看它的运行状态。如果有错误,`systemctl` 会告诉你。一般常见的错误都是 `/etc/radvd.conf` 中的语法错误。
在 Twitter 上抱怨了上述问题之后,我学到了一件很酷的技巧:当你运行 ` journalctl -xe --no-pager` 去调试 `systemctl` 错误时,你的输出会被换行,然后,你就可以看到错误信息。
现在检查你的主机,查看它们自动分配的新地址:
```
$ ifconfig
ens7 Link encap:Ethernet HWaddr 52:54:00:57:71:50
[...]
inet6 addr: fd7d:844d:3e17:f3ae:9808:98d5:bea9:14d9/64 Scope:Global
[...]
```
本文到此为止,下周继续学习如何为 ULA 管理 DNS这样你就可以使用一个合适的主机名来代替这些长长的 IPv6 地址。
通过来自 Linux 基金会和 edX 的 [“Linux 入门”][2] 免费课程学习更多 Linux 的知识。
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2017/12/ipv6-auto-configuration-linux
作者:[Carla Schroder][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/cschroder
[1]:https://www.linux.com/learn/intro-to-linux/2017/11/testing-ipv6-networking-kvm-part-1
[2]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@@ -0,0 +1,62 @@
什么是容器?为什么我们关注它?
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/containers-basics.jpg?itok=ZLH9VSaC)
什么是容器?你需要它们吗?为什么?在这篇文章中,我们会回答这些基本问题。
但是,为了回答这些问题,我们要提出更多的问题。当你开始考虑怎么用容器适配你的工作时,你需要弄清楚:你在哪开发应用?你在哪测试它?你在哪使用它?
你可能在你的笔记本电脑上开发应用,你的电脑上已经装好了所需要的库文件、扩展包、开发工具和开发框架。它在一个模拟生产环境的机器上进行测试,然后被用于生产环境。问题是这三种环境不一定都是一样的;它们没有同样的工具、框架和库。你在你机器上开发的应用不一定可以在生产环境中正常工作。
容器解决了这个问题。正如 Docker 解释的,“容器镜像是软件的一个轻量的、独立的、可执行的包,包括了执行它所需要的所有东西:代码、运行环境、系统工具、系统库、设置。”
这代表着,一旦一个应用被封装成容器,那么它所依赖的下层环境就不再重要了。它可以在任何地方运行,甚至在混合云环境下也可以。这是容器在开发人员,执行团队,甚至 CIO (信息主管)中变得如此流行的原因之一。
### 容器对开发人员的好处
现在开发人员或运维人员不再需要关注他们要使用什么平台来运行应用。开发人员不会再说:“这在我的系统上运行得好好的。”
容器的另一个重大优势是它的隔离性和安全性。因为容器将应用和运行平台隔离开了,应用以及它周边的东西都会变得安全。同时,不同的团队可以在一台设备上同时运行不同的应用——对于传统应用来说这是不可以的。
这不是虚拟机( VM )所提供的吗?既是,也不是。虚拟机可以隔离应用,但它负载太高了。[在一份文献中][1]Canonical 比较了容器和虚拟机,结果是:“容器提供了一种新的虚拟化方法,它有着和传统虚拟机几乎相同的资源隔离水平。但容器的负载更小,它占用更少的内存,更为高效。这意味着可以实现高密度的虚拟化:一旦安装,你可以在相同的硬件上运行更多应用。”另外,虚拟机启动前需要更多的准备,而容器只需几秒就能运行,可以瞬间启动。
### 容器对应用生态的好处
现在,一个庞大的,由供应商和解决方案组成的生态系统已经可以让公司大规模地运用容器,不管是用于编排、监控、记录或者生命周期管理。
为了保证容器可以运行在任何地方,容器生态系统一起成立了[开源容器倡议][2]OCI。这是一个 Linux 基金会的项目,目标在于创建关于容器运行环境和容器镜像格式这两个容器核心部分的规范。这两个规范确保容器领域中不会有任何不一致。
在很长的一段时间里,容器是专门用于 Linux 内核的,但微软和 Docker 的密切合作将容器带到了微软平台上。现在你可以在 Linux、Windows、Azure、AWS、Google 计算引擎、Rackspace以及大型计算机上使用容器。甚至 VMware 也正在发展容器,它的 [vSphere Integrated Container][3]VIC允许 IT 专业人员在他们平台的传统工作负载上运行容器。
### 容器对 CIO 的好处
容器在开发人员中因为以上的原因而变得十分流行,同时他们也给 CIO 提供了很大的便利。将工作负载迁移到容器中的优势正在改变着公司运行的模式。
传统的应用有大约十年的生命周期。新版本的发布需要多年的努力,因为应用是依赖于平台的,有时几年也不能到达产品阶段。由于这个生命周期,开发人员会尽可能在应用里塞满各种功能,这会使应用变得庞大笨拙,漏洞百出。
这个过程影响了公司内部的创新文化。当人们几个月甚至几年都不能看到他们的创意被实现时,他们就不再有动力了。
容器解决了这个问题。因为你可以将应用切分成更小的微服务。你可以在几周或几天内开发、测试和部署。新特性可以添加成为新的容器。他们可以在测试结束后以最快的速度被投入生产。公司可以更快转型,超过他们的竞争者。因为想法可以被很快转化为容器并部署,这个方式使得创意爆炸式增长。
### 结论
容器解决了许多传统工作负载所面对的问题。但是,它并不能解决所有 IT 专业人员面对的问题。它只是众多解决方案中的一个。在下一篇文章中,我们将会覆盖一些容器的基本术语,然后我们会解释如何开始构建容器。
通过 Linux 基金会和 edX 提供的免费的 ["Introduction to Linux" ][4] 课程学习更多 Linux 知识。
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/intro-to-Linux/2017/12/what-are-containers-and-why-should-you-care
作者:[SWAPNIL BHARTIYA][a]
译者:[lonaparte](https://github.com/lonaparte)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/arnieswap
[1]:https://www.ubuntu.com/containers
[2]:https://www.opencontainers.org/
[3]:https://www.vmware.com/products/vsphere/integrated-containers.html
[4]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@@ -0,0 +1,70 @@
什么是 CGManager
============================================================
CGManager 是一个核心的特权守护进程,通过一个简单的 D-Bus API 管理你所有的 cgroup。它被设计用来处理嵌套的 LXC 容器以及接受无特权的请求,包括解析用户名称空间的 UID/GID。
### 组件
#### cgmanager
这个守护进程在宿主机上运行,​​将 cgroupfs 挂载到一个独立的挂载名称空间(所以它不能从宿主机上看到),绑定 `/sys/fs/cgroup/cgmanager/sock` 用于传入的 D-Bus 查询,并通常处理宿主机上直接运行的所有客户端。
cgmanager 既接受使用 D-Bus + SCM 凭证的身份验证请求,用于在命名空间之间转换 uid、gid 和 pid也可以使用简单的 “unauthenticated”只是初始的 ucredD-Bus 来查询来自宿主机级别的查询。
#### cgproxy
你可能会在两种情况下看到这个守护进程运行。在宿主机上,如果你的内核老于 3.8(没有 pidns 连接支持)或处于容器中(只有 cgproxy 运行)。
cgproxy 本身并不做任何 cgroup 配置更改,而是如其名称所示,代理请求给主 cgmanager 进程。
这是必要的,所以一个进程可以直接使用 D-Bus例如使用 dbus-send`/sys/fs/cgroup/cgmanager/sock` 进行通信。
之后 cgproxy 将从该查询中得到 ucred并对真正的 cgmanager 套接字进行身份验证的 SCM 查询,并通过 ucred 结构体传递参数,使它们能够正确地转换为 cgmanager 可以理解的宿主机命名空间 。
#### cgm
一个简单的命令行工具,与 D-Bus 服务通信,并允许你从命令行执行所有常见的 cgroup 操作。
### 通信协议
如上所述cgmanager 和 cgproxy 使用 D-Bus。建议外部客户端所以不要是 cgproxy使用标准的 D-Bus API不要试图实现 SCM creds 协议,因为它是不必要的,并且容易出错。
相反,只要简单假设与 `/sys/fs/cgroup/cgmanager/sock` 的通信总是正确的。
cgmanager API 仅在独立的 D-Bus 套接字上可用cgmanager 本身不连接到系统总线,所以 cgmanager/cgproxy 不要求有运行中的 dbus 守护进程。
你可以在[这里][7]阅读更多关于 D-Bus API。
### 许可证
CGManager 是免费软件,大部分代码是根据 GNU LGPLv2.1+ 许可条款发布的,一些二进制文件是在 GNU GPLv2 许可下发布的。
该项目的默认许可证是 GNU LGPLv2.1+
### 支持
CGManager 的稳定版本支持依赖于 Linux 发行版以及它们自己承诺推出稳定修复和安全更新。
你可以从 [Canonical Ltd][10] 获得对 Ubuntu LTS 版本的 CGManager 的商业支持。
--------------------------------------------------------------------------------
via: https://linuxcontainers.org/cgmanager/introduction/
作者:[Canonical Ltd.][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.canonical.com/
[1]:https://linuxcontainers.org/cgmanager/introduction/#whats-cgmanager
[2]:https://linuxcontainers.org/cgmanager/introduction/#components
[3]:https://linuxcontainers.org/cgmanager/introduction/#cgmanager
[4]:https://linuxcontainers.org/cgmanager/introduction/#cgproxy
[5]:https://linuxcontainers.org/cgmanager/introduction/#cgm
[6]:https://linuxcontainers.org/cgmanager/introduction/#communication-protocol
[7]:https://linuxcontainers.org/cgmanager/dbus-api/
[8]:https://linuxcontainers.org/cgmanager/introduction/#licensing
[9]:https://linuxcontainers.org/cgmanager/introduction/#support
[10]:http://www.canonical.com/

View File

@@ -0,0 +1,277 @@
邮件传输代理MTA基础
======
### 概述
本教程中,你将学习:
* 使用 `mail` 命令。
* 创建邮件别名。
* 配置电子邮件转发。
* 了解常见邮件传输代理MTA比如postfix、sendmail、qmail、以及 exim。
### 控制邮件去向
Linux 系统上的电子邮件是使用 MTA 投递的。你的 MTA 投递邮件到你的系统上的其他用户,并且 MTA 彼此通讯跨越系统投递到全世界。
Sendmail 是最古老的 Linux MTA。它最初起源于 1979 年用于阿帕网ARPANET的 delivermail 程序。如今它有几个替代品,在本教程中,我也会介绍它们。
#### 前提条件
为完成本系列教程的大部分内容,你需要具备 Linux 的基础知识,你需要拥有一个 Linux 系统来实践本教程中的命令。你应该熟悉 GNU 以及 UNIX 命令。有时候不同版本的程序的输出格式可能不同,因此,在你的系统中输出的结果可能与我在下面列出的稍有不同。
在本教程中,我使用的是 Ubuntu 14.04 LTS 和 sendmail 8.14.4 来做的演示。
### 邮件传输
邮件传输代理(比如 sendmail在用户之间和系统之间投递邮件。大量的因特网邮件使用简单邮件传输协议SMTP但是本地邮件可能是通过文件或者套接字等其它可能的方式来传输的。邮件是一种存储和转发的操作因此在用户接收邮件或者接收系统和通讯联系可用之前邮件一直是存储在某种文件或者数据库中。配置和确保 MTA 的安全是非常复杂的任务,它们中的大部分内容都已经超出了本教程的范围。
### mail 命令
如果你使用 SMTP 协议传输电子邮件,你或许知道你可以使用许多邮件客户端,包括 `mail``mutt``alpine``notmuch`、以及其它基于主机控制台或者图形界面的邮件客户端。`mail` 命令是最老的、可用于脚本中的、发送和接收以及管理收到的邮件的备用命令。
你可以使用 `mail` 命令交互式的向列表中的收件人发送信息,或者不使用参数去查看你收到的邮件。清单 1 展示了如何在你的系统上去发送信息到用户 steve 和 pat同时抄送拷贝给用户 bob。当提示 `Cc:``subject:` 时,输入相应的抄送用户以及邮件主题,接着输入邮件正文,输入完成后按下 `Ctrl+D` (按下 `Ctrl` 键并保持再按下 `D` 之后全部松开)。
```
ian@attic4-u14:~$ mail steve,pat
Cc: bob
Subject: Test message 1
This is a test message
Ian
```
*清单 1. 使用 `mail` 交互式发送邮件*
如果一切顺利,你的邮件已经发出。如果在这里发生错误,你将看到错误信息。例如,如果你在接收者列表中输入一个无效的用户名,邮件将无法发送。注意在本示例中,所有的用户都在本地系统上存在,因此他们都是有效用户。
你也可以使用命令行以非交互式发送邮件。清单 2 展示了如何给用户 steve 和 pat 发送一封邮件。这种方式可以用在脚本中。在不同的软件包中 `mail` 命令的版本不同。对于抄送(`Cc:`)有些支持一个 `-c` 选项,但是我使用的这个版本不支持这个选项,因此,我仅将邮件发送到收件人。
```
ian@attic4-u14:~$ mail -t steve,pat -s "Test message 2" <<< "Another test.\n\nIan"
```
*清单 2. 使用 `mail` 命令非交互式发送邮件*
如果你使用没有选项的 `mail` 命令,你将看到一个如清单 3 中所展示的那样一个收到信息的列表。你将看到用户 steve 有我上面发送的两个信息,再加上我以前发送的一个信息和后来用户 bob 发送的信息。所有的邮件都用 'N' 标记为新邮件。
```
steve@attic4-u14:~$ mail
"/var/mail/steve": 4 messages 4 new
>N 1 Ian Shields Tue Dec 12 21:03 16/704 test message
N 2 Ian Shields Tue Dec 12 21:04 18/701 Test message 1
N 3 Ian Shields Tue Dec 12 21:23 15/661 Test message 2
N 4 Bob C Tue Dec 12 21:45 17/653 How about lunch tomorrow?
?
```
*清单 3. 使用 `mail` 查看收到的邮件*
当前选中的信息使用一个 `>` 来标识,它是清单 3 中的第一封邮件。如果你按下回车键(`Enter`),将显示下一封未读邮件的第一页。按下空格楗将显示这个邮件的下一页。当你读完这个邮件并想返回到 `?` 提示符时,按下回车键再次查看下一封邮件,依次类推。在 `?` 提示符下,你可以输入 `h` 再次去查看邮件头。你看过的邮件前面将显示一个 `R` 状态,如清单 4 所示。
```
? h
R 1 Ian Shields Tue Dec 12 21:03 16/704 test message
R 2 Ian Shields Tue Dec 12 21:04 18/701 Test message 1
>R 3 Ian Shields Tue Dec 12 21:23 15/661 Test message 2
N 4 Bob C Tue Dec 12 21:45 17/653 How about lunch tomorrow?
?
```
*清单 4. 使用 `h` 去显示邮件头*
在这个图中Steve 已经读了三个邮件,但是没有读来自 bob 的邮件。你可以通过数字来选择单个的信息,你也可以通过输入 `d` 删除你不想要的信息,或者输入 `3d` 去删除第三个信息。如果你输入 `q` 你将退出 `mail` 命令。已读的信息将被转移到你的家目录下的 `mbox` 文件中,而未读的信息仍然保留在你的收件箱中,默认在 `/var/mail/$(id -un)`。如清单 5 所示。
```
? h
R 1 Ian Shields Tue Dec 12 21:03 16/704 test message
R 2 Ian Shields Tue Dec 12 21:04 18/701 Test message 1
>R 3 Ian Shields Tue Dec 12 21:23 15/661 Test message 2
N 4 Bob C Tue Dec 12 21:45 17/653 How about lunch tomorrow?
? q
Saved 3 messages in /home/steve/mbox
Held 1 message in /var/mail/steve
You have mail in /var/mail/steve
```
*清单 5. 使用 `q` 退出 `mail`*
如果你输入 `x` 而不是使用 `q` 去退出,你的邮箱在退出后将不保留你做的改变。因为这在 `/var` 文件系统中,你的系统管理员可能仅允许邮件在一个有限的时间范围内保留。要重新读取或者以其它方式再次处理保存在你的本地邮箱中的邮件,你可以使用 `-f` 选项去指定想要去读的文件。比如,`mail -f mbox`
### 邮件别名
在前面的节中,看了如何在系统上给许多用户发送邮件。你可以使用一个全限定名字(比如 ian@myexampledomain.com给其它系统上的用户发送邮件。
有时候你可能希望用户的所有邮件都可以发送到其它地方。比如,你有一个服务器群,你希望所有的 root 用户的邮件都发给中心的系统管理员。或者你可能希望去创建一个邮件列表,将邮件发送给一些人。为实现上述目标,你可以使用别名,别名允许你为一个给定的用户名定义一个或者多个目的地。这个目的地或者是其它用户的邮箱、文件、管道、或者是某个进一步处理的命令。你可以在 `/etc/mail/aliases` 或者 `/etc/aliases` 中创建别名来实现上述目的。根据你的系统的不同,你可以找到上述其中一个,符号链接到它们、或者其中之一。改变别名文件你需要有 root 权限。
别名的格式一般是:
```
name: addr_1, addr_2, addr_3, ...
```
这里 `name` 是一个要别名的本地用户名字(即别名),而 `addr_1``addr_2`... 可以是一个或多个别名。别名可以是一个本地用户、一个本地文件名、另一个别名、一个命令、一个包含文件,或者一个外部地址。
因此发送邮件时如何区分别名呢addr-N
* 本地用户名是你机器上系统中的一个用户名字。从技术角度来说,它可以通过调用 `getpwnam` 命令找到它。
* 本地文件名是以 `/` 开始的完全路径和文件名。它必须是 `sendmail` 可写的。信息会追加到这个文件上。
* 命令是以一个管道符号开始的(`|`)。信息是通过标准输入的方式发送到命令的。
* 包含文件别名是以 `:include:` 和指定的路径和文件名开始的。在该文件中的别名被添加到该名字所代表的别名中。
* 外部地址是一个电子邮件地址,比如 john@somewhere.com。
你可以在你的系统中找到一个示例文件,它是与你的 sendmail 包一起安装的,它的位置在 `/usr/share/sendmail/examples/db/aliases`。它包含一些给 `postmaster``MAILER-DAEMON``abuse``spam 的别名建议。在清单 6我把我的 Ubuntu 14.04 LTS 系统上的一些示例文件,和人工修改的示例结合起来说明一些可能的情况。
```
ian@attic4-u14:~$ cat /etc/mail/aliases
# First include some default system aliases from
# /usr/share/sendmail/examples/db/aliases
#
# Mail aliases for sendmail
#
# You must run newaliases(1) after making changes to this file.
#
# Required aliases
postmaster: root
MAILER-DAEMON: postmaster
# Common aliases
abuse: postmaster
spam: postmaster
# Other aliases
# Send steve's mail to bob and pat instead
steve: bob,pat
# Send pat's mail to a file in her home directory and also to her inbox.
# Finally send it to a command that will make another copy.
pat: /home/pat/accumulated-mail,
\pat,
|/home/pat/makemailcopy.sh
# Mailing list for system administrators
sysadmins: :include: /etc/aliases-sysadmins
```
*清单 6. 人工修改的 /etc/mail/aliases 示例*
注意那个 pat 既是一个别名也是一个系统中的用户。别名是以递归的方式展开的因此如果一个别名也是一个名字那么它将被展开。Sendmail 并不会给同一个用户发送相同的邮件两遍,因此,如果你正好将 pat 作为 pat 的别名,那么 sendmail 在已经找到并处理完用户 pat 之后,将忽略别名 pat。为避免这种问题你可以在别名前使用一个 `\` 做为前缀去指示它是一个不要进一步引起混淆的名字。在这种情况下pat 的邮件除了文件和命令之外,其余的可能会被发送到他的正常的邮箱中。
`aliases` 文件中以 `#` 开始的行是注释,它会被忽略。以空白开始的行会以延续行来处理。
清单 7 展示了包含文件 `/etc/aliases-sysadmins`
```
ian@attic4-u14:~$ cat /etc/aliases-sysadmins
# Mailing list for system administrators
bob,pat
```
*清单 7 包含文件 /etc/aliases-sysadmins*
### newaliases 命令
sendmail 使用的主要配置文件会被编译成数据库文件。邮件别名也是如此。你可以使用 `newaliases` 命令去编译你的 `/etc/mail/aliases` 和任何包含文件到 `/etc/mail/aliases.db` 中。注意,`newaliases` 命令等价于 `sendmail -bi`。清单 8 展示了一个示例。
```
ian@attic4-u14:~$ sudo newaliases
/etc/mail/aliases: 7 aliases, longest 62 bytes, 184 bytes total
ian@attic4-u14:~$ ls -l /etc/mail/aliases*
lrwxrwxrwx 1 root smmsp 10 Dec 8 15:48 /etc/mail/aliases -> ../aliases
-rw-r----- 1 smmta smmsp 12288 Dec 13 23:18 /etc/mail/aliases.db
```
*清单 8. 为邮件别名重建数据库*
### 使用别名的示例
清单 9 展示了一个简单的 shell 脚本,它在我的别名示例中以一个命令的方式来使用。
```
ian@attic4-u14:~$ cat ~pat/makemailcopy.sh
#!/bin/bash
# Note: Target file ~/mail-copy must be writeable by sendmail!
cat >> ~pat/mail-copy
```
*清单 9. makemailcopy.sh 脚本*
清单 10 展示了用于测试时更新的文件。
```
ian@attic4-u14:~$ date
Wed Dec 13 22:54:22 EST 2017
ian@attic4-u14:~$ mail -t sysadmins -s "sysadmin test 1" <<< "Testing mail"
ian@attic4-u14:~$ ls -lrt $(find /var/mail ~pat -type f -mmin -3 2>/dev/null )
-rw-rw---- 1 pat mail 2046 Dec 13 22:54 /home/pat/mail-copy
-rw------- 1 pat mail 13240 Dec 13 22:54 /var/mail/pat
-rw-rw---- 1 pat mail 9442 Dec 13 22:54 /home/pat/accumulated-mail
-rw-rw---- 1 bob mail 12522 Dec 13 22:54 /var/mail/bob
```
*清单 10. /etc/aliases-sysadmins 包含文件*
需要注意的几点:
* sendmail 使用的用户和组的名字是 mail。
* sendmail 在 `/var/mail` 保存用户邮件,它也是用户 mail 的家目录。用户 ian 的默认收件箱在 `/var/mail/ian` 中。
* 如果你希望 sendmail 在用户目录下写入文件,这个文件必须允许 sendmail 可写入。与其让任何人都可以写入,还不如定义一个组可写入,组名称为 mail。这需要系统管理员来帮你完成。
### 使用一个 `.forward` 文件去转发邮件
别名文件是由系统管理员来管理的。个人用户可以使用它们自己的家目录下的 `.forward` 文件去转发他们自己的邮件。你可以在你的 `.forward` 文件中放任何可以出现在别名文件的右侧的东西。这个文件的内容是明文的不需要编译。当你收到邮件时sendmail 将检查你的家目录中的 `.forward` 文件,然后就像处理别名一样处理它。
### 邮件队列和 mailq 命令
Linux 邮件使用存储-转发的处理模式。你已经看到的已接收邮件,在你读它之前一直保存在文件 `/var/mail` 中。你发出的邮件在接收服务器连接可用之前也会被保存。你可以使用 `mailq` 命令去查看邮件队列。清单 11 展示了一个发送给外部用户 ian@attic4-c6 的一个邮件示例,以及运行 `mailq` 命令的结果。在这个案例中,当前服务器没有连接到 attic4-c6因此邮件在与对方服务器连接可用之前一直保存在队列中。
```
ian@attic4-u14:~$ mail -t ian@attic4-c6 -s "External mail" <<< "Testing external mail queues"
ian@attic4-u14:~$ mailq
MSP Queue status...
/var/spool/mqueue-client is empty
Total requests: 0
MTA Queue status...
/var/spool/mqueue (1 request)
-----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient-----------
vBE4mdE7025908* 29 Wed Dec 13 23:48 <ian@attic4-u14.hopto.org>
<ian@attic4-c6.hopto.org>
Total requests: 1
```
*清单 11. 使用 `mailq` 命令*
### 其它邮件传输代理
为解决使用 sendmail 时安全方面的问题在上世纪九十年代开发了几个其它的邮件传输代理。Postfix 或许是最流行的一个,但是 qmail 和 exim 也大量使用。
Postfix 是 IBM 为代替 sendmail 而研发的。它更快、也易于管理、安全性更好一些。从外表看它非常像 sendmail但是它的内部完全与 sendmail 不同。
Qmail 是一个安全、可靠、高效、简单的邮件传输代理,它由 Dan Bernstein 开发。但是最近几年以来它的核心包已经不再更新了。Qmail 和几个其它的包已经被吸收到 IndiMail 中了。
Exim 是另外一个 MTA它由 University of Cambridge 开发。最初,它的名字是 `EXperimental Internet Mailer`
所有的这些 MTA 都是为代替 sendmail 而设计的,因此,它们它们都兼容 sendmail 的一些格式。它们都能够处理别名和 `.forward` 文件。有些封装了一个 `sendmail` 命令作为一个到特定的 MTA 自有命令的前端。尽管一些选项可能会被静默忽略,但是大多数都允许使用常见的 sendmail 选项。`mailq` 命令是被直接支持的,或者使用一个类似功能的命令来代替。比如,你可以使用 `mailq` 或者 `exim -bp` 去显示 exim 邮件队列。当然,输出可以看到与 sendmail 的 `mailq` 命令的不同之外。
查看相关的主题,你可以找到更多的关于这些 MTA 的更多信息。
对 Linux 上的邮件传输代理的介绍到此结束。
--------------------------------------------------------------------------------
via: https://www.ibm.com/developerworks/library/l-lpic1-108-3/index.html
作者:[Ian Shields][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.ibm.com
[1]:http://www.lpi.org
[2]:https://www.ibm.com/developerworks/library/l-lpic1-map/

View File

@@ -0,0 +1,176 @@
如何修复 WordPress 中的 HTTP 错误
======
![http error wordpress][1]
我们会向你介绍,如何在 Linux VPS 上修复 WordPress 中的 HTTP 错误。 下面列出了 WordPress 用户遇到的最常见的 HTTP 错误,我们的建议侧重于如何发现错误原因以及解决方法。
### 1、 修复在上传图像时出现的 HTTP 错误
如果你在基于 WordPress 的网页中上传图像时出现错误,这也许是因为服务器上 PHP 的配置,例如存储空间不足或者其他配置问题造成的。
用如下命令查找 php 配置文件:
```
php -i | grep php.ini
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini
```
根据输出结果php 配置文件位于 `/etc` 文件夹下。编辑 `/etc/php.ini` 文件,找出下列行,并按照下面的例子修改其中相对应的值:
```
vi /etc/php.ini
```
```
upload_max_filesize = 64M
post_max_size = 32M
max_execution_time = 300
max_input_time 300
memory_limit = 128M
```
当然,如果你不习惯使用 vi 文本编辑器,你可以选用自己喜欢的。
不要忘记重启你的网页服务器来让改动生效。
如果你安装的网页服务器是 Apache你也可以使用 `.htaccess` 文件。首先,找到 `.htaccess` 文件。它位于 WordPress 安装路径的根文件夹下。如果没有找到 `.htaccess` 文件,需要自己手动创建一个,然后加入如下内容:
```
vi /www/html/path_to_wordpress/.htaccess
```
```
php_value upload_max_filesize 64M
php_value post_max_size 32M
php_value max_execution_time 180
php_value max_input_time 180
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
```
如果你使用的网页服务器是 nginx在 nginx 的 `server` 配置块中配置你的 WordPress 实例。详细配置和下面的例子相似:
```
server {
listen 80;
client_max_body_size 128m;
client_body_timeout 300;
server_name your-domain.com www.your-domain.com;
root /var/www/html/wordpress;
index index.php;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
```
根据自己的 PHP 配置,你需要将 `fastcgi_pass 127.0.0.1:9000;` 用类似于 `fastcgi_pass unix:/var/run/php7-fpm.sock;` 替换掉(依照实际连接方式)
重启 nginx 服务来使改动生效。
### 2、 修复因为不恰当的文件权限而产生的 HTTP 错误
如果你在 WordPress 中出现一个意外错误,也许是因为不恰当的文件权限导致的,所以需要给 WordPress 文件和文件夹设置一个正确的权限:
```
chown www-data:www-data -R /var/www/html/path_to_wordpress/
```
`www-data` 替换成实际的网页服务器用户,将 `/var/www/html/path_to_wordpress` 换成 WordPress 的实际安装路径。
### 3、 修复因为内存不足而产生的 HTTP 错误
你可以通过在 `wp-config.php` 中添加如下内容来设置 PHP 的最大内存限制:
```
define('WP_MEMORY_LIMIT', '128MB');
```
### 4、 修复因为 php.ini 文件错误配置而产生的 HTTP 错误
编辑 PHP 配置主文件,然后找到 `cgi.fix_pathinfo` 这一行。 这一行内容默认情况下是被注释掉的,默认值为 `1`。取消这一行的注释(删掉这一行最前面的分号),然后将 `1` 改为 `0` 。同时需要修改 `date.timezone` 这一 PHP 设置,再次编辑 PHP 配置文件并将这一选项改成 `date.timezone = Asia/Shanghai` (或者将等号后内容改为你所在的时区)。
```
vi /etc/php.ini
```
```
cgi.fix_pathinfo=0
date.timezone = Asia/Shanghai
```
### 5、 修复因为 Apache mod_security 模块而产生的 HTTP 错误
如果你在使用 Apache mod_security 模块,这可能也会引起问题。试着禁用这一模块,确认是否因为在 `.htaccess` 文件中加入如下内容而引起了问题:
```
<IfModule mod_security.c>
SecFilterEngine Off
SecFilterScanPOST Off
</IfModule>
```
### 6、 修复因为有问题的插件/主题而产生的 HTTP 错误
一些插件或主题也会导致 HTTP 错误以及其他问题。你可以首先禁用有问题的插件/主题,或暂时禁用所有 WordPress 插件。如果你有 phpMyAdmin使用它来禁用所有插件在其中找到 `wp_options` 数据表,在 `option_name` 这一列中找到 `active_plugins` 这一记录,然后将 `option_value` 改为 `a:0:{}`
或者用以下命令通过SSH重命名插件所在文件夹
```
mv /www/html/path_to_wordpress/wp-content/plugins /www/html/path_to_wordpress/wp-content/plugins.old
```
通常情况下HTTP 错误会被记录在网页服务器的日志文件中,所以寻找错误时一个很好的切入点就是查看服务器日志。
--------------------------------------------------------------------------------
via: https://www.rosehosting.com/blog/http-error-wordpress/
作者:[rosehosting][a]
译者:[wenwensnow](https://github.com/wenwensnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.rosehosting.com
[1]:https://www.rosehosting.com/blog/wp-content/uploads/2018/01/http-error-wordpress.jpg
[2]:https://www.rosehosting.com/wordpress-hosting.html

View File

@@ -0,0 +1,177 @@
如何在 Linux 中查找最大的 10 个文件
======
当系统的磁盘空间不足时,您可能会使用 `df``du``ncdu` 命令进行检查,但这些命令只会显示当前目录的文件,并不会显示整个系统范围的文件。
您得花费大量的时间才能用上述命令获取系统中最大的文件,因为要进入到每个目录重复运行上述命令。
这种方法比较麻烦,也并不恰当。
如果是这样,那么该如何在 Linux 中找到最大的 10 个文件呢?
我在谷歌上搜索了很久,却没发现类似的文章,我反而看到了很多关于列出当前目录中最大的 10 个文件的文章。所以,我希望这篇文章对那些有类似需求的人有所帮助。
本教程中,我们将教您如何使用以下四种方法在 Linux 系统中查找最大的前 10 个文件。
### 方法 1
在 Linux 中没有特定的命令可以直接执行此操作,因此我们需要将多个命令结合使用。
```
# find / -type f -print0 | xargs -0 du -h | sort -rh | head -n 10
1.4G /swapfile
1.1G /home/magi/ubuntu-17.04-desktop-amd64.iso
564M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA
378M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8
377M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU
100M /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0
93M /usr/lib/firefox/libxul.so
84M /var/lib/snapd/snaps/core_3604.snap
84M /var/lib/snapd/snaps/core_3440.snap
84M /var/lib/snapd/snaps/core_3247.snap
```
详解:
- `find`:在目录结构中搜索文件的命令
- `/`:在整个系统(从根目录开始)中查找
- `-type`:指定文件类型
- `f`:普通文件
- `-print0`在标准输出显示完整的文件名其后跟一个空字符null
- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理
- `xargs`:将标准输入转换成命令行参数的命令
- `-0`以空字符null而不是空白字符LCTT 译者注:即空格、制表符和换行)来分割记录
- `du -h`:以可读格式计算磁盘空间使用情况的命令
- `sort`:对文本文件进行排序的命令
- `-r`:反转结果
- `-h`:用可读格式打印输出
- `head`:输出文件开头部分的命令
- `n -10`:打印前 10 个文件
### 方法 2
这是查找 Linux 系统中最大的前 10 个文件的另一种方法。我们依然使用多个命令共同完成这个任务。
```
# find / -type f -exec du -Sh {} + | sort -rh | head -n 10
1.4G /swapfile
1.1G /home/magi/ubuntu-17.04-desktop-amd64.iso
564M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA
378M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8
377M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU
100M /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0
93M /usr/lib/firefox/libxul.so
84M /var/lib/snapd/snaps/core_3604.snap
84M /var/lib/snapd/snaps/core_3440.snap
84M /var/lib/snapd/snaps/core_3247.snap
```
详解:
- `find`:在目录结构中搜索文件的命令
- `/`:在整个系统(从根目录开始)中查找
- `-type`:指定文件类型
- `f`:普通文件
- `-exec`:在所选文件上运行指定命令
- `du`:计算文件占用的磁盘空间的命令
- `-S`:不包含子目录的大小
- `-h`:以可读格式打印
- `{}`:递归地查找目录,统计每个文件占用的磁盘空间
- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理
- `sort`:对文本文件进行按行排序的命令
- `-r`:反转结果
- `-h`:用可读格式打印输出
- `head`:输出文件开头部分的命令
- `n -10`:打印前 10 个文件
### 方法 3
这里介绍另一种在 Linux 系统中搜索最大的前 10 个文件的方法。
```
# find / -type f -print0 | xargs -0 du | sort -n | tail -10 | cut -f2 | xargs -I{} du -sh {}
84M /var/lib/snapd/snaps/core_3247.snap
84M /var/lib/snapd/snaps/core_3440.snap
84M /var/lib/snapd/snaps/core_3604.snap
93M /usr/lib/firefox/libxul.so
100M /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0
377M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU
378M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8
564M /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA
1.1G /home/magi/ubuntu-17.04-desktop-amd64.iso
1.4G /swapfile
```
详解:
- `find`:在目录结构中搜索文件的命令
- `/`:在整个系统(从根目录开始)中查找
- `-type`:指定文件类型
- `f`:普通文件
- `-print0`输出完整的文件名其后跟一个空字符null
- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理
- `xargs`:将标准输入转换成命令行参数的命令
- `-0`以空字符null而不是空白字符来分割记录
- `du`:计算文件占用的磁盘空间的命令
- `sort`:对文本文件进行按行排序的命令
- `-n`:根据数字大小进行比较
- `tail -10`:输出文件结尾部分的命令(最后 10 个文件)
- `cut`:从每行删除特定部分的命令
- `-f2`:只选择特定字段值
- `-I{}`:将初始参数中出现的每个替换字符串都替换为从标准输入读取的名称
- `-s`:仅显示每个参数的总和
- `-h`:用可读格式打印输出
- `{}`:递归地查找目录,统计每个文件占用的磁盘空间
### 方法 4
还有一种在 Linux 系统中查找最大的前 10 个文件的方法。
```
# find / -type f -ls | sort -k 7 -r -n | head -10 | column -t | awk '{print $7,$11}'
1494845440 /swapfile
1085984380 /home/magi/ubuntu-17.04-desktop-amd64.iso
591003648 /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqTFU0XzkzUlJUZzA
395770383 /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqeldzUmhPeC03Zm8
394891761 /home/magi/.gdfuse/magi/cache/0B5nso_FPaZFqRGd4V0VrOXM4YVU
103999072 /usr/lib/x86_64-linux-gnu/libOxideQtCore.so.0
97356256 /usr/lib/firefox/libxul.so
87896064 /var/lib/snapd/snaps/core_3604.snap
87793664 /var/lib/snapd/snaps/core_3440.snap
87089152 /var/lib/snapd/snaps/core_3247.snap
```
详解:
- `find`:在目录结构中搜索文件的命令
- `/`:在整个系统(从根目录开始)中查找
- `-type`:指定文件类型
- `f`:普通文件
- `-ls`:在标准输出中以 `ls -dils` 的格式列出当前文件
- `|`:控制操作符,将一条命令的输出传递给下一个命令以供进一步处理
- `sort`:对文本文件进行按行排序的命令
- `-k`:按指定列进行排序
- `-r`:反转结果
- `-n`:根据数字大小进行比较
- `head`:输出文件开头部分的命令
- `-10`:打印前 10 个文件
- `column`:将其输入格式化为多列的命令
- `-t`:确定输入包含的列数并创建一个表
- `awk`:模式扫描和处理语言
- `'{print $7,$11}'`:只打印指定的列
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/how-to-find-search-check-print-top-10-largest-biggest-files-in-linux/
作者:[Magesh Maruthamuthu][a]
译者:[jessie-pang](https://github.com/jessie-pang)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.2daygeek.com/author/magesh/

View File

@@ -0,0 +1,98 @@
Tlog录制/播放终端 IO 和会话的工具
======
Tlog 是 Linux 中终端 I/O 录制和回放软件包。它用于实现一个集中式用户会话录制。它将所有经过的消息录制为 JSON 消息。录制为 JSON 格式的主要目的是将数据传送到 ElasticSearch 之类的存储服务,可以从中搜索和查询,以及回放。同时,它们保留所有通过的数据和时序。
Tlog 包含三个工具,分别是 `tlog-rec`、tlog-rec-session` 和 `tlog-play`。
* `tlog-rec` 工具一般用于录制终端、程序或 shell 的输入或输出。
* `tlog-rec-session` 工具用于录制整个终端会话的 I/O包括录制的用户。
* `tlog-play` 工具用于回放录制。
在本文中,我将解释如何在 CentOS 7.4 服务器上安装 Tlog。
### 安装
在安装之前,我们需要确保我们的系统满足编译和安装程序的所有软件要求。在第一步中,使用以下命令更新系统仓库和软件包。
```
# yum update
```
我们需要安装此软件安装所需的依赖项。在安装之前,我已经使用这些命令安装了所有依赖包。
```
# yum install wget gcc
# yum install systemd-devel json-c-devel libcurl-devel m4
```
完成这些安装后,我们可以下载该工具的[源码包][1]并根据需要将其解压到服务器上:
```
# wget https://github.com/Scribery/tlog/releases/download/v3/tlog-3.tar.gz
# tar -xvf tlog-3.tar.gz
# cd tlog-3
```
现在,你可以使用我们通常的配置和编译方法开始构建此工具。
```
# ./configure --prefix=/usr --sysconfdir=/etc && make
# make install
# ldconfig
```
最后,你需要运行 `ldconfig`。它对命令行中指定目录、`/etc/ld.so.conf` 文件,以及信任的目录( `/lib` 和 `/usr/lib`)中最近的共享库创建必要的链接和缓存。
### Tlog 工作流程图
![Tlog working process][2]
首先,用户通过 PAM 进行身份验证登录。名称服务交换器NSS提供的 `tlog` 信息是用户的 shell。这初始化了 tlog 部分,并从环境变量/配置文件收集关于实际 shell 的信息,并在 PTY 中启动实际的 shell。然后通过 syslog 或 sd-journal 开始录制在终端和 PTY 之间传递的所有内容。
### 用法
你可以使用 `tlog-rec` 录制一个会话并使用 `tlog-play` 回放它,以测试新安装的 tlog 是否能够正常录制和回放会话。
#### 录制到文件中
要将会话录制到文件中,请在命令行中执行 `tlog-rec`,如下所示:
```
tlog-rec --writer=file --file-path=tlog.log
```
该命令会将我们的终端会话录制到名为 `tlog.log` 的文件中,并将其保存在命令中指定的路径中。
#### 从文件中回放
你可以在录制过程中或录制后使用 `tlog-play` 命令回放录制的会话。
```
tlog-play --reader=file --file-path=tlog.log
```
该命令从指定的路径读取先前录制的文件 `tlog.log`。
### 总结
Tlog 是一个开源软件包,可用于实现集中式用户会话录制。它主要是作为一个更大的用户会话录制解决方案的一部分使用,但它被设计为独立且可重用的。该工具可以帮助录制用户所做的一切,并将其存储在服务器的某个位置,以备将来参考。你可以从这个[文档][3]中获得关于这个软件包使用的更多细节。我希望这篇文章对你有用。请发表你的宝贵建议和意见。
**关于 Saheetha Shameer (作者)**
我正在担任高级系统管理员。我是一名快速学习者,有轻微的倾向跟随行业中目前和正在出现的趋势。我的爱好包括听音乐、玩策略游戏、阅读和园艺。我对尝试各种美食也有很高的热情 :-)
--------------------------------------------------------------------------------
via: https://linoxide.com/linux-how-to/tlog-tool-record-play-terminal-io-sessions/
作者:[Saheetha Shameer][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://linoxide.com/author/saheethas/
[1]:https://github.com/Scribery/tlog/releases/download/v3/tlog-3.tar.gz
[2]:https://linoxide.com/wp-content/uploads/2018/01/Tlog-working-process.png
[3]:https://github.com/Scribery/tlog/blob/master/README.md

View File

@@ -0,0 +1,180 @@
Ansible像系统管理员一样思考的自动化框架
======
这些年来,我已经写了许多关于 DevOps 工具的文章,也培训了这方面的人员。尽管这些工具很棒,但很明显,大多数都是按照开发人员的思路设计出来的。这也没有什么问题,因为以编程的方式接近配置管理是重点。不过,直到我开始接触 Ansible我才觉得这才是系统管理员喜欢的东西。
喜欢的一部分原因是 Ansible 与客户端计算机通信的方式,是通过 SSH 的。作为系统管理员,你们都非常熟悉通过 SSH 连接到计算机,所以从单词“去”的角度来看,相对于其它选择,你更容易理解 Ansible。
考虑到这一点,我打算写一些文章,探讨如何使用 Ansible。这是一个很好的系统但是当我第一次接触到这个系统的时候不知道如何开始。这并不是学习曲线陡峭。事实上问题是在开始使用 Ansible 之前我并没有太多的东西要学这才是让人感到困惑的。例如如果您不必安装客户端程序Ansible 没有在客户端计算机上安装任何软件),那么您将如何启动?
### 踏出第一步
起初 Ansible 对我来说非常困难的原因在于配置服务器/客户端的关系是非常灵活的我不知道我该从何入手。事实是Ansible 并不关心你如何设置 SSH 系统。它会利用你现有的任何配置。需要考虑以下几件事情:
1. Ansible 需要通过 SSH 连接到客户端计算机。
2. 连接后Ansible 需要提升权限才能配置系统,安装软件包等等。
不幸的是,这两个考虑真的带来了一堆蠕虫。连接到远程计算机并提升权限是一件可怕的事情。当您在远程计算机上安装代理并使用 Chef 或 Puppet 处理特权升级问题时,似乎感觉就没那么可怕了。 Ansible 并非不安全,而是安全的决定权在你手中。
接下来,我将列出一系列潜在的配置,以及每个配置的优缺点。这不是一个详尽的清单,但是你会受到正确的启发,去思考在你自己的环境中什么是理想的配置。也需要注意,我不会提到像 Vagrant 这样的系统,因为尽管 Vagrant 在构建测试和开发的敏捷架构时非常棒,但是和一堆服务器是非常不同的,因此考虑因素是极不相似的。
### 一些 SSH 场景
#### 1在 Ansible 配置中root 用户以密码进入远程计算机。
拥有这个想法是一个非常可怕的开始。这个设置的“优点”是它消除了对特权提升的需要,并且远程服务器上不需要其他用户帐户。 但是,这种便利的成本是不值得的。 首先,大多数系统不会让你在不改变默认配置的情况下以 root 身份进行 SSH 登录。默认的配置之所以如此,坦率地说,是因为允许 root 用户远程连接是一个不好的主意。 其次,将 root 密码放在 Ansible 机器上的纯文本配置文件中是不合适的。 真的,我提到了这种可能性,因为这是可以的,但这是应该避免的。 请记住Ansible 允许你自己配置连接,它可以让你做真正愚蠢的事情。 但是请不要这么做。
#### 2使用存储在 Ansible 配置中的密码,以普通用户的身份进入远程计算机。
这种情况的一个优点是它不需要太多的客户端配置。 大多数用户默认情况下都可以使用 SSH因此 Ansible 应该能够使用用户凭据并且能够正常登录。 我个人不喜欢在配置文件中以纯文本形式存储密码,但至少它不是 root 密码。 如果您使用此方法,请务必考虑远程服务器上的权限提升方式。 我知道我还没有谈到权限提升,但是如果你在配置文件中配置了一个密码,这个密码可能会被用来获得 sudo 访问权限。 因此,一旦发生泄露,您不仅已经泄露了远程用户的帐户,还可能泄露整个系统。
#### 3使用具有空密码的密钥对进行身份验证以普通用户身份进入远程计算机。
这消除了将密码存储在配置文件中的弊端,至少在登录的过程中消除了。 没有密码的密钥对并不理想,但这是我经常做的事情。 在我的个人内部网络中,我通常使用没有密码的密钥对来自动执行许多事情,如需要身份验证的定时任务。 这不是最安全的选择,因为私钥泄露意味着可以无限制地访问远程用户的帐户,但是相对于在配置文件中存储密码我更喜欢这种方式。
#### 4使用通过密码保护的密钥对进行身份验证以普通用户的身份通过 SSH 连接到远程计算机。
这是处理远程访问的一种非常安全的方式,因为它需要两种不同的身份验证因素来解密:私钥和密码。 如果你只是以交互方式运行 Ansible这可能是理想的设置。 当你运行命令时Ansible 会提示你输入私钥的密码,然后使用密钥对登录到远程系统。 是的,只需使用标准密码登录并且不用在配置文件中指定密码即可完成,但是如果不管怎样都要在命令行上输入密码,那为什么不在保护层添加密钥对呢?
#### 5使用密码保护密钥对进行 SSH 连接,但是使用 ssh-agent “解锁”私钥。
这并不能完美地解决无人值守、自动化的 Ansible 命令的问题,但是它确实也使安全设置变得相当方便。 ssh-agent 程序一次验证密码,然后使用该验证进行后续连接。当我使用 Ansible 时,这是我想要做的事情。如果我是完全值得信任的,我通常仍然使用没有密码的密钥对,但是这通常是因为我在我的家庭服务器上工作,是不是容易受到攻击的。
在配置 SSH 环境时还要记住一些其他注意事项。 也许你可以限制 Ansible 用户(通常是你的本地用户),以便它只能从一个特定的 IP 地址登录。 也许您的 Ansible 服务器可以位于不同的子网中,位于强大的防火墙之后,因此其私钥更难以远程访问。 也许 Ansible 服务器本身没有安装 SSH 服务器,所以根本没法访问。 同样Ansible 的优势之一是它使用 SSH 协议进行通信,而且这是一个你用了多年的协议,你已经把你的系统调整到最适合你的环境了。 我不是宣传“最佳实践”的忠实粉丝,因为实际上最好的做法是考虑你的环境,并选择最适合你情况的设置。
### 权限提升
一旦您的 Ansible 服务器通过 SSH 连接到它的客户端,就需要能够提升特权。 如果你选择了上面的选项 1那么你已经是 root 了,这是一个有争议的问题。 但是由于没有人选择选项 1对吧您需要考虑客户端计算机上的普通用户如何获得访问权限。 Ansible 支持各种权限提升的系统,但在 Linux 中,最常用的选项是 `sudo``su`。 和 SSH 一样,有几种情况需要考虑,虽然肯定还有其他选择。
#### 1使用 su 提升权限。
对于 RedHat/CentOS 用户来说,可能默认是使用 `su` 来获得系统访问权限。 默认情况下,这些系统在安装过程中配置了 root 密码,要想获得特殊访问权限,您需要输入该密码。使用 `su` 的问题在于,虽说它可以给了您完全访问远程系统,而您确实也可以完全访问远程系统。 (是的,这是讽刺。)另外,`su` 程序没有使用密钥对进行身份验证的能力,所以密码必须以交互方式输入或存储在配置文件中。 由于它实际上是 root 密码,因此将其存储在配置文件中听起来像、也确实是一个可怕的想法。
#### 2使用 sudo 提升权限。
这就是 Debian/Ubuntu 系统的配置方式。 正常用户组中的用户可以使用 `sudo` 命令并使用 root 权限执行该命令。 随之而来的是,这仍然存在密码存储或交互式输入的问题。 由于在配置文件中存储用户的密码看起来不太可怕,我猜这是使用 `su` 的一个进步,但是如果密码被泄露,仍然可以完全访问系统。 (毕竟,输入 `sudo``su -` 都将允许用户成为 root 用户,就像拥有 root 密码一样。)
#### 3 使用 sudo 提升权限,并在 sudoers 文件中配置 NOPASSWD。
再次,在我的本地环境中,我就是这么做的。 这并不完美,因为它给予用户帐户无限制的 root 权限,并且不需要任何密码。 但是,当我这样做并且使用没有密码短语的 SSH 密钥对时,我可以让 Ansible 命令更轻松的自动化。 再次提示,虽然这很方便,但这不是一个非常安全的想法。
#### 4使用 sudo 提升权限,并在特定的可执行文件上配置 NOPASSWD。
这个想法可能是安全性和便利性的最佳折衷。 基本上,如果你知道你打算用 Ansible 做什么,那么你可以为远程用户使用的那些应用程序提供 NOPASSWD 权限。 这可能会让人有些困惑,因为 Ansible 使用 Python 来处理很多事情,但是经过足够的尝试和错误,你应该能够弄清原理。 这是额外的工作,但确实消除了一些明显的安全漏洞。
### 计划实施
一旦你决定如何处理 Ansible 认证和权限提升,就需要设置它。 在熟悉 Ansible 之后,您可能会使用该工具来帮助“引导”新客户端,但首先手动配置客户端非常重要,以便您知道发生了什么事情。 将你熟悉的事情变得自动化比从头开始自动化要好。
我已经写过关于 SSH 密钥对的文章,网上有无数的设置类的文章。 来自 Ansible 服务器的简短版本看起来像这样:
```
# ssh-keygen
# ssh-copy-id -i .ssh/id_dsa.pub remoteuser@remote.computer.ip
# ssh remoteuser@remote.computer.ip
```
如果您在创建密钥对时选择不使用密码,最后一步您应该可以直接进入远程计算机,而不用输入密码或密钥串。
为了在 `sudo` 中设置权限提升,您需要编辑 `sudoers` 文件。 你不应该直接编辑文件,而是使用:
```
# sudo visudo
```
这将打开 `sudoers` 文件并允许您安全地进行更改(保存时会进行错误检查,所以您不会意外地因为输入错误将自己锁住)。 这个文件中有一些例子,所以你应该能够弄清楚如何分配你想要的确切的权限。
一旦配置完成,您应该在使用 Ansible 之前进行手动测试。 尝试 SSH 到远程客户端,然后尝试使用您选择的任何方法提升权限。 一旦你确认配置的方式可以连接,就可以安装 Ansible 了。
### 安装 Ansible
由于 Ansible 程序仅安装在一台计算机上,因此开始并不是一件繁重的工作。 Red Hat/Ubuntu 系统的软件包安装有点不同,但都不是很困难。
在 Red Hat/CentOS 中,首先启用 EPEL 库:
```
sudo yum install epel-release
```
然后安装 Ansible
```
sudo yum install ansible
```
在 Ubuntu 中,首先启用 Ansible PPA
```
sudo apt-add-repository spa:ansible/ansible
(press ENTER to access the key and add the repo)
```
然后安装 Ansible
```
sudo apt-get update
sudo apt-get install ansible
```
### Ansible 主机文件配置
Ansible 系统无法知道您希望它控制哪个客户端,除非您给它一个计算机列表。 该列表非常简单,看起来像这样:
```
# file /etc/ansible/hosts
[webservers]
blogserver ansible_host=192.168.1.5
wikiserver ansible_host=192.168.1.10
[dbservers]
mysql_1 ansible_host=192.168.1.22
pgsql_1 ansible_host=192.168.1.23
```
方括号内的部分是指定的组。 单个主机可以列在多个组中,而 Ansible 可以指向单个主机或组。 这也是配置文件,比如纯文本密码的东西将被存储,如果这是你计划的那种设置。 配置文件中的每一行配置一个主机地址,并且可以在 `ansible_host` 语句之后添加多个声明。 一些有用的选项是:
```
ansible_ssh_pass
ansible_become
ansible_become_method
ansible_become_user
ansible_become_pass
```
### Ansible <ruby>保险库<rt>Vault</rt></ruby>
LCTT 译注Vault 作为 ansible 的一项新功能可将例如密码、密钥等敏感数据文件进行加密,而非明文存放)
我也应该注意到,尽管安装程序比较复杂,而且这不是在您首次进入 Ansible 世界时可能会做的事情,但该程序确实提供了一种加密保险库中的密码的方法。 一旦您熟悉 Ansible并且希望将其投入生产将这些密码存储在加密的 Ansible 保险库中是非常理想的。 但是本着先学会爬再学会走的精神,我建议首先在非生产环境下使用无密码方法。
### 系统测试
最后,你应该测试你的系统,以确保客户端可以正常连接。 `ping` 测试将确保 Ansible 计算机可以 `ping` 每个主机:
```
ansible -m ping all
```
运行后,如果 `ping` 成功,您应该看到每个定义的主机显示 `ping` 的消息:`pong`。 这实际上并没有测试认证,只是测试网络连接。 试试这个来测试你的认证:
```
ansible -m shell -a 'uptime' webservers
```
您应该可以看到 webservers 组中每个主机的运行时间命令的结果。
在后续文章中,我计划开始深入 Ansible 管理远程计算机的功能。 我将介绍各种模块,以及如何使用 ad-hoc 模式来完成一些按键操作,这些操作在命令行上单独处理都需要很长时间。 如果您没有从上面的示例 Ansible 命令中获得预期的结果,请花些时间确保身份验证可以工作。 如果遇到困难,请查阅 [Ansible 文档][1]获取更多帮助。
--------------------------------------------------------------------------------
via: http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin
作者:[Shawn Powers][a]
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxjournal.com/users/shawn-powers
[1]:http://docs.ansible.com

View File

@@ -0,0 +1,110 @@
如何使用 syslog-ng 从远程 Linux 机器上收集日志
======
![linuxhero.jpg][1]
如果你的数据中心全是 Linux 服务器,而你就是系统管理员。那么你的其中一项工作内容就是查看服务器的日志文件。但是,如果你在大量的机器上去查看日志文件,那么意味着你需要挨个去登入到机器中来阅读日志文件。如果你管理的机器很多,仅这项工作就可以花费你一天的时间。
另外的选择是,你可以配置一台单独的 Linux 机器去收集这些日志。这将使你的每日工作更加高效。要实现这个目的,有很多的不同系统可供你选择,而 syslog-ng 就是其中之一。
syslog-ng 的不足是文档并不容易梳理。但是,我已经解决了这个问题,我可以通过这种方法马上进行安装和配置 syslog-ng。下面我将在 Ubuntu Server 16.04 上示范这两种方法:
* UBUNTUSERVERVM 的 IP 地址是 192.168.1.118 ,将配置为日志收集器
* UBUNTUSERVERVM2 将配置为一个客户端,发送日志文件到收集器
现在我们来开始安装和配置。
### 安装
安装很简单。为了尽可能容易,我将从标准仓库安装。打开一个终端窗口,运行如下命令:
```
sudo apt install syslog-ng
```
你必须在收集器和客户端的机器上都要运行上面的命令。安装完成之后,你将开始配置。
### 配置收集器
现在,我们开始日志收集器的配置。它的配置文件是 `/etc/syslog-ng/syslog-ng.conf`。syslog-ng 安装完成时就已经包含了一个配置文件。我们不使用这个默认的配置文件,可以使用 `mv /etc/syslog-ng/syslog-ng.conf /etc/syslog-ng/syslog-ng.conf.BAK` 将这个自带的默认配置文件重命名。现在使用 `sudo nano /etc/syslog/syslog-ng.conf` 命令创建一个新的配置文件。在这个文件中添加如下的行:
```
@version: 3.5
@include "scl.conf"
@include "`scl-root`/system/tty10.conf"
options {
time-reap(30);
mark-freq(10);
keep-hostname(yes);
};
source s_local { system(); internal(); };
source s_network {
syslog(transport(tcp) port(514));
};
destination d_local {
file("/var/log/syslog-ng/messages_${HOST}"); };
destination d_logs {
file(
"/var/log/syslog-ng/logs.txt"
owner("root")
group("root")
perm(0777)
); };
log { source(s_local); source(s_network); destination(d_logs); };
```
需要注意的是syslog-ng 使用 514 端口,你需要确保在你的网络上它可以被访问。
保存并关闭这个文件。上面的配置将转存期望的日志文件(由 `system()``internal()` 指出)到 `/var/log/syslog-ng/logs.txt` 中。因此,你需要使用如下的命令去创建所需的目录和文件:
```
sudo mkdir /var/log/syslog-ng
sudo touch /var/log/syslog-ng/logs.txt
```
使用如下的命令启动和启用 syslog-ng
```
sudo systemctl start syslog-ng
sudo systemctl enable syslog-ng
```
### 配置客户端
我们将在客户端上做同样的事情(移动默认配置文件并创建新配置文件)。拷贝下列文本到新的客户端配置文件中:
```
@version: 3.5
@include "scl.conf"
@include "`scl-root`/system/tty10.conf"
source s_local { system(); internal(); };
destination d_syslog_tcp {
syslog("192.168.1.118" transport("tcp") port(514)); };
log { source(s_local);destination(d_syslog_tcp); };
```
请注意:请将 IP 地址修改为收集器的 IP 地址。
保存和关闭这个文件。与在配置为收集器的机器上一样的方法启动和启用 syslog-ng。
## 查看日志文件
回到你的配置为收集器的服务器上,运行这个命令 `sudo tail -f /var/log/syslog-ng/logs.txt`。你将看到包含了收集器和客户端的日志条目的输出(图 A
![图 A][3]
恭喜你syslog-ng 已经正常工作了。你现在可以登入到你的收集器上查看本地机器和远程客户端的日志了。如果你的数据中心有很多 Linux 服务器,在每台服务器上都安装上 syslog-ng 并配置它们作为客户端发送日志到收集器,这样你就不需要登入到每个机器去查看它们的日志了。
--------------------------------------------------------------------------------
via: https://www.techrepublic.com/article/how-to-use-syslog-ng-to-collect-logs-from-remote-linux-machines/
作者:[Jack Wallen][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:
[1]:https://tr1.cbsistatic.com/hub/i/r/2017/01/11/51204409-68e0-49b8-a637-01af26be85f6/resize/770x/688dfedad4ed30ec4baf548c2adb8cd4/linuxhero.jpg
[3]:https://tr4.cbsistatic.com/hub/i/2018/01/09/6a24e5c0-6a29-46d3-8a66-bc72747b5beb/6f94d3e6c6c2121fab6223ed9d8c6aa6/syslognga.jpg

View File

@@ -0,0 +1,138 @@
Linux 下最好的图片截取和视频截录工具
======
![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/best-linux-screenshot-and-screencasting-tools_orig.jpg)
可能有一个困扰你多时的问题,当你想要获取一张屏幕截图向开发者反馈问题,或是在 Stack Overflow 寻求帮助时,你可能缺乏一个可靠的屏幕截图工具去保存和发送截图。在 GNOME 中有一些这种类型的程序和 shell 拓展工具。这里介绍的是 Linux 最好的屏幕截图工具,可以供你截取图片或截录视频。
### 1. Shutter
[![shutter Linux 截图工具](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/shutter-linux-screenshot-taking-tools_orig.jpg)][2]
[Shutter][3] 可以截取任意你想截取的屏幕,是 Linux 最好的截屏工具之一。得到截屏之后,它还可以在保存截屏之前预览图片。它也有一个扩展菜单,展示在 GNOME 顶部面板,使得用户进入软件变得更人性化,非常方便使用。
你可以截取选区、窗口、桌面、当前光标下的窗口、区域、菜单、提示框或网页。Shutter 允许用户直接上传屏幕截图到设置内首选的云服务商。它同样允许用户在保存截图之前编辑器图片;同时提供了一些可自由添加或移除的插件。
终端内键入下列命令安装此工具:
```
sudo add-apt-repository -y ppa:shutter/ppa
sudo apt-get update && sudo apt-get install shutter
```
### 2. Vokoscreen
[![vokoscreen Linux 屏幕录制工具](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vokoscreen-screencasting-tool-for-linux_orig.jpg)][4]
[Vokoscreen][5] 是一款允许你记录和叙述屏幕活动的一款软件。它易于使用,有一个简洁的界面和顶部面板的菜单,方便用户录制视频。
你可以选择记录整个屏幕,或是记录一个窗口,抑或是记录一个选区。自定义记录可以让你轻松得到所需的保存类型,你甚至可以将屏幕录制记录保存为 gif 文件。当然,你也可以使用网络摄像头记录自己的情况,用于你写作教程吸引学习者。记录完成后,你还可以在该应用程序中回放视频记录,这样就不必到处去找你记录的内容。
[![vokoscreen preferences](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vokoscreen-preferences_orig.jpg)][6]
你可以从你的发行版仓库安装 Vocoscreen或者你也可以在 [pkgs.org][7] 选择下载你需要的版本。
```
sudo dpkg -i vokoscreen_2.5.0-1_amd64.deb
```
### 3. OBS
[![obs Linux 视频截录](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/obs-linux-screencasting-tool_orig.jpg)][8]
[OBS][9] 可以用来录制自己的屏幕亦可用来录制互联网上的流媒体。它允许你看到自己所录制的内容或你叙述的屏幕录制。它允许你根据喜好选择录制视频的品质;它也允许你选择文件的保存类型。除了视频录制功能之外,你还可以切换到 Studio 模式,不借助其他软件进行视频编辑。要在你的 Linux 系统中安装 OBS你必须确保你的电脑已安装 FFmpeg。ubuntu 14.04 或更早的版本安装 FFmpeg 可以使用如下命令:
```
sudo add-apt-repository ppa:kirillshkrogalev/ffmpeg-next
sudo apt-get update && sudo apt-get install ffmpeg
```
ubuntu 15.04 以及之后的版本,你可以在终端中键入如下命令安装 FFmpeg
```
sudo apt-get install ffmpeg
```
​如果 FFmpeg 安装完成,在终端中键入如下安装 OBS
```
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt-get update
sudo apt-get install obs-studio
```
### 4. Green Recorder
[![屏幕录制工具](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/green-recording-linux-tool_orig.jpg)][10]
[Green recorder][11] 是一款界面简单的程序,它可以让你记录屏幕。你可以选择包括视频和单纯的音频在内的录制内容,也可以显示鼠标指针,甚至可以跟随鼠标录制视频。同样,你可以选择记录窗口或是屏幕上的选区,以便于只在自己的记录中保留需要的内容;你还可以自定义最终保存的视频的帧数。如果你想要延迟录制,它提供给你一个选项可以设置出你想要的延迟时间。它还提供一个录制结束后的命令运行选项,这样,就可以在视频录制结束后立即运行。​
在终端中键入如下命令来安装 green recorder
```
sudo add-apt-repository ppa:fossproject/ppa
sudo apt update && sudo apt install green-recorder
```
### 5. Kazam
[![kazam screencasting tool for linux](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/kazam-screencasting-tool-for-linux_orig.jpg)][12]
[Kazam][13] 在几乎所有使用截图工具的 Linux 用户中都十分流行。这是一款简单直观的软件它可以让你做一个屏幕截图或是视频录制也同样允许在屏幕截图或屏幕录制之前设置延时。它可以让你选择录制区域窗口或是你想要抓取的整个屏幕。Kazam 的界面接口安排的非常好和其它软件相比毫无复杂感。它的特点就是让你优雅的截图。Kazam 在系统托盘和菜单中都有图标,无需打开应用本身,你就可以开始屏幕截图。​​
终端中键入如下命令来安装 Kazam
```
sudo apt-get install kazam
```
​如果没有找到该 PPA你需要使用下面的命令安装它
```
sudo add-apt-repository ppa:kazam-team/stable-series
sudo apt-get update && sudo apt-get install kazam
```
### 6. GNOME 扩展截屏工具
[![gnome screenshot extension](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnome-screenshot-extension-compressed_orig.jpg)][1]
GNOME 的一个扩展软件就叫做 screenshot tool它常驻系统面板如果你没有设置禁用它的话。由于它是常驻系统面板的软件所以它会一直等待你的调用获取截图方便和容易获取是它最主要的特点除非你在调整工具中禁用否则它将一直在你的系统面板中。这个工具也有用来设置首选项的选项窗口。在 extensions.gnome.org 中搜索 “_Screenshot Tool_”在你的 GNOME 中安装它。
你需要安装 gnome 扩展的 chrome 扩展组件和 GNOME 调整工具才能使用这个工具。
[![gnome screenshot 拓展选项](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnome-screenshot-extension-preferences_orig.jpg)][14]
当你碰到一个问题,不知道怎么处理,想要在 [Linux 社区][15] 或者其他开发社区分享、寻求帮助的的时候, **Linux 截图工具** 尤其合适。学习开发、程序或者其他任何事物都会发现这些工具在分享截图的时候真的很实用。Youtube 用户和教程制作爱好者会发现视频截录工具真的很适合录制可以发表的教程。
--------------------------------------------------------------------------------
via: http://www.linuxandubuntu.com/home/best-linux-screenshot-screencasting-tools
作者:[linuxandubuntu][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.linuxandubuntu.com
[1]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnome-screenshot-extension-compressed_orig.jpg
[2]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/shutter-linux-screenshot-taking-tools_orig.jpg
[3]:http://shutter-project.org/
[4]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vokoscreen-screencasting-tool-for-linux_orig.jpg
[5]:https://github.com/vkohaupt/vokoscreen
[6]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vokoscreen-preferences_orig.jpg
[7]:https://pkgs.org/download/vokoscreen
[8]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/obs-linux-screencasting-tool_orig.jpg
[9]:https://obsproject.com/
[10]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/green-recording-linux-tool_orig.jpg
[11]:https://github.com/foss-project/green-recorder
[12]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/kazam-screencasting-tool-for-linux_orig.jpg
[13]:https://launchpad.net/kazam
[14]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/gnome-screenshot-extension-preferences_orig.jpg
[15]:http://www.linuxandubuntu.com/home/top-10-communities-to-help-you-learn-linux

View File

@@ -0,0 +1,171 @@
如何在 Linux 上安装/更新 Intel 微码固件
======
如果你是一个 Linux 系统管理方面的新手,如何在 Linux 上使用命令行方式去安装或者更新 Intel/AMD CPU 的微码固件呢?
<ruby>微码<rt>microcode</rt></ruby>就是由 Intel/AMD 提供的 CPU 固件。Linux 的内核可以在引导时更新 CPU 固件,而无需 BIOS 更新。处理器的微码保存在内存中,在每次启动系统时,内核可以更新这个微码。这些来自 Intel/AMD 的微码的更新可以去修复 bug 或者使用补丁来防范 bug。这篇文章演示了如何使用包管理器或由 lntel 提供的 Linux 处理器微码更新来安装 AMD 或 Intel 的微码更新。
### 如何查看当前的微码状态
以 root 用户运行下列命令:
```
# dmesg | grep microcode
```
输出如下:
[![Verify microcode update on a CentOS RHEL Fedora Ubuntu Debian Linux][1]][1]
请注意,你的 CPU 在这里完全有可能出现没有可用的微码更新的情况。如果是这种情况,它的输出可能是如下这样的:
```
[ 0.952699] microcode: sig=0x306a9, pf=0x10, revision=0x1c
[ 0.952773] microcode: Microcode Update Driver: v2.2.
```
### 如何在 Linux 上使用包管理器去安装微码固件更新
对于运行在 x86/amd64 架构的 CPU 上的 Linux 系统Linux 自带了工具去更改或者部署微码固件。在 Linux 上安装 AMD 或者 Intel 的微码固件的过程如下:
1. 打开终端应用程序
2. Debian/Ubuntu Linux 用户推输入:`sudo apt install intel-microcode`
3. CentOS/RHEL Linux 用户输入:`sudo yum install microcode_ctl`
对于流行的 Linux 发行版,这个包的名字一般如下
* `microcode_ctl``linux-firmware` —— CentOS/RHEL 微码更新包
* `intel-microcode` —— Debian/Ubuntu 和衍生发行版的适用于 Intel CPU 的微码更新包
* `amd64-microcode` —— Debian/Ubuntu 和衍生发行版的适用于 AMD CPU 的微码固件
* `linux-firmware` —— 适用于 AMD CPU 的 Arch Linux 发行版的微码固件(你不用做任何操作,它是默认安装的)
* `intel-ucode` —— 适用于 Intel CPU 的 Arch Linux 发行版微码固件
* `microcode_ctl``linux-firmware``ucode-intel` —— Suse/OpenSUSE Linux 微码更新包
**警告 :在某些情况下,微码更新可能会导致引导问题,比如,服务器在引导时被挂起或者自动重置。以下的步骤是在我的机器上运行过的,并且我是一个经验丰富的系统管理员。对于由此引发的任何硬件故障,我不承担任何责任。在做固件更新之前,请充分评估操作风险!**
#### 示例
在使用 Intel CPU 的 Debian/Ubuntu Linux 系统上,输入如下的 [apt 命令][2]/[apt-get 命令][3]
```
$ sudo apt-get install intel-microcode
```
示例输出如下:
[![How to install Intel microcode firmware Linux][4]][4]
你 [必须重启服务器以激活微码][5] 更新:
```
$ sudo reboot
```
重启后检查微码状态:
```
# dmesg | grep 'microcode'
```
示例输出如下:
```
[ 0.000000] microcode: microcode updated early to revision 0x1c, date = 2015-02-26
[ 1.604672] microcode: sig=0x306a9, pf=0x10, revision=0x1c
[ 1.604976] microcode: Microcode Update Driver: v2.01 <tigran@aivazian.fsnet.co.uk>, Peter Oruba
```
如果你使用的是 RHEL/CentOS 系统,使用 [yum 命令][6] 尝试去安装或者更新以下两个包:
```
$ sudo yum install linux-firmware microcode_ctl
$ sudo reboot
$ sudo dmesg | grep 'microcode'
```
### 如何更新/安装从 Intel 网站上下载的微码
只有在你的 CPU 制造商建议这么做的时候,才可以使用下列的方法去更新/安装微码,除此之外,都应该使用上面的方法去更新。大多数 Linux 发行版都可以通过包管理器来维护、更新微码。使用包管理器的方法是经过测试的,对大多数用户来说是最安全的方式。
#### 如何为 Linux 安装 Intel 处理器微码块20180108 发布)
首先通过 AMD 或 [Intel 网站][7] 去获取最新的微码固件。在本示例中,我有一个名称为 `~/Downloads/microcode-20180108.tgz` 的文件(不要忘了去验证它的检验和),它的用途是去防范 `meltdown/Spectre` bug。先使用 `tar` 命令去提取它:
```
$ mkdir firmware
$ cd firmware
$ tar xvf ~/Downloads/microcode-20180108.tgz
$ ls -l
```
示例输出如下:
```
drwxr-xr-x 2 vivek vivek 4096 Jan 8 12:41 intel-ucode
-rw-r--r-- 1 vivek vivek 4847056 Jan 8 12:39 microcode.dat
-rw-r--r-- 1 vivek vivek 1907 Jan 9 07:03 releasenote
```
> 我只在 CentOS 7.x/RHEL、 7.x/Debian 9.x 和 Ubuntu 17.10 上测试了如下操作。如果你没有找到 `/sys/devices/system/cpu/microcode/reload` 文件的话,更老的发行版所带的更老的内核也许不能使用此方法。参见下面的讨论。请注意,在应用了固件更新之后,有一些客户遇到了系统重启现象。特别是对于[那些运行 Intel Broadwell 和 Haswell CPU][12] 的用于客户机和数据中心服务器上的系统。不要在 Intel Broadwell 和 Haswell CPU 上应用 20180108 版本。尽可能使用软件包管理器方式。
检查一下,确保存在 `/sys/devices/system/cpu/microcode/reload`
```
$ ls -l /sys/devices/system/cpu/microcode/reload
```
你必须使用 [cp 命令][8] 拷贝 `intel-ucode` 目录下的所有文件到 `/lib/firmware/intel-ucode/` 下面:
```
$ sudo cp -v intel-ucode/* /lib/firmware/intel-ucode/
```
你只需要将 `intel-ucode` 这个目录整个拷贝到 `/lib/firmware/` 目录下即可。然后在重新加载接口中写入 `1` 去重新加载微码文件:
```
# echo 1 > /sys/devices/system/cpu/microcode/reload
```
更新现有的 initramfs以便于下次启动时它能通过内核来加载
```
$ sudo update-initramfs -u
$ sudo reboot
```
重启后通过以下的命令验证微码是否已经更新:
```
# dmesg | grep microcode
```
到此为止,就是更新处理器微码的全部步骤。如果一切顺利的话,你的 Intel CPU 的固件将已经是最新的版本了。
### 关于作者
作者是 nixCraft 的创始人、一位经验丰富的系统管理员、Linux/Unix 操作系统 shell 脚本培训师。他与全球的包括 IT、教育、国防和空间研究、以及非盈利组织等各行业的客户一起工作。可以在 [Twitter][9]、[Facebook][10]、[Google+][11] 上关注他。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/install-update-intel-microcode-firmware-linux/
作者:[Vivek Gite][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/media/new/faq/2018/01/Verify-microcode-update-on-a-CentOS-RHEL-Fedora-Ubuntu-Debian-Linux.jpg
[2]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ "See Linux/Unix apt command examples for more info"
[3]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html "See Linux/Unix apt-get command examples for more info"
[4]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-Intel-microcode-firmware-Linux.jpg
[5]:https://www.cyberciti.biz/faq/howto-reboot-linux/
[6]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ "See Linux/Unix yum command examples for more info"
[7]:https://downloadcenter.intel.com/download/27431/Linux-Processor-Microcode-Data-File
[8]:https://www.cyberciti.biz/faq/cp-copy-command-in-unix-examples/ "See Linux/Unix cp command examples for more info"
[9]:https://twitter.com/nixcraft
[10]:https://facebook.com/nixcraft
[11]:https://plus.google.com/+CybercitiBiz
[12]:https://newsroom.intel.com/news/intel-security-issue-update-addressing-reboot-issues/

View File

@@ -0,0 +1,232 @@
如何在 Linux 上安装应用程序
=====
> 学习在你的 Linux 计算机上摆弄那些软件。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux-penguins.png?itok=yKOpaJM_)
图片提供Internet Archive Book Images。由 Opensource.com 修改。CC BY-SA 4.0
如何在 Linux 上安装应用程序?因为有许多操作系统,这个问题不止有一个答案。应用程序可以可以来自许多来源 —— 几乎不可能数的清,并且每个开发团队都可以以他们认为最好的方式提供软件。知道如何安装你所得到的软件是成为操作系统高级用户的一部分。
### 仓库
十多年来Linux 已经在使用软件库来分发软件。在这种情况下“仓库”是一个托管可安装软件包的公共服务器。Linux 发行版提供了一条命令,以及该命令的图形界面,用于从服务器获取软件并将其安装到你的计算机。这是一个非常简单的概念,它已经成为所有主流手机操作系统的模式,最近,该模式也成为了两大闭源计算机操作系统的“应用商店”。
![Linux repository][2]
*不是应用程序商店*
从软件仓库安装是在 Linux 上安装应用程序的主要方法,它应该是你寻找想要安装的任何应用程序的首选地方。
从软件仓库安装,通常需要一个命令,如:
```
$ sudo dnf install inkscape
```
实际使用的命令取决于你所使用的 Linux 发行版。Fedora 使用 `dnf`OpenSUSE 使用 `zypper`Debian 和 Ubuntu 使用 `apt`Slackware 使用 `sbopkg`FreeBSD 使用 `pkg_add`,而基于 lllumos 的 Openlndiana 使用 `pkg`。无论你使用什么,该命令通常要搜索你想要安装应用程序的正确名称,因为有时候你认为的软件名称不是它官方或独有的名称:
```
$ sudo dnf search pyqt
PyQt.x86_64 : Python bindings for Qt3
PyQt4.x86_64 : Python bindings for Qt4
python-qt5.x86_64 : PyQt5 is Python bindings for Qt5
```
一旦你找到要安装的软件包的名称后,使用 `install` 子命令执行实际的下载和自动安装:
```
$ sudo dnf install python-qt5
```
有关从软件仓库安装的具体信息,请参阅你的 Linux 发行版的文档。
图形工具通常也是如此。搜索你认为你想要的,然后安装它。
![](https://opensource.com/sites/default/files/u128651/apper.png)
与底层命令一样,图形安装程序的名称取决于你正在运行的 Linux 发行版。相关的应用程序通常使用“软件software”或“包package”等关键字进行标记因此请在你的启动项或菜单中搜索这些词汇然后你将找到所需的内容。 由于开源全由用户来选择所以如果你不喜欢你的发行版提供的图形用户界面GUI那么你可以选择安装替代品。 你知道该如何做到这一点。
#### 额外仓库
你的 Linux 发行版为其打包的软件提供了标准仓库,通常也有额外的仓库。例如,[EPEL][3] 服务于 Red Hat Enterprise Linux 和 CentOS[RPMFusion][4] 服务于 FedoraUbuntu 有各种级别的支持以及个人包存档PPA[Packman][5] 为 OpenSUSE 提供额外的软件以及 [SlackBuilds.org][6] 为 Slackware 提供社区构建脚本。
默认情况下,你的 Linux 操作系统设置为只查看其官方仓库,因此如果你想使用其他软件集合,则必须自己添加额外库。你通常可以像安装软件包一样安装仓库。实际上,当你安装例如 [GNU Ring][7] 视频聊天,[Vivaldi][8] web 浏览器,谷歌浏览器等许多软件时,你的实际安装是访问他们的私有仓库,从中将最新版本的应用程序安装到你的机器上。
![Installing a repo][10]
*安装仓库*
你还可以通过编辑文本文件将仓库手动添加到你的软件包管理器的配置目录,或者运行命令来添加添加仓库。像往常一样,你使用的确切命令取决于 Linux 发行版本。例如,这是一个 `dnf` 命令,它将一个仓库添加到系统中:
```
$ sudo dnf config-manager --add-repo=http://example.com/pub/centos/7
```
### 不使用仓库来安装应用程序
仓库模型非常流行,因为它提供了用户(你)和开发人员之间的链接。重要更新发布之后,系统会提示你接受更新,并且你可以从一个集中位置接受所有更新。
然而,有时候一个软件包还没有放到仓库中时。这些安装包有几种形式。
#### Linux 包
有时候,开发人员会以通用的 Linux 打包格式分发软件,例如 RPM、DEB 或较新但非常流行的 FlatPak 或 Snap 格式。你不是访问仓库下载的,你只是得到了这个包。
例如,视频编辑器 [Lightworks][11] 为 APT 用户提供了一个 `.deb` 文件RPM 用户提供了 `.rpm` 文件。当你想要更新时,可以到网站下载最新的适合的文件。
这些一次性软件包可以使用从仓库进行安装时所用的一样的工具进行安装。如果双击下载的软件包,图形安装程序将启动并逐步完成安装过程。
或者,你可以从终端进行安装。这里的区别在于你从互联网下载的独立包文件不是来自仓库。这是一个“本地”安装,这意味着你的软件安装包不需要下载来安装。大多数软件包管理器都是透明处理的:
```
$ sudo dnf install ~/Downloads/lwks-14.0.0-amd64.rpm
```
在某些情况下,你需要采取额外的步骤才能使应用程序运行,因此请仔细阅读有关你正在安装软件的文档。
#### 通用安装脚本
一些开发人员以几种通用格式发布他们的包。常见的扩展名包括 `.run``.sh`。NVIDIA 显卡驱动程序、像 Nuke 和 Mari 这样的 Foundry visual FX 软件包以及来自 [GOG][12] 的许多非 DRM 游戏都是用这种安装程序。LCTT 译注DRM 是数字版权管理。)
这种安装模式依赖于开发人员提供安装“向导”。一些安装程序是图形化的,而另一些只是在终端中运行。
有两种方式来运行这些类型的安装程序。
1、 你可以直接从终端运行安装程序:
```
$ sh ./game/gog_warsow_x.y.z.sh
```
2、 另外,你可以通过标记其为可执行文件来运行它。要标记为安装程序可执行文件,右键单击它的图标并选择其属性。
![Giving an installer executable permission][14]
*给安装程序可执行权限。*
一旦你允许其运行,双击图标就可以安装了。
![GOG installer][16]
*GOG 安装程序*
对于其余的安装程序,只需要按照屏幕上的说明进行操作。
#### AppImage 便携式应用程序
AppImage 格式对于 Linux 相对来说比较新,尽管它的概念是基于 NeXT 和 Rox 的。这个想法很简单:运行应用程序所需的一切都应该放在一个目录中,然后该目录被视为一个“应用程序”。要运行该应用程序,只需双击该图标即可运行。不需要也要不应该把应用程序安装在传统意义的地方;它从你在硬盘上的任何地方运行都行。
尽管它可以作为独立应用运行,但 AppImage 通常提供一些系统集成。
![AppImage system integration][18]
*AppImage 系统集成*
如果你接受此条件,则将一个本地的 `.desktop` 文件安装到你的主目录。`.desktop` 文件是 Linux 桌面的应用程序菜单和 mimetype 系统使用的一个小配置文件。实质上,只是将桌面配置文件放置在主目录的应用程序列表中“安装”应用程序,而不实际安装它。你获得了安装某些东西的所有好处,以及能够在本地运行某些东西的好处,即“便携式应用程序”。
#### 应用程序目录
有时,开发人员只是编译一个应用程序,然后将结果发布到下载中,没有安装脚本,也没有打包。通常,这意味着你下载了一个 TAR 文件,然后 [解压缩][19],然后双击可执行文件(通常是你下载软件的名称)。
![Twine downloaded for Linux][21]
*下载 Twine*
当使用这种软件方式交付时,你可以将它放在你下载的地方,当你需要它时,你可以手动启动它,或者你可以自己进行快速但是麻烦的安装。这包括两个简单的步骤:
1. 将目录保存到一个标准位置,并在需要时手动启动它。
2. 将目录保存到一个标准位置,并创建一个 `.desktop` 文件,将其集成到你的系统中。
如果你只是为自己安装应用程序,那么传统上会在你的主目录中放个 `bin` (“<ruby>二进制文件<rt>binary</rt></ruby>” 的简称)目录作为本地安装的应用程序和脚本的存储位置。如果你的系统上有其他用户需要访问这些应用程序,传统上将二进制文件放置在 `/opt` 中。最后,这取决于你存储应用程序的位置。
下载通常以带版本名称的目录进行,如 `twine_2.13` 或者 `pcgen-v6.07.04`。由于假设你将在某个时候更新应用程序,因此将版本号删除或创建目录的符号链接是个不错的主意。这样,即使你更新应用程序本身,为应用程序创建的启动程序也可以保持不变。
要创建一个 `.desktop` 启动文件,打开一个文本编辑器并创建一个名为 `twine.desktop` 的文件。[桌面条目规范][22] 由 [FreeDesktop.org][23] 定义。下面是一个简单的启动器,用于一个名为 Twine 的游戏开发 IDE安装在系统范围的 `/opt` 目录中:
```
[Desktop Entry]
Encoding=UTF-8
Name=Twine
GenericName=Twine
Comment=Twine
Exec=/opt/twine/Twine
Icon=/usr/share/icons/oxygen/64x64/categories/applications-games.png
Terminal=false
Type=Application
Categories=Development;IDE;
```
棘手的一行是 `Exec` 行。它必须包含一个有效的命令来启动应用程序。通常它只是你下载的东西的完整路径但在某些情况下它更复杂一些。例如Java 应用程序可能需要作为 Java 自身的参数启动。
```
Exec=java -jar /path/to/foo.jar
```
有时,一个项目包含一个可以运行的包装脚本,这样你就不必找出正确的命令:
```
Exec=/opt/foo/foo-launcher.sh
```
在这个 Twine 例子中,没有与该下载的软件捆绑的图标,因此示例 `.desktop` 文件指定了 KDE 桌面附带的通用游戏图标。你可以使用类似的解决方法,但如果你更具艺术性,可以创建自己的图标,或者可以在 Internet 上搜索一个好的图标。只要 `Icon` 行指向一个有效的 PNG 或 SVG 文件,你的应用程序就会以该图标为代表。
示例脚本还将应用程序类别主要设置为 Development因此在 KDE、GNOME 和大多数其他应用程序菜单中Twine 出现在开发类别下。
为了让这个例子出现在应用程序菜单中,把 `twine.desktop` 文件放这到两个地方之一:
* 如果你将应用程序存储在你自己的家目录下,那么请将其放在 `~/.local/share/applications`
* 如果你将应用程序存储在 `/opt` 目录或者其他系统范围的位置,并希望它出现在所有用户的应用程序菜单中,请将它放在 `/usr/share/applications` 目录中。
现在,该应用程序已安装,因为它需要与系统的其他部分集成。
### 从源代码编译
最后,还有真正的通用格式安装格式:源代码。从源代码编译应用程序是学习如何构建应用程序,如何与系统交互以及如何定制应用程序的好方法。尽管如此,它绝不是一个点击按钮式过程。它需要一个构建环境,通常需要安装依赖库和头文件,有时还要进行一些调试。
要了解更多关于从源代码编译的内容,请阅读[我这篇文章][24]。
### 现在你明白了
有些人认为安装软件是一个神奇的过程,只有开发人员理解,或者他们认为它“激活”了应用程序,就好像二进制可执行文件在“安装”之前无效。学习许多不同的安装方法会告诉你安装实际上只是“将文件从一个地方复制到系统中适当位置”的简写。 没有什么神秘的。只要你去了解每次安装,不是期望应该如何发生,并且寻找开发者为安装过程设置了什么,那么通常很容易,即使它与你的习惯不同。
重要的是安装器要诚实于你。 如果你遇到未经你的同意尝试安装其他软件的安装程序(或者它可能会以混淆或误导的方式请求同意),或者尝试在没有明显原因的情况下对系统执行检查,则不要继续安装。
好的软件是灵活的、诚实的、开放的。 现在你知道如何在你的计算机上获得好软件了。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/1/how-install-apps-linux
作者:[Seth Kenlon][a]
译者:[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/seth
[1]:/file/382591
[2]:https://opensource.com/sites/default/files/u128651/repo.png (Linux repository)
[3]:https://fedoraproject.org/wiki/EPEL
[4]:http://rpmfusion.org
[5]:http://packman.links2linux.org/
[6]:http://slackbuilds.org
[7]:https://ring.cx/en/download/gnu-linux
[8]:http://vivaldi.com
[9]:/file/382566
[10]:https://opensource.com/sites/default/files/u128651/access.png (Installing a repo)
[11]:https://www.lwks.com/
[12]:http://gog.com
[13]:/file/382581
[14]:https://opensource.com/sites/default/files/u128651/exec.jpg (Giving an installer executable permission)
[15]:/file/382586
[16]:https://opensource.com/sites/default/files/u128651/gog.jpg (GOG installer)
[17]:/file/382576
[18]:https://opensource.com/sites/default/files/u128651/appimage.png (AppImage system integration)
[19]:https://opensource.com/article/17/7/how-unzip-targz-file
[20]:/file/382596
[21]:https://opensource.com/sites/default/files/u128651/twine.jpg (Twine downloaded for Linux)
[22]:https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
[23]:http://freedesktop.org
[24]:https://opensource.com/article/17/10/open-source-cats

View File

@@ -0,0 +1,119 @@
fold 命令入门示例教程
======
![](https://www.ostechnix.com/wp-content/uploads/2018/01/Fold-Command-2-720x340.png)
你有没有发现自己在某种情况下想要折叠或中断命令的输出,以适应特定的宽度?在运行虚拟机的时候,我遇到了几次这种的情况,特别是没有 GUI 的服务器。 以防万一,如果你想限制一个命令的输出为一个特定的宽度,现在看看这里! `fold` 命令在这里就能派的上用场了! `fold` 命令会以适合指定的宽度调整输入文件中的每一行,并将其打印到标准输出。
在这个简短的教程中,我们将看到 `fold` 命令的用法,带有实例。
### fold 命令示例教程
`fold` 命令是 GNU coreutils 包的一部分,所以我们不用为安装的事情烦恼。
`fold` 命令的典型语法:
```
fold [OPTION]... [FILE]...
```
请允许我向您展示一些示例,以便您更好地了解 `fold` 命令。 我有一个名为 `linux.txt` 文件,内容是随机的。
![][2]
要将上述文件中的每一行换行为默认宽度,请运行:
```
fold linux.txt
```
每行 80 列是默认的宽度。 这里是上述命令的输出:
![][3]
正如你在上面的输出中看到的,`fold` 命令已经将输出限制为 80 个字符的宽度。
当然,我们可以指定您的首选宽度,例如 50如下所示
```
fold -w50 linux.txt
```
示例输出:
![][4]
我们也可以将输出写入一个新的文件,如下所示:
```
fold -w50 linux.txt > linux1.txt
```
以上命令将把 `linux.txt` 的行宽度改为 50 个字符,并将输出写入到名为 `linux1.txt` 的新文件中。
让我们检查一下新文件的内容:
```
cat linux1.txt
```
![][5]
你有没有注意到前面的命令的输出? 有些词在行之间被中断。 为了解决这个问题,我们可以使用 `-s` 标志来在空格处换行。
以下命令将给定文件中的每行调整为宽度 50并在空格处换到新行
```
fold -w50 -s linux.txt
```
示例输出:
![][6]
看清楚了吗? 现在,输出很清楚。 换到新行中的单词都是用空格隔开的,所在行单词的长度大于 50 的时候就会被调整到下一行。
在所有上面的例子中,我们用列来限制输出宽度。 但是,我们可以使用 `-b` 选项将输出的宽度强制为指定的字节数。 以下命令以 20 个字节中断输出。
```
fold -b20 linux.txt
```
示例输出:
![][7]
另请阅读:
- [Uniq 命令入门级示例教程][8]
有关更多详细信息,请参阅 man 手册页。
```
man fold
```
这些就是所有的内容了。 您现在知道如何使用 `fold` 命令以适应特定的宽度来限制命令的输出。 我希望这是有用的。 我们将每天发布更多有用的指南。 敬请关注!
干杯!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/fold-command-tutorial-examples-beginners/
作者:[SK][a]
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[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/2018/01/fold-command-1.png
[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/fold-command-2.png
[4]:http://www.ostechnix.com/wp-content/uploads/2018/01/fold-command-3-1.png
[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/fold-command-4.png
[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/fold-command-5-1.png
[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/fold-command-6-1.png
[8]:https://www.ostechnix.com/uniq-command-tutorial-examples-beginners/

View File

@@ -0,0 +1,95 @@
Partclone多功能的分区和克隆的自由软件
======
![](https://www.fossmint.com/wp-content/uploads/2018/01/Partclone-Backup-Tool-For-Linux.png)
[Partclone][1] 是由 Clonezilla 的开发者们开发的用于创建和克隆分区镜像的自由开源软件。实际上Partclone 是 Clonezilla 所基于的工具之一。
它为用户提供了备份与恢复已用分区的工具,并与多个文件系统高度兼容,这要归功于它能够使用像 e2fslibs 这样的现有库来读取和写入分区,例如 ext2。
它最大的优点是支持各种格式,包括 ext2、ext3、ext4、hfs+、reiserfs、reiser4、btrfs、vmfs3、vmfs5、xfs、jfs、ufs、ntfs、fat12/16/32、exfat、f2fs 和 nilfs。
它还有许多的程序,包括 partclone.ext2ext3ext4、partclone.ntfs、partclone.exfat、partclone.hfsp 和 partclone.vmfsv3和v5 等等。
### Partclone中的功能
* 免费软件: Partclone 免费供所有人下载和使用。
  * 开源: Partclone 是在 GNU GPL 许可下发布的,并在 [GitHub][2] 上公开。
  * 跨平台:适用于 Linux、Windows、MAC、ESX 文件系统备份/恢复和 FreeBSD。
  * 一个在线的[文档页面][3],你可以从中查看帮助文档并跟踪其 GitHub 问题。
  * 为初学者和专业人士提供的在线[用户手册][4]。
  * 支持救援。
  * 克隆分区成镜像文件。
  * 将镜像文件恢复到分区。
  * 快速复制分区。
  * 支持 raw 克隆。
  * 显示传输速率和持续时间。
  * 支持管道。
  * 支持 crc32 校验。
  * 支持 ESX vmware server 的 vmfs 和 FreeBSD 的文件系统 ufs。
Partclone 中还捆绑了更多功能,你可以在[这里][5]查看其余的功能。
- [下载 Linux 中的 Partclone][6]
### 如何安装和使用 Partclone
在 Linux 上安装 Partclone。
```
$ sudo apt install partclone [On Debian/Ubuntu]
$ sudo yum install partclone [On CentOS/RHEL/Fedora]
```
克隆分区为镜像。
```
# partclone.ext4 -d -c -s /dev/sda1 -o sda1.img
```
将镜像恢复到分区。
```
# partclone.ext4 -d -r -s sda1.img -o /dev/sda1
```
分区到分区克隆。
```
# partclone.ext4 -d -b -s /dev/sda1 -o /dev/sdb1
```
显示镜像信息。
```
# partclone.info -s sda1.img
```
检查镜像。
```
# partclone.chkimg -s sda1.img
```
你是 Partclone 的用户吗?我最近在 [Deepin Clone][7] 上写了一篇文章显然Partclone 有擅长处理的任务。你使用其他备份和恢复工具的经验是什么?
请在下面的评论区与我们分享你的想法和建议。
--------------------------------------------------------------------------------
via: https://www.fossmint.com/partclone-linux-backup-clone-tool/
作者:[Martins D. Okoi][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.fossmint.com/author/dillivine/
[1]:https://partclone.org/
[2]:https://github.com/Thomas-Tsai/partclone
[3]:https://partclone.org/help/
[4]:https://partclone.org/usage/
[5]:https://partclone.org/features/
[6]:https://partclone.org/download/
[7]:https://www.fossmint.com/deepin-clone-system-backup-restore-for-deepin-users/

View File

@@ -0,0 +1,224 @@
Linux 启动过程分析
======
> 理解运转良好的系统对于处理不可避免的故障是最好的准备。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_boot.png?itok=FUesnJQp)
*图片由企鹅和靴子“赞助”,由 Opensource.com 修改。CC BY-SA 4.0。*
关于开源软件最古老的笑话是:“代码是<ruby>自具文档化的<rt>self-documenting</rt></ruby>”。经验表明,阅读源代码就像听天气预报一样:明智的人依然出门会看看室外的天气。本文讲述了如何运用调试工具来观察和分析 Linux 系统的启动。分析一个功能正常的系统启动过程,有助于用户和开发人员应对不可避免的故障。
从某些方面看,启动过程非常简单。内核在单核上以单线程和同步状态启动,似乎可以理解。但内核本身是如何启动的呢?[initrdinitial ramdisk][1] 和<ruby>引导程序<rt>bootloader</rt></ruby>具有哪些功能?还有,为什么以太网端口上的 LED 灯是常亮的呢?
请继续阅读寻找答案。在 GitHub 上也提供了 [介绍演示和练习的代码][2]。
### 启动的开始OFF 状态
#### <ruby>局域网唤醒<rt>Wake-on-LAN</rt></ruby>
OFF 状态表示系统没有上电没错吧表面简单其实不然。例如如果系统启用了局域网唤醒机制WOL以太网指示灯将亮起。通过以下命令来检查是否是这种情况
```
# sudo ethtool <interface name>
```
其中 `<interface name>` 是网络接口的名字,比如 `eth0`。(`ethtool` 可以在同名的 Linux 软件包中找到。)如果输出中的 `Wake-on` 显示 `g`,则远程主机可以通过发送 [<ruby>魔法数据包<rt>MagicPacket</rt></ruby>][3] 来启动系统。如果您无意远程唤醒系统,也不希望其他人这样做,请在系统 BIOS 菜单中将 WOL 关闭,或者用以下方式:
```
# sudo ethtool -s <interface name> wol d
```
响应魔法数据包的处理器可能是网络接口的一部分,也可能是 [<ruby>底板管理控制器<rt>Baseboard Management Controller</rt></ruby>][4]BMC
#### 英特尔管理引擎、平台控制器单元和 Minix
BMC 不是唯一的在系统关闭时仍在监听的微控制器MCU。x86_64 系统还包含了用于远程管理系统的英特尔管理引擎IME软件套件。从服务器到笔记本电脑各种各样的设备都包含了这项技术它开启了如 KVM 远程控制和英特尔功能许可服务等 [功能][5]。根据 [Intel 自己的检测工具][7][IME 存在尚未修补的漏洞][6]。坏消息是,要禁用 IME 很难。Trammell Hudson 发起了一个 [me_cleaner 项目][8],它可以清除一些相对恶劣的 IME 组件,比如嵌入式 Web 服务器,但也可能会影响运行它的系统。
IME 固件和<ruby>系统管理模式<rt>System Management Mode</rt></ruby>SMM软件是 [基于 Minix 操作系统][9] 的,并运行在单独的<ruby>平台控制器单元<rt>Platform Controller Hub</rt></ruby>上LCTT 译注:即南桥芯片),而不是主 CPU 上。然后SMM 启动位于主处理器上的<ruby>通用可扩展固件接口<rt>Universal Extensible Firmware Interface</rt></ruby>UEFI软件相关内容 [已被提及多次][10]。Google 的 Coreboot 小组已经启动了一个雄心勃勃的 [<ruby>非扩展性缩减版固件<rt>Non-Extensible Reduced Firmware</rt></ruby>][11]NERF项目其目的不仅是要取代 UEFI还要取代早期的 Linux 用户空间组件,如 systemd。在我们等待这些新成果的同时Linux 用户现在就可以从 Purism、System76 或 Dell 等处购买 [禁用了 IME][12] 的笔记本电脑,另外 [带有 ARM 64 位处理器笔记本电脑][13] 还是值得期待的。
#### 引导程序
除了启动那些问题不断的间谍软件外,早期引导固件还有什么功能呢?引导程序的作用是为新上电的处理器提供通用操作系统(如 Linux所需的资源。在开机时不但没有虚拟内存在控制器启动之前连 DRAM 也没有。然后引导程序打开电源并扫描总线和接口以定位内核镜像和根文件系统的位置。U-Boot 和 GRUB 等常见的引导程序支持 USB、PCI 和 NFS 等接口,以及更多的嵌入式专用设备,如 NOR 闪存和 NAND 闪存。引导程序还与 [<ruby>可信平台模块<rt>Trusted Platform Module</rt></ruby>][14]TPM等硬件安全设备进行交互在启动最开始建立信任链。
![Running the U-boot bootloader][16]
*在构建主机上的沙盒中运行 U-boot 引导程序。*
包括树莓派、任天堂设备、汽车主板和 Chromebook 在内的系统都支持广泛使用的开源引导程序 [U-Boot][17]。它没有系统日志当发生问题时甚至没有任何控制台输出。为了便于调试U-Boot 团队提供了一个沙盒可以在构建主机甚至是夜间的持续集成CI系统上测试补丁程序。如果系统上安装了 Git 和 GNU Compiler CollectionGCC等通用的开发工具使用 U-Boot 沙盒会相对简单:
```
# git clone git://git.denx.de/u-boot; cd u-boot
# make ARCH=sandbox defconfig
# make; ./u-boot
=> printenv
=> help
```
在 x86_64 上运行 U-Boot可以测试一些棘手的功能如 [模拟存储设备][2] 的重新分区、基于 TPM 的密钥操作以及 USB 设备热插拔等。U-Boot 沙盒甚至可以在 GDB 调试器下单步执行。使用沙盒进行开发的速度比将引导程序刷新到电路板上的测试快 10 倍,并且可以使用 `Ctrl + C` 恢复一个“变砖”的沙盒。
### 启动内核
#### 配置引导内核
引导程序完成任务后将跳转到已加载到主内存中的内核代码,并开始执行,传递用户指定的任何命令行选项。内核是什么样的程序呢?用命令 `file /boot/vmlinuz` 可以看到它是一个 “bzImage”意思是一个大的压缩的镜像。Linux 源代码树包含了一个可以解压缩这个文件的工具—— [extract-vmlinux][18]
```
# scripts/extract-vmlinux /boot/vmlinuz-$(uname -r) > vmlinux
# file vmlinux
vmlinux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically
linked, stripped
```
内核是一个 [<ruby>可执行与可链接格式<rt> Executable and Linking Format</rt></ruby>][19]ELF的二进制文件就像 Linux 的用户空间程序一样。这意味着我们可以使用 `binutils` 包中的命令,如 `readelf` 来检查它。比较一下输出,例如:
```
# readelf -S /bin/date
# readelf -S vmlinux
```
这两个二进制文件中的段内容大致相同。
所以内核必须像其他的 Linux ELF 文件一样启动,但用户空间程序是如何启动的呢?在 `main()` 函数中?并不确切。
`main()` 函数运行之前,程序需要一个执行上下文,包括堆栈内存以及 `stdio``stdout``stderr` 的文件描述符。用户空间程序从标准库(多数 Linux 系统在用 “glibc”中获取这些资源。参照以下输出
```
# file /bin/date
/bin/date: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32,
BuildID[sha1]=14e8563676febeb06d701dbee35d225c5a8e565a,
stripped
```
ELF 二进制文件有一个解释器,就像 Bash 和 Python 脚本一样,但是解释器不需要像脚本那样用 `#!` 指定,因为 ELF 是 Linux 的原生格式。ELF 解释器通过调用 `_start()` 函数来用所需资源 [配置一个二进制文件][20],这个函数可以从 glibc 源代码包中找到,可以 [用 GDB 查看][21]。内核显然没有解释器,必须自我配置,这是怎么做到的呢?
用 GDB 检查内核的启动给出了答案。首先安装内核的调试软件包,内核中包含一个<ruby>未剥离的<rt>unstripped</rt></ruby> vmlinux例如 `apt-get install linux-image-amd64-dbg`,或者从源代码编译和安装你自己的内核,可以参照 [Debian Kernel Handbook][22] 中的指令。`gdb vmlinux` 后加 `info files` 可显示 ELF 段 `init.text`。在 `init.text` 中用 `l *(address)` 列出程序执行的开头,其中 `address``init.text` 的十六进制开头。用 GDB 可以看到 x86_64 内核从内核文件 [arch/x86/kernel/head_64.S][23] 开始启动,在这个文件中我们找到了汇编函数 `start_cpu0()`,以及一段明确的代码显示在调用 `x86_64 start_kernel()` 函数之前创建了堆栈并解压了 zImage。ARM 32 位内核也有类似的文件 [arch/arm/kernel/head.S][24]。`start_kernel()` 不针对特定的体系结构,所以这个函数驻留在内核的 [init/main.c][25] 中。`start_kernel()` 可以说是 Linux 真正的 `main()` 函数。
### 从 start_kernel() 到 PID 1
#### 内核的硬件清单:设备树和 ACPI 表
在引导时,内核需要硬件信息,不仅仅是已编译过的处理器类型。代码中的指令通过单独存储的配置数据进行扩充。有两种主要的数据存储方法:[<ruby>设备树<rt>device-tree</rt></ruby>][26] 和 [高级配置和电源接口ACPI表][27]。内核通过读取这些文件了解每次启动时需要运行的硬件。
对于嵌入式设备,设备树是已安装硬件的清单。设备树只是一个与内核源代码同时编译的文件,通常与 `vmlinux` 一样位于 `/boot` 目录中。要查看 ARM 设备上的设备树的内容,只需对名称与 `/boot/*.dtb` 匹配的文件执行 `binutils` 包中的 `strings` 命令即可,这里 `dtb` 是指<ruby>设备树二进制文件<rt>device-tree binary</rt></ruby>。显然,只需编辑构成它的类 JSON 的文件并重新运行随内核源代码提供的特殊 `dtc` 编译器即可修改设备树。虽然设备树是一个静态文件,其文件路径通常由命令行引导程序传递给内核,但近年来增加了一个 [设备树覆盖][28] 的功能,内核在启动后可以动态加载热插拔的附加设备。
x86 系列和许多企业级的 ARM64 设备使用 [ACPI][27] 机制。与设备树不同的是ACPI 信息存储在内核在启动时通过访问板载 ROM 而创建的 `/sys/firmware/acpi/tables` 虚拟文件系统中。读取 ACPI 表的简单方法是使用 `acpica-tools` 包中的 `acpidump` 命令。例如:
![ACPI tables on Lenovo laptops][30]
*联想笔记本电脑的 ACPI 表都是为 Windows 2001 设置的。*
是的,你的 Linux 系统已经准备好用于 Windows 2001 了你要考虑安装吗与设备树不同ACPI 具有方法和数据而设备树更多地是一种硬件描述语言。ACPI 方法在启动后仍处于活动状态。例如,运行 `acpi_listen` 命令(在 `apcid` 包中),然后打开和关闭笔记本机盖会发现 ACPI 功能一直在运行。暂时地和动态地 [覆盖 ACPI 表][31] 是可能的,而永久地改变它需要在引导时与 BIOS 菜单交互或刷新 ROM。如果你遇到那么多麻烦也许你应该 [安装 coreboot][32],这是开源固件的替代品。
#### 从 start_kernel() 到用户空间
[init/main.c][25] 中的代码竟然是可读的,而且有趣的是,它仍然在使用 1991 - 1992 年的 Linus Torvalds 的原始版权。在一个刚启动的系统上运行 `dmesg | head`,其输出主要来源于此文件。第一个 CPU 注册到系统中全局数据结构被初始化并且调度程序、中断处理程序IRQ、定时器和控制台按照严格的顺序逐一启动。在 `timekeeping_init()` 函数运行之前,所有的时间戳都是零。内核初始化的这部分是同步的,也就是说执行只发生在一个线程中,在最后一个完成并返回之前,没有任何函数会被执行。因此,即使在两个系统之间,`dmesg` 的输出也是完全可重复的,只要它们具有相同的设备树或 ACPI 表。Linux 的行为就像在 MCU 上运行的 RTOS实时操作系统一样如 QNX 或 VxWorks。这种情况持续存在于函数 `rest_init()` 中,该函数在终止时由 `start_kernel()` 调用。
![Summary of early kernel boot process.][34]
*早期的内核启动流程。*
函数 `rest_init()` 产生了一个新进程以运行 `kernel_init()`,并调用了 `do_initcalls()`。用户可以通过将 `initcall_debug` 附加到内核命令行来监控 `initcalls`,这样每运行一次 `initcall` 函数就会产生 一个 `dmesg` 条目。`initcalls` 会历经七个连续的级别early、core、postcore、arch、subsys、fs、device 和 late。`initcalls` 最为用户可见的部分是所有处理器外围设备的探测和设置:总线、网络、存储和显示器等等,同时加载其内核模块。`rest_init()` 也会在引导处理器上产生第二个线程,它首先运行 `cpu_idle()`,然后等待调度器分配工作。
`kernel_init()` 也可以 [设置对称多处理SMP结构][35]。在较新的内核中,如果 `dmesg` 的输出中出现 “Bringing up secondary CPUs...” 等字样,系统便使用了 SMP。SMP 通过“热插拔” CPU 来进行,这意味着它用状态机来管理其生命周期,这种状态机在概念上类似于热插拔的 U 盘一样。内核的电源管理系统经常会使某个<ruby>核<rt>core</rt></ruby>离线,然后根据需要将其唤醒,以便在不忙的机器上反复调用同一段的 CPU 热插拔代码。观察电源管理系统调用 CPU 热插拔代码的 [BCC 工具][36] 称为 `offcputime.py`
请注意,`init/main.c` 中的代码在 `smp_init()` 运行时几乎已执行完毕:引导处理器已经完成了大部分一次性初始化操作,其它核无需重复。尽管如此,跨 CPU 的线程仍然要在每个核上生成以管理每个核的中断IRQ、工作队列、定时器和电源事件。例如通过 `ps -o psr` 命令可以查看服务每个 CPU 上的线程的 softirqs 和 workqueues。
```
# ps -o pid,psr,comm $(pgrep ksoftirqd)
PID PSR COMMAND
7 0 ksoftirqd/0
16 1 ksoftirqd/1
22 2 ksoftirqd/2
28 3 ksoftirqd/3
# ps -o pid,psr,comm $(pgrep kworker)
PID PSR COMMAND
4 0 kworker/0:0H
18 1 kworker/1:0H
24 2 kworker/2:0H
30 3 kworker/3:0H
[ . . . ]
```
其中PSR 字段代表“<ruby>处理器<rt>processor</rt></ruby>”。每个核还必须拥有自己的定时器和 `cpuhp` 热插拔处理程序。
那么用户空间是如何启动的呢?在最后,`kernel_init()` 寻找可以代表它执行 `init` 进程的 `initrd`。如果没有找到,内核直接执行 `init` 本身。那么为什么需要 `initrd` 呢?
#### 早期的用户空间:谁规定要用 initrd
除了设备树之外,在启动时可以提供给内核的另一个文件路径是 `initrd` 的路径。`initrd` 通常位于 `/boot` 目录中,与 x86 系统中的 bzImage 文件 vmlinuz 一样,或是与 ARM 系统中的 uImage 和设备树相同。用 `initramfs-tools-core` 软件包中的 `lsinitramfs` 工具可以列出 `initrd` 的内容。发行版的 `initrd` 方案包含了最小化的 `/bin``/sbin``/etc` 目录以及内核模块,还有 `/scripts` 中的一些文件。所有这些看起来都很熟悉,因为 `initrd` 大致上是一个简单的最小化 Linux 根文件系统。看似相似,其实不然,因为位于虚拟内存盘中的 `/bin``/sbin` 目录下的所有可执行文件几乎都是指向 [BusyBox 二进制文件][38] 的符号链接,由此导致 `/bin``/sbin` 目录比 glibc 的小 10 倍。
如果要做的只是加载一些模块,然后在普通的根文件系统上启动 `init`,为什么还要创建一个 `initrd` 呢?想想一个加密的根文件系统,解密可能依赖于加载一个位于根文件系统 `/lib/modules` 的内核模块,当然还有 `initrd` 中的。加密模块可能被静态地编译到内核中而不是从文件加载但有多种原因不希望这样做。例如用模块静态编译内核可能会使其太大而不能适应存储空间或者静态编译可能会违反软件许可条款。不出所料存储、网络和人类输入设备HID驱动程序也可能存在于 `initrd` 中。`initrd` 基本上包含了任何挂载根文件系统所必需的非内核代码。`initrd` 也是用户存放 [自定义ACPI][38] 表代码的地方。
![Rescue shell and a custom <code>initrd</code>.][40]
*救援模式的 shell 和自定义的 `initrd` 还是很有意思的。*
`initrd` 对测试文件系统和数据存储设备也很有用。将这些测试工具存放在 `initrd` 中,并从内存中运行测试,而不是从被测对象中运行。
最后,当 `init` 开始运行时,系统就启动啦!由于第二个处理器现在在运行,机器已经成为我们所熟知和喜爱的异步、可抢占、不可预测和高性能的生物。的确,`ps -o pid,psr,comm -p 1` 很容易显示用户空间的 `init` 进程已不在引导处理器上运行了。
### 总结
Linux 引导过程听起来或许令人生畏即使是简单嵌入式设备上的软件数量也是如此。但换个角度来看启动过程相当简单因为启动中没有抢占、RCU 和竞争条件等扑朔迷离的复杂功能。只关注内核和 PID 1 会忽略了引导程序和辅助处理器为运行内核执行的大量准备工作。虽然内核在 Linux 程序中是独一无二的,但通过一些检查 ELF 文件的工具也可以了解其结构。学习一个正常的启动过程,可以帮助运维人员处理启动的故障。
要了解更多信息,请参阅 Alison Chaiken 的演讲——[Linux: The first second][41],已于 1 月 22 日至 26 日在悉尼举行。参见 [linux.conf.au][42]。
感谢 [Akkana Peck][43] 的提议和指正。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/1/analyzing-linux-boot-process
作者:[Alison Chaiken][a]
译者:[jessie-pang](https://github.com/jessie-pang)
校对:[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/Initial_ramdisk
[2]:https://github.com/chaiken/LCA2018-Demo-Code
[3]:https://en.wikipedia.org/wiki/Wake-on-LAN
[4]:https://lwn.net/Articles/630778/
[5]:https://www.youtube.com/watch?v=iffTJ1vPCSo&amp;amp;amp;amp;amp;amp;index=65&amp;amp;amp;amp;amp;amp;list=PLbzoR-pLrL6pISWAq-1cXP4_UZAyRtesk
[6]:https://security-center.intel.com/advisory.aspx?intelid=INTEL-SA-00086&amp;amp;amp;amp;amp;amp;languageid=en-fr
[7]:https://www.intel.com/content/www/us/en/support/articles/000025619/software.html
[8]:https://github.com/corna/me_cleaner
[9]:https://lwn.net/Articles/738649/
[10]:https://lwn.net/Articles/699551/
[11]:https://trmm.net/NERF
[12]:https://www.extremetech.com/computing/259879-dell-now-shipping-laptops-intels-management-engine-disabled
[13]:https://lwn.net/Articles/733837/
[14]:https://linuxplumbersconf.org/2017/ocw/events/LPC2017/tracks/639
[15]:/file/383501
[16]:https://opensource.com/sites/default/files/u128651/linuxboot_1.png "Running the U-boot bootloader"
[17]:http://www.denx.de/wiki/DULG/Manual
[18]:https://github.com/torvalds/linux/blob/master/scripts/extract-vmlinux
[19]:http://man7.org/linux/man-pages/man5/elf.5.html
[20]:https://0xax.gitbooks.io/linux-insides/content/Misc/program_startup.html
[21]:https://github.com/chaiken/LCA2018-Demo-Code/commit/e543d9812058f2dd65f6aed45b09dda886c5fd4e
[22]:http://kernel-handbook.alioth.debian.org/
[23]:https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/head_64.S
[24]:https://github.com/torvalds/linux/blob/master/arch/arm/boot/compressed/head.S
[25]:https://github.com/torvalds/linux/blob/master/init/main.c
[26]:https://www.youtube.com/watch?v=m_NyYEBxfn8
[27]:http://events.linuxfoundation.org/sites/events/files/slides/x86-platform.pdf
[28]:http://lwn.net/Articles/616859/
[29]:/file/383506
[30]:https://opensource.com/sites/default/files/u128651/linuxboot_2.png "ACPI tables on Lenovo laptops"
[31]:https://www.mjmwired.net/kernel/Documentation/acpi/method-customizing.txt
[32]:https://www.coreboot.org/Supported_Motherboards
[33]:/file/383511
[34]:https://opensource.com/sites/default/files/u128651/linuxboot_3.png "Summary of early kernel boot process."
[35]:http://free-electrons.com/pub/conferences/2014/elc/clement-smp-bring-up-on-arm-soc
[36]:http://www.brendangregg.com/ebpf.html
[37]:https://www.busybox.net/
[38]:https://www.mjmwired.net/kernel/Documentation/acpi/initrd_table_override.txt
[39]:/file/383516
[40]:https://opensource.com/sites/default/files/u128651/linuxboot_4.png "Rescue shell and a custom <code>initrd</code>."
[41]:https://rego.linux.conf.au/schedule/presentation/16/
[42]:https://linux.conf.au/index.html
[43]:http://shallowsky.com/

View File

@@ -0,0 +1,100 @@
SPARTA用于网络渗透测试的 GUI 工具套件
======
![](https://i0.wp.com/gbhackers.com/wp-content/uploads/2018/01/GjWDZ1516079830.png?resize=696%2C379&ssl=1)
SPARTA 是使用 Python 开发的 GUI 应用程序,它是 Kali Linux 内置的网络渗透测试工具。它简化了扫描和枚举阶段,并更快速的得到结果。
SPARTA GUI 工具套件最擅长的事情是扫描和发现目标端口和运行的服务。
此外,作为枚举阶段的一部分功能,它提供对开放端口和服务的暴力攻击。
延伸阅读:[网络渗透检查清单][1]
### 安装
请从 GitHub 上克隆最新版本的 SPARTA
```
git clone https://github.com/secforce/sparta.git
```
或者,从 [这里][2] 下载最新版本的 Zip 文件。
```
cd /usr/share/
git clone https://github.com/secforce/sparta.git
```
`sparta` 文件放到 `/usr/bin/` 目录下并赋于可运行权限。
在任意终端中输入 'sparta' 来启动应用程序。
### 网络渗透测试的范围
添加一个目标主机或者目标主机的列表到测试范围中,来发现一个组织的网络基础设备在安全方面的薄弱环节。
选择菜单条 - “File” -> “Add host(s) to scope”
[![Network Penetration Testing][3]][4]
[![Network Penetration Testing][5]][6]
上图展示了在扫描范围中添加 IP 地址。根据你网络的具体情况,你可以添加一个 IP 地址的范围去扫描。
扫描范围添加之后Nmap 将开始扫描,并很快得到结果,扫描阶段结束。
### 打开的端口及服务
Nmap 扫描结果提供了目标上开放的端口和服务。
[![Network Penetration Testing][7]][8]
上图展示了扫描发现的目标操作系统、开发的端口和服务。
### 在开放端口上实施暴力攻击
我们来通过 445 端口的服务器消息块SMB协议来暴力获取用户列表和它们的有效密码。
[![Network Penetration Testing][9]][10]
右键并选择 “Send to Brute” 选项。也可以选择发现的目标上的开放端口和服务。
浏览和在用户名密码框中添加字典文件。
[![Network Penetration Testing][11]][12]
点击 “Run” 去启动对目标的暴力攻击。上图展示了对目标 IP 地址进行的暴力攻击取得成功,找到了有效的密码。
在 Windows 中失败的登陆尝试总是被记录到事件日志中。
密码每 15 到 30 天改变一次的策略是非常好的一个实践经验。
强烈建议使用强密码策略。密码锁定策略是阻止这种暴力攻击的最佳方法之一( 5 次失败的登录尝试之后将锁定帐户)。
将关键业务资产整合到 SIEM 安全冲突 & 事件管理)中将尽可能快地检测到这类攻击行为。
SPARTA 对渗透测试的扫描和枚举阶段来说是一个非常省时的 GUI 工具套件。SPARTA 可以扫描和暴力破解各种协议。它有许多的功能!祝你测试顺利!
--------------------------------------------------------------------------------
via: https://gbhackers.com/sparta-network-penetration-testing-gui-toolkit/
作者:[Balaganesh][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://gbhackers.com/author/balaganesh/
[1]:https://gbhackers.com/network-penetration-testing-checklist-examples/
[2]:https://github.com/SECFORCE/sparta/archive/master.zip
[3]:https://i0.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-526.png?resize=696%2C495&amp;ssl=1
[4]:https://i0.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-526.png?ssl=1
[5]:https://i2.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-527.png?resize=696%2C516&amp;ssl=1
[6]:https://i2.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-527.png?ssl=1
[7]:https://i2.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-528.png?resize=696%2C519&amp;ssl=1
[8]:https://i2.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-528.png?ssl=1
[9]:https://i1.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-529.png?resize=696%2C525&amp;ssl=1
[10]:https://i1.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-529.png?ssl=1
[11]:https://i2.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-531.png?resize=696%2C523&amp;ssl=1
[12]:https://i2.wp.com/gbhackers.com/wp-content/uploads/2018/01/Screenshot-531.png?ssl=1

View File

@@ -0,0 +1,274 @@
如何在 Linux 上使用 Vundle 管理 Vim 插件
======
![](https://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-4-720x340.png)
毋庸置疑Vim 是一款强大的文本文件处理的通用工具能够管理系统配置文件和编写代码。通过插件Vim 可以被拓展出不同层次的功能。通常,所有的插件和附属的配置文件都会存放在 `~/.vim` 目录中。由于所有的插件文件都被存储在同一个目录下,所以当你安装更多插件时,不同的插件文件之间相互混淆。因而,跟踪和管理它们将是一个恐怖的任务。然而,这正是 Vundle 所能处理的。Vundle分别是 **V** im 和 B **undle** 的缩写,它是一款能够管理 Vim 插件的极其实用的工具。
Vundle 为每一个你安装的插件创建一个独立的目录树并在相应的插件目录中存储附加的配置文件。因此相互之间没有混淆的文件。简言之Vundle 允许你安装新的插件、配置已有的插件、更新插件配置、搜索安装的插件和清理不使用的插件。所有的操作都可以在一键交互模式下完成。在这个简易的教程中,让我告诉你如何安装 Vundle如何在 GNU/Linux 中使用它来管理 Vim 插件。
### Vundle 安装
如果你需要 Vundle那我就当作你的系统中已将安装好了 Vim。如果没有请安装 Vim 和 git以下载 Vundle。在大部分 GNU/Linux 发行版中的官方仓库中都可以获取到这两个包。比如,在 Debian 系列系统中,你可以使用下面的命令安装这两个包。
```
sudo apt-get install vim git
```
#### 下载 Vundle
复制 Vundle 的 GitHub 仓库地址:
```
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
```
#### 配置 Vundle
创建 `~/.vimrc` 文件,以通知 Vim 使用新的插件管理器。安装、更新、配置和移除插件需要这个文件。
```
vim ~/.vimrc
```
在此文件顶部,加入如下若干行内容:
```
set nocompatible " be iMproved, required
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')
" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'
" The following are examples of different formats supported.
" Keep Plugin commands between vundle#begin/end.
" plugin on GitHub repo
Plugin 'tpope/vim-fugitive'
" plugin from http://vim-scripts.org/vim/scripts.html
" Plugin 'L9'
" Git plugin not hosted on GitHub
Plugin 'git://git.wincent.com/command-t.git'
" git repos on your local machine (i.e. when working on your own plugin)
Plugin 'file:///home/gmarik/path/to/plugin'
" The sparkup vim script is in a subdirectory of this repo called vim.
" Pass the path to set the runtimepath properly.
Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}
" Install L9 and avoid a Naming conflict if you've already installed a
" different version somewhere else.
" Plugin 'ascenator/L9', {'name': 'newL9'}
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList - lists configured plugins
" :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line
```
被标记为 “required” 的行是 Vundle 的所需配置。其余行仅是一些例子。如果你不想安装那些特定的插件,可以移除它们。完成后,键入 `:wq` 保存退出。
最后,打开 Vim
```
vim
```
然后键入下列命令安装插件:
```
:PluginInstall
```
![][2]
将会弹出一个新的分窗口,我们加在 `.vimrc` 文件中的所有插件都会自动安装。
![][3]
安装完毕之后,键入下列命令,可以删除高速缓存区缓存并关闭窗口:
```
:bdelete
```
你也可以在终端上使用下面命令安装插件,而不用打开 Vim
```
vim +PluginInstall +qall
```
使用 [fish shell][4] 的朋友,添加下面这行到你的 `.vimrc` 文件中。
```
set shell=/bin/bash
```
### 使用 Vundle 管理 Vim 插件
#### 添加新的插件
首先,使用下面的命令搜索可以使用的插件:
```
:PluginSearch
```
要从 vimscripts 网站刷新本地的列表,请在命令之后添加 `!`
```
:PluginSearch!
```
会弹出一个列出可用插件列表的新分窗口:
![][5]
你还可以通过直接指定插件名的方式,缩小搜索范围。
```
:PluginSearch vim
```
这样将会列出包含关键词 “vim” 的插件。
当然你也可以指定确切的插件名,比如:
```
:PluginSearch vim-dasm
```
移动焦点到正确的一行上,按下 `i` 键来安装插件。现在,被选择的插件将会被安装。
![][6]
类似的,在你的系统中安装所有想要的插件。一旦安装成功,使用下列命令删除 Vundle 缓存:
```
:bdelete
```
现在,插件已经安装完成。为了让插件正确的自动加载,我们需要在 `.vimrc` 文件中添加安装好的插件名。
这样做:
```
:e ~/.vimrc
```
添加这一行:
```
[...]
Plugin 'vim-dasm'
[...]
```
用自己的插件名替换 vim-dasm。然后敲击 `ESC`,键入 `:wq` 保存退出。
请注意,所有插件都必须在 `.vimrc` 文件中追加如下内容。
```
[...]
filetype plugin indent on
```
#### 列出已安装的插件
键入下面命令列出所有已安装的插件:
```
:PluginList
```
![][7]
#### 更新插件
键入下列命令更新插件:
```
:PluginUpdate
```
键入下列命令重新安装所有插件:
```
:PluginInstall!
```
#### 卸载插件
首先,列出所有已安装的插件:
```
:PluginList
```
之后将焦点置于正确的一行上,按下 `SHITF+d` 组合键。
![][8]
然后编辑你的 `.vimrc` 文件:
```
:e ~/.vimrc
```
删除插件入口。最后,键入 `:wq` 保存退出。
或者,你可以通过移除插件所在 `.vimrc` 文件行,并且执行下列命令,卸载插件:
```
:PluginClean
```
这个命令将会移除所有不在你的 `.vimrc` 文件中但是存在于 bundle 目录中的插件。
你应该已经掌握了 Vundle 管理插件的基本方法了。在 Vim 中使用下列命令,查询帮助文档,获取更多细节。
```
:h vundle
```
现在我已经把所有内容都告诉你了。很快,我就会出下一篇教程。保持关注!
干杯!
### 资源
[Vundle GitHub 仓库][9]
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/manage-vim-plugins-using-vundle-linux/
作者:[SK][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[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/2018/01/Vundle-1.png
[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-2.png
[4]:https://www.ostechnix.com/install-fish-friendly-interactive-shell-linux/
[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-3.png
[6]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-4-2.png
[7]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-5-1.png
[8]:http://www.ostechnix.com/wp-content/uploads/2018/01/Vundle-6.png
[9]:https://github.com/VundleVim/Vundle.vim

View File

@@ -0,0 +1,132 @@
为初学者介绍的 Linux tee 命令6 个例子)
======
有时候你会想手动跟踪命令的输出内容同时又想将输出的内容写入文件确保之后可以用来参考。如果你想寻找这相关的工具那么恭喜你Linux 已经有了一个叫做 `tee` 的命令可以帮助你。
本教程中,我们将基于 `tee` 命令,用一些简单的例子开始讨论。但是在此之前,值得一提的是,本文我们所有的测试实例都基于 Ubuntu 16.04 LTS。
### Linux tee 命令
`tee` 命令基于标准输入读取数据,标准输出或文件写入数据。感受下这个命令的语法:
```
tee [OPTION]... [FILE]...
```
这里是帮助文档的说明:
> 从标准输入中复制到每一个文件,并输出到标准输出。
让 Q&A问&答)风格的实例给我们带来更多灵感,深入了解这个命令。
### Q1、 如何在 Linux 上使用这个命令?
假设因为某些原因,你正在使用 `ping` 命令。
```
ping google.com
```
[![如何在 Linux 上使用 tee 命令][1]][2]
然后同时,你想要输出的信息也同时能写入文件。这个时候,`tee` 命令就有其用武之地了。
```
ping google.com | tee output.txt
```
下面的截图展示了这个输出内容不仅被写入 `output.txt` 文件,也被显示在标准输出中。
[![tee command 输出][3]][4]
如此应当明白了 `tee` 的基础用法。
### Q2、 如何确保 tee 命令追加信息到文件中?
默认情况下,在同一个文件下再次使用 `tee` 命令会覆盖之前的信息。如果你想的话,可以通过 `-a` 命令选项改变默认设置。
```
[command] | tee -a [file]
```
基本上,`-a` 选项强制 `tee` 命令追加信息到文件。
### Q3、 如何让 tee 写入多个文件?
这非常之简单。你仅仅只需要写明文件名即可。
```
[command] | tee [file1] [file2] [file3]
```
比如:
```
ping google.com | tee output1.txt output2.txt output3.txt
```
[![如何让 tee 写入多个文件][5]][6]
### Q4. 如何让 tee 命令的输出内容直接作为另一个命令的输入内容?
使用 `tee` 命令,你不仅可以将输出内容写入文件,还可以把输出内容作为另一个命令的输入内容。比如说,下面的命令不仅会将文件名存入 `output.txt` 文件中,还会通过 `wc` 命令让你知道输入到 `output.txt` 中的文件数目。
```
ls file* | tee output.txt | wc -l
```
[![如何让 tee 命令的输出内容直接作为另一个命令的输入内容][7]][8]
### Q5. 如何使用 tee 命令提升文件写入权限?
假如你使用 [Vim 编辑器][9] 打开文件,并且做了很多更改,然后当你尝试保存修改时,你得到一个报错,让你意识到那是一个 root 所拥有的文件,这意味着你需要使用 `sudo` 权限保存修改。
[![如何使用 tee 命令提升文件写入权限][10]][11]
如此情况下,你可以(在 Vim 内)使用 `tee` 命令来提高权限。
```
:w !sudo tee %
```
上述命令会向你索要 root 密码,然后就能让你保存修改了。
### Q6. 如何让 tee 命令忽视中断?
`-i` 命令行选项使 `tee` 命令忽视通常由 `ctrl+c` 组合键发起的中断信号(`SIGINT`)。
```
[command] | tee -i [file]
```
当你想要使用 `ctrl+c` 中断该命令,同时让 `tee` 命令优雅的退出,这个选项尤为实用。
### 总结
现在你可能已经认同 `tee` 是一个非常实用的命令。基于 `tee` 命令的用法,我们已经介绍了其绝大多数的命令行选项。这个工具并没有什么陡峭的学习曲线,所以,只需跟随这几个例子练习,你就可以运用自如了。更多信息,请查看 [帮助文档][12].
--------------------------------------------------------------------------------
via: https://www.howtoforge.com/linux-tee-command/
作者:[Himanshu Arora][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.howtoforge.com
[1]:https://www.howtoforge.com/images/command-tutorial/ping-example.png
[2]:https://www.howtoforge.com/images/command-tutorial/big/ping-example.png
[3]:https://www.howtoforge.com/images/command-tutorial/ping-with-tee.png
[4]:https://www.howtoforge.com/images/command-tutorial/big/ping-with-tee.png
[5]:https://www.howtoforge.com/images/command-tutorial/tee-mult-files1.png
[6]:https://www.howtoforge.com/images/command-tutorial/big/tee-mult-files1.png
[7]:https://www.howtoforge.com/images/command-tutorial/tee-redirect-output.png
[8]:https://www.howtoforge.com/images/command-tutorial/big/tee-redirect-output.png
[9]:https://www.howtoforge.com/vim-basics
[10]:https://www.howtoforge.com/images/command-tutorial/vim-write-error.png
[11]:https://www.howtoforge.com/images/command-tutorial/big/vim-write-error.png
[12]:https://linux.die.net/man/1/tee

View File

@@ -0,0 +1,73 @@
5 个在视觉上最轻松的黑暗主题
======
![](https://www.maketecheasier.com/assets/uploads/2017/12/linux-themes.png)
人们在电脑上选择黑暗主题有几个原因。有些人觉得对于眼睛轻松,而另一些人因为他们的医学条件选择黑色。特别地,程序员喜欢黑暗的主题,因为可以减少眼睛的眩光。
如果你是一位 Linux 用户和黑暗主题爱好者,那么你很幸运。这里有五个最好的 Linux 黑暗主题。去看一下!
### 1. OSX-Arc-Shadow
![OSX-Arc-Shadow Theme][1]
顾名思义,这个主题受 OS X 的启发,它是基于 Arc 的平面主题。该主题支持 GTK 3 和 GTK 2 桌面环境,因此 Gnome、Cinnamon、Unity、Manjaro、Mate 和 XFCE 用户可以安装和使用该主题。[OSX-Arc-Shadow][2] 是 OSX-Arc 主题集合的一部分。该集合还包括其他几个主题(黑暗和明亮)。你可以下载整个系列并使用黑色主题。
基于 Debian 和 Ubuntu 的发行版用户可以选择使用此[页面][3]中找到的 .deb 文件来安装稳定版本。压缩的源文件也位于同一页面上。Arch Linux 用户,请查看此 [AUR 链接][4]。最后,要手动安装主题,请将 zip 解压到 `~/.themes` ,并将其设置为当前主题、控件和窗口边框。
### 2. Kiss-Kool-Red version 2
![Kiss-Kool-Red version 2 ][5]
该主题发布不久。与 OSX-Arc-Shadow 相比它有更黑的外观和红色选择框。对于那些希望电脑屏幕上有更强对比度和更少眩光的人尤其有吸引力。因此,它可以减少在夜间使用或在光线较暗的地方使用时的注意力分散。它支持 GTK 3 和 GTK2。
前往 [gnome-looks][6],在“文件”菜单下下载主题。安装过程很简单:将主题解压到 `~/.themes` 中,并将其设置为当前主题、控件和窗口边框。
### 3. Equilux
![Equilux][7]
Equilux 是另一个基于 Materia 主题的简单的黑暗主题。它有一个中性的深色调,并不过分花哨。选择框之间的对比度也很小,并且没有 Kiss-Kool-Red 中红色的锐利。这个主题的确是为减轻眼睛疲劳而做的。
[下载压缩文件][8]并将其解压缩到你的 `~/.themes` 中。然后,你可以将其设置为你的主题。你可以查看[它的 GitHub 页面][9]了解最新的增加内容。
### 4. Deepin Dark
![Deepin Dark][10]
Deepin Dark 是一个完全黑暗的主题。对于那些喜欢更黑暗的人来说,这个主题绝对是值得考虑的。此外,它还可以减少电脑屏幕的眩光量。另外,它支持 Unity。[在这里下载 Deepin Dark][11]。
### 5. Ambiance DS BlueSB12
![Ambiance DS BlueSB12 ][12]
Ambiance DS BlueSB12 是一个简单的黑暗主题,它使得重要细节突出。它有助于专注,不花哨。它与 Deepin Dark 非常相似。特别是对于 Ubuntu 用户,它与 Ubuntu 17.04 兼容。你可以从[这里][13]下载并尝试。
### 总结
如果你长时间使用电脑,黑暗主题是减轻眼睛疲劳的好方法。即使你不这样做,黑暗主题也可以在其他方面帮助你,例如提高专注。让我们知道你最喜欢哪一个。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/best-linux-dark-themes/
作者:[Bruno Edoh][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.maketecheasier.com
[1]:https://www.maketecheasier.com/assets/uploads/2017/12/osx-arc-shadow.png (OSX-Arc-Shadow Theme)
[2]:https://github.com/LinxGem33/OSX-Arc-Shadow/
[3]:https://github.com/LinxGem33/OSX-Arc-Shadow/releases
[4]:https://aur.archlinux.org/packages/osx-arc-shadow/
[5]:https://www.maketecheasier.com/assets/uploads/2017/12/Kiss-Kool-Red.png (Kiss-Kool-Red version 2 )
[6]:https://www.gnome-look.org/p/1207964/
[7]:https://www.maketecheasier.com/assets/uploads/2017/12/equilux.png (Equilux)
[8]:https://www.gnome-look.org/p/1182169/
[9]:https://github.com/ddnexus/equilux-theme
[10]:https://www.maketecheasier.com/assets/uploads/2017/12/deepin-dark.png (Deepin Dark )
[11]:https://www.gnome-look.org/p/1190867/
[12]:https://www.maketecheasier.com/assets/uploads/2017/12/ambience.png (Ambiance DS BlueSB12 )
[13]:https://www.gnome-look.org/p/1013664/

View File

@@ -0,0 +1,138 @@
如何在 Linux 上使用 snap 安装 Spotify声破天
======
如何在 Ubuntu Linux 桌面上安装 spotify 来在线听音乐?
Spotify 是一个可让你访问大量歌曲的数字音乐流服务。你可以免费收听或者购买订阅,可以创建播放列表。订阅用户可以免广告收听音乐,你会得到更好的音质。本教程展示如何使用在 Ubuntu、Mint、Debian、Fedora、Arch 和其他更多发行版上的 snap 包管理器安装 Spotify。
### 在 Linux 上安装 spotify
在 Linux 上安装 spotify 的步骤如下:
1. 安装 snapd
2. 打开 snapd
3. 找到 Spotify snap`snap find spotify`
4. 安装 spotify`sudo snap install spotify`
5. 运行:`spotify &`
让我们详细看看所有的步骤和例子。
### 步骤 1 - 安装 snapd
你需要安装 snapd 包。它是一个守护进程(服务),并能在 Linux 系统上启用 snap 包管理。
#### Debian/Ubuntu/Mint Linux 上的 snapd
输入以下 [apt 命令][1]/ [apt-get 命令][2]
```
$ sudo apt install snapd
```
#### 在 Arch Linux 上安装 snapd
snapd 只包含在 Arch User RepositoryAUR中。运行 `yaourt` 命令(参见[如何在 Archlinux 上安装 yaourt][3]
```
$ sudo yaourt -S snapd
$ sudo systemctl enable --now snapd.socket
```
#### 在 Fedora 上获取 snapd
运行 snapd 命令:
```
sudo dnf install snapd
sudo ln -s /var/lib/snapd/snap /snap
```
#### OpenSUSE 安装 snapd
执行如下的 `zypper` 命令:
```
### Tumbleweed verson ###
$ sudo zypper addrepo http://download.opensuse.org/repositories/system:/snappy/openSUSE_Tumbleweed/ snappy
### Leap version ##
$ sudo zypper addrepo http://download.opensuse.org/repositories/system:/snappy/openSUSE_Leap_42.3/ snappy
```
安装:
```
$ sudo zypper install snapd
$ sudo systemctl enable --now snapd.socket
```
### 步骤 2 - 在 Linux 上使用 snap 安装 spofity
执行 snap 命令:
```
$ snap find spotify
```
[![snap search for spotify app command][4]][4]
安装它:
```
$ sudo snap install spotify
```
[![How to install Spotify application on Linux using snap command][5]][5]
### 步骤 3 - 运行 spotify 并享受它
从 GUI 运行它,或者只需输入:
```
$ spotify
```
在启动时自动登录你的帐户:
```
$ spotify --username vivek@nixcraft.com
$ spotify --username vivek@nixcraft.com --password 'myPasswordHere'
```
在初始化时使用给定的 URI 启动 Spotify 客户端:
```
$ spotify --uri=<uri>
```
以指定的网址启动:
```
$ spotify --url=<url>
```
[![Spotify client app running on my Ubuntu Linux desktop][6]][6]
### 关于作者
作者是 nixCraft 的创建者,是经验丰富的系统管理员,也是 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及 IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][7]、[Facebook][8]、[Google +][9] 上关注他。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/how-to-install-spotify-application-on-linux/
作者:[Vivek Gite][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info)
[2]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
[3]:https://www.cyberciti.biz/faq/how-to-install-yaourt-in-arch-linux/
[4]:https://www.cyberciti.biz/media/new/faq/2018/01/snap-search-for-spotify-app-command.jpg
[5]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-Spotify-application-on-Linux-using-snap-command.jpg
[6]:https://www.cyberciti.biz/media/new/faq/2018/01/Spotify-client-app-running-on-my-Ubuntu-Linux-desktop.jpg
[7]:https://twitter.com/nixcraft
[8]:https://facebook.com/nixcraft
[9]:https://plus.google.com/+CybercitiBiz

View File

@@ -0,0 +1,174 @@
用 Python 构建你自己的 RSS 提示系统
======
![](https://fedoramagazine.org/wp-content/uploads/2018/01/learn-python-rss-notifier.png-945x400.jpg)
人生苦短,我用 PythonPython 是非常棒的快速构建应用程序的编程语言。在这篇文章中我们将学习如何使用 Python 去构建一个 RSS 提示系统,目标是使用 Fedora 快乐地学习 Python。如果你正在寻找一个完整的 RSS 提示应用程序,在 Fedora 中已经准备好了几个包。
### Fedora 和 Python —— 入门知识
Python 3.6 在 Fedora 中是默认安装的,它包含了 Python 的很多标准库。标准库提供了一些可以让我们的任务更加简单完成的模块的集合。例如,在我们的案例中,我们将使用 [sqlite3][1] 模块在数据库中去创建表、添加和读取数据。在这个案例中,我们试图去解决的是这样的一个特定问题,在标准库中没有包含,而有可能已经有人为我们开发了这样一个模块。最好是使用像大家熟知的 [PyPI][2] Python 包索引去搜索一下。在我们的示例中,我们将使用 [feedparser][3] 去解析 RSS 源。
因为 feedparser 并不是标准库,我们需要将它安装到我们的系统上。幸运的是,在 Fedora 中有这个 RPM 包,因此,我们可以运行如下的命令去安装 feedparser
```
$ sudo dnf install python3-feedparser
```
我们现在已经拥有了编写我们的应用程序所需的东西了。
### 存储源数据
我们需要存储已经发布的文章的数据,这样我们的系统就可以只提示新发布的文章。我们要保存的数据将是用来辨别一篇文章的唯一方法。因此,我们将存储文章的标题和发布日期。
因此,我们来使用 Python sqlite3 模块和一个简单的 SQL 语句来创建我们的数据库。同时也添加一些后面将要用到的模块feedparsesmtplib和 email
#### 创建数据库
```
#!/usr/bin/python3
import sqlite3
import smtplib
from email.mime.text import MIMEText
import feedparser
db_connection = sqlite3.connect('/var/tmp/magazine_rss.sqlite')
db = db_connection.cursor()
db.execute(' CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)')
```
这几行代码创建一个名为 `magazine_rss.sqlite` 文件的新 sqlite 数据库,然后在数据库创建一个名为 `magazine` 的新表。这个表有两个列 —— `title``date` —— 它们能存诸 TEXT 类型的数据,也就是说每个列的值都是文本字符。
#### 检查数据库中的旧文章
由于我们仅希望增加新的文章到我们的数据库中,因此我们需要一个功能去检查 RSS 源中的文章在数据库中是否存在。我们将根据它来判断是否发送有新文章的邮件提示。Ok现在我们来写这个功能的代码。
```
def article_is_not_db(article_title, article_date):
""" Check if a given pair of article title and date
is in the database.
Args:
article_title (str): The title of an article
article_date (str): The publication date of an article
Return:
True if the article is not in the database
False if the article is already present in the database
"""
db.execute("SELECT * from magazine WHERE title=? AND date=?", (article_title, article_date))
if not db.fetchall():
return True
else:
return False
```
这个功能的主要部分是一个 SQL 查询,我们运行它去搜索数据库。我们使用一个 `SELECT` 命令去定义我们将要在哪个列上运行这个查询。我们使用 `*` 符号去选取所有列(`title``date`)。然后,我们使用查询的 `WHERE` 条件 `article_title``article_date` 去匹配标题和日期列中的值,以检索出我们需要的内容。
最后,我们使用一个简单的返回 `True` 或者 `False` 的逻辑来表示是否在数据库中找到匹配的文章。
#### 在数据库中添加新文章
现在我们可以写一些代码去添加新文章到数据库中。
```
def add_article_to_db(article_title, article_date):
""" Add a new article title and date to the database
Args:
article_title (str): The title of an article
article_date (str): The publication date of an article
"""
db.execute("INSERT INTO magazine VALUES (?,?)", (article_title, article_date))
db_connection.commit()
```
这个功能很简单,我们使用了一个 SQL 查询去插入一个新行到 `magazine` 表的 `article_title``article_date` 列中。然后提交它到数据库中永久保存。
这些就是在数据库中所需要的东西,接下来我们看一下,如何使用 Python 实现提示系统和发送电子邮件。
### 发送电子邮件提示
我们使用 Python 标准库模块 smtplib 来创建一个发送电子邮件的功能。我们也可以使用标准库中的 email 模块去格式化我们的电子邮件信息。
```
def send_notification(article_title, article_url):
""" Add a new article title and date to the database
Args:
article_title (str): The title of an article
article_url (str): The url to access the article
"""
smtp_server = smtplib.SMTP('smtp.gmail.com', 587)
smtp_server.ehlo()
smtp_server.starttls()
smtp_server.login('your_email@gmail.com', '123your_password')
msg = MIMEText(f'\nHi there is a new Fedora Magazine article : {article_title}. \nYou can read it here {article_url}')
msg['Subject'] = 'New Fedora Magazine Article Available'
msg['From'] = 'your_email@gmail.com'
msg['To'] = 'destination_email@gmail.com'
smtp_server.send_message(msg)
smtp_server.quit()
```
在这个示例中,我使用了谷歌邮件系统的 smtp 服务器去发送电子邮件,在你自己的代码中你需要将它更改为你自己的电子邮件服务提供者的 SMTP 服务器。这个功能是个样板,大多数的内容要根据你的 smtp 服务器的参数来配置。代码中的电子邮件地址和凭证也要更改为你自己的。
如果在你的 Gmail 帐户中使用了双因子认证,那么你需要配置一个密码应用程序为你的这个应用程序提供一个唯一密码。可以看这个 [帮助页面][4]。
### 读取 Fedora Magazine 的 RSS 源
我们已经有了在数据库中存储文章和发送提示电子邮件的功能,现在来创建一个解析 Fedora Magazine RSS 源并提取文章数据的功能。
```
def read_article_feed():
""" Get articles from RSS feed """
feed = feedparser.parse('https://fedoramagazine.org/feed/')
for article in feed['entries']:
if article_is_not_db(article['title'], article['published']):
send_notification(article['title'], article['link'])
add_article_to_db(article['title'], article['published'])
if __name__ == '__main__':
read_article_feed()
db_connection.close()
```
在这里我们将使用 `feedparser.parse` 功能。这个功能返回一个用字典表示的 RSS 源,对于 feedparser 的完整描述可以参考它的 [文档][5]。
RSS 源解析将返回最后的 10 篇文章作为 `entries`,然后我们提取以下信息:标题、链接、文章发布日期。因此,我们现在可以使用前面定义的检查文章是否在数据库中存在的功能,然后,发送提示电子邮件并将这个文章添加到数据库中。
当运行我们的脚本时,最后的 `if` 语句运行我们的 `read_article_feed` 功能,然后关闭数据库连接。
### 运行我们的脚本
给脚本文件赋于正确运行权限。接下来,我们使用 cron 实用程序去每小时自动运行一次我们的脚本。cron 是一个作业计划程序,我们可以使用它在一个固定的时间去运行一个任务。
```
$ chmod a+x my_rss_notifier.py
$ sudo cp my_rss_notifier.py /etc/cron.hourly
```
为了使该教程保持简单,我们使用了 `cron.hourly` 目录每小时运行一次我们的脚本,如果你想学习关于 cron 的更多知识以及如何配置 crontab请阅读 cron 的 wikipedia [页面][6]。
### 总结
在本教程中,我们学习了如何使用 Python 去创建一个简单的 sqlite 数据库、解析一个 RSS 源、以及发送电子邮件。我希望通过这篇文章能够向你展示,使用 Python 和 Fedora 构建你自己的应用程序是件多么容易的事。
这个脚本在 [GitHub][7] 上可以找到。
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/never-miss-magazines-article-build-rss-notification-system/
作者:[Clément Verna][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://fedoramagazine.org
[1]:https://docs.python.org/3/library/sqlite3.html
[2]:https://pypi.python.org/pypi
[3]:https://pypi.python.org/pypi/feedparser/5.2.1
[4]:https://support.google.com/accounts/answer/185833?hl=en
[5]:https://pythonhosted.org/feedparser/reference.html
[6]:https://en.wikipedia.org/wiki/Cron
[7]:https://github.com/cverna/rss_feed_notifier

View File

@@ -0,0 +1,85 @@
COPR 仓库中 4 个很酷的新软件
======
![](https://fedoramagazine.org/wp-content/uploads/2017/08/4-copr-945x400.jpg)
COPR 是一个个人软件仓库[集合][1],它们不存在于 Fedora 中。有些软件不符合标准而不容易打包。或者它可能不符合其他的 Fedora 标准尽管它是自由和开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己签名的。但是,它是尝试新的或实验性软件的一种很好的方法。
这是 COPR 中一系列新的和有趣的项目。
### Elisa
[Elisa][2] 是一个极小的音乐播放器。它可以让你通过专辑、艺术家或曲目浏览音乐。它会自动检测你的 `~/Music` 目录中的所有可播放音乐,因此它根本不需要设置 - 它也不提供任何音乐。目前Elisa 专注于做一个简单的音乐播放器,所以它不提供管理音乐收藏的工具。
![][3]
#### 安装说明
仓库目前为 Fedora 26、27 和 Rawhide 提供 Elisa。要安装 Elisa请使用以下命令
```
sudo dnf copr enable eclipseo/elisa
sudo dnf install elisa
```
### 必应壁纸
[必应壁纸][4]是一个简单的程序,它会下载当日的必应壁纸,并将其设置为桌面壁纸或锁屏图片。该程序可以在设定的时间间隔内轮转目录中的图片,并在一段时间后删除旧图片。
#### 安装说明
仓库目前为 Fedora 25、26、27 和 Rawhide 提供必应壁纸。要安装必应壁纸,请使用以下命令:
```
sudo dnf copr enable julekgwa/Bingwallpapers
sudo dnf install bingwallpapers
```
### Polybar
[Polybar][5] 是一个创建状态栏的工具。它有很多自定义选项以及显示常用服务的信息的内置功能,例如 [bspwm][6]、[i3][7] 的系统托盘图标、窗口标题、工作区和桌面面板等。你也可以为你的状态栏配置你自己的模块。有关使用和配置的更多信息,请参考[ Polybar 的 wiki][8]。
#### 安装说明
仓库目前为 Fedora 27 提供 Polybar。要安装 Polybar请使用以下命令
```
sudo dnf copr enable tomwishaupt/polybar
sudo dnf install polybar
```
### Netdata
[Netdata][9] 是一个分布式监控系统。它可以运行在包括个人电脑、服务器、容器和物联网设备在内的所有系统上,从中实时收集指标。所有的信息都可以使用 netdata 的 web 面板访问。此外Netdata 还提供预配置的警报和通知来检测性能问题,以及用于创建自己的警报的模板。
![][10]
#### 安装说明
仓库目前提供 EPEL 7、Fedora 27 和 Rawhide 提供 netdata。要安装 netdata请使用以下命令
```
sudo dnf copr enable recteurlp/netdata
sudo dnf install netdata
```
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-january/
作者:[Dominik Turecek][a]
译者:[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]:https://community.kde.org/Elisa
[3]:https://fedoramagazine.org/wp-content/uploads/2018/01/elisa.png
[4]:http://bingwallpapers.lekgoara.com/
[5]:https://github.com/jaagr/polybar
[6]:https://github.com/baskerville/bspwm
[7]:https://i3wm.org/
[8]:https://github.com/jaagr/polybar/wiki
[9]:http://my-netdata.io/
[10]:https://fedoramagazine.org/wp-content/uploads/2018/01/netdata.png

View File

@@ -0,0 +1,149 @@
使用 Ansible 在树莓派上构建一个基于 Linux 的高性能计算系统
============================================================
> 使用低成本的硬件和开源软件设计一个高性能计算集群。
![Building a Linux-based HPC system on the Raspberry Pi with Ansible](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_computer_development_programming.png?itok=4OM29-82 "Building a Linux-based HPC system on the Raspberry Pi with Ansible")
图片来源opensource.com
在我的 [之前发表在 Opensource.com 上的文章中][14],我介绍了 [OpenHPC][15] 项目它的目标是致力于加速高性能计算HPC的创新。这篇文章将更深入来介绍使用 OpenHPC 的特性来构建一个小型的 HPC 系统。将它称为 _HPC 系统_  可能有点“扯虎皮拉大旗”的意思,因此,更确切的说法应该是,它是一个基于 OpenHPC 项目发布的 [集群构建方法][16] 的系统。
这个集群由两台树莓派 3 系统作为计算节点,以及一台虚拟机作为主节点,结构示意如下:
![Map of HPC cluster](https://opensource.com/sites/default/files/u128651/hpc_with_pi-1.png "Map of HPC cluster")
我的主节点运行的是 x86_64 架构的 CentOS 操作系统,而计算节点运行了 aarch64 的轻度修改版的 CentOS 操作系统。
下图是真实的设备工作照:
![HPC hardware setup](https://opensource.com/sites/default/files/u128651/hpc_with_pi-2.jpg "HPC hardware setup")
要把我的系统配置成像上图这样的 HPC 系统,我是按照 OpenHPC 的集群构建方法的 [CentOS 7.4/aarch64 + Warewulf + Slurm 安装指南][17] PDF的一些步骤来做的。这个方法包括了使用 [Warewulf][18] 的配置说明;因为我的那三个系统是手动安装的,我跳过了 Warewulf 部分以及创建 [Ansible 剧本][19] 的一些步骤。
在 [Ansible][26] 剧本中设置完成我的集群之后,我就可以向资源管理器提交作业了。在我的这个案例中, [Slurm][27] 充当了资源管理器,它是集群中的一个实例,由它来决定我的作业什么时候在哪里运行。在集群上启动一个简单的作业的方式之一:
```
[ohpc@centos01 ~]$ srun hostname
calvin
```
如果需要更多的资源,我可以去告诉 Slurm我希望在 8 个 CPU 上去运行我的命令:
```
[ohpc@centos01 ~]$ srun -n 8 hostname
hobbes
hobbes
hobbes
hobbes
calvin
calvin
calvin
calvin
```
在第一个示例中Slurm 在一个单个的 CPU 上运行了指定的命令(`hostname`而在第二个示例中Slurm 在 8 个 CPU 上运行了那个命令。我的计算节点一个命名为 `calvin`,而另一个命名为 `hobbes`;在上面的命令输出部分可以看到它们的名字。每个计算节点都是由 4 个 CPU 核心的树莓派 3 构成的。
在我的集群中提交作业的另一种方法是使用命令 `sbatch`,它可以用于运行脚本,将输出写入到一个文件,而不是我的终端上。
```
[ohpc@centos01 ~]$ cat script1.sh
#!/bin/sh
date
hostname
sleep 10
date
[ohpc@centos01 ~]$ sbatch script1.sh
Submitted batch job 101
```
它将创建一个名为 `slurm-101.out` 的输出文件,这个输出文件包含下列的内容:
```
Mon 11 Dec 16:42:31 UTC 2017
calvin
Mon 11 Dec 16:42:41 UTC 2017
```
为示范资源管理器的基本功能,简单的串行命令行工具就行,但是,做各种工作去配置一个类似 HPC 系统就有点无聊了。
一个更有趣的应用是在这个集群的所有可用 CPU 上运行一个 [Open MPI][20] 的并行作业。我使用了一个基于 [康威生命游戏][21] 的应用,它被用于一个名为“使用 Red Hat 企业版 Linux 跨多种架构运行康威生命游戏”的 [视频][22]。除了以前基于 MPI 的 `Game of Life` 版本之外,在我的集群中现在运行的这个版本对每个涉及的主机的单元格颜色都是不同的。下面的脚本以图形输出的方式来交互式启动应用:
```
$ cat life.mpi
#!/bin/bash
module load gnu6 openmpi3
if [[ "$SLURM_PROCID" != "0" ]]; then
    exit
fi
mpirun ./mpi_life -a -p -b
```
我使用下面的命令来启动作业,它告诉 Slurm为这个作业分配 8 个 CPU
```
$ srun -n 8 --x11 life.mpi
```
为了演示,这个作业有一个图形界面,它展示了当前计算的结果:
![](https://opensource.com/sites/default/files/u128651/hpc_with_pi-3.png)
红色单元格是由其中一个计算节点来计算的,而绿色单元格是由另外一个计算节点来计算的。我也可以让康威生命游戏程序为使用的每个 CPU 核心(这里的每个计算节点有四个核心)去生成不同的颜色,这样它的输出如下:
![](https://opensource.com/sites/default/files/u128651/hpc_with_pi-4.png)
感谢 OpenHPC 提供的软件包和安装方法,因为它们让我可以去配置一个由两个计算节点和一个主节点的 HPC 式的系统。我可以在资源管理器上提交作业,然后使用 OpenHPC 提供的软件在我的树莓派的 CPU 上去启动 MPI 应用程序。
* * *
_想学习更多的关于使用 OpenHPC 去构建树莓派集群,请参与 Adrian Reber 在 [DevConf.cz 2018][10] 的讨论,它于 1月 26-28 日在 BrnoCzech Republic 举行,以及在 [CentOS Dojo 2018][11] ,它于 2 月 2 日在 Brussels 举行。_
### 关于作者
[![](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/gotchi-square.png?itok=PJKu7LHn)][23] Adrian Reber —— Adrian 是 Red Hat 的高级软件工程师,他早在 2010 年就开始了迁移处理过程到高性能计算环境,从那个时候起迁移了许多的处理过程,并因此获得了博士学位,然后加入了 Red Hat 公司并开始去迁移到容器。偶尔他仍然去迁移单个处理过程,并且它至今仍然对高性能计算非常感兴趣。[关于我的更多信息点这里][12]
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/1/how-build-hpc-system-raspberry-pi-and-openhpc
作者:[Adrian Reber][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/adrianreber
[1]:https://opensource.com/resources/what-are-linux-containers?utm_campaign=containers&amp;intcmp=70160000000h1s6AAA
[2]:https://opensource.com/resources/what-docker?utm_campaign=containers&amp;intcmp=70160000000h1s6AAA
[3]:https://opensource.com/resources/what-is-kubernetes?utm_campaign=containers&amp;intcmp=70160000000h1s6AAA
[4]:https://developers.redhat.com/blog/2016/01/13/a-practical-introduction-to-docker-container-terminology/?utm_campaign=containers&amp;intcmp=70160000000h1s6AAA
[5]:https://opensource.com/file/384031
[6]:https://opensource.com/file/384016
[7]:https://opensource.com/file/384021
[8]:https://opensource.com/file/384026
[9]:https://opensource.com/article/18/1/how-build-hpc-system-raspberry-pi-and-openhpc?rate=l9n6B6qRcR20LJyXEoUoWEZ4mb2nDc9sFZ1YSPc60vE
[10]:https://devconfcz2018.sched.com/event/DJYi/openhpc-introduction
[11]:https://wiki.centos.org/Events/Dojo/Brussels2018
[12]:https://opensource.com/users/adrianreber
[13]:https://opensource.com/user/188446/feed
[14]:https://opensource.com/article/17/11/openhpc
[15]:https://openhpc.community/
[16]:https://openhpc.community/downloads/
[17]:https://github.com/openhpc/ohpc/releases/download/v1.3.3.GA/Install_guide-CentOS7-Warewulf-SLURM-1.3.3-aarch64.pdf
[18]:https://en.wikipedia.org/wiki/Warewulf
[19]:http://people.redhat.com/areber/openhpc/ansible/
[20]:https://www.open-mpi.org/
[21]:https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
[22]:https://www.youtube.com/watch?v=n8DvxMcOMXk
[23]:https://opensource.com/users/adrianreber
[24]:https://opensource.com/users/adrianreber
[25]:https://opensource.com/users/adrianreber
[26]:https://www.ansible.com/
[27]:https://slurm.schedmd.com/
[28]:https://opensource.com/tags/raspberry-pi
[29]:https://opensource.com/tags/programming
[30]:https://opensource.com/tags/linux
[31]:https://opensource.com/tags/ansible

View File

@@ -0,0 +1,147 @@
在 Linux 上使用 NTP 保持精确的时间
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/usno-amc.jpg?itok=KA8HwI02)
如何保持正确的时间,如何使用 NTP 和 systemd 让你的计算机在不滥用时间服务器的前提下保持同步。
### 它的时间是多少?
让 Linux 来告诉你时间的时候,它是很奇怪的。你可能认为是使用 `time` 命令来告诉你时间,其实并不是,因为 `time` 只是一个测量一个进程运行了多少时间的计时器。为得到时间,你需要运行的是 `date` 命令,你想查看更多的日期,你可以运行 `cal` 命令。文件上的时间戳也是一个容易混淆的地方,因为根据你的发行版默认情况不同,它一般有两种不同的显示方法。下面是来自 Ubuntu 16.04 LTS 的示例:
```
$ ls -l
drwxrwxr-x 5 carla carla 4096 Mar 27 2017 stuff
drwxrwxr-x 2 carla carla 4096 Dec 8 11:32 things
-rw-rw-r-- 1 carla carla 626052 Nov 21 12:07 fatpdf.pdf
-rw-rw-r-- 1 carla carla 2781 Apr 18 2017 oddlots.txt
```
有些显示年有些显示时间这样的方式让你的文件更混乱。GNU 默认的情况是,如果你的文件在六个月以内,则显示时间而不是年。我想这样做可能是有原因的。如果你的 Linux 是这样的,尝试用 `ls -l --time-style=long-iso` 命令,让时间戳用同一种方式去显示,按字母顺序排序。请查阅 [如何更改 Linux 的日期和时间:简单的命令][1] 去学习 Linux 上管理时间的各种方法。
### 检查当前设置
NTP —— 网络时间协议,它是保持计算机正确时间的老式方法。`ntpd` 是 NTP 守护程序它通过周期性地查询公共时间服务器来按需调整你的计算机时间。它是一个简单的、轻量级的协议使用它的基本功能时设置非常容易。systemd 通过使用 `systemd-timesyncd.service` 已经越俎代庖地 “干了 NTP 的活”,它可以用作 `ntpd` 的客户端。
在我们开始与 NTP “打交道” 之前,先花一些时间来了检查一下当前的时间设置是否正确。
你的系统上(至少)有两个时钟:系统时间 —— 它由 Linux 内核管理第二个是你的主板上的硬件时钟它也称为实时时钟RTC。当你进入系统的 BIOS 时,你可以看到你的硬件时钟的时间,你也可以去改变它的设置。当你安装一个新的 Linux 时,在一些图形化的时间管理器中,你会被询问是否设置你的 RTC 为 UTC<ruby>世界标准时间<rt>Coordinated Universal Time</rt></ruby>)时区,因为所有的时区和夏令时都是基于 UTC 的。你可以使用 `hwclock` 命令去检查:
```
$ sudo hwclock --debug
hwclock from util-linux 2.27.1
Using the /dev interface to the clock.
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
...got clock tick
Time read from Hardware Clock: 2018/01/22 22:14:31
Hw clock time : 2018/01/22 22:14:31 = 1516659271 seconds since 1969
Time since last adjustment is 1516659271 seconds
Calculated Hardware Clock drift is 0.000000 seconds
Mon 22 Jan 2018 02:14:30 PM PST .202760 seconds
```
`Hardware clock is on UTC time` 表明了你的计算机的 RTC 是使用 UTC 时间的,虽然它把该时间转换为你的本地时间。如果它被设置为本地时间,它将显示 `Hardware clock is on local time`
你应该有一个 `/etc/adjtime` 文件。如果没有的话,使用如下命令同步你的 RTC 为系统时间,
```
$ sudo hwclock -w
```
这个命令将生成该文件,内容看起来类似如下:
```
$ cat /etc/adjtime
0.000000 1516661953 0.000000
1516661953
UTC
```
新发明的 systemd 方式是去运行 `timedatectl` 命令,运行它不需要 root 权限:
```
$ timedatectl
Local time: Mon 2018-01-22 14:17:51 PST
Universal time: Mon 2018-01-22 22:17:51 UTC
RTC time: Mon 2018-01-22 22:17:51
Time zone: America/Los_Angeles (PST, -0800)
Network time on: yes
NTP synchronized: yes
RTC in local TZ: no
```
`RTC in local TZ: no` 表明它使用 UTC 时间。那么怎么改成使用本地时间?这里有许多种方法可以做到。最简单的方法是使用一个图形配置工具,比如像 openSUSE 中的 YaST。你也可使用 `timedatectl`
```
$ timedatectl set-local-rtc 0
```
或者编辑 `/etc/adjtime`,将 `UTC` 替换为 `LOCAL`
### systemd-timesyncd 客户端
现在,我已经累了,但是我们刚到非常精彩的部分。谁能想到计时如此复杂?我们甚至还没有了解到它的皮毛;阅读 `man 8 hwclock` 去了解你的计算机如何保持时间的详细内容。
systemd 提供了 `systemd-timesyncd.service` 客户端,它可以查询远程时间服务器并调整你的本地系统时间。在 `/etc/systemd/timesyncd.conf` 中配置你的(时间)服务器。大多数 Linux 发行版都提供了一个默认配置,它指向他们维护的时间服务器上,比如,以下是 Fedora 的:
```
[Time]
#NTP=
#FallbackNTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org
```
你可以输入你希望使用的其它时间服务器,比如你自己的本地 NTP 服务器,在 `NTP=` 行上输入一个以空格分隔的服务器列表。(别忘了取消这一行的注释)`NTP=` 行上的任何内容都将覆盖掉 `FallbackNTP` 行上的配置项。
如果你不想使用 systemd 呢?那么,你将需要 NTP 就行。
### 配置 NTP 服务器和客户端
配置你自己的局域网 NTP 服务器是一个非常好的实践,这样你的网内计算机就不需要不停查询公共 NTP 服务器。在大多数 Linux 上的 NTP 都来自 `ntp` 包,它们大多都提供 `/etc/ntp.conf` 文件去配置时间服务器。查阅 [NTP 时间服务器池][2] 去找到你所在的区域的合适的 NTP 服务器池。然后在你的 `/etc/ntp.conf` 中输入 4 - 5 个服务器,每个服务器用单独的一行:
```
driftfile /var/ntp.drift
logfile /var/log/ntp.log
server 0.europe.pool.ntp.org
server 1.europe.pool.ntp.org
server 2.europe.pool.ntp.org
server 3.europe.pool.ntp.org
```
`driftfile` 告诉 `ntpd` 它需要保存用于启动时使用时间服务器快速同步你的系统时钟的信息。而日志也将保存在他们自己指定的目录中,而不是转储到 syslog 中。如果你的 Linux 发行版默认提供了这些文件,请使用它们。
现在去启动守护程序;在大多数主流的 Linux 中它的命令是 `sudo systemctl start ntpd`。让它运行几分钟之后,我们再次去检查它的状态:
```
$ ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================
+dev.smatwebdesi 192.168.194.89 3 u 25 64 37 92.456 -6.395 18.530
*chl.la 127.67.113.92 2 u 23 64 37 75.175 8.820 8.230
+four0.fairy.mat 35.73.197.144 2 u 22 64 37 116.272 -10.033 40.151
-195.21.152.161 195.66.241.2 2 u 27 64 37 107.559 1.822 27.346
```
我不知道这些内容是什么意思,但重要的是,你的守护程序已经与时间服务器开始对话了,而这正是我们所需要的。你可以去运行 `sudo systemctl enable ntpd` 命令,永久启用它。如果你的 Linux 没有使用 systemd那么给你留下的家庭作业就是找出如何去运行 `ntpd`
现在,你可以在你的局域网中的其它计算机上设置 `systemd-timesyncd`,这样它们就可以使用你的本地 NTP 服务器了,或者,在它们上面安装 NTP然后在它们的 `/etc/ntp.conf` 上输入你的本地 NTP 服务器。
NTP 服务器会受到攻击,而且需求在不断增加。你可以通过运行你自己的公共 NTP 服务器来提供帮助。下周我们将学习如何运行你自己的公共服务器。
通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”][3] 来学习更多 Linux 的知识。
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2018/1/keep-accurate-time-linux-ntp
作者:[CARLA SCHRODER][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/cschroder
[1]:https://www.linux.com/learn/how-change-linux-date-and-time-simple-commands
[2]:http://support.ntp.org/bin/view/Servers/NTPPoolServers
[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@@ -0,0 +1,401 @@
如何搭建“我的世界”服务器
======
![](https://thishosting.rocks/wp-content/uploads/2018/01/how-to-make-minecraft-server.jpg)
我们将通过一个一步步的、新手友好的教程来向你展示如何搭建一个“我的世界Minecraft”服务器。这将会是一个长期的多人游戏服务器你可以与来自世界各地的朋友们一起玩而不用在同一个局域网下。
### 如何搭建一个“我的世界”服务器 - 快速指南
如果你很急,想直达重点的话,这是我们的目录。我们推荐通读整篇文章。
* [学点东西][1] (可选)
* [再学点东西][2] (可选)
* [需求][3] (必读)
* [安装并运行“我的世界”服务器][4] (必读)
* [在你登出 VPS 后继续运行服务端][5] (可选)
* [让服务端随系统启动][6] (可选)
* [配置你的“我的世界”服务器][7] (必读)
* [常见问题][8] (可选)
在你开始行动之前,要先了解一些事情:
#### 为什么你**不**应该使用专门的“我的世界”服务器提供商
既然你正在阅读这篇文章,你肯定对搭建自己的“我的世界”服务器感兴趣。不应该使用专门的“我的世界”服务器提供商的原因有很多,以下是其中一些:
* 它们通常很慢。这是因为你是在和很多用户一起共享资源。这有的时候会超负荷,他们中很多都会超售。
* 你并不能完全控制“我的世界”服务端或真正的服务器。你没法按照你的意愿进行自定义。
* 你是受限制的。这种主机套餐或多或少都会有限制。
当然,使用现成的提供商也是有优点的。最好的就是你不用做下面这些操作。但是那还有什么意思呢?!
#### 为什么不应该用你的个人电脑作为“我的世界”服务器
我们注意到很多教程都展示的是如何在你自己的电脑上搭建服务器。这样做有一些弊端,比如:
* 你的家庭网络不够安全,无法抵挡 DDoS 攻击。游戏服务器通常容易被 DDoS 攻击,而你的家庭网络设置通常不够安全,来抵挡它们。很可能连小型攻击都无法阻挡。
* 你得处理端口转发。如果你试着在家庭网络中搭建“我的世界”服务器的话,你肯定会偶然发现端口转发的问题,并且处理时可能会有问题。
* 你得保持你的电脑一直开着。你的电费将会突破天际,并且你会增加不必要的硬件负载。大部分服务器硬件都是企业级的,提升了稳定性和持久性,专门设计用来处理负载。
* 你的家庭网络速度不够快。家庭网络并不是设计用来负载多人联机游戏的。即使你想搭建一个小型服务器你也需要一个更好的网络套餐。幸运的是数据中心有多个高速的、企业级的互联网连接来保证他们达到或尽量达到100%在线。
* 你的硬件很可能不够好。再说一次,服务器使用的都是企业级硬件,最新最快的处理器、固态硬盘,等等。你的个人电脑很可能不是的。
* 你的个人电脑很可能是 Windows/MacOS。尽管这有所争议但我们相信 Linux 更适合搭建游戏服务器。不用担心,搭建“我的世界”服务器不需要完全了解 Linux尽管推荐这样。我们会向你展示你需要了解的。
我们的建议是不要使用个人电脑,即使从技术角度来说你能做到。买一个云服务器并不是很贵。下面我们会向你展示如何在云服务器上搭建“我的世界”服务端。小心地遵守以下步骤,就很简单。
### 搭建一个“我的世界”服务器 - 需求
这是一些需求,你在教程开始之前需要拥有并了解它们:
* 你需要一个 [Linux 云服务器][9]。我们推荐 [Vultr][10]。这家价格便宜,服务质量高,客户支持很好,并且所有的服务器硬件都很高端。检查[“我的世界”服务器需求][11]来选择你需要哪种类型的服务器(像内存和硬盘之类的资源)。我们推荐每月 20 美元的套餐。他们也支持按小时收费,所以如果你只是临时需要服务器和朋友们联机的话,你的花费会更少。注册时选择 Ubuntu 16.04 发行版。在注册时选择离你的朋友们最近的地域。这样的话你就需要保护并管理服务器。如果你不想这样的话,你可以选择[托管的服务器][12],这样的话服务器提供商可能会给你搭建好一个“我的世界”服务器。
* 你需要一个 SSH 客户端来连接到你的 Linux 云服务器。新手通常建议使用 [PuTTy][13],但我们也推荐使用 [MobaXTerm][14]。也有很多 SSH 客户端,所以挑一个你喜欢的吧。
* 你需要设置你的服务器(至少做好基本的安全设置)。谷歌一下你会发现很多教程。你也可以按照 [Linode 的 安全指南][15],然后在你的 [Vultr][16] 服务器上一步步操作。
* 下面我们将会处理软件依赖,比如 Java。
终于,到我们真正的教程了:
### 如何在 UbuntuLinux上搭建一个“我的世界”服务器
这篇教程是为 [Vultr][17] 上的 Ubuntu 16.04 撰写并测试可行的。但是这对 Ubuntu 14.04 [Ubuntu 18.04][18],以及其他基于 Ubuntu 的发行版、其他服务器提供商也是可行的。
我们使用默认的 Vanilla 服务端。你也可以使用像 CraftBukkit 或 Spigot 这样的服务端,来支持更多的自定义和插件。虽然如果你使用过多插件的话会影响服务端。这各有优缺点。不管怎么说,下面的教程使用默认的 Vanilla 服务端,来使事情变得简单和更新手友好。如果有兴趣的话我们可能会发表一篇 CraftBukkit 的教程。
#### 1. 登录到你的服务器
我们将使用 root 账户。如果你使用受限的账户的话,大部分命令都需要 `sudo`。做你没有权限的事情时会出现警告。
你可以通过 SSH 客户端来登录你的服务器。使用你的 IP 和端口(大部分都是 22
在你登录之后,确保你的[服务器安全][19]。
#### 2. 更新 Ubuntu
在你做任何事之前都要先更新你的 Ubuntu。你可以通过以下命令更新
```
apt-get update && apt-get upgrade
```
在提示时敲击“回车键” 和/或 `y`
#### 3. 安装必要的工具
在这篇教程中你需要一些工具和软件来编辑文本、长久保持服务端运行等。使用下面的命令安装:
```
apt-get install nano wget screen bash default-jdk ufw
```
其中一些可能已经安装好了。
#### 4. 下载“我的世界”服务端
首先,创建一个目录来保存你的“我的世界”服务端和其他文件:
```
mkdir /opt/minecraft
```
然后进入新目录:
```
cd /opt/minecraft
```
现在你可以下载“我的世界“服务端文件了。去往[下载页面][20]获取下载链接。使用 `wget` 下载文件:
```
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.2/minecraft_server.1.12.2.jar
```
#### 5. 安装“我的世界”服务端
下载好了服务端的 .jar 文件之后,你就需要先运行一下,它会生成一些文件,包括一个 `eula.txt` 许可文件。第一次运行的时候,它会返回一个错误并退出。这是正常的。使用下面的命令运行它:
```
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
```
`-Xms2048M` 是你的服务端能使用的最小的内存,`-Xmx3472M` 是最大的内存。[调整][21]基于你服务器的硬件资源。如果你在 [Vultr][22] 服务器上有 4GB 内存,并且不用服务器来干其他事情的话可以就这样留着不动。
在这条命令结束并返回一个错误之后,将会生成一个新的 `eula.txt` 文件。你需要同意那个文件里的协议。你可以通过下面这条命令将 `eula=true` 添加到文件中:
```
sed -i.orig 's/eula=false/eula=true/g' eula.txt
```
你现在可以通过和上面一样的命令来开启服务端并进入“我的世界”服务端控制台了:
```
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
```
确保你在 `/opt/minecraft` 目录,或者其他你安装你的 MC 服务端的目录下。
如果你只是测试或暂时需要的话,到这里就可以停了。如果你在登录服务器时有问题的话,你就需要[配置你的防火墙][23]。
第一次成功启动服务端时会花费一点时间来生成。
我们将向你展示如何创建一个脚本来启动。
#### 6. 使用脚本启动“我的世界”服务端,让服务端长期运行并在启动时开启
方便起见,我们将创建一个自动启动服务端的 bash 脚本。
首先,使用 nano 创建一个 bash 脚本:
```
nano /opt/minecraft/startminecraft.sh
```
这将会打开一个新的(空白)文件。粘贴以下内容:
```
#!/bin/bash
cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.2.jar nogui
```
如果你不熟悉 nano 的话 - 你可以使用 `CTRL + X`,再敲击 `Y`,然后回车。这个脚本将进入你先前创建的“我的世界”服务端并运行 Java 命令来开启服务端。你需要执行下面的命令来使脚本可执行:
```
chmod +x startminecraft.sh
```
然后,你就可以通过下面的命令随时运行服务端了:
```
/opt/minecraft/startminecraft.sh
```
但是,如果/当你登出 SSH 会话的话,服务端就会关闭。要想让服务端不登录也持续运行的话,你可以使用 `screen` 会话。`screen` 会话会一直运行,直到实际的服务器被关闭或重启。
使用下面的命令开启一个 screen 会话:
```
screen -S minecraft
```
一旦你进入了 `screen` 会话(看起来就像是你新建了一个 SSH 会话),你就可以使用先前创建的 bash 脚本来启动服务端:
```
/opt/minecraft/startminecraft.sh
```
要退出 `screen` 会话的话,你应该按 `CTRL+A-D`。即使你离开 `screen` 会话(断开的),服务端也会继续运行。你现在可以安全的登出 Ubuntu 服务器了,你创建的“我的世界”服务端将会继续运行。
但是,如果 Ubuntu 服务器重启或关闭了的话,`screen` 会话将不再起作用。所以**为了让我们之前做的这些在启动时自动运行**,做下面这些:
打开 `/etc/rc.local` 文件:
```
nano /etc/rc.local
```
`exit 0` 语句前添加如下内容:
```
screen -dm -S minecraft /opt/minecraft/startminecraft.sh
exit 0
```
保存并关闭文件。
要访问“我的世界”服务端控制台,只需运行下面的命令来重新连接 `screen` 会话:
```
screen -r minecraft
```
现在就是这样。祝贺你,玩的开心!你现在可以连接到你的“我的世界”服务端或配置/修改它了。
### 配置你的 Ubuntu 服务器
你首先肯定要设置并确保你的 Ubuntu 服务器安全,如果你还没有这么做的话。按照[我们之前提及的指南][24]并谷歌一下来获取更多信息。你需要在服务器上配置的有这些:
#### 开启并配置防火墙
首先,如果防火墙还没有开启的话,你应该先开启先前安装的 UFW
```
ufw enable
```
你应该开放默认的“我的世界”服务端端口:
```
ufw allow 25565/tcp
```
你应该根据你的使用情况开放或拒绝其他规则。如果你不用服务器负载网站的话,就应该拒绝 80 和 443 端口。谷歌一下 Ubuntu 的 UFW/防火墙指南,你会得到建议的。设置防火墙的时候小心一些,如果你屏蔽了 SSH 端口的话你会把自己锁在服务器外面。
由于这是默认端口,这个端口经常被扫描以及攻击。你可以通过屏蔽白名单之外的访问权限来阻挡攻击。
首先,你需要在你的 [server.properties][25] 文件中开启白名单模式。要开启的话,打开文件:
```
nano /opt/minecraft/server.properties
```
并将 `white-list` 行改为 `true`
```
white-list=true
```
保存并关闭文件。
然后重启你的服务器(重启你的服务器或重新运行启动脚本):
```
/opt/minecraft/startminecraft.sh
```
访问“我的世界”服务端控制台:
```
screen -r minecraft
```
如果你想要某人进入你的服务端,你需要通过以下命令把他们添加到白名单:
```
whitelist add PlayerUsername
```
运行以下命令来将他们移出白名单:
```
whitelist remove PlayerUsername
```
使用 `CTRL+A-D` 来退出 `screen`(服务器控制台)。值得注意的是,这会拒绝除白名单以外的所有人连接到服务端。
[![how to create a minecraft server](https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg)][26]
### 如何搭建“我的世界”服务器 - 常见问题
我们将解答一些有关“我的世界”服务器和我们的指南的常见问题。
#### 我该如何重启“我的世界”服务器?
如果你按照我们的教程来的话,包括开启了服务端随系统启动,你可以直接重启你的 Ubuntu 服务器。如果没有设置岁系统启动的话,你可以通过重新运行启动脚本来重启“我的世界”服务端:
```
/opt/minecraft/startminecraft.sh
```
#### 我该如何配置我的“我的世界”服务端?
你可以使用 [server.properties][27] 文件来配置你的服务端。查看“我的世界”维基来获取更多信息,你也可以什么都不动,它会工作的很好。
如果你想改变游戏模式、难度等诸如此类的东西,你可以使用服务端控制台。通过下面的命令访问服务端控制台:
```
screen -r minecraft
```
并执行[命令][28]。像下面这些命令:
```
difficulty hard
```
```
gamemode survival @a
```
你可能需要重新启动服务端,这取决于你使用了什么命令。你可以使用很多命令,查看[维基][29]来获取更多。
#### 我该如何升级我的“我的世界”服务端?
如果有新版本发布的话,你需要这样做:
进入“我的世界”目录:
```
cd /opt/minecraft
```
下载最新的版本,比如使用 wget 下载 1.12.3 版本:
```
wget https://s3.amazonaws.com/Minecraft.Download/versions/1.12.3/minecraft_server.1.12.3.jar
```
接下来,运行并构建新服务端:
```
java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui
```
最后,更新你的启动脚本:
```
nano /opt/minecraft/startminecraft.sh
```
更新版本号数字:
```
#!/bin/bash
cd /opt/minecraft/ && java -Xms2048M -Xmx3472M -jar minecraft_server.1.12.3.jar nogui
```
现在你可以重启服务端了,一切都应该没有问题。
#### 为什么你们的教程这么长,而其他的只有 2 行那么长?!
我们想让这个教程对新手来说更友好,并且尽可能详细。我们还向你展示了如何让服务端长期运行并跟随系统启动,我们向你展示了如何配置你的服务端以及所有的东西。我是说,你当然可以用几行来启动“我的世界”服务器,但那样的话绝对很烂,从不仅一方面说。
#### 我不知道 Linux 或者这里说的什么东西,我该如何搭建一个“我的世界”服务器呢?
只要通篇阅读我们的文章,复制粘贴几个命令就行了。如果你真的不知道该如何做的话,[我们可以帮你][30],或者直接找一个[托管的][31]服务器[提供商][32],让他们帮你做这些。
#### 我该如何在服务端上安装 mod 和插件?
我们的文章意图作一篇入门指南,你应该查看[“我的世界维基”][33],或者谷歌一下来获取更多信息。网上有很多教程。
--------------------------------------------------------------------------------
via: https://thishosting.rocks/how-to-make-a-minecraft-server/
作者:[ThisHosting.Rocks][a]
译者:[heart4lor](https://github.com/heart4lor)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://thishosting.rocks
[1]:https://thishosting.rocks/how-to-make-a-minecraft-server/#reasons
[2]:https://thishosting.rocks/how-to-make-a-minecraft-server/#not-pc
[3]:https://thishosting.rocks/how-to-make-a-minecraft-server/#requirements
[4]:https://thishosting.rocks/how-to-make-a-minecraft-server/#make-minecraft-server
[5]:https://thishosting.rocks/how-to-make-a-minecraft-server/#persistent
[6]:https://thishosting.rocks/how-to-make-a-minecraft-server/#boot
[7]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server
[8]:https://thishosting.rocks/how-to-make-a-minecraft-server/#faqs
[9]:https://thishosting.rocks/cheap-cloud-hosting-providers-comparison/
[10]:https://thishosting.rocks/go/vultr/
[11]:https://minecraft.gamepedia.com/Server/Requirements/Dedicated
[12]:https://thishosting.rocks/best-cheap-managed-vps/
[13]:https://www.chiark.greenend.org.uk/~sgtatham/putty/
[14]:https://mobaxterm.mobatek.net/
[15]:https://www.linode.com/docs/security/securing-your-server/
[16]:https://thishosting.rocks/go/vultr/
[17]:https://thishosting.rocks/go/vultr/
[18]:https://thishosting.rocks/ubuntu-18-04-new-features-release-date/
[19]:https://www.linode.com/docs/security/securing-your-server/
[20]:https://minecraft.net/en-us/download/server
[21]:https://minecraft.gamepedia.com/Commands
[22]:https://thishosting.rocks/go/vultr/
[23]:https://thishosting.rocks/how-to-make-a-minecraft-server/#configure-minecraft-server
[24]:https://www.linode.com/docs/security/securing-your-server/
[25]:https://minecraft.gamepedia.com/Server.properties
[26]:https://thishosting.rocks/wp-content/uploads/2018/01/create-a-minecraft-server.jpg
[27]:https://minecraft.gamepedia.com/Server.properties
[28]:https://minecraft.gamepedia.com/Commands
[29]:https://minecraft.gamepedia.com/Commands
[30]:https://thishosting.rocks/support/
[31]:https://thishosting.rocks/best-cheap-managed-vps/
[32]:https://thishosting.rocks/best-cheap-managed-vps/
[33]:https://minecraft.gamepedia.com/Minecraft_Wiki

View File

@@ -0,0 +1,426 @@
如何在 CentOS 7 / RHEL 7 终端服务器上安装 KVM
======
如何在 CnetOS 7 或 RHEL 7Red Hat 企业版 Linux服务器上安装和配置 KVM基于内核的虚拟机如何在 CentOS 7 上设置 KVM 并使用云镜像 / cloud-init 来安装客户虚拟机?
基于内核的虚拟机KVM是 CentOS 或 RHEL 7 的虚拟化软件。KVM 可以将你的服务器变成虚拟机管理器。本文介绍如何在 CentOS 7 或 RHEL 7 中使用 KVM 设置和管理虚拟化环境。还介绍了如何使用命令行在物理服务器上安装和管理虚拟机VM。请确保在服务器的 BIOS 中启用了**虚拟化技术(VT)**。你也可以运行以下命令[测试 CPU 是否支持 Intel VT 和 AMD_V 虚拟化技术][1]。
```
$ lscpu | grep Virtualization
Virtualization: VT-x
```
按照 CentOS 7/RHEL 7 终端服务器上的 KVM 安装步骤进行操作。
### 步骤 1 安装 kvm
输入以下 [yum 命令][2]:
```
# yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install
```
[![How to install KVM on CentOS 7 RHEL 7 Headless Server][3]][3]
启动 libvirtd 服务:
```
# systemctl enable libvirtd
# systemctl start libvirtd
```
### 步骤 2 确认 kvm 安装
使用 `lsmod` 命令和 [grep命令][4] 确认加载了 KVM 模块:
```
# lsmod | grep -i kvm
```
### 步骤 3 配置桥接网络
默认情况下,由 libvirtd 配置基于 dhcpd 的网桥。你可以使用以下命令验证:
```
# brctl show
# virsh net-list
```
[![KVM default networking][5]][5]
所有虚拟机(客户机)只能对同一台服务器上的其它虚拟机进行网络访问。为你创建的私有网络是 192.168.122.0/24。验证
```
# virsh net-dumpxml default
```
如果你希望你的虚拟机可用于 LAN 上的其他服务器,请在连接到你的 LAN 的服务器上设置一个网桥。更新你的网卡配置文件,如 ifcfg-enp3s0 或 em1
```
# vi /etc/sysconfig/network-scripts/ifcfg-enp3s0
```
添加一行:
```
BRIDGE=br0
```
[使用 vi 保存并关闭文件][6]。编辑 `/etc/sysconfig/network-scripts/ifcfg-br0`
```
# vi /etc/sysconfig/network-scripts/ifcfg-br0
```
添加以下内容:
```
DEVICE="br0"
# I am getting ip from DHCP server #
BOOTPROTO="dhcp"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
ONBOOT="yes"
TYPE="Bridge"
DELAY="0"
```
重新启动网络服务警告ssh 命令将断开连接,最好重新启动该设备):
```
# systemctl restart NetworkManager
```
`brctl` 命令验证它:
```
# brctl show
```
### 步骤 4 创建你的第一个虚拟机
我将会创建一个 CentOS 7.x 虚拟机。首先,使用 `wget` 命令获取 CentOS 7.x 最新的 ISO 镜像:
```
# cd /var/lib/libvirt/boot/
# wget https://mirrors.kernel.org/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso
```
验证 ISO 镜像:
```
# wget https://mirrors.kernel.org/centos/7.4.1708/isos/x86_64/sha256sum.txt
# sha256sum -c sha256sum.txt
```
#### 创建 CentOS 7.x 虚拟机
在这个例子中,我创建了 2GB RAM2 个 CPU 核心1 个网卡和 40 GB 磁盘空间的 CentOS 7.x 虚拟机,输入:
```
# virt-install \
--virt-type=kvm \
--name centos7 \
--ram 2048 \
--vcpus=1 \
--os-variant=centos7.0 \
--cdrom=/var/lib/libvirt/boot/CentOS-7-x86_64-Minimal-1708.iso \
--network=bridge=br0,model=virtio \
--graphics vnc \
--disk path=/var/lib/libvirt/images/centos7.qcow2,size=40,bus=virtio,format=qcow2
```
从另一个终端通过 `ssh` 配置 vnc 登录,输入:
```
# virsh dumpxml centos7 | grep v nc
<graphics type='vnc' port='5901' autoport='yes' listen='127.0.0.1'>
```
请记录下端口值(即 5901。你需要使用 SSH 客户端来建立隧道和 VNC 客户端才能访问远程 vnc 服务器。在客户端/桌面/ macbook pro 系统中输入以下 SSH 端口转发命令:
```
$ ssh vivek@server1.cyberciti.biz -L 5901:127.0.0.1:5901
```
一旦你建立了 ssh 隧道,你可以将你的 VNC 客户端指向你自己的 127.0.0.1 (localhost) 地址和端口 5901如下所示
[![][7]][7]
你应该看到 CentOS Linux 7 客户虚拟机安装屏幕如下:
[![][8]][8]
现在只需按照屏幕说明进行操作并安装CentOS 7。一旦安装完成后请继续并单击重启按钮。 远程服务器关闭了我们的 VNC 客户端的连接。 你可以通过 KVM 客户端重新连接,以配置服务器的其余部分,包括基于 SSH 的会话或防火墙。
### 使用云镜像
以上安装方法对于学习目的或单个虚拟机而言是可行的。你需要部署大量的虚拟机吗? 可以试试云镜像。你可以根据需要修改预先构建的云镜像。例如,使用 [Cloud-init][9] 添加用户、ssh 密钥、设置时区等等,这是处理云实例的早期初始化的事实上的多分发包。让我们看看如何创建带有 1024MB RAM20GB 磁盘空间和 1 个 vCPU 的 CentOS 7 虚拟机。LCTT 译注: vCPU 即电脑中的虚拟处理器)
#### 获取 CentOS 7 云镜像
```
# cd /var/lib/libvirt/boot
# wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
```
#### 创建所需的目录
```
# D=/var/lib/libvirt/images
# VM=centos7-vm1 ## vm name ##
# mkdir -vp $D/$VM
mkdir: created directory '/var/lib/libvirt/images/centos7-vm1'
```
#### 创建元数据文件
```
# cd $D/$VM
# vi meta-data
```
添加以下内容:
```
instance-id: centos7-vm1
local-hostname: centos7-vm1
```
#### 创建用户数据文件
我将使用 ssh 密钥登录到虚拟机。所以确保你有 ssh 密钥:
```
# ssh-keygen -t ed25519 -C "VM Login ssh key"
```
[![ssh-keygen command][10]][11]
请参阅 “[如何在 Linux/Unix 系统上设置 SSH 密钥][12]” 来获取更多信息。编辑用户数据如下:
```
# cd $D/$VM
# vi user-data
```
添加如下(根据你的设置替换 `hostname``users``ssh-authorized-keys`
```
#cloud-config
# Hostname management
preserve_hostname: False
hostname: centos7-vm1
fqdn: centos7-vm1.nixcraft.com
# Users
users:
- default
- name: vivek
groups: ['wheel']
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh-authorized-keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMP3MOF2ot8MOdNXCpHem0e2Wemg4nNmL2Tio4Ik1JY VM Login ssh key
# Configure where output will go
output:
all: ">> /var/log/cloud-init.log"
# configure interaction with ssh server
ssh_genkeytypes: ['ed25519', 'rsa']
# Install my public ssh key to the first user-defined user configured
# in cloud.cfg in the template (which is centos for CentOS cloud images)
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMP3MOF2ot8MOdNXCpHem0e2Wemg4nNmL2Tio4Ik1JY VM Login ssh key
# set timezone for VM
timezone: Asia/Kolkata
# Remove cloud-init
runcmd:
- systemctl stop network && systemctl start network
- yum -y remove cloud-init
```
#### 复制云镜像
```
# cd $D/$VM
# cp /var/lib/libvirt/boot/CentOS-7-x86_64-GenericCloud.qcow2 $VM.qcow2
```
#### 创建 20GB 磁盘映像
```
# cd $D/$VM
# export LIBGUESTFS_BACKEND=direct
# qemu-img create -f qcow2 -o preallocation=metadata $VM.new.image 20G
# virt-resize --quiet --expand /dev/sda1 $VM.qcow2 $VM.new.image
```
[![Set VM image disk size][13]][13]
用压缩后的镜像覆盖它:
```
# cd $D/$VM
# mv $VM.new.image $VM.qcow2
```
#### 创建一个 cloud-init ISO
```
# mkisofs -o $VM-cidata.iso -V cidata -J -r user-data meta-data
```
[![Creating a cloud-init ISO][14]][14]
#### 创建一个池
```
# virsh pool-create-as --name $VM --type dir --target $D/$VM
Pool centos7-vm1 created
```
#### 安装 CentOS 7 虚拟机
```
# cd $D/$VM
# virt-install --import --name $VM \
--memory 1024 --vcpus 1 --cpu host \
--disk $VM.qcow2,format=qcow2,bus=virtio \
--disk $VM-cidata.iso,device=cdrom \
--network bridge=virbr0,model=virtio \
--os-type=linux \
--os-variant=centos7.0 \
--graphics spice \
--noautoconsole
```
删除不需要的文件:
```
# cd $D/$VM
# virsh change-media $VM hda --eject --config
# rm meta-data user-data centos7-vm1-cidata.iso
```
#### 查找虚拟机的 IP 地址
```
# virsh net-dhcp-leases default
```
[![CentOS7-VM1- Created][15]][15]
#### 登录到你的虚拟机
使用 ssh 命令:
```
# ssh vivek@192.168.122.85
```
[![Sample VM session][16]][16]
### 有用的命令
让我们看看管理虚拟机的一些有用的命令。
#### 列出所有虚拟机
```
# virsh list --all
```
#### 获取虚拟机信息
```
# virsh dominfo vmName
# virsh dominfo centos7-vm1
```
#### 停止/关闭虚拟机
```
# virsh shutdown centos7-vm1
```
#### 开启虚拟机
```
# virsh start centos7-vm1
```
#### 将虚拟机标记为在引导时自动启动
```
# virsh autostart centos7-vm1
```
#### 重新启动(软安全重启)虚拟机
```
# virsh reboot centos7-vm1
```
重置(硬重置/不安全)虚拟机
```
# virsh reset centos7-vm1
```
#### 删除虚拟机
```
# virsh shutdown centos7-vm1
# virsh undefine centos7-vm1
# virsh pool-destroy centos7-vm1
# D=/var/lib/libvirt/images
# VM=centos7-vm1
# rm -ri $D/$VM
```
查看 virsh 命令类型的完整列表:
```
# virsh help | less
# virsh help | grep reboot
```
### 关于作者
作者是 nixCraft 的创建者,也是经验丰富的系统管理员和 Linux 操作系统/ Unix shell 脚本的培训师。 他曾与全球客户以及 IT教育国防和空间研究以及非营利部门等多个行业合作。 在 [Twitter][17][Facebook][18][Google +][19] 上关注他。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/how-to-install-kvm-on-centos-7-rhel-7-headless-server/
作者:[Vivek Gite][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/faq/linux-xen-vmware-kvm-intel-vt-amd-v-support/
[2]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info)
[3]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-KVM-on-CentOS-7-RHEL-7-Headless-Server.jpg
[4]:https://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/ (See Linux/Unix grep command examples for more info)
[5]:https://www.cyberciti.biz/media/new/faq/2018/01/KVM-default-networking.jpg
[6]:https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/
[7]:https://www.cyberciti.biz/media/new/faq/2016/01/vnc-client.jpg
[8]:https://www.cyberciti.biz/media/new/faq/2016/01/centos7-guest-vnc.jpg
[9]:https://cloudinit.readthedocs.io/en/latest/index.html
[10]:https://www.cyberciti.biz/media/new/faq/2018/01/ssh-keygen-pub-key.jpg
[11]:https://www.cyberciti.biz/faq/linux-unix-generating-ssh-keys/
[12]:https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/
[13]:https://www.cyberciti.biz/media/new/faq/2018/01/Set-VM-image-disk-size.jpg
[14]:https://www.cyberciti.biz/media/new/faq/2018/01/Creating-a-cloud-init-ISO.jpg
[15]:https://www.cyberciti.biz/media/new/faq/2018/01/CentOS7-VM1-Created.jpg
[16]:https://www.cyberciti.biz/media/new/faq/2018/01/Sample-VM-session.jpg
[17]:https://twitter.com/nixcraft
[18]:https://facebook.com/nixcraft
[19]:https://plus.google.com/+CybercitiBiz

View File

@@ -0,0 +1,113 @@
搭建私有云OwnCloud
======
所有人都在讨论云。尽管市面上有很多为我们提供云存储和其他云服务的主要服务商,但是我们还是可以为自己搭建一个私有云。
在本教程中,我们将讨论如何利用 OwnCloud 搭建私有云。OwnCloud 是一个可以安装在我们 Linux 设备上的 web 应用程序能够存储和用我们的数据提供服务。OwnCloud 可以分享日历、联系人和书签,共享音/视频流等等。
本教程中,我们使用的是 CentOS 7 系统,但是本教程同样适用于其他 Linux 发行版中安装 OwnCloud。让我们开始安装 OwnCloud 并且做一些准备工作,
- 推荐阅读:[如何在 CentOS & RHEL 上使用 Apache 作为反向代理服务器][1]
- 同时推荐:[实时 Linux 服务器监测和 GLANCES 监测工具][2]
### 预备
* 我们需要在机器上配置 LAMP。参照阅读我们的文章《[在 CentOS/RHEL 上配置 LAMP 服务器最简单的教程][3]》 & 《[在 Ubuntu 搭建 LAMP][4]》。
* 我们需要在自己的设备里安装这些包,`php-mysql``php-json``php-xml``php-mbstring``php-zip``php-gd``curl、 `php-curl` 、`php-pdo`。使用包管理器安装它们。
```
$ sudo yum install php-mysql php-json php-xml php-mbstring php-zip php-gd curl php-curl php-pdo
```
### 安装
安装 OwnCloud我们现在需要在服务器上下载 OwnCloud 安装包。使用下面的命令从官方网站下载最新的安装包10.0.4-1
```
$ wget https://download.owncloud.org/community/owncloud-10.0.4.tar.bz2
```
使用下面的命令解压:
```
$ tar -xvf owncloud-10.0.4.tar.bz2
```
现在,将所有解压后的文件移动至 `/var/www/html`
```
$ mv owncloud/* /var/www/html
```
下一步,我们需要在 Apache 的配置文件 `httpd.conf` 上做些修改:
```
$ sudo vim /etc/httpd/conf/httpd.conf
```
更改下面的选项:
```
AllowOverride All
```
保存该文件,并修改 OwnCloud 文件夹的文件权限:
```
$ sudo chown -R apache:apache /var/www/html/
$ sudo chmod 777 /var/www/html/config/
```
然后重启 Apache 服务器执行修改:
```
$ sudo systemctl restart httpd
```
现在,我们需要在 MariaDB 上创建一个数据库,保存来自 OwnCloud 的数据。使用下面的命令创建数据库和数据库用户:
```
$ mysql -u root -p
MariaDB [(none)] > create database owncloud;
MariaDB [(none)] > GRANT ALL ON owncloud.* TO ocuser@localhost IDENTIFIED BY 'owncloud';
MariaDB [(none)] > flush privileges;
MariaDB [(none)] > exit
```
服务器配置部分完成后,现在我们可以在网页浏览器上访问 OwnCloud。打开浏览器输入您的服务器 IP 地址,我这边的服务器是 10.20.30.100
![安装 owncloud][7]
一旦 URL 加载完毕我们将呈现上述页面。这里我们将创建管理员用户同时提供数据库信息。当所有信息提供完毕点击“Finish setup”。
我们将被重定向到登录页面,在这里,我们需要输入先前创建的凭据:
![安装 owncloud][9]
认证成功之后,我们将进入 OwnCloud 面板:
![安装 owncloud][11]
我们可以使用手机应用程序,同样也可以使用网页界面更新我们的数据。现在,我们已经有自己的私有云了,同时,关于如何安装 OwnCloud 创建私有云的教程也进入尾声。请在评论区留下自己的问题或建议。
--------------------------------------------------------------------------------
via: http://linuxtechlab.com/create-personal-cloud-install-owncloud/
作者:[SHUSAIN][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://linuxtechlab.com/author/shsuain/
[1]:http://linuxtechlab.com/apache-as-reverse-proxy-centos-rhel/
[2]:http://linuxtechlab.com/linux-server-glances-monitoring-tool/
[3]:http://linuxtechlab.com/easiest-guide-creating-lamp-server/
[4]:http://linuxtechlab.com/install-lamp-stack-on-ubuntu/
[6]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=400%2C647
[7]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2018/01/owncloud1-compressor.jpg?resize=400%2C647
[8]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=876%2C541
[9]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2018/01/owncloud2-compressor1.jpg?resize=876%2C541
[10]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=981%2C474
[11]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2018/01/owncloud3-compressor1.jpg?resize=981%2C474

View File

@@ -0,0 +1,62 @@
程序员如何学习编码
============================================================
[![How programmers learn to code](https://mybroadband.co.za/news/wp-content/uploads/2016/01/Programmer-working-computer-code.jpg)][8]
HackerRank 最近公布了 2018 年开发者技能报告的结果,其中向程序员询问了他们何时开始编码。
39,441 名专业人员和学生开发者于 2016 年 10 月 16 日至 11 月 1 日完成了在线调查,超过 25 的被调查的开发者在 16 岁前编写了他们的第一段代码。LCTT 译注:日期恐有误)
### 程序员是如何学习的
报告称,就程序员如何学习编码而言,自学是所有年龄段开发者的常态。
“尽管 67 的开发者拥有计算机科学学位,但大约 74 的人表示他们至少一部分是自学的。”
开发者平均了解四种语言,但他们想学习更多语言。
对学习的渴望因人而异 —— 18 至 24 岁的开发者计划学习 6 种语言,而 35 岁以上的开发者只计划学习 3 种语言。
[![HackerRank 2018 how did you learn to code](https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-did-you-learn-to-code.jpg)][5]
### 程序员想要什么
HackerRank 还研究了开发者最想从雇主那里得到什么。
平均而言,良好的工作与生活平衡,紧随其后的是专业成长与学习,是最理想的要求。
按地区划分的数据显示,美国人比亚洲和欧洲的开发者更渴望工作与生活的平衡。
学生倾向于将成长和学习列在工作与生活的平衡之上,而专业人员对薪酬的排名比学生高得多。
在小公司工作的人倾向于降低工作与生活的平衡,但仍处于前三名。
年龄也制造了不同25 岁以上的开发者将工作与生活的平衡评为最重要的,而 18 岁至 24 岁的人们则认为其重要性较低。
HackerRank 说:“在某些方面,我们发现了一个小矛盾。开发人员需要工作与生活的平衡,但他们也渴望学习“。
它建议,专注于做你喜欢的事情,而不是试图学习一切,这可以帮助实现更好的工作与生活的平衡。
[![HackerRank 2018 what do developers want most](https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-what-do-developers-want-most-640x342.jpg)][6]
[![HackerRank 2018 how to improve work-life balance](https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-to-improve-work-life-balance-378x430.jpg)][7]
--------------------------------------------------------------------------------
via: https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html
作者:[Staff Writer][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://mybroadband.co.za/news/author/staff-writer
[1]:https://mybroadband.co.za/news/author/staff-writer
[2]:https://twitter.com/intent/tweet/?text=How+programmers+learn+to+code%20https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html&via=mybroadband
[3]:mailto:?subject=How%20programmers%20learn%20to%20code&body=HackerRank%20recently%20published%20the%20results%20of%20its%202018%20Developer%20Skills%20Report.%0A%0Ahttps%3A%2F%2Fmybroadband.co.za%2Fnews%2Fsmartphones%2F246583-how-programmers-learn-to-code.html
[4]:https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html#disqus_thread
[5]:https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-did-you-learn-to-code.jpg
[6]:https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-what-do-developers-want-most.jpg
[7]:https://mybroadband.co.za/news/wp-content/uploads/2018/01/HackerRank-2018-how-to-improve-work-life-balance.jpg
[8]:https://mybroadband.co.za/news/smartphones/246583-how-programmers-learn-to-code.html

View File

@@ -0,0 +1,225 @@
如何用 Python 解析 HTML
======
用一些简单的脚本,可以很容易地清理文档和其它大量的 HTML 文件。但是首先你需要解析它们。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/bus_html_code.png?itok=VjUmGsnl)
图片由 Jason Baker 为 Opensource.com 所作。
作为 Scribus 文档团队的长期成员,我要随时了解最新的源代码更新,以便对文档进行更新和补充。 我最近在刚升级到 Fedora 27 系统的计算机上使用 Subversion 进行检出操作时,对于下载该文档所需要的时间我感到很惊讶,文档由 HTML 页面和相关图像组成。 我恐怕该项目的文档看起来比项目本身大得多,并且怀疑其中的一些内容是“僵尸”文档——不再使用的 HTML 文件以及 HTML 中无法访问到的图像。
我决定为自己创建一个项目来解决这个问题。 一种方法是搜索未使用的现有图像文件。 如果我可以扫描所有 HTML 文件中的图像引用,然后将该列表与实际图像文件进行比较,那么我可能会看到不匹配的文件。
这是一个典型的图像标签:
```
<img src="images/edit_shapes.png" ALT="Edit examples" ALIGN=left>
```
我对 `src=` 之后的第一组引号之间的部分很感兴趣。 在寻找了一些解决方案后,我找到一个名为 [BeautifulSoup][1] 的 Python 模块。 脚本的核心部分如下所示:
```
soup = BeautifulSoup(all_text, 'html.parser')
match = soup.findAll("img")
if len(match) > 0:
for m in match:
imagelist.append(str(m))
```
我们可以使用这个 `findAll` 方法来挖出图片标签。 这是一小部分输出:
```
<img src="images/pdf-form-ht3.png"/><img src="images/pdf-form-ht4.png"/><img src="images/pdf-form-ht5.png"/><img src="images/pdf-form-ht6.png"/><img align="middle" alt="GSview - Advanced Options Panel" src="images/gsadv1.png" title="GSview - Advanced Options Panel"/><img align="middle" alt="Scribus External Tools Preferences" src="images/gsadv2.png" title="Scribus External Tools Preferences"/>
```
到现在为止还挺好。我原以为下一步就可以搞定了,但是当我在脚本中尝试了一些字符串方法时,它返回了有关标记的错误而不是字符串的错误。 我将输出保存到一个文件中,并在 [KWrite][2] 中进行编辑。 KWrite 的一个好处是你可以使用正则表达式regex来做“查找和替换”操作所以我可以用 `\n<img` 替换 `<img`,这样可以看得更清楚。 KWrite 的另一个好处是,如果你用正则表达式做了一个不明智的选择,你还可以撤消。
但我认为,肯定有比这更好的东西,所以我转而使用正则表达式,或者更具体地说 Python 的 `re` 模块。 这个新脚本的相关部分如下所示:
```
match = re.findall(r'src="(.*)/>', all_text)
if len(match)>0:
for m in match:
imagelist.append(m)
```
它的一小部分输出如下所示:
```
images/cmcanvas.png" title="Context Menu for the document canvas" alt="Context Menu for the document canvas" /></td></tr></table><br images/eps-imp1.png" title="EPS preview in a file dialog" alt="EPS preview in a file dialog" images/eps-imp5.png" title="Colors imported from an EPS file" alt="Colors imported from an EPS file" images/eps-imp4.png" title="EPS font substitution" alt="EPS font substitution" images/eps-imp2.png" title="EPS import progress" alt="EPS import progress" images/eps-imp3.png" title="Bitmap conversion failure" alt="Bitmap conversion failure"
```
乍一看,它看起来与上面的输出类似,并且附带有去除图像的标签部分的好处,但是有令人费解的是还夹杂着表格标签和其他内容。 我认为这涉及到这个正则表达式 `src="(.*)/>`,这被称为*贪婪*,意味着它不一定停止在遇到 `/>` 的第一个实例。我应该补充一点,我也尝试过 `src="(.*)"`,这真的没有什么更好的效果,我不是一个正则表达式专家(只是做了这个),找了各种方法来改进这一点但是并没什么用。
做了一系列的事情之后,甚至尝试了 Perl 的 `HTML::Parser` 模块,最终我试图将这与我为 Scribus 编写的一些脚本进行比较,这些脚本逐个字符的分析文本内容,然后采取一些行动。 为了最终目的,我终于想出了所有这些方法,并且完全不需要正则表达式或 HTML 解析器。 让我们回到展示的那个 `img` 标签的例子。
```
<img src="images/edit_shapes.png" ALT="Edit examples" ALIGN=left>
```
我决定回到 `src=` 这一块。 一种方法是等待 `s` 出现,然后看下一个字符是否是 `r`,下一个是 `c`,下一个是否 `=`。 如果是这样,那就匹配上了! 那么两个双引号之间的内容就是我所需要的。 这种方法的问题在于需要连续识别上面这样的结构。 一种查看代表一行 HTML 文本的字符串的方法是:
```
for c in all_text:
```
但是这个逻辑太乱了,以至于不能持续匹配到前面的 `c`,还有之前的字符,更之前的字符,更更之前的字符。
最后,我决定专注于 `=` 并使用索引方法,以便我可以轻松地引用字符串中的任何先前或将来的字符。 这里是搜索部分:
```
index = 3
while index < linelength:
if (all_text[index] == '='):
if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and (all_text[index-1] == 'c'):
imagefound(all_text, imagelist, index)
index += 1
else:
index += 1
else:
index += 1
```
我用第四个字符开始搜索(索引从 0 开始),所以我在下面没有出现索引错误,并且实际上,在每一行的第四个字符之前不会有等号。 第一个测试是看字符串中是否出现了 `=`,如果没有,我们就会前进。 如果我们确实看到一个等号,那么我们会看前三个字符是否是 `s``r``c`。 如果全都匹配了,就调用函数 `imagefound`
```
def imagefound(all_text, imagelist, index):
end = 0
index += 2
newimage = ''
while end == 0:
if (all_text[index] != '"'):
newimage = newimage + all_text[index]
index += 1
else:
newimage = newimage + '\n'
imagelist.append(newimage)
end = 1
return
```
我们给函数发送当前索引,它代表着 `=`。 我们知道下一个字符将会是 `"`,所以我们跳过两个字符,并开始向名为 `newimage` 的控制字符串添加字符,直到我们发现下一个 `"`,此时我们完成了一次匹配。 我们将字符串加一个换行符(`\n`)添加到列表 `imagelist` 中并返回(`return`),请记住,在剩余的这个 HTML 字符串中可能会有更多图片标签,所以我们马上回到搜索循环中。
以下是我们的输出现在的样子:
```
images/text-frame-link.png
images/text-frame-unlink.png
images/gimpoptions1.png
images/gimpoptions3.png
images/gimpoptions2.png
images/fontpref3.png
images/font-subst.png
images/fontpref2.png
images/fontpref1.png
images/dtp-studio.png
```
啊,干净多了,而这只花费几秒钟的时间。 我本可以将索引前移 7 步来剪切 `images/` 部分,但我更愿意把这个部分保存下来,以确保我没有剪切掉图像文件名的第一个字母,这很容易用 KWrite 编辑成功 —— 你甚至不需要正则表达式。 做完这些并保存文件后,下一步就是运行我编写的另一个脚本 `sortlist.py`
```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# sortlist.py
import os
imagelist = []
for line in open('/tmp/imagelist_parse4.txt').xreadlines():
imagelist.append(line)
imagelist.sort()
outfile = open('/tmp/imagelist_parse4_sorted.txt', 'w')
outfile.writelines(imagelist)
outfile.close()
```
这会读取文件内容,并存储为列表,对其排序,然后另存为另一个文件。 之后,我可以做到以下几点:
```
ls /home/gregp/development/Scribus15x/doc/en/images/*.png > '/tmp/actual_images.txt'
```
然后我需要在该文件上运行 `sortlist.py`,因为 `ls` 方法的排序与 Python 不同。 我原本可以在这些文件上运行比较脚本,但我更愿意以可视方式进行操作。 最后,我成功找到了 42 个图像,这些图像没有来自文档的 HTML 引用。
这是我的完整解析脚本:
```
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# parseimg4.py
import os
def imagefound(all_text, imagelist, index):
end = 0
index += 2
newimage = ''
while end == 0:
if (all_text[index] != '"'):
newimage = newimage + all_text[index]
index += 1
else:
newimage = newimage + '\n'
imagelist.append(newimage)
end = 1
return
htmlnames = []
imagelist = []
tempstring = ''
filenames = os.listdir('/home/gregp/development/Scribus15x/doc/en/')
for name in filenames:
if name.endswith('.html'):
htmlnames.append(name)
#print htmlnames
for htmlfile in htmlnames:
all_text = open('/home/gregp/development/Scribus15x/doc/en/' + htmlfile).read()
linelength = len(all_text)
index = 3
while index < linelength:
if (all_text[index] == '='):
if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and
(all_text[index-1] == 'c'):
imagefound(all_text, imagelist, index)
index += 1
else:
index += 1
else:
index += 1
outfile = open('/tmp/imagelist_parse4.txt', 'w')
outfile.writelines(imagelist)
outfile.close()
imageno = len(imagelist)
print str(imageno) + " images were found and saved"
```
脚本名称为 `parseimg4.py`,这并不能真实反映我陆续编写的脚本数量(包括微调的和大改的以及丢弃并重新开始写的)。 请注意,我已经对这些目录和文件名进行了硬编码,但是很容易变得通用化,让用户输入这些信息。 同样,因为它们是工作脚本,所以我将输出发送到 `/tmp` 目录,所以一旦重新启动系统,它们就会消失。
这不是故事的结尾,因为下一个问题是:僵尸 HTML 文件怎么办? 任何未使用的文件都可能会引用图像,不能被前面的方法所找出。 我们有一个 `menu.xml` 文件作为联机手册的目录,但我还需要考虑 TOCLCTT 译注TOC 是 table of contents 的缩写)中列出的某些文件可能引用了不在 TOC 中的文件,是的,我确实找到了一些这样的文件。
最后我可以说,这是一个比图像搜索更简单的任务,而且开发的过程对我有很大的帮助。
### 关于作者
[![](https://opensource.com/sites/default/files/styles/profile_pictures/public/20150529_gregp.jpg?itok=nv02g6PV)][7]
Greg Pittman 是 Kentucky 州 Louisville 市的一名退休的神经学家,从二十世纪六十年代的 Fortran IV 语言开始长期以来对计算机和编程有着浓厚的兴趣。 当 Linux 和开源软件出现的时候Greg 深受启发,去学习更多知识,并实现最终贡献的承诺。 他是 Scribus 团队的成员。[更多关于我][8]
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/1/parsing-html-python
作者:[Greg Pittman][a]
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/greg-p
[1]:https://www.crummy.com/software/BeautifulSoup/
[2]:https://www.kde.org/applications/utilities/kwrite/
[7]:https://opensource.com/users/greg-p
[8]:https://opensource.com/users/greg-p

View File

@@ -0,0 +1,109 @@
du 及 df 命令的使用(附带示例)
======
在本文中,我将讨论 `du``df` 命令。`du``df` 命令都是 Linux 系统的重要工具,来显示 Linux 文件系统的磁盘使用情况。这里我们将通过一些例子来分享这两个命令的用法。
- **(推荐阅读:[使用 scp 和 rsync 命令传输文件][1]**
- **(另请阅读:[使用 dd 和 cat 命令为 Linux 系统克隆磁盘][2]**
### du 命令
`du`disk usage 的简称)是用于查找文件和目录的磁盘使用情况的命令。`du` 命令在与各种选项一起使用时能以多种格式提供结果。
下面是一些例子:
#### 1、 得到一个目录下所有子目录的磁盘使用概况
```
$ du /home
```
![du command][4]
该命令的输出将显示 `/home` 中的所有文件和目录以及显示块大小。
#### 2、 以人类可读格式也就是 kb、mb 等显示文件/目录大小
```
$ du -h /home
```
![du command][6]
#### 3、 目录的总磁盘大小
```
$ du -s /home
```
![du command][8]
它是 `/home` 目录的总大小
### df 命令
dfdisk filesystem 的简称)用于显示 Linux 系统的磁盘利用率。LCTT 译注:`df` 可能应该是 disk free 的简称。)
下面是一些例子。
#### 1、 显示设备名称、总块数、总磁盘空间、已用磁盘空间、可用磁盘空间和文件系统上的挂载点。
```
$ df
```
![df command][10]
#### 2、 人类可读格式的信息
```
$ df -h
```
![df command][12]
上面的命令以人类可读格式显示信息。
#### 3、 显示特定分区的信息
```
$ df -hT /etc
```
![df command][14]
`-hT` 加上目标目录将以可读格式显示 `/etc` 的信息。
虽然 `du``df` 命令有更多选项,但是这些例子可以让你初步了解。如果在这里找不到你要找的东西,那么你可以参考有关命令的 man 页面。
另外,[**在这**][15]阅读我的其他帖子,在那里我分享了一些其他重要和经常使用的 Linux 命令。
如往常一样,欢迎你留下评论和疑问,因此在下面留下你的评论和疑问,我会回复你。
--------------------------------------------------------------------------------
via: http://linuxtechlab.com/du-df-commands-examples/
作者:[SHUSAIN][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://linuxtechlab.com/author/shsuain/
[1]:http://linuxtechlab.com/files-transfer-scp-rsync-commands/
[2]:http://linuxtechlab.com/linux-cloning-disks-using-dd-cat-commands/
[3]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=453%2C162
[4]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/du1.jpg?resize=453%2C162
[5]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=491%2C163
[6]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/du2.jpg?resize=491%2C163
[7]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=584%2C61
[8]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/du3.jpg?resize=584%2C61
[9]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=638%2C157
[10]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/df1.jpg?resize=638%2C157
[11]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=641%2C149
[12]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/df2.jpg?resize=641%2C149
[13]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=638%2C62
[14]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/df3-1.jpg?resize=638%2C62
[15]:http://linuxtechlab.com/tips-tricks/

View File

@@ -0,0 +1,136 @@
我喜欢 Vue 的 10 个方面
============================================================
![](https://cdn-images-1.medium.com/max/1600/1*X4ipeKVYzmY2M3UPYgUYuA.png)
我喜欢 Vue。当我在 2016 年第一次接触它时,也许那时我已经对 JavaScript 框架感到疲劳了因为我已经具有Backbone、Angular、React 等框架的经验,没有太多的热情去尝试一个新的框架。直到我在 Hacker News 上读到一份评论,其描述 Vue 是类似于“新 jQuery” 的 JavaScript 框架,从而激发了我的好奇心。在那之前,我已经相当满意 React 这个框架,它是一个很好的框架,建立于可靠的设计原则之上,围绕着视图模板、虚拟 DOM 和状态响应等技术。而 Vue 也提供了这些重要的内容。
在这篇文章中,我旨在解释为什么 Vue 适合我,为什么在上文中那些我尝试过的框架中选择它。也许你将同意我的一些观点,但至少我希望能够给大家使用 Vue 开发现代 JavaScript 应用一些灵感。
### 1、 极少的模板语法
Vue 默认提供的视图模板语法是极小的、简洁的和可扩展的。像其他 Vue 部分一样,可以很简单的使用类似 JSX 一样语法而不使用标准的模板语法甚至有官方文档说明了如何做但是我觉得没必要这么做。JSX 有好的方面,也有一些有依据的批评,如混淆了 JavaScript 和 HTML使得很容易导致在模板中出现复杂的代码而本来应该分开写在不同的地方的。
Vue 没有使用标准的 HTML 来编写视图模板,而是使用极少的模板语法来处理简单的事情,如基于视图数据迭代创建元素。
```
<template>
<div id="app">
<ul>
<li v-for='number in numbers' :key='number'>{{ number }}</li>
</ul>
<form @submit.prevent='addNumber'>
<input type='text' v-model='newNumber'>
<button type='submit'>Add another number</button>
</form>
</div>
</template>
<script>
export default {
name: 'app',
methods: {
addNumber() {
const num = +this.newNumber;
if (typeof num === 'number' && !isNaN(num)) {
this.numbers.push(num);
}
}
},
data() {
return {
newNumber: null,
numbers: [1, 23, 52, 46]
};
}
}
</script>
<style lang="scss">
ul {
padding: 0;
li {
list-style-type: none;
color: blue;
}
}
</style>
```
我也喜欢 Vue 提供的简短绑定语法,`:` 用于在模板中绑定数据变量,`@` 用于绑定事件。这是一个细节,但写起来很爽而且能够让你的组件代码简洁。
### 2、 单文件组件
大多数人使用 Vue都使用“单文件组件”。本质上就是一个 .vue 文件对应一个组件其中包含三部分CSS、HTML和JavaScript
这种技术结合是对的。它让人很容易在一个单独的地方了解每个组件,同时也非常好的鼓励了大家保持每个组件代码的简短。如果你的组件中 JavaScript、CSS 和 HTML 代码占了很多行,那么就到了进一步模块化的时刻了。
在使用 Vue 组件中的 `<style>` 标签时,我们可以添加 `scoped` 属性。这会让整个样式完全的封装到当前组件,意思是在组件中如果我们写了 `.name` 的 css 选择器,它不会把样式应用到其他组件中。我非常喜欢这种方式来应用样式而不是像其他主要框架流行在 JS 中编写 CSS 的方式。
关于单文件组件另一个好处是 .vue 文件实际上是一个有效的 HTML 5 文件。`<template>``<script>``<style>` 都是 w3c 官方规范的标签。这就表示很多如 linters LCTT 译注:一种代码检查工具插件)这样我们用于开发过程中的工具能够开箱即用或者添加一些适配后使用。
### 3、 Vue “新的 jQuery”
事实上,这两个库不相似而且用于做不同的事。让我提供给你一个很精辟的类比(我实际上非常喜欢描述 Vue 和 jQuery 之间的关系披头士乐队和齐柏林飞船乐队LCTT 译注:两个都是英国著名的乐队)。披头士乐队不需要介绍,他们是 20 世纪 60 年代最大的和最有影响力的乐队。但很难说披头士乐队是 20 世纪 70 年代最大的乐队,因为有时这个荣耀属于是齐柏林飞船乐队。你可以说两个乐队之间有着微妙的音乐联系或者说他们的音乐是明显不同的,但两者一些先前的艺术和影响力是不可否认的。也许 21 世纪初 JavaScript 的世界就像 20 世纪 70 年代的音乐世界一样,随着 Vue 获得更多关注使用,只会吸引更多粉丝。
一些使 jQuery 牛逼的哲学理念在 Vue 中也有呈现:非常容易的学习曲线但却具有基于现代 web 标准构建牛逼 web 应用所有你需要的功能。Vue 的核心本质上就是在 JavaScript 对象上包装了一层。
### 4、 极易扩展
正如前述Vue 默认使用标准的 HTML、JS 和 CSS 构建组件但可以很容易插入其他技术。如果我们想使用pugLCTT译注一款功能丰富的模板引擎专门为 Node.js 平台开发)替换 HTML 或者使用 TypescriptLCTT译注一种由微软开发的编程语言是 JavaScript 的一个超集)替换 js 或者 Sass LCTT 译注:一种 CSS 扩展语言)替换 CSS只需要安装相关的 node 模块和在我们的单文件组件中添加一个属性到相关的标签即可。你甚至可以在一个项目中混合搭配使用 —— 如一些组件使用 HTML 其他使用 pug ——然而我不太确定这么做是最好的做法。
### 5、 虚拟 DOM
虚拟 DOM 是很好的技术,被用于现如今很多框架。其意味着这些框架能够做到根据我们状态的改变来高效的完成 DOM 更新,减少重新渲染,从而优化我们应用的性能。现如今每个框架都有虚拟 DOM 技术,所以虽然它不是什么独特的东西,但它仍然很出色。
### 6、 Vuex 很棒
对于大多数应用管理状态成为一个棘手的问题单独使用一个视图库不能解决这个问题。Vue 使用 Vuex 库来解决这个问题。Vuex 很容易构建而且和 Vue 集成的很好。熟悉 redux另一个管理状态的库的人学习 Vuex 会觉得轻车熟路,但是我发现 Vue 和 Vuex 集成起来更加简洁。最新 JavaScript 草案中LCTT 译注:应该是指 ES7提供了对象展开运算符LCTT 译注:符号为 `...`),允许我们在状态或函数中进行合并,以操纵从 Vuex 到需要它的 Vue 组件中的状态。
### 7、 Vue 的命令行界面CLI
Vue 提供的命令行界面非常不错,很容易用 Vue 搭建一个基于 WebpackLCTT 译注:一个前端资源加载/打包工具的项目。单文件组件支持、babelLCTT 译注js 语法转换器、lintingLCTT译注代码检查工具、测试工具支持以及合理的项目结构都可以在终端中一行命令创建。
然而有一个命令,我在 CLI 中没有找到,那就是 `vue build`
> 如:
> ```
echo '<template><h1>Hello World!</h1></template>' > Hello.vue && vue build Hello.vue -o
```
`vue build` 命令构建和运行组件并在浏览器中测试看起来非常简单。很不幸这个命令后来在 Vue 中删除了,现在推荐使用 Poi。Poi 本质上是在 Webpack 工具上封装了一层,但我不认我它像推特上说的那样简单。
### 8、 重新渲染优化
使用 Vue你不必手动声明 DOM 的哪部分应该被重新渲染。我从来都不喜欢操纵 React 组件的渲染,像在`shouldComponentUpdate` 方法中停止整个 DOM 树重新渲染这种。Vue 在这方面非常巧妙。
### 9、 容易获得帮助
Vue 已经达到了使用这个框架来构建各种各样的应用的一种群聚效应。开发文档非常完善。如果你需要进一步的帮助有多种渠道可用每个渠道都有很多活跃开发者stackoverflow、discord、twitter 等。相对于其他用户量少的框架这就应该给你更多的信心来使用Vue构建应用。
### 10、 多机构维护
我认为,一个开源库,在发展方向方面的投票权利没有被单一机构操纵过多,是一个好事。就如同 React 的许可证问题现已解决Vue 就不可能涉及到。
总之,作为你接下来要开发的任何 JavaScript 项目,我认为 Vue 都是一个极好的选择。Vue 可用的生态圈比我博客中涉及到的其他库都要大。如果想要更全面的产品,你可以关注 Nuxt.js。如果你需要一些可重复使用的样式组件你可以关注类似 Vuetify 的库。
Vue 是 2017 年增长最快的库之一,我预测在 2018 年增长速度不会放缓。
如果你有空闲的 30 分钟,为什么不尝试下 Vue看它可以给你提供什么呢
P.S. — 这篇文档很好的展示了 Vue 和其他框架的比较:[https://vuejs.org/v2/guide/comparison.html][1]
--------------------------------------------------------------------------------
via: https://medium.com/@dalaidunc/10-things-i-love-about-vue-505886ddaff2
作者:[Duncan Grant][a]
译者:[yizhuoyan](https://github.com/yizhuoyan)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://medium.com/@dalaidunc
[1]:https://vuejs.org/v2/guide/comparison.html

View File

@@ -0,0 +1,955 @@
440+ 个免费的编程 & 计算机科学的在线课程
============================================================
![](https://cdn-images-1.medium.com/max/1250/1*c28Ze3oxasgGMGaV7-qoFw.png)
六年前,一些大学如 MIT 和斯坦福首次向公共免费开放了他们的在线课程。现在,全世界超过 800 所学校已经创建了成千上万的免费课程。
我编制了一个有 440 多个免费在线课程的清单,你可以从这个月开始去学习它了。为了这个清单,我使用了[<ruby>班级中心<rt>Class Central</rt></ruby>][450] 的数据库,它有超过 9000 门课程,我也包括了每个课程的平均评分。
![](https://cdn-images-1.medium.com/max/1250/1*qc6pW2c3mjTHVo45iCJaaQ.png)
*[班级中心][1] 的主页*
按它们不同的级别,我将这些课程分成以下三类:
* 初级
* 中级
* 高级
对于首次出现的课程,我标记为 [NEW]。
这些课程中的大多数都是可以自学的。其余的将在二月份的某个时间为你奉上。在班级中心的 2018 年 [计算机科学][451]、[数据科学][452]、和 [编程][453] 主题的页面上,你可以找到与这个技术相关的完整的清单。
我也知道,这个长长的清单,可能会让学习编程的新手望而却步。在这些课程中,你可以找到 [David Venturi][454] 推荐的非常有用的最佳 [数据科学在线课程][455]  —  即使你不想学习数据科学。以后,我想去创建更多的这种指南。
最后,如果你不知道如何去注册这些免费课程,没关系 —— 我也写了一篇 [如何去注册][456] 的文章。
### 初级112
* [Python 交互式编程入门(第 1 部分)][2] 来自 _Rice University_  ★★★★★(3018)
* [计算机科学入门和使用 Python 编程][3] 来自  _Massachusetts Institute of Technology_  ★★★★★(115)
* [学习编程:基本原理][4] 来自  _University of Toronto_ ★★★★★(100)
* [计算机科学入门][5] 来自  _University of Virginia_  ★★★★☆(68)
* [CS50 的计算机科学入门][6] 来自  _Harvard University_ ★★★★★(65)
* [Python 交互式编程入门(第 2 部分)][7] 来自  _Rice University_  ★★★★★(52)
* [如何使用 Git 和 GitHub][8]
* [Linux 入门][9] 来自  _Linux Foundation_  ★★★★☆(37)
* [因特网历史、技术、和安全][10] 来自  _University of Michigan_ ★★★★★(36)
* [HTML 和 CSS 入门][11]
* [VBA/Excel 编程入门][12] 来自  _Cal Poly Pomona_ ★★★★☆(26)
* [[New] CS50 的理解技术][13] 来自  _Harvard University_
* [[New] CS50 的为商务人士的计算机科学][14] 来自  _Harvard University_
* [[New] Java 编程导论:如何开始编程(西班牙语)][15] 来自  _Universidad Carlos iii de Madrid_
* [[New] 物联网 (IoT) 入门][16] 来自  _Curtin University_
* [[New] 使用 Git 管理版本][17] 来自  _Atlassian_
* [JavaScript 基础][18]
* [CS101: 计算机科学 101][19] 来自  _Stanford University_  ★★★★☆(15)
* [编程基础][20] 来自  _Indian Institute of Technology Bombay_ ★★☆☆☆(13)
* [Web 安全基本原理][21] 来自  _KU Leuven University_  ★★★★☆(12)
* [Python 编程基础][22]
* [网络:计算机网络入门][23] 来自  _Stanford University_  ★★★★★(11)
* [DB数据库入门][24] 来自  _Stanford University_  ★★★★★(11)
* [数字多媒体 & 移动应用创意编程][25] 来自  _University of London International Programmes_  ★★★★☆(10)
* [使用 JavaScript、HTML 和 CSS 基础][26] 来自  _Duke University_  ★★★★☆(9)
* [实用安全][27] 来自  _University of Maryland, College Park_  ★★★☆☆(9)
* [Bootstrap 入门 — 一个教程][28] 来自  _Microsoft_  ★★★☆☆(9)
* [HTML5 编码基础和最佳实践][29] 来自  _World Wide Web Consortium (W3C)_  ★★★★☆(9)
* [大家都来学 Python  —  浏览信息][30]
* [学习编程:编写高品质代码][31] 来自  _University of Toronto_ ★★★★☆(7)
* [使用 p5.js 入门视觉艺术编程][32] 来自  _University of California, Los Angeles_  ★★★★★(7)
* [关系型数据库入门][33]
* [jQuery 入门][34] 来自  _Microsoft_  ★★★★☆(5)
* [HTML5 和 CSS 基础][35] 来自  _World Wide Web Consortium (W3C)_ ★★★★☆(5)
* [Java 编程基础][36]
* [Linux 命令行基础][37]
* [Java 编程入门 — 第 1 部分][38] 来自  _The Hong Kong University of Science and Technology_  ★★★★☆(4)
* [Java 编程入门:用 Java 写代码][39] 来自  _Universidad Carlos iii de Madrid_  ★★★★☆(4)
* [计算机编程范例 — 抽象和并发][40]来自  _Université catholique de Louvain_  ★★★★☆(4)
* [计算机编程范例 — 基本原理][41] 来自  _Université catholique de Louvain_  ★★★★★(4)
* [在 Scratch 中编程][42] 来自  _Harvey Mudd College_  ★★★★★(4)
* [使用 JavaScript 的 Web 编程][43] 来自  _University of Pennsylvania_ ★★★★★(2)
* [计算的美与乐AP® CS 原理 第 1 部分][44] 来自  _University of California, Berkeley_  ★★★★★(2)
* [Python 计算入门][45] 来自  _Georgia Institute of Technology_  ★★★★★(2)
* [面向对象的编程][46] 来自  _Indian Institute of Technology Bombay_ ★★★★☆(2)
* [思维·创新·代码][47] 来自  _University of Adelaide_  ★★★★★(2)
* [智能手机中的计算技术][48] 来自  _Cornell University_  ★★★★★(2)
* [Android 基础:编写你的第一个 App][49] 来自  _Google_  ★★★★☆(2)
* [学习 Python 编程][50] 来自  _University of Texas Arlington_ ★★★★★(2)
* [HTML 和 JavaScript 入门][51] 来自  _Microsoft_  ★★★★★(2)
* [大众计算机科学:计算机科学和 Python 编程入门][52]来自  _Harvey Mudd College_  ★★★★★(2)
* [JavaScript 入门][53]
* [Android 新手入门][54]
* [网络:朋友、金钱和字节][55] 来自  _Princeton University_ ★★★☆☆(1)
* [如何编码:数据基础][56] 来自  _The University of British Columbia_ ★★★★★(1)
* [使用 Wordpress 开发和设计 Web][57] 来自  _California Institute of the Arts_  ★★★★☆(1)
* [Android App 新手开发指南][58] 来自  _Galileo University_ ★☆☆☆☆(1)
* [Android App 新手开发指南][59] 来自  _Galileo University_ ★☆☆☆☆(1)
* [艺术家的 Web 编码基础][60] 来自  _National University of Singapore_  ★★★★☆(1)
* [ReactJS 入门][61] 来自  _Microsoft_  ★★☆☆☆(1)
* [Node.js 入门][62] 来自  _Microsoft_  ★★★★★(1)
* [学习 Java 编程][63] 来自  _Microsoft_  ★★★★★(1)
* [计算:艺术、魔法与科学][64] 来自  _ETH Zurich_  ★★★★☆(1)
* [计算:艺术、魔法与科学 — 第 2 部分][102] 来自  _ETH Zurich_
* [Cyber 安全:居家安全、在线与生活][65] 来自  _Newcastle University_ ★★★☆☆(1)
* [软件工程师基础][66] 来自  _Technische Universität München (Technical University of Munich)_  ★★★★★(1)
* [我的计算机科学: 计算机科学新手指南][67] 来自  _Harvey Mudd College_ ★★★☆☆(1)
* [使用 Git 管理版本][68]
* [大众 Web 应用][69]
* [CS50s AP® 计算机科学原理][70] 来自  _Harvard University_
* [编程基础][71] 来自  _Duke University_
* [Cyber 安全入门][72] 来自  _University of Washington_
* [Python 数据表现][73] 来自  _Rice University_
* [Python 编程基础][74] 来自  _Rice University_
* [软件工程师:入门][75] 来自  _The University of British Columbia_
* [Web 开发入门][76] 来自  _University of California, Davis_
* [Java 编程入门 — 第 2 部分][77] 来自  _The Hong Kong University of Science and Technology_
* [Excel/VBA 解决创意问题,第 2 部分][79] 来自  _University of Colorado Boulder_
* [AP 计算机科学 AJava 编程的多态和高级数据结构][80] 来自  _Purdue University_
* [AP 计算机科学 AJava 编程的循环和数据结构][81]来自  _Purdue University_
* [AP 计算机科学 AJava 编程的类和对象][82] 来自  _Purdue University_
* [Android 开发的 Java 基础][83] 来自  _Galileo University_
* [很赚钱的 Android Apps 所使用的商业模式][84] 来自  _Galileo University_
* [很赚钱的 Android Apps 所使用的商业模式][85] 来自  _Galileo University_
* [Android 开发的 Java 基础][86] 来自  _Galileo University_
* [Java 编程入门:写出好代码][87] 来自  _Universidad Carlos iii de Madrid_
* [Cyber 安全基础:动手实践][88] 来自  _Universidad Carlos iii de Madrid_
* [业务深度学习][89] 来自  _Yonsei University_
* [TCP/IP 入门][90] 来自  _Yonsei University_
* [视频游戏设计和平衡][91] 来自  _Rochester Institute of Technology_
* [Web 易用性][92] 来自  _Google_
* [移动 Web 开发][93] 来自  _Google_
* [Python 编程入门][94] 来自  _University of Texas Arlington_
* [Python 入门:从零开始][95] 来自  _Microsoft_
* [Python基础][96] 来自  _Microsoft_
* [设计思想入门][97] 来自  _Microsoft_
* [逻辑和计算思维][98] 来自  _Microsoft_
* [像专家一样写代码][99] 来自  _Microsoft_
* [Java 中的面向对象编程][100] 来自  _Microsoft_
* [CSS 基础 来自  _Microsoft_
* [JavaScript 入门][103] 来自  _World Wide Web Consortium (W3C)_
* [Python 的面向对象编程:创建你自己的冒险游戏][104] 来自  _Raspberry Pi Foundation_
* [学习 Swift 编程语法][105]
* [JavaScript 和 DOM][106]
* [能源行业中的区块链][107] 来自  _InnoEnergy_
* [虚拟现实入门][108]
* [ES6改进后的 JavaScript][109]
* [Python 入门][110]
* [HTTP & Web 服务器][111]
* [GitHub & 合作][112]
* [Swift 新手指南][113]
### 中级259
* [机器学习][114] 来自  _Stanford University_  ★★★★★(325)
* [算法,第 1 部分][115] 来自  _Princeton University_  ★★★★★(58)
* [算法,第 II 部分][126] 来自  _Princeton University_  ★★★★★(21)
* [为音乐家和艺术家的机器学习][116] 来自  _Goldsmiths, University of London_  ★★★★★(57)
* [密码学 I][117] 来自  _Stanford University_  ★★★★★(49)
* [CS188.1x:人工智能][118] 来自  _University of California, Berkeley_ ★★★★★(30)
* [计算原理(第 1 部分)][119] 来自  _Rice University_  ★★★★★(29)
* [计算原理(第 2 部分)][132] 来自  _Rice University_  ★★★★☆(16)
* [[New] 算法设计和技术][120] 来自  _University of California, San Diego_
* [软件安全][121]来自  _University of Maryland, College Park_ ★★★★☆(25)
* [[New] 弹性计算入门][122] 来自  _Indian Institute of Technology, Kharagpur_
* [[New] 云计算][123] 来自  _Indian Institute of Technology, Kharagpur_
* [[New] 数据库管理系统][124] 来自  _Indian Institute of Technology, Kharagpur_
* [[New] Haskell 编程入门][125] 来自  _Chennai Mathematical Institute_
* [越来越容易的专业 Web 易访问性审计][127] 来自  _Chang School of Continuing Education_  ★★★★★(21)
* [在 Rails 上使用 Ruby 进行敏捷开发 — 基础篇][128] 来自  _University of California, Berkeley_  ★★★★★(19)
* [自动化理论][129] 来自  _Stanford University_  ★★★★☆(18)
* [机器学习入门][130] 来自  _Stanford University_  ★★★★☆(18)
* [Web 开发][131]
* [Android 开发新手指南][133] 来自  _Google_  ★★★★☆(16)
* [C 程序员学习 C++Part A][134] 来自  _University of California, Santa Cruz_ ★★★☆☆(16)
* [代码的本质][135] 来自  _Processing Foundation_  ★★★★★(16)
* [游戏开发的概念][136] 来自  _Swinburne University of Technology_ ★★★★☆(15)
* [算法的思想(第 1 部分)][137] 来自  _Rice University_  ★★★★☆(14)
* [算法的思想(第 2 部分)][147] 来自  _Rice University_  ★★★★☆(9)
* [计算机程序的设计][138] 来自  _Stanford University_  ★★★★☆(13)
* [Java 编程:用软件解决问题][139] 来自  _Duke University_ ★★★☆☆(13)
* [Web 响应设计][140] 来自  _University of London International Programmes_  ★★★★☆(12)
* [离散优化][141] 来自  _University of Melbourne_  ★★★★☆(12)
* [游戏开发入门][142] 来自  _Michigan State University_ ★★★★★(12)
* [函数式编程入门][143] 来自  _Delft University of Technology_  ★★★★☆(11)
* [开发 Android Apps][144] 来自  _Google_  ★★★☆☆(11)
* [面向对象的 JavaScript][145] 来自  _Hack Reactor_  ★★★★★(11)
* [编程语言][146] 来自  _University of Virginia_  ★★★☆☆(10)
* [编程语言Part B][205] 来自  _University of Washington_ ★★★★★(2)
* [编程语言Part C][225] 来自  _University of Washington_ ★★★★★(1)
* [Web 响应设计基础][148] 来自  _Google_  ★★★★★(9)
* [图像和视频处理:从火星到好莱坞而止于医院][149] 来自  _Duke University_  ★★★★☆(8)
* [密码学][150] 来自  _University of Maryland, College Park_  ★★★★☆(8)
* [学习数据(机器学习入门)][152] 来自  _California Institute of Technology_  ★★★★★(8)
* [Julia 科学编程][153] 来自  _University of Cape Town_  ★★★★★(8)
* [云计算应用程序,第 1 部分:云系统和基础设施][154]来自  _University of Illinois at Urbana-Champaign_  ★★★☆☆(7)
* [云计算概念:第 2 部分][172] 来自  _University of Illinois at Urbana-Champaign_  ★★★★★(5)
* [Swift 编程入门][155] 来自  _University of Toronto_ ★☆☆☆☆(7)
* [Software 测试][156] 来自  _University of Utah_  ★★★★☆(7)
* [使用 MongoDB 管理数据][157] 来自  _MongoDB University_  ★★★★☆(7)
* [AJAX 入门][158]
* [计算机架构][159] 来自  _Princeton University_  ★★★★☆(6)
* [物联网:我们如何用它?][160] 来自  _University of California, San Diego _ ★★☆☆☆(6)
* [Meteor.js 开发入门][161]来自  _University of London International Programmes_  ★★★★☆(6)
* [DevOps 入门][163] 来自  _Nutanix_  ★★★☆☆(6)
* [全栈基础][164]
* [算法入门][165]
* [Java 中的软件架构][166] 来自  _Massachusetts Institute of Technology_ ★★★★★(5)
* [在 Rails 上使用 Ruby 进行敏捷开发  —  高级篇][167] 来自  _University of California, Berkeley_  ★★★★★(5)
* [计算机图形][168] 来自  _University of California, Berkeley_  ★★★★☆(5)
* [软件开发过程][169] 来自  _Georgia Institute of Technology_ ★★★★☆(5)
* [计算机网络][170] 来自  _Georgia Institute of Technology_  ★★★★☆(5)
* [Java 编程:数组、列表、和数据结构][171] 来自  _Duke University_  ★★★★★(5)
* [HTML5 游戏开发][173] 来自  _Google_  ★★★☆☆(5)
* [C++ 入门][174] 来自  _Microsoft_  ★★★★☆(5)
* [软件调试][175] 来自  _Saarland University_  ★★★★★(5)
* [并行编程概念][176]
* [使用 Swift 开发 iOS App 入门][177]
* [物联网:配置你的 DragonBoard™ 开发平台][178]来自  _University of California, San Diego _ ★★★☆☆(4)
* [物联网 & 增强现实新技术][179] 来自  _Yonsei University_  ★★★☆☆(4)
* [Database 管理基础][180] 来自  _University of Colorado System_ ★★★★☆(4)
* [Web 网络性能优化][181] 来自  _Google_  ★★★★☆(4)
* [移动开发者的 UX 设计][182] 来自  _Google_  ★★★★★(4)
* [使用 Transact-SQL 查询数据][183] 来自  _Microsoft_  ★★★★☆(4)
* [计算机图形交互][184] 来自  _The University of Tokyo_  ★★☆☆☆(4)
* [jQuery 入门][185]
* [将 Python 用于研究][186] 来自  _Harvard University_  ★★★☆☆(3)
* [图解网络:无需微积分][187] 来自  _Princeton University_ ★★★★☆(3)
* [VLSI CAD 第 I 部分:逻辑][188] 来自  _University of Illinois at Urbana-Champaign_ ★★★★★(3)
* [物联网:通讯技术][189] 来自  _University of California, San Diego _ ★★★☆☆(3)
* [MATLAB 和 Octave 的新手指南][190] 来自  _École Polytechnique Fédérale de Lausanne_  ★★★☆☆(3)
* [无线通讯新技术][191] 来自  _Yonsei University_ ★★★★☆(3)
* [JavaScript Promises][192] 来自  _Google_  ★★★★★(3)
* [Android 基础:多屏 Apps][193] 来自  _Google_  ★★★★☆(3)
* [Android 基础:用户输入][194] 来自  _Google_  ★★★★☆(3)
* [DevOps开发者如何入门][195] 来自  _Microsoft_  ★★★★☆(3)
* [自主移动机器人][196] 来自  _ETH Zurich_  ★★★☆☆(3)
* [敏捷软件开发][197] 来自  _ETH Zurich_  ★★★★☆(3)
* [JavaScript 调试][198]
* [配置 Linux Web 服务器][199]
* [JavaScript 设计模式][200]
* [编译器][201] 来自  _Stanford University_  ★★★★☆(2)
* [LPL: 语言,验证和逻辑][202] 来自  _Stanford University_  ★★★★★(2)
* [移动应用程序体验 第 1 部分:从一个领域到一个应用程序创意][203]来自  _Massachusetts Institute of Technology_  ★★★★★(2)
* [移动应用程序体验 第 2 部分:移动应用设计][265] 来自  _Massachusetts Institute of Technology_
* [移动应用程序体验 第 3 部分:构建移动应用程序][267] 来自  _Massachusetts Institute of Technology_
* [机器学习:自主学习][204] 来自  _Brown University_ ★★★★★(2)
* [响应式 Web 网站教程和示例][206] 来自  _University of London International Programmes_  ★★★★★(2)
* [iOS App 开发基础][207] 来自  _University of Toronto_  ★★★★☆(2)
* [编程、数据结构和算法][208] 来自  _Indian Institute of Technology Madras_  ★★☆☆☆(2)
* [Android App 组件 — 服务、本地 IPC、以及内容提供者][209]来自  _Vanderbilt University_  ★★★☆☆(2)
* [Android App 组件Intents、Activities、和广播接收器][210]来自  _Vanderbilt University_  ★★★☆☆(2)
* [Android 移动应用程序开发入门][211] 来自  _The Hong Kong University of Science and Technology_  ★★★★☆(2)
* [因特网新兴技术][212] 来自  _Yonsei University_  ★★★☆☆(2)
* [面向对象的设计][213] 来自  _University of Alberta_  ★★★☆☆(2)
* [Android 基础:网络][214] 来自  _Google_  ★★★★☆(2)
* [浏览器底层优化][215] 来自  _Google_  ★★★★☆(2)
* [Google 云平台基础:核心基础设施][216] 来自  _Google_ ★★★★☆(2)
* [客户端-服务器通讯][217] 来自  _Google_  ★★★★★(2)
* [开发国际化软件,第 1 部分][218] 来自  _Microsoft_  ★★★★☆(2)
* [使用 Power BI 分析和可视化数据][219] 来自  _Microsoft_ ★★★★★(2)
* [Web 开发者之网络][220]
* [计算结构2计算机架构][221] 来自  _Massachusetts Institute of Technology_  ★★★★☆(1)
* [软件开发基础][222] 来自  _University of Pennsylvania_ ★★★☆☆(1)
* [软件架构与设计][223] 来自  _Georgia Institute of Technology_ ★★★★★(1)
* [数据库系统概念与设计][224] 来自  _Georgia Institute of Technology_ ★★★★☆(1)
* [如何编码:复杂数据][226] 来自  _The University of British Columbia_ ★★★★★(1)
* [产品设计冲刺][227] 来自  _University of Virginia_  ★★★☆☆(1)
* [Android 之 Java][228] 来自  _Vanderbilt University_  ★☆☆☆☆(1)
* [使用 NodeJS、Express 和 MongoDB 进行服务器侧开发][229] 来自  _The Hong Kong University of Science and Technology_  ★★★★★(1)
* [Cyber 安全经济][230] 来自  _Delft University of Technology_ ★★☆☆☆(1)
* [Web 应用程序开发:基本概念][231] 来自  _University of New Mexico_  ★★★★☆(1)
* [算法][232] 来自  _Indian Institute of Technology Bombay_  ★★★★★(1)
* [AndroidIntroducción a la Programación][233] 来自  _Universitat Politècnica de València_  ★★★★☆(1)
* [面向服务的架构][234] 来自  _University of Alberta_  ★★★★★(1)
* 设计模式][235] 来自  _University of Alberta_  ★☆☆☆☆(1)
* [Cybersecurity 和便捷性][236] 来自  _University System of Georgia_ ★☆☆☆☆(1)
* [Google 云平台基础之 AWS 安全专家篇][237] 来自  _Google Cloud_  ★★☆☆☆(1)
* [Android 基础:用户界面][238] 来自  _Google_  ★★☆☆☆(1)
* [使用 Kubernetes 的弹性微服务][239] 来自  _Google_  ★★★★☆(1)
* [用 Java 开发弹性应用程序][240] 来自  _Google_  ★★★★☆(1)
* [Android 性能][241] 来自  _Google_  ★★★★★(1)
* [Android 基础:点击按钮][242] 来自  _Google_  ★★★☆☆(1)
* [Android 和 Java 的 Gradle][243] 来自  _Google_  ★★★★★(1)
* [VR 软件开发][244] 来自  _Google_  ★★★★☆(1)
* [用 Python 开发弹性应用程序][245] 来自  _Google_  ★★★★☆(1)
* [Android 开发者的内容设计][246] 来自  _Google_  ★★★★★(1)
* [中级 C++][247] 来自  _Microsoft_  ★★★★☆(1)
* [C# 入门][248] 来自  _Microsoft_  ★★☆☆☆(1)
* [AngularJS高级框架技术][249] 来自  _Microsoft_ ★★★★☆(1)
* [机器学习原理][250] 来自  _Microsoft_  ★★★★★(1)
* [Javascript 异步编程][251] 来自  _Microsoft_ ★★★★★(1)
* [从第一原则构建现代化计算机Nand 到 Tetris 第 II 部分(以项目为中心的课程)][252] 来自  _Hebrew University of Jerusalem_ ★★★★★(1)
* [物联网开发者指南][253] 来自  _IBM_ ★★★★☆(1)
* [云基础设施技术入门][254] 来自  _Linux Foundation_ ★★★★☆(1)
* [使用 libGDX 开发 2D 游戏][255] 来自  _Amazon_  ★★★★★(1)
* [实时系统入门][256] 来自  _IEEE_  ★★★★☆(1)
* [算法设计与分析][257] 来自  _Chennai Mathematical Institute_ ★★★☆☆(1)
* [如何赢得编码比赛:冠军的秘密][258] 来自  _ITMO University_  ★★★☆☆(1)
* [HTML5 应用程序和游戏][259] 来自  _World Wide Web Consortium (W3C)_ ★★★☆☆(1)
* [面试技术][260] 来自  _Pramp_  ★★★★★(1)
* [Android 基础:数据存储][261]
* [计算机科学理论入门][262]
* [算法:设计与分析][263] 来自  _Stanford University_
* [最短路径回访、完整 NP 问题以及如何实现][264] 来自  _Stanford University_
* [Java 中的高级软件结构][266] 来自  _Massachusetts Institute of Technology_
* [算法设计与分析][268] 来自  _University of Pennsylvania_
* [数据结构与软件设计][269] 来自  _University of Pennsylvania_
* [R 中的 Neurohacking 入门][270] 来自  _Johns Hopkins University_
* [数据库系统概念与设计][271] 来自  _Georgia Institute of Technology_
* [软件分析与测试][272] 来自  _Georgia Institute of Technology_
* [在 C 中编写、运行和修复代码][273] 来自  _Duke University_
* [动画和 CGI 手势][274] 来自  _Columbia University_
* [Minecraft、编码和测试][275] 来自  _University of California, San Diego_
* [物联网:来自设备的传感和驱动][276] 来自  _University of California, San Diego_
* [虚拟现实如何工作][277] 来自  _University of California, San Diego_
* [创建虚拟现实应用程序][278] 来自  _University of California, San Diego_
* [构建一个Cybersecurity 工具箱][279] 来自  _University of Washington_
* [Cybersecurity: The CISOs View][280] 来自  _University of Washington_
* [构建你自己的 iOS App][281] 来自  _University of Toronto_
* [算法设计与分析][282] 来自  _Peking University_
* [面向对象技术高级课程][283]来自  _Peking University_
* [如何编码系统化程序设计Part 1][162] 来自  _The University of British Columbia_  ★★★★☆(6)
* [如何编码系统化程序设计Part 2][285] 来自  _The University of British Columbia_
* [如何编码系统化程序设计Part 3][284] 来自  _The University of British Columbia_
* [软件结构:数据抽象][286] 来自  _The University of British Columbia_
* [软件结构:面向对象的设计][287] 来自  _The University of British Columbia_
* [敏捷测试][288] 来自  _University of Virginia_
* [数据科学中的 SQL][289] 来自  _University of California, Davis_
* [LAFF正确编程][290] 来自  _The University of Texas at Austin_
* [使用 NativeScript 进行跨平台移动 App 开发][291] 来自  _The Hong Kong University of Science and Technology_
* [前后端 JavaScript 框架Angular][292] 来自  _The Hong Kong University of Science and Technology_
* [使用 Web 技术开发跨平台移动 AppIonic 和 Cordova][293] 来自  _The Hong Kong University of Science and Technology_
* [使用 App Inventor 开发 Android Apps][294] 来自  _The Hong Kong University of Science and Technology_
* [前后端 Web UI 框架和工具Bootstrap 4][295] 来自  _The Hong Kong University of Science and Technology_
* [全球软件发布引擎][296] 来自  _Delft University of Technology_
* [C++ 开发基础(俄语)][297] 来自  _Moscow Institute of Physics and Technology_
* [构建机器人和设备][298] 来自  _Moscow Institute of Physics and Technology_
* [数据结构实现][299] 来自  _Indian Institute of Technology Bombay_
* [数据结构基础][300] 来自  _Indian Institute of Technology Bombay_
* [专业 Android App 开发][301] 来自  _Galileo University_
* [专业 Android App 开发][302] 来自  _Galileo University_
* [软件架构师代码:构建数字世界][303] 来自  _Universidad Carlos iii de Madrid_
* [Java 编程入门:数据结构和算法基础][304] 来自  _Universidad Carlos iii de Madrid_
* [企业软件生命周期管理][305] 来自  _National Research Nuclear University MEPhI_
* [在软件开发中使用操作系统机制(俄语)][306] 来自  _National Research Nuclear University MEPhI_
* [需求获取:加工和利益相关者分析][307] 来自  _University of Colorado System_
* [Linux 服务器管理与安全性][308] 来自  _University of Colorado System_
* [特殊需求:目标和冲突分析][309] 来自  _University of Colorado System_
* [软件需求优先级:风险分析][310] 来自  _University of Colorado System_
* [国家安全与 Cybersecurity 的联系 — 它是恐怖主义者的公证人][311] 来自  _University of Colorado System_
* [SRS 文档:需求与图解][312] 来自  _University of Colorado System_
* [安全软件开发的需求收集][313] 来自  _University of Colorado System_
* [软件测试管理][314] 来自  _University System of Maryland_
* [企业云计算][315] 来自  _University System of Maryland_
* [云计算基础设施][316] 来自  _University System of Maryland_
* [软件验证形式][317] 来自  _University System of Maryland_
* [软件测试基础][318] 来自  _University System of Maryland_
* [云计算管理][319] 来自  _University System of Maryland_
* [数据结构入门][320] 来自  _University of Adelaide_
* [视频游戏设计者的 Gameplay 编程][321] 来自  _Rochester Institute of Technology_
* [团队工作与协作][322] 来自  _Rochester Institute of Technology_
* [嵌入式系统的 Web 连接与安全][323] 来自  _EIT Digital_
* [物联网设备的智能架构][324] 来自  _EIT Digital_
* [物联网智能架构入门][325] 来自  _EIT Digital_
* [Cybersecurity 和 X-Factor][326] 来自  _University System of Georgia_
* [循序渐进介绍 Web 应用程序][327] 来自  _Google_
* [高级 Android 应用程序开发][328] 来自  _Google_
* [Google 地图 APIs][329] 来自  _Google_
* [离线 Web 应用程序][330] 来自  _Google_
* [Android 的 Firebase 基础][331] 来自  _Google_
* [开发聪明的 Apps 和机器人][332] 来自  _Microsoft_
* [开发 SQL 数据库][333] 来自  _Microsoft_
* [使用 Node.js 构建功能原型][334] 来自  _Microsoft_
* [使用 JavaScript 构建交互原型][335] 来自  _Microsoft_
* [算法和数据结构][336] 来自  _Microsoft_
* [在 C# 中的算法和数据结构][337] 来自  _Microsoft_
* [创建系统化的 SQL 数据库对象][338] 来自  _Microsoft_
* [AngularJS框架基础][339] 来自  _Microsoft_
* [TypeScript 2 入门][340] 来自  _Microsoft_
* [高级 CSS 概念][341] 来自  _Microsoft_
* [实现 In-Memory SQL 数据库对象][342] 来自  _Microsoft_
* [优化基于 SQL 的应用程序][343] 来自  _Microsoft_
* [并发编程 (avec Java)][344] 来自  _Sorbonne Universités_
* [C 程序员学习 C++Part B][345] 来自  _University of California, Santa Cruz_
* [Kubernetes 入门][346] 来自  _Linux Foundation_
* [DevOps 入门:转变和改善运营][347] 来自  _Linux Foundation_
* [DevOps 入门:转变和改善运营][348] 来自  _Linux Foundation_
* [软件工程师的 UML 类示意图][349] 来自  _KU Leuven University_
* [Android 的移动适用性与设计][350] 来自  _Facebook_
* [IOS 的移动适用性与设计][351] 来自  _Facebook_
* [并发][352] 来自  _AdaCore University_
* [Red Hat 企业 Linux 基础][353] 来自  _Red Hat_
* [Containers 基础、Kubernetes、和 Red Hat OpenShift][354] 来自  _Red Hat_
* [程序员的 C++][355]
* [学习 Backbone.js][356]
* [如何在 Android 中创建][357]
* [如何制作一个 iOS App][358]
* [iOS 持久化与核心数据][359]
* [UIKit 基础][360]
* [使用 Swift 实现 iOS 网络][361]
* [设计 RESTful APIs][362]
* [VR 平台与应用程序][363]
* [为开发者的 Swift 语言][364]
* [Ruby 中的 MVC 模式][365]
* [使用 Heroku 部署应用程序][366]
* [使用 Sinatra 开发动态 Web 应用程序][367]
* [构建 iOS 界面][368]
* [VR 设计][369]
* [[New] Android 基础][370]
* [iOS 设计模式][371]
* [VR 场景与对象][372]
### 高级78
* [使用 TensorFlow 深度学习创新应用程序][373]
* [[New] 计算中的概率入门][374] 来自  _Indian Institute of Technology Madras_
* [[New] 信息安全IV][375] 来自  _Indian Institute of Technology Madras_
* [[New] 数学计算的 Matlab 编程][376] 来自  _Indian Institute of Technology Madras_
* [[New] 数字开关I][377] 来自  _Indian Institute of Technology Kanpur_
* [[New] 高级图形理论][378] 来自  _Indian Institute of Technology Kanpur_
* [[New] 计算机视觉中的深度学习][379] 来自  _Higher School of Economics_
* [[New] 自然语言处理][380] 来自  _Higher School of Economics_
* [[New] 实践强化学习][381] 来自  _Higher School of Economics_
* [[New] 实时操作系统][382] 来自  _Indian Institute of Technology, Kharagpur_
* [[New] 传统的和非传统的优化工具][383] 来自  _Indian Institute of Technology, Kharagpur_
* [[New] 软件定义无线与实际应用程序][384] 来自  _Indian Institute of Technology Roorkee_
* [[New] 图像处理中的稀疏表示:从理论到实践][385] 来自  _TechnionIsrael Institute of Technology_
* [人工智能入门][386] 来自  _Stanford University_ ★★★★☆(24)
* [机器学习之神经网络][387] 来自  _University of Toronto_ ★★★★☆(22)
* [机器学习之数据科学与分析][388] 来自  _Columbia University_ ★★★☆☆(15)
* [机器学习之交易][389] 来自  _Georgia Institute of Technology_ ★★★☆☆(13)
* [神经网络与深度学习][390] 来自  _deeplearning.ai_  ★★★★★(9)
* [人工智能(AI)][391] 来自  _Columbia University_  ★★★★☆(9)
* [计算神经科学][392] 来自  _University of Washington_  ★★★★☆(8)
* [计算机视觉入门][393] 来自  _Georgia Institute of Technology_ ★★★★★(6)
* [强化学习][394] 来自  _Brown University_  ★★☆☆☆(6)
* [并行编程入门][395] 来自  _Nvidia_  ★★★★☆(6)
* [互动 3D 图形][396] 来自  _Autodesk_  ★★★★☆(6)
* [机器学习][397] 来自  _Georgia Institute of Technology_  ★★★★★(5)
* [数据科学与分析的可用技术:物联网][398] 来自  _Columbia University_  ★☆☆☆☆(5)
* [应用密码学][399] 来自  _University of Virginia_  ★★★★☆(5)
* [开发者的深度学习实践:第 1 部分][400] 来自  _fast.ai_  ★★★★☆(5)
* [高级操作系统][401] 来自  _Georgia Institute of Technology_ ★★★★★(4)
* [机器学习][402] 来自  _Columbia University_  ★★★★★(4)
* [计算机架构入门][403] 来自  _Carnegie Mellon University_ ★★★★★(4)
* [概率图形模型 2推测][404] 来自  _Stanford University_ ★★★★☆(3)
* [Python 中应用机器学习][405] 来自  _University of Michigan_ ★★★★☆(3)
* [定量形式模型与最坏性能分析][406] 来自  _EIT Digital _ ★★★☆☆(3)
* [6.S191深度学习入门][407] 来自  _Massachusetts Institute of Technology_  ★★★★☆(2)
* [操作系统入门][408] 来自  _Georgia Institute of Technology_ ★★★★★(2)
* [近场合作过滤器][409] 来自  _University of Minnesota_ ★★☆☆☆(2)
* [6.S094汽车自动驾驶之深度学习][410] 来自  _Massachusetts Institute of Technology_  ★★★★☆(1)
* [高性能计算架构][411] 来自  _Georgia Institute of Technology_  ★★★★★(1)
* [可计算性、复杂性和算法][412] 来自  _Georgia Institute of Technology_  ★★★★(1)
* [计算摄影学][413] 来自  _Georgia Institute of Technology_ ★★★★☆(1)
* [信息安全入门][414] 来自  _Georgia Institute of Technology_ ★☆☆☆☆(1)
* [AI 知识库:认知系统][415] 来自  _Georgia Institute of Technology_  ★★★☆☆(1)
* [嵌入式硬件和操作系统][416] 来自  _EIT Digital _ ★☆☆☆☆(1)
* [学习 TensorFlow 与深度学习][417] 来自  _Google_ ★★★★☆(1)
* [DevOps 实践和原则][418] 来自  _Microsoft_  ★★☆☆☆(1)
* [信号与图像处理中的稀疏表示:基础][419]来自  _TechnionIsrael Institute of Technology_  ★★★★★(1)
* [云计算和云原生软件架构入门][420]来自  _Linux Foundation_  ★★★★★(1)
* [商业应用区块链Hyperledger 技术][421]来自  _Linux Foundation_  ★★★★☆(1)
* [计算结构 3计算机组织][422] 来自  _Massachusetts Institute of Technology_
* [GTRefresherAdvanced OS][423] 来自  _Georgia Institute of Technology_
* [高性能计算][424] 来自  _Georgia Institute of Technology_
* [编译器:理论与实践][425] 来自  _Georgia Institute of Technology_
* [Cyber-物理系统安全][426] 来自  _Georgia Institute of Technology_
* [网络安全][427] 来自  _Georgia Institute of Technology_
* [人工智能][428] 来自  _Georgia Institute of Technology_
* [信息安全:环境与入门][429] 来自  _University of London International Programmes_
* [离散优化之基本模型][431] 来自  _University of Melbourne_
* [离散优化之高级模型][430] 来自  _University of Melbourne_
* [代码的本质JavaScript 中的生物学][432] 来自  _École Polytechnique Fédérale de Lausanne_
* [模型因子与高级技术][433] 来自  _University of Minnesota_
* [系统验证:自动化与等价行为][434] 来自  _EIT Digital_
* [系统验证(2):建模过程行为][435] 来自  _EIT Digital_
* [系统验证(4):软件模型、协议和其它行为][436] 来自  _EIT Digital_
* [DevOps 测试][437] 来自  _Microsoft_
* [深度学习说明][438] 来自  _Microsoft_
* [人工智能入门][439] 来自  _Microsoft_
* [DevOps 之数据库][440] 来自  _Microsoft_
* [基础设施代码化][441] 来自  _Microsoft_
* [深度学习之自然语言处理][442] 来自  _University of Oxford_
* [机器学习之统计学][443] 来自  _Carnegie Mellon University_
* [信息物理系统:建模与仿真][444] 来自  _University of California, Santa Cruz_
* [OpenStack 入门][445] 来自  _Linux Foundation_
* [计算机系统设计:现代微处理器的高级概念][446]来自  _Chalmers University of Technology_
* [可靠的分布式算法,第 2 部分][447] 来自  _KTH Royal Institute of Technology_
* [深度学习暑期课程][448]
* [持续集成与部署][449]
--------------------------------------------------------------------------------
作者简介:
www.class-central.com — 最流行的在线课程搜索引擎的创始人
----
via: https://medium.freecodecamp.org/440-free-online-programming-computer-science-courses-you-can-start-in-february-e075f920cb5b
作者:[Dhawal Shah][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://medium.freecodecamp.org/@dhawalhs
[1]:https://www.class-central.com/
[2]:https://www.class-central.com/mooc/408/coursera-an-introduction-to-interactive-programming-in-python-part-1
[3]:https://www.class-central.com/mooc/1341/edx-introduction-to-computer-science-and-programming-using-python
[4]:https://www.class-central.com/mooc/385/coursera-learn-to-program-the-fundamentals
[5]:https://www.class-central.com/mooc/320/udacity-intro-to-computer-science
[6]:https://www.class-central.com/mooc/442/edx-cs50-s-introduction-to-computer-science
[7]:https://www.class-central.com/mooc/3196/coursera-an-introduction-to-interactive-programming-in-python-part-2
[8]:https://www.class-central.com/mooc/2661/udacity-how-to-use-git-and-github
[9]:https://www.class-central.com/mooc/1857/edx-introduction-to-linux
[10]:https://www.class-central.com/mooc/335/coursera-internet-history-technology-and-security
[11]:https://www.class-central.com/mooc/2659/udacity-intro-to-html-and-css
[12]:https://www.class-central.com/mooc/1797/open-education-by-blackboard-introduction-to-vba-excel-programming
[13]:https://www.class-central.com/mooc/10142/edx-cs50-s-understanding-technology
[14]:https://www.class-central.com/mooc/10143/edx-cs50-s-computer-science-for-business-professionals
[15]:https://www.class-central.com/mooc/10316/edx-introduccion-a-la-programacion-en-java-como-comenzar-a-programar
[16]:https://www.class-central.com/mooc/9750/edx-introduction-to-the-internet-of-things-iot
[17]:https://www.class-central.com/mooc/10166/coursera-version-control-with-git
[18]:https://www.class-central.com/mooc/2660/udacity-javascript-basics
[19]:https://www.class-central.com/mooc/2175/stanford-openedx-cs101-computer-science-101
[20]:https://www.class-central.com/mooc/1650/edx-programming-basics
[21]:https://www.class-central.com/mooc/8726/edx-web-security-fundamentals
[22]:https://www.class-central.com/mooc/2013/udacity-programming-foundations-with-python
[23]:https://www.class-central.com/mooc/1578/stanford-openedx-networking-introduction-to-computer-networking
[24]:https://www.class-central.com/mooc/1580/stanford-openedx-db-introduction-to-databases
[25]:https://www.class-central.com/mooc/529/coursera-creative-programming-for-digital-media-mobile-apps
[26]:https://www.class-central.com/mooc/4256/coursera-programming-foundations-with-javascript-html-and-css
[27]:https://www.class-central.com/mooc/1727/coursera-usable-security
[28]:https://www.class-central.com/mooc/3338/edx-introduction-to-bootstrap-a-tutorial
[29]:https://www.class-central.com/mooc/3444/edx-html5-coding-essentials-and-best-practices
[30]:https://www.class-central.com/mooc/7363/python-for-everybody-exploring-information
[31]:https://www.class-central.com/mooc/390/coursera-learn-to-program-crafting-quality-code
[32]:https://www.class-central.com/mooc/3770/kadenze-introduction-to-programming-for-the-visual-arts-with-p5-js
[33]:https://www.class-central.com/mooc/3253/udacity-intro-to-relational-databases
[34]:https://www.class-central.com/mooc/4062/edx-introduction-to-jquery
[35]:https://www.class-central.com/mooc/5764/edx-html5-and-css-fundamentals
[36]:https://www.class-central.com/mooc/6686/udacity-java-programming-basics
[37]:https://www.class-central.com/mooc/4049/udacity-linux-command-line-basics
[38]:https://www.class-central.com/mooc/1983/edx-introduction-to-java-programming-part-1
[39]:https://www.class-central.com/mooc/2813/edx-introduction-to-java-programming-starting-to-code-in-java
[40]:https://www.class-central.com/mooc/2630/edx-paradigms-of-computer-programming-abstraction-and-concurrency
[41]:https://www.class-central.com/mooc/2298/edx-paradigms-of-computer-programming-fundamentals
[42]:https://www.class-central.com/mooc/2954/edx-programming-in-scratch
[43]:https://www.class-central.com/mooc/8518/edx-programming-for-the-web-with-javascript
[44]:https://www.class-central.com/mooc/2525/edx-the-beauty-and-joy-of-computing-ap-cs-principles-part-1
[45]:https://www.class-central.com/mooc/7622/edx-introduction-to-computing-using-python
[46]:https://www.class-central.com/mooc/1651/edx-object-oriented-programming
[47]:https://www.class-central.com/mooc/3231/edx-think-create-code
[48]:https://www.class-central.com/mooc/2809/edx-the-computing-technology-inside-your-smartphone
[49]:https://www.class-central.com/mooc/7278/udacity-android-basics-make-your-first-app
[50]:https://www.class-central.com/mooc/3695/edx-learn-to-program-using-python
[51]:https://www.class-central.com/mooc/5923/edx-introduction-to-html-and-javascript
[52]:https://www.class-central.com/mooc/3483/edx-cs-for-all-introduction-to-computer-science-and-python-programming
[53]:https://www.class-central.com/mooc/8059/udacity-intro-to-javascript
[54]:https://www.class-central.com/mooc/7623/udacity-android-for-beginners
[55]:https://www.class-central.com/mooc/359/coursera-networks-friends-money-and-bytes
[56]:https://www.class-central.com/mooc/8202/edx-how-to-code-simple-data
[57]:https://www.class-central.com/mooc/6408/kadenze-web-development-and-design-using-wordpress
[58]:https://www.class-central.com/mooc/7315/edx-android-app-development-for-beginners
[59]:https://www.class-central.com/mooc/7315/edx-android-app-development-for-beginners
[60]:https://www.class-central.com/mooc/3781/kadenze-web-coding-fundamentals-for-artists
[61]:https://www.class-central.com/mooc/8770/edx-introduction-to-reactjs
[62]:https://www.class-central.com/mooc/9597/edx-introduction-to-node-js
[63]:https://www.class-central.com/mooc/8718/edx-learn-to-program-in-java
[64]:https://www.class-central.com/mooc/2195/edx-computing-art-magic-science
[65]:https://www.class-central.com/mooc/6265/futurelearn-cyber-security-safety-at-home-online-in-life
[66]:https://www.class-central.com/mooc/8527/edx-software-engineering-essentials
[67]:https://www.class-central.com/mooc/2957/edx-mycs-computer-science-for-beginners
[68]:https://www.class-central.com/mooc/8430/udacity-version-control-with-git
[69]:https://www.class-central.com/mooc/7362/web-applications-for-everybody
[70]:https://www.class-central.com/mooc/7017/edx-cs50-s-ap-computer-science-principles
[71]:https://www.class-central.com/mooc/9574/coursera-programming-fundamentals
[72]:https://www.class-central.com/mooc/8651/edx-introduction-to-cybersecurity
[73]:https://www.class-central.com/mooc/9550/coursera-python-data-representations
[74]:https://www.class-central.com/mooc/9549/coursera-python-programming-essentials
[75]:https://www.class-central.com/mooc/8205/edx-software-engineering-introduction
[76]:https://www.class-central.com/mooc/7027/coursera-introduction-to-web-development
[77]:https://www.class-central.com/mooc/3486/edx-introduction-to-java-programming-part-2
[78]:https://www.class-central.com/mooc/9943/coursera-excel-vba-for-creative-problem-solving-part-2
[79]:https://www.class-central.com/mooc/9943/coursera-excel-vba-for-creative-problem-solving-part-2
[80]:https://www.class-central.com/mooc/7219/edx-ap-computer-science-a-java-programming-polymorphism-and-advanced-data-structures
[81]:https://www.class-central.com/mooc/7212/edx-ap-computer-science-a-java-programming-loops-and-data-structures
[82]:https://www.class-central.com/mooc/7211/edx-ap-computer-science-a-java-programming-classes-and-objects
[83]:https://www.class-central.com/mooc/7313/edx-java-fundamentals-for-android-development
[84]:https://www.class-central.com/mooc/7345/edx-monetize-android-apps-with-business-models
[85]:https://www.class-central.com/mooc/7345/edx-monetize-android-apps-with-business-models
[86]:https://www.class-central.com/mooc/7313/edx-java-fundamentals-for-android-development
[87]:https://www.class-central.com/mooc/5735/edx-introduction-to-java-programming-writing-good-code
[88]:https://www.class-central.com/mooc/7849/edx-cyber-security-basics-a-hands-on-approach
[89]:https://www.class-central.com/mooc/9431/coursera-deep-learning-for-business
[90]:https://www.class-central.com/mooc/9143/coursera-introduction-to-tcp-ip
[91]:https://www.class-central.com/mooc/6660/edx-video-game-design-and-balance
[92]:https://www.class-central.com/mooc/6531/udacity-web-accessibility
[93]:https://www.class-central.com/mooc/1046/udacity-mobile-web-development
[94]:https://www.class-central.com/mooc/10134/edx-introduction-to-programming-using-python
[95]:https://www.class-central.com/mooc/8671/edx-introduction-to-python-absolute-beginner
[96]:https://www.class-central.com/mooc/8650/edx-introduction-to-python-fundamentals
[97]:https://www.class-central.com/mooc/8845/edx-introduction-to-design-thinking
[98]:https://www.class-central.com/mooc/8725/edx-logic-and-computational-thinking
[99]:https://www.class-central.com/mooc/8808/edx-writing-professional-code
[100]:https://www.class-central.com/mooc/8723/edx-object-oriented-programming-in-java
[101]:https://www.class-central.com/mooc/7199/edx-css-basics
[102]:https://www.class-central.com/mooc/4084/edx-computing-art-magic-science-part-ii
[103]:https://www.class-central.com/mooc/8496/edx-javascript-introduction
[104]:https://www.class-central.com/mooc/8884/futurelearn-object-oriented-programming-in-python-create-your-own-adventure-game
[105]:https://www.class-central.com/mooc/3925/udacity-learn-swift-programming-syntax
[106]:https://www.class-central.com/mooc/9990/udacity-javascript-and-the-dom
[107]:https://www.class-central.com/mooc/9526/futurelearn-blockchain-in-the-energy-sector
[108]:https://www.class-central.com/mooc/7379/udacity-introduction-to-virtual-reality
[109]:https://www.class-central.com/mooc/8543/udacity-es6-javascript-improved
[110]:https://www.class-central.com/mooc/8577/udacity-introduction-to-python
[111]:https://www.class-central.com/mooc/8374/udacity-http-web-servers
[112]:https://www.class-central.com/mooc/8542/udacity-github-collaboration
[113]:https://www.class-central.com/mooc/7494/udacity-swift-for-beginners
[114]:https://www.class-central.com/mooc/835/coursera-machine-learning
[115]:https://www.class-central.com/mooc/339/coursera-algorithms-part-i
[116]:https://www.class-central.com/mooc/3768/kadenze-machine-learning-for-musicians-and-artists
[117]:https://www.class-central.com/mooc/616/coursera-cryptography-i
[118]:https://www.class-central.com/mooc/445/edx-cs188-1x-artificial-intelligence
[119]:https://www.class-central.com/mooc/1724/coursera-principles-of-computing-part-1
[120]:https://www.class-central.com/mooc/10241/edx-algorithmic-design-and-techniques
[121]:https://www.class-central.com/mooc/1728/coursera-software-security
[122]:https://www.class-central.com/mooc/10053/nptel-introduction-to-soft-computing
[123]:https://www.class-central.com/mooc/10027/nptel-cloud-computing
[124]:https://www.class-central.com/mooc/9914/nptel-database-management-system
[125]:https://www.class-central.com/mooc/10044/nptel-introduction-to-haskell-programming
[126]:https://www.class-central.com/mooc/340/coursera-algorithms-part-ii
[127]:https://www.class-central.com/mooc/5174/canvas-network-professional-web-accessibility-auditing-made-easy
[128]:https://www.class-central.com/mooc/443/edx-agile-development-using-ruby-on-rails-the-basics
[129]:https://www.class-central.com/mooc/376/stanford-openedx-automata-theory
[130]:https://www.class-central.com/mooc/2996/udacity-intro-to-machine-learning
[131]:https://www.class-central.com/mooc/324/udacity-web-development
[132]:https://www.class-central.com/mooc/3198/coursera-principles-of-computing-part-2
[133]:https://www.class-central.com/mooc/3579/udacity-android-development-for-beginners
[134]:https://www.class-central.com/mooc/671/coursera-c-for-c-programmers-part-a
[135]:https://www.class-central.com/mooc/3777/kadenze-the-nature-of-code
[136]:https://www.class-central.com/mooc/1176/open2study-concepts-in-game-development
[137]:https://www.class-central.com/mooc/1725/coursera-algorithmic-thinking-part-1
[138]:https://www.class-central.com/mooc/323/udacity-design-of-computer-programs
[139]:https://www.class-central.com/mooc/4305/coursera-java-programming-solving-problems-with-software
[140]:https://www.class-central.com/mooc/4200/coursera-responsive-web-design
[141]:https://www.class-central.com/mooc/487/coursera-discrete-optimization
[142]:https://www.class-central.com/mooc/4275/coursera-introduction-to-game-development
[143]:https://www.class-central.com/mooc/2147/edx-introduction-to-functional-programming
[144]:https://www.class-central.com/mooc/2211/udacity-developing-android-apps
[145]:https://www.class-central.com/mooc/2658/udacity-object-oriented-javascript
[146]:https://www.class-central.com/mooc/325/udacity-programming-languages
[147]:https://www.class-central.com/mooc/3200/coursera-algorithmic-thinking-part-2
[148]:https://www.class-central.com/mooc/3255/udacity-responsive-web-design-fundamentals
[149]:https://www.class-central.com/mooc/462/coursera-image-and-video-processing-from-mars-to-hollywood-with-a-stop-at-the-hospital
[150]:https://www.class-central.com/mooc/1730/coursera-cryptography
[151]:https://www.class-central.com/mooc/1730/coursera-cryptography
[152]:https://www.class-central.com/mooc/366/learning-from-data-introductory-machine-learning-course
[153]:https://www.class-central.com/mooc/7092/coursera-julia-scientific-programming
[154]:https://www.class-central.com/mooc/2738/coursera-cloud-computing-applications-part-1-cloud-systems-and-infrastructure
[155]:https://www.class-central.com/mooc/4248/coursera-introduction-to-swift-programming
[156]:https://www.class-central.com/mooc/365/udacity-software-testing
[157]:https://www.class-central.com/mooc/1479/udacity-data-wrangling-with-mongodb
[158]:https://www.class-central.com/mooc/2997/udacity-intro-to-ajax
[159]:https://www.class-central.com/mooc/342/coursera-computer-architecture
[160]:https://www.class-central.com/mooc/4276/coursera-internet-of-things-how-did-we-get-here
[161]:https://www.class-central.com/mooc/4328/coursera-introduction-to-meteor-js-development
[162]:https://www.class-central.com/mooc/3465/edx-how-to-code-systematic-program-design-part-1
[163]:https://www.class-central.com/mooc/4013/udacity-intro-to-devops
[164]:https://www.class-central.com/mooc/3254/udacity-full-stack-foundations
[165]:https://www.class-central.com/mooc/364/udacity-intro-to-algorithms
[166]:https://www.class-central.com/mooc/6469/edx-software-construction-in-java
[167]:https://www.class-central.com/mooc/558/edx-agile-development-using-ruby-on-rails-advanced
[168]:https://www.class-central.com/mooc/548/edx-computer-graphics
[169]:https://www.class-central.com/mooc/2335/udacity-software-development-process
[170]:https://www.class-central.com/mooc/2336/udacity-computer-networking
[171]:https://www.class-central.com/mooc/4362/coursera-java-programming-arrays-lists-and-structured-data
[172]:https://www.class-central.com/mooc/2942/coursera-cloud-computing-concepts-part-2
[173]:https://www.class-central.com/mooc/551/udacity-html5-game-development
[174]:https://www.class-central.com/mooc/4758/edx-introduction-to-c
[175]:https://www.class-central.com/mooc/457/udacity-software-debugging
[176]:https://www.class-central.com/mooc/1701/openhpi-parallel-programming-concepts
[177]:https://www.class-central.com/mooc/2861/udacity-intro-to-ios-app-development-with-swift
[178]:https://www.class-central.com/mooc/4260/coursera-internet-of-things-setting-up-your-dragonboard-development-platform
[179]:https://www.class-central.com/mooc/3934/coursera-internet-of-things-augmented-reality-emerging-technologies
[180]:https://www.class-central.com/mooc/4337/coursera-database-management-essentials
[181]:https://www.class-central.com/mooc/2189/udacity-website-performance-optimization
[182]:https://www.class-central.com/mooc/2212/udacity-ux-design-for-mobile-developers
[183]:https://www.class-central.com/mooc/3341/edx-querying-data-with-transact-sql
[184]:https://www.class-central.com/mooc/2067/coursera-interactive-computer-graphics
[185]:https://www.class-central.com/mooc/2998/udacity-intro-to-jquery
[186]:https://www.class-central.com/mooc/7204/edx-using-python-for-research
[187]:https://www.class-central.com/mooc/891/coursera-networks-illustrated-principles-without-calculus
[188]:https://www.class-central.com/mooc/428/coursera-vlsi-cad-part-i-logic
[189]:https://www.class-central.com/mooc/4173/coursera-internet-of-things-communication-technologies
[190]:https://www.class-central.com/mooc/7376/edx-matlab-and-octave-for-beginners
[191]:https://www.class-central.com/mooc/3936/coursera-wireless-communication-emerging-technologies
[192]:https://www.class-central.com/mooc/5680/udacity-javascript-promises
[193]:https://www.class-central.com/mooc/6549/udacity-android-basics-multiscreen-apps
[194]:https://www.class-central.com/mooc/7343/udacity-android-basics-user-input
[195]:https://www.class-central.com/mooc/6333/edx-devops-for-developers-how-to-get-started
[196]:https://www.class-central.com/mooc/1564/edx-autonomous-mobile-robots
[197]:https://www.class-central.com/mooc/6878/edx-agile-software-development
[198]:https://www.class-central.com/mooc/3351/udacity-javascript-testing
[199]:https://www.class-central.com/mooc/4050/udacity-configuring-linux-web-servers
[200]:https://www.class-central.com/mooc/3082/udacity-javascript-design-patterns
[201]:https://www.class-central.com/mooc/2716/stanford-openedx-compilers
[202]:https://www.class-central.com/mooc/2340/stanford-openedx-lpl-language-proof-and-logic
[203]:https://www.class-central.com/mooc/1523/edx-mobile-application-experiences-part-1-from-a-domain-to-an-app-idea
[204]:https://www.class-central.com/mooc/1848/udacity-machine-learning-unsupervised-learning
[205]:https://www.class-central.com/mooc/6920/coursera-programming-languages-part-b
[206]:https://www.class-central.com/mooc/4356/coursera-responsive-website-tutorial-and-examples
[207]:https://www.class-central.com/mooc/4348/coursera-ios-app-development-basics
[208]:https://www.class-central.com/mooc/2778/nptel-programming-data-structures-and-algorithms
[209]:https://www.class-central.com/mooc/7763/coursera-android-app-components-services-local-ipc-and-content-providers
[210]:https://www.class-central.com/mooc/5500/coursera-android-app-components-intents-activities-and-broadcast-receivers
[211]:https://www.class-central.com/mooc/3758/edx-introduction-to-mobile-application-development-using-android
[212]:https://www.class-central.com/mooc/3933/coursera-internet-emerging-technologies
[213]:https://www.class-central.com/mooc/9216/coursera-object-oriented-design
[214]:https://www.class-central.com/mooc/6728/udacity-android-basics-networking
[215]:https://www.class-central.com/mooc/3524/udacity-browser-rendering-optimization
[216]:https://www.class-central.com/mooc/7784/coursera-google-cloud-platform-fundamentals-core-infrastructure
[217]:https://www.class-central.com/mooc/6527/udacity-client-server-communication
[218]:https://www.class-central.com/mooc/3996/edx-developing-international-software-part-1
[219]:https://www.class-central.com/mooc/5156/edx-analyzing-and-visualizing-data-with-power-bi
[220]:https://www.class-central.com/mooc/5965/udacity-networking-for-web-developers
[221]:https://www.class-central.com/mooc/4810/edx-computation-structures-2-computer-architecture
[222]:https://www.class-central.com/mooc/8516/edx-software-development-fundamentals
[223]:https://www.class-central.com/mooc/3418/udacity-software-architecture-design
[224]:https://www.class-central.com/mooc/8573/udacity-database-systems-concepts-design
[225]:https://www.class-central.com/mooc/7187/coursera-programming-languages-part-c
[226]:https://www.class-central.com/mooc/8199/edx-how-to-code-complex-data
[227]:https://www.class-central.com/mooc/5592/coursera-running-product-design-sprints
[228]:https://www.class-central.com/mooc/5446/coursera-java-for-android
[229]:https://www.class-central.com/mooc/8888/coursera-server-side-development-with-nodejs-express-and-mongodb
[230]:https://www.class-central.com/mooc/6991/edx-cyber-security-economics
[231]:https://www.class-central.com/mooc/5497/coursera-web-application-development-basic-concepts
[232]:https://www.class-central.com/mooc/5752/edx-algorithms
[233]:https://www.class-central.com/mooc/2964/edx-android-introduccion-a-la-programacion
[234]:https://www.class-central.com/mooc/9219/coursera-service-oriented-architecture
[235]:https://www.class-central.com/mooc/9215/coursera-design-patterns
[236]:https://www.class-central.com/mooc/6584/coursera-cybersecurity-and-mobility
[237]:https://www.class-central.com/mooc/8614/coursera-google-cloud-platform-fundamentals-for-aws-professionals
[238]:https://www.class-central.com/mooc/7342/udacity-android-basics-user-interface
[239]:https://www.class-central.com/mooc/6275/udacity-scalable-microservices-with-kubernetes
[240]:https://www.class-central.com/mooc/2215/udacity-developing-scalable-apps-in-java
[241]:https://www.class-central.com/mooc/3455/udacity-android-performance
[242]:https://www.class-central.com/mooc/7279/udacity-android-basics-button-clicks
[243]:https://www.class-central.com/mooc/3584/udacity-gradle-for-android-and-java
[244]:https://www.class-central.com/mooc/7463/udacity-vr-software-development
[245]:https://www.class-central.com/mooc/3525/udacity-developing-scalable-apps-in-python
[246]:https://www.class-central.com/mooc/3581/udacity-material-design-for-android-developers
[247]:https://www.class-central.com/mooc/7590/edx-intermediate-c
[248]:https://www.class-central.com/mooc/8823/edx-introduction-to-c
[249]:https://www.class-central.com/mooc/7384/edx-angularjs-advanced-framework-techniques
[250]:https://www.class-central.com/mooc/6511/edx-principles-of-machine-learning
[251]:https://www.class-central.com/mooc/8002/edx-asynchronous-programming-with-javascript
[252]:https://www.class-central.com/mooc/8025/coursera-build-a-modern-computer-from-first-principles-nand-to-tetris-part-ii-project-centered-course
[253]:https://www.class-central.com/mooc/6040/coursera-a-developer-s-guide-to-the-internet-of-things-iot
[254]:https://www.class-central.com/mooc/6000/edx-introduction-to-cloud-infrastructure-technologies
[255]:https://www.class-central.com/mooc/4856/udacity-2d-game-development-with-libgdx
[256]:https://www.class-central.com/mooc/4990/edx-introduction-to-real-time-systems
[257]:https://www.class-central.com/mooc/3984/nptel-design-and-analysis-of-algorithms
[258]:https://www.class-central.com/mooc/6300/edx-how-to-win-coding-competitions-secrets-of-champions
[259]:https://www.class-central.com/mooc/4671/edx-html5-apps-and-games
[260]:https://www.class-central.com/mooc/6143/udacity-technical-interview
[261]:https://www.class-central.com/mooc/6956/udacity-android-basics-data-storage
[262]:https://www.class-central.com/mooc/455/udacity-intro-to-theoretical-computer-science
[263]:https://www.class-central.com/mooc/8984/stanford-openedx-algorithms-design-and-analysis
[264]:https://www.class-central.com/mooc/7351/coursera-shortest-paths-revisited-np-complete-problems-and-what-to-do-about-them
[265]:https://www.class-central.com/mooc/5724/edx-mobile-application-experiences-part-2-mobile-app-design
[266]:https://www.class-central.com/mooc/6475/edx-advanced-software-construction-in-java
[267]:https://www.class-central.com/mooc/5633/edx-mobile-application-experiences-part-3-building-mobile-apps
[268]:https://www.class-central.com/mooc/8520/edx-algorithm-design-and-analysis
[269]:https://www.class-central.com/mooc/8517/edx-data-structures-and-software-design
[270]:https://www.class-central.com/mooc/6420/coursera-introduction-to-neurohacking-in-r
[271]:https://www.class-central.com/mooc/8994/edx-database-systems-concepts-and-design
[272]:https://www.class-central.com/mooc/8568/udacity-software-analysis-testing
[273]:https://www.class-central.com/mooc/9797/coursera-writing-running-and-fixing-code-in-c
[274]:https://www.class-central.com/mooc/7242/edx-animation-and-cgi-motion
[275]:https://www.class-central.com/mooc/7480/edx-minecraft-coding-and-teaching
[276]:https://www.class-central.com/mooc/4182/coursera-internet-of-things-sensing-and-actuation-from-devices
[277]:https://www.class-central.com/mooc/8514/edx-how-virtual-reality-vr-works
[278]:https://www.class-central.com/mooc/8515/edx-creating-virtual-reality-vr-apps
[279]:https://www.class-central.com/mooc/8653/edx-building-a-cybersecurity-toolkit
[280]:https://www.class-central.com/mooc/8652/edx-cybersecurity-the-ciso-s-view
[281]:https://www.class-central.com/mooc/6235/coursera-build-your-own-ios-app
[282]:https://www.class-central.com/mooc/3230/coursera--design-and-analysis-of-algorithms
[283]:https://www.class-central.com/mooc/1737/coursera--the-advanced-object-oriented-technology
[284]:https://www.class-central.com/mooc/3464/edx-how-to-code-systematic-program-design-part-3
[285]:https://www.class-central.com/mooc/3466/edx-how-to-code-systematic-program-design-part-2
[286]:https://www.class-central.com/mooc/8200/edx-software-construction-data-abstraction
[287]:https://www.class-central.com/mooc/8201/edx-software-construction-object-oriented-design
[288]:https://www.class-central.com/mooc/6523/coursera-testing-with-agile
[289]:https://www.class-central.com/mooc/9725/coursera-sql-for-data-science
[290]:https://www.class-central.com/mooc/7852/edx-laff-on-programming-for-correctness
[291]:https://www.class-central.com/mooc/8684/coursera-multiplatform-mobile-app-development-with-nativescript
[292]:https://www.class-central.com/mooc/8681/coursera-front-end-javascript-frameworks-angular
[293]:https://www.class-central.com/mooc/8683/coursera-multiplatform-mobile-app-development-with-web-technologies-ionic-and-cordova
[294]:https://www.class-central.com/mooc/8687/coursera-developing-android-apps-with-app-inventor
[295]:https://www.class-central.com/mooc/8682/coursera-front-end-web-ui-frameworks-and-tools-bootstrap-4
[296]:https://www.class-central.com/mooc/9119/edx-globally-distributed-software-engineering
[297]:https://www.class-central.com/mooc/10071/coursera----c--
[298]:https://www.class-central.com/mooc/7785/coursera-building-arduino-robots-and-devices
[299]:https://www.class-central.com/mooc/5753/edx-implementation-of-data-structures
[300]:https://www.class-central.com/mooc/5755/edx-foundations-of-data-structures
[301]:https://www.class-central.com/mooc/7346/edx-professional-android-app-development
[302]:https://www.class-central.com/mooc/7346/edx-professional-android-app-development
[303]:https://www.class-central.com/mooc/4812/edx-the-software-architect-code-building-the-digital-world
[304]:https://www.class-central.com/mooc/7454/edx-introduction-to-java-programming-fundamental-data-structures-and-algorithms
[305]:https://www.class-central.com/mooc/6304/edx-enterprise-software-lifecycle-management
[306]:https://www.class-central.com/mooc/10036/coursera--------
[307]:https://www.class-central.com/mooc/9811/coursera-requirements-elicitation-artifact-and-stakeholder-analysis
[308]:https://www.class-central.com/mooc/9319/coursera-linux-server-management-and-security
[309]:https://www.class-central.com/mooc/9807/coursera-requirements-specifications-goals-and-conflict-analysis
[310]:https://www.class-central.com/mooc/9810/coursera-software-requirements-prioritization-risk-analysis
[311]:https://www.class-central.com/mooc/8820/coursera-homeland-security-cybersecurity-connection-it-s-not-about-the-terrorists
[312]:https://www.class-central.com/mooc/9808/coursera-srs-documents-requirements-and-diagrammatic-notations
[313]:https://www.class-central.com/mooc/9809/coursera-requirements-gathering-for-secure-software-development
[314]:https://www.class-central.com/mooc/8171/edx-software-testing-management
[315]:https://www.class-central.com/mooc/8168/edx-cloud-computing-for-enterprises
[316]:https://www.class-central.com/mooc/8181/edx-cloud-computing-infrastructure
[317]:https://www.class-central.com/mooc/8180/edx-formal-software-verification
[318]:https://www.class-central.com/mooc/8179/edx-software-testing-fundamentals
[319]:https://www.class-central.com/mooc/8172/edx-cloud-computing-management
[320]:https://www.class-central.com/mooc/7391/edx-introduction-to-data-structures
[321]:https://www.class-central.com/mooc/6657/edx-gameplay-programming-for-video-game-designers
[322]:https://www.class-central.com/mooc/6658/edx-teamwork-collaboration
[323]:https://www.class-central.com/mooc/7415/coursera-web-connectivity-and-security-in-embedded-systems
[324]:https://www.class-central.com/mooc/6839/coursera-architecting-smart-iot-devices
[325]:https://www.class-central.com/mooc/6748/coursera-introduction-to-architecting-smart-iot-devices
[326]:https://www.class-central.com/mooc/6585/coursera-cybersecurity-and-the-x-factor
[327]:https://www.class-central.com/mooc/6548/udacity-intro-to-progressive-web-apps
[328]:https://www.class-central.com/mooc/3580/udacity-advanced-android-app-development
[329]:https://www.class-central.com/mooc/6477/udacity-google-maps-apis
[330]:https://www.class-central.com/mooc/5679/udacity-offline-web-applications
[331]:https://www.class-central.com/mooc/5055/udacity-firebase-essentials-for-android
[332]:https://www.class-central.com/mooc/6357/edx-developing-intelligent-apps-and-bots
[333]:https://www.class-central.com/mooc/7405/edx-developing-sql-databases
[334]:https://www.class-central.com/mooc/8722/edx-building-functional-prototypes-using-node-js
[335]:https://www.class-central.com/mooc/8719/edx-building-interactive-prototypes-using-javascript
[336]:https://www.class-central.com/mooc/8937/edx-algorithms-and-data-structures
[337]:https://www.class-central.com/mooc/9483/edx-algorithms-and-data-structures-in-c
[338]:https://www.class-central.com/mooc/7401/edx-creating-programmatic-sql-database-objects
[339]:https://www.class-central.com/mooc/7377/edx-angularjs-framework-fundamentals
[340]:https://www.class-central.com/mooc/8633/edx-introduction-to-typescript-2
[341]:https://www.class-central.com/mooc/7208/edx-advanced-css-concepts
[342]:https://www.class-central.com/mooc/7399/edx-implementing-in-memory-sql-database-objects
[343]:https://www.class-central.com/mooc/7398/edx-optimizing-performance-for-sql-based-applications
[344]:https://www.class-central.com/mooc/8369/edx-programmation-concurrente-avec-java
[345]:https://www.class-central.com/mooc/6931/coursera-c-for-c-programmers-part-b
[346]:https://www.class-central.com/mooc/8764/edx-introduction-to-kubernetes
[347]:https://www.class-central.com/mooc/7506/edx-introduction-to-devops-transforming-and-improving-operations
[348]:https://www.class-central.com/mooc/7506/edx-introduction-to-devops-transforming-and-improving-operations
[349]:https://www.class-central.com/mooc/7837/edx-uml-class-diagrams-for-software-engineering
[350]:https://www.class-central.com/mooc/9701/udacity-mobile-usability-and-design-for-android
[351]:https://www.class-central.com/mooc/9700/udacity-mobile-usability-and-design-for-ios
[352]:https://www.class-central.com/mooc/6493/concurrency
[353]:https://www.class-central.com/mooc/8670/edx-fundamentals-of-red-hat-enterprise-linux
[354]:https://www.class-central.com/mooc/9105/edx-fundamentals-of-containers-kubernetes-and-red-hat-openshift
[355]:https://www.class-central.com/mooc/8839/udacity-c-for-programmers
[356]:https://www.class-central.com/mooc/4071/udacity-learn-backbone-js
[357]:https://www.class-central.com/mooc/4419/udacity-how-to-create-anything-in-android
[358]:https://www.class-central.com/mooc/3527/udacity-how-to-make-an-ios-app
[359]:https://www.class-central.com/mooc/3526/udacity-ios-persistence-and-core-data
[360]:https://www.class-central.com/mooc/3350/udacity-uikit-fundamentals
[361]:https://www.class-central.com/mooc/3393/udacity-ios-networking-with-swift
[362]:https://www.class-central.com/mooc/4887/udacity-designing-restful-apis
[363]:https://www.class-central.com/mooc/8422/udacity-vr-platforms-applications
[364]:https://www.class-central.com/mooc/7495/udacity-swift-for-developers
[365]:https://www.class-central.com/mooc/6797/udacity-the-mvc-pattern-in-ruby
[366]:https://www.class-central.com/mooc/6798/udacity-deploying-applications-with-heroku
[367]:https://www.class-central.com/mooc/6796/udacity-dynamic-web-applications-with-sinatra
[368]:https://www.class-central.com/mooc/7753/udacity-building-ios-interfaces
[369]:https://www.class-central.com/mooc/8394/udacity-vr-design
[370]:https://www.class-central.com/mooc/7755/udacity-new-android-fundamentals
[371]:https://www.class-central.com/mooc/7754/udacity-ios-design-patterns
[372]:https://www.class-central.com/mooc/7380/udacity-vr-scenes-and-objects
[373]:https://www.class-central.com/mooc/6679/kadenze-creative-applications-of-deep-learning-with-tensorflow
[374]:https://www.class-central.com/mooc/10029/nptel-an-introduction-to-probability-in-computing
[375]:https://www.class-central.com/mooc/9913/nptel-information-security-iv
[376]:https://www.class-central.com/mooc/10094/nptel-matlab-programming-for-numerical-computation
[377]:https://www.class-central.com/mooc/10051/nptel-digital-switching-i
[378]:https://www.class-central.com/mooc/9817/nptel-advanced-graph-theory
[379]:https://www.class-central.com/mooc/9608/coursera-deep-learning-in-computer-vision
[380]:https://www.class-central.com/mooc/9603/coursera-natural-language-processing
[381]:https://www.class-central.com/mooc/9924/coursera-practical-reinforcement-learning
[382]:https://www.class-central.com/mooc/9848/nptel-real-time-operating-system
[383]:https://www.class-central.com/mooc/10066/nptel-traditional-and-non-traditional-optimization-tools
[384]:https://www.class-central.com/mooc/10088/nptel-basics-of-software-defined-radios-and-practical-applications
[385]:https://www.class-central.com/mooc/9135/edx-sparse-representations-in-image-processing-from-theory-to-practice
[386]:https://www.class-central.com/mooc/301/udacity-introduction-to-artificial-intelligence
[387]:https://www.class-central.com/mooc/398/coursera-neural-networks-for-machine-learning
[388]:https://www.class-central.com/mooc/4912/edx-machine-learning-for-data-science-and-analytics
[389]:https://www.class-central.com/mooc/1026/udacity-machine-learning-for-trading
[390]:https://www.class-central.com/mooc/9058/coursera-neural-networks-and-deep-learning
[391]:https://www.class-central.com/mooc/7230/edx-artificial-intelligence-ai
[392]:https://www.class-central.com/mooc/449/coursera-computational-neuroscience
[393]:https://www.class-central.com/mooc/1022/udacity-introduction-to-computer-vision
[394]:https://www.class-central.com/mooc/1849/udacity-reinforcement-learning
[395]:https://www.class-central.com/mooc/549/udacity-intro-to-parallel-programming
[396]:https://www.class-central.com/mooc/552/udacity-interactive-3d-graphics
[397]:https://www.class-central.com/mooc/1020/udacity-machine-learning
[398]:https://www.class-central.com/mooc/4911/edx-enabling-technologies-for-data-science-and-analytics-the-internet-of-things
[399]:https://www.class-central.com/mooc/326/udacity-applied-cryptography
[400]:https://www.class-central.com/mooc/7887/practical-deep-learning-for-coders-part-1
[401]:https://www.class-central.com/mooc/1016/udacity-advanced-operating-systems
[402]:https://www.class-central.com/mooc/7231/edx-machine-learning
[403]:https://www.class-central.com/mooc/642/introduction-to-computer-architecture
[404]:https://www.class-central.com/mooc/7292/coursera-probabilistic-graphical-models-2-inference
[405]:https://www.class-central.com/mooc/6673/coursera-applied-machine-learning-in-python
[406]:https://www.class-central.com/mooc/4864/coursera-quantitative-formal-modeling-and-worst-case-performance-analysis
[407]:https://www.class-central.com/mooc/8083/6-s191-introduction-to-deep-learning
[408]:https://www.class-central.com/mooc/3419/udacity-introduction-to-operating-systems
[409]:https://www.class-central.com/mooc/6927/coursera-nearest-neighbor-collaborative-filtering
[410]:https://www.class-central.com/mooc/8132/6-s094-deep-learning-for-self-driving-cars
[411]:https://www.class-central.com/mooc/1018/udacity-high-performance-computer-architecture
[412]:https://www.class-central.com/mooc/1024/udacity-computability-complexity-algorithms
[413]:https://www.class-central.com/mooc/1023/udacity-computational-photography
[414]:https://www.class-central.com/mooc/3420/udacity-intro-to-information-security
[415]:https://www.class-central.com/mooc/1025/udacity-knowledge-based-ai-cognitive-systems
[416]:https://www.class-central.com/mooc/6826/coursera-embedded-hardware-and-operating-systems
[417]:https://www.class-central.com/mooc/8480/learn-tensorflow-and-deep-learning-without-a-ph-d
[418]:https://www.class-central.com/mooc/9475/edx-devops-practices-and-principles
[419]:https://www.class-central.com/mooc/9133/edx-sparse-representations-in-signal-and-image-processing-fundamentals
[420]:https://www.class-central.com/mooc/8387/edx-introduction-to-cloud-foundry-and-cloud-native-software-architecture
[421]:https://www.class-central.com/mooc/9484/edx-blockchain-for-business-an-introduction-to-hyperledger-technologies
[422]:https://www.class-central.com/mooc/6245/edx-computation-structures-3-computer-organization
[423]:https://www.class-central.com/mooc/4734/udacity-gt-refresher-advanced-os
[424]:https://www.class-central.com/mooc/1028/udacity-high-performance-computing
[425]:https://www.class-central.com/mooc/8572/udacity-compilers-theory-and-practice
[426]:https://www.class-central.com/mooc/8569/udacity-cyber-physical-systems-security
[427]:https://www.class-central.com/mooc/8570/udacity-network-security
[428]:https://www.class-central.com/mooc/8565/udacity-artificial-intelligence
[429]:https://www.class-central.com/mooc/8123/coursera-information-security-context-and-introduction
[430]:https://www.class-central.com/mooc/7757/coursera-advanced-modeling-for-discrete-optimization
[431]:https://www.class-central.com/mooc/7759/coursera-basic-modeling-for-discrete-optimization
[432]:https://www.class-central.com/mooc/6881/edx-nature-in-code-biology-in-javascript
[433]:https://www.class-central.com/mooc/6933/coursera-matrix-factorization-and-advanced-techniques
[434]:https://www.class-central.com/mooc/6825/coursera-system-validation-automata-and-behavioural-equivalences
[435]:https://www.class-central.com/mooc/7420/coursera-system-validation-2-model-process-behaviour
[436]:https://www.class-central.com/mooc/7803/coursera-system-validation-4-modelling-software-protocols-and-other-behaviour
[437]:https://www.class-central.com/mooc/9479/edx-devops-testing
[438]:https://www.class-central.com/mooc/8746/edx-deep-learning-explained
[439]:https://www.class-central.com/mooc/9164/edx-introduction-to-artificial-intelligence-ai
[440]:https://www.class-central.com/mooc/9480/edx-devops-for-databases
[441]:https://www.class-central.com/mooc/9476/edx-infrastructure-as-code
[442]:https://www.class-central.com/mooc/8097/deep-learning-for-natural-language-processing
[443]:https://www.class-central.com/mooc/8509/statistical-machine-learning
[444]:https://www.class-central.com/mooc/9791/coursera-cyber-physical-systems-modeling-and-simulation
[445]:https://www.class-central.com/mooc/7202/edx-introduction-to-openstack
[446]:https://www.class-central.com/mooc/7046/edx-computer-system-design-advanced-concepts-of-modern-microprocessors
[447]:https://www.class-central.com/mooc/6603/edx-reliable-distributed-algorithms-part-2
[448]:https://www.class-central.com/mooc/8481/deep-learning-summer-school
[449]:https://www.class-central.com/mooc/8021/udacity-continuous-integration-and-deployment
[450]:https://www.class-central.com/
[451]:https://www.class-central.com/subject/cs
[452]:https://www.class-central.com/subject/data-science
[453]:https://www.class-central.com/subject/programming-and-software-development
[454]:https://medium.com/@davidventuri
[455]:https://medium.freecodecamp.com/the-best-data-science-courses-on-the-internet-ranked-by-your-reviews-6dc5b910ea40
[456]:https://medium.freecodecamp.org/how-to-sign-up-for-coursera-courses-for-free-98266efaa531

View File

@@ -0,0 +1,50 @@
Docker 容器中的老式 DOS BBS
======
不久前,我写了一篇[我的 Debian Docker 基本映像][1]。我决定进一步扩展这个概念:在 Docker 中运行 DOS 程序。
但首先,来看一张截图:
![][2]
事实证明这是可能的,但很难。我使用了所有三种主要的 DOS 模拟器dosbox、qemu 和 dosemu。我让它们都能在 Docker 容器中运行,但有很多有趣的问题需要解决。
都要做的事是在 DOS 环境下提供一个伪造的调制解调器。它需要作为 TCP 端口暴露在容器外部。有很多方法可以做到 —— 我使用的是 tcpser。dosbox 有一个 TCP 调制解调器接口,但事实证明,这样做太问题太多了。
挑战来自你希望能够一次接受多个传入 telnet或 TCP连接。DOS 不是一个多任务操作系统,所以当时有很多黑客式的方法。一种是有多台物理机,每个有一根传入电话线。或者它们可能会在 [DESQview][3]、OS/2 甚至 Windows 3.1 等多任务层下运行多个伪 DOS 实例。
(注意:我刚刚了解到 [DESQview/X][4],它将 DESQview 与 X11R5 集成在一起,并[取代了 Windows 3 驱动程序][5]来把 Windows 作为 X 应用程序运行。)
出于各种原因,我不想尝试在 Docker 中运行其中任何一个系统。这让我模拟了原来的多物理节点设置。从理论上讲,非常简单 —— 运行一组 DOS 实例,每个实例最多使用 1MB 的模拟 RAM这就行了。但是这里面临挑战。
在多物理节点设置中,你需要某种文件共享,因为你的节点需要访问共享的消息和文件存储。在老式的 DOS 时代,有很多笨重的方法可以做到这一点 —— [Netware][6]、[LAN manager][7],甚至一些 PC NFS 客户端。我没有访问 Netware。我尝试了 DOS 中的 Microsoft LM 客户端,与在 Docker 容器内运行的 Samba 服务器交互。这样可以使用,但 LM 客户端即使有各种高内存技巧还是占用了很多内存BBS 软件也无法运行。我无法在多个 dosbox 实例中挂载底层文件系统,因为 dosbox 缓存不兼容。
这就是为什么我使用 dosemu 的原因。除了有比 dosbox 更完整的模拟器之外,它还有一种共享主机文件系统的方式。
所以,所有这一切都在此:[jgoerzen/docker-bbs-renegade][8]。
我还为其他想做类似事情的人准备了构建块:[docker-dos-bbs][9] 和底层 [docker-dosemu][10]。
意外的收获是,我也试图了在 Joyent 的 Triton基于 Solaris 的 SmartOS下运行它。让我感到高兴的印象是几乎可以在这下面工作。是的在 Solaris 机器上的一个基于 Linux 的 DOS 模拟器的容器中运行 Renegade DOS BBS。
--------------------------------------------------------------------------------
via: http://changelog.complete.org/archives/9836-an-old-dos-bbs-in-a-docker-container
作者:[John Goerzen][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://changelog.complete.org/archives/author/jgoerzen
[1]:https://changelog.complete.org/archives/9794-fixing-the-problems-with-docker-images
[2]:https://raw.githubusercontent.com/jgoerzen/docker-bbs-renegade/master/renegade-login.png
[3]:https://en.wikipedia.org/wiki/DESQview
[4]:http://toastytech.com/guis/dvx.html
[5]:http://toastytech.com/guis/dvx3.html
[6]:https://en.wikipedia.org/wiki/NetWare
[7]:https://en.wikipedia.org/wiki/LAN_Manager
[8]:https://github.com/jgoerzen/docker-bbs-renegade
[9]:https://github.com/jgoerzen/docker-dos-bbs
[10]:https://github.com/jgoerzen/docker-dosemu

View File

@@ -0,0 +1,119 @@
如何在使用 Vim 时访问/查看 Python 帮助
======
我是一名新的 Vim 编辑器用户。我用它编写 Python 代码。有没有办法在 vim 中查看 Python 文档而无需访问互联网?假设我的光标在 Python 的 `print` 关键字下,然后按下 F1我想查看关键字 `print` 的帮助。如何在 vim 中显示 python `help()` ?如何在不离开 vim 的情况下调用 `pydoc3`/`pydoc` 寻求帮助?
`pydoc``pydoc3` 命令可以根据 Python 关键字、主题、函数、模块或包的名称显示文本文档,或在模块内或包中的模块对类或函数的引用。你可以从 Vim 中调用 `pydoc`。让我们看看如何在 Vim 编辑器中使用 `pydoc` 访问 Python 文档。
### 使用 pydoc 访问 python 帮助
语法是:
```
pydoc keyword
pydoc3 keyword
pydoc len
pydoc print
```
编辑你的 `~/.vimrc`
```
$ vim ~/.vimrc
```
`pydoc3` 添加以下配置python v3.x 文档)。在正常模式下创建 `H` 键的映射:
```
nnoremap <buffer> H :<C-u>execute "!pydoc3 " . expand("<cword>")<CR>
```
保存并关闭文件。打开 Vim 编辑器:
```
$ vim file.py
```
写一些代码:
```
#!/usr/bin/python3
x=5
y=10
z=x+y
print(z)
print("Hello world")
```
将光标置于 Python 关键字 `print` 的下方,然后按下 `Shift`,然后按 `H`。你将看到下面的输出:
[![Access Python Help Within Vim][1]][1]
*按 H 查看 Python 关键字 print 的帮助*
### 如何在使用 Vim 时查看 python 帮助
[jedi-vim][2] 是一个绑定自动补全库 Jed 的 Vim 插件。它可以做很多事情,包括当你按下 `Shift` 后跟 `K` (即按大写 `K` 就显示关键字的帮助。
#### 如何在 Linux 或类 Unix 系统上安装 jedi-vim
使用 [pathogen][3]、[vim-plug][4] 或 [Vundle][5] 安装 jedi-vim。我使用的是 vim-plug。在 `~/.vimrc` 中添加以下行:
```
Plug 'davidhalter/jedi-vim'
```
保存并关闭文件。启动 Vim 并输入:
```
PlugInstall
```
在 Arch Linux 上,你还可以使用 `pacman` 命令从官方仓库中的 vim-jedi 安装 jedi-vim
```
$ sudo pacman -S vim-jedi
```
它也可以在 Debian比如 8和 Ubuntu 比如 14.04)上使用 [apt-get command][6]/[apt-get command][7] 安装 vim-python-jedi
```
$ sudo apt install vim-python-jedi
```
在 Fedora Linux 上,它可以用 `dnf` 安装 vim-jedi
```
$ sudo dnf install vim-jedi
```
Jedi 默认是自动初始化的。所以你不需要进一步的配置。要查看 Documentation/Pydoc请按 `K`。它将弹出帮助窗口:
[![How to view python help when using vim][8]][8]
### 关于作者
作者是 nixCraft 的创建者,也是经验丰富的系统管理员和 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及 IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][9]、[Facebook][10]、[Google +][11] 上关注他。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/how-to-access-view-python-help-when-using-vim/
作者:[Vivek Gite][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz
[1]:https://www.cyberciti.biz/media/new/faq/2018/01/Access-Python-Help-Within-Vim.gif
[2]:https://github.com/davidhalter/jedi-vim
[3]:https://github.com/tpope/vim-pathogen
[4]:https://www.cyberciti.biz/programming/vim-plug-a-beautiful-and-minimalist-vim-plugin-manager-for-unix-and-linux-users/
[5]:https://github.com/gmarik/vundle
[6]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info)
[7]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
[8]:https://www.cyberciti.biz/media/new/faq/2018/01/How-to-view-Python-Documentation-using-pydoc-within-vim-on-Linux-Unix.jpg
[9]:https://twitter.com/nixcraft
[10]:https://facebook.com/nixcraft
[11]:https://plus.google.com/+CybercitiBiz

View File

@@ -0,0 +1,107 @@
我是如何创造“开源”这个词的
============================================================
> Christine Peterson 最终公开讲述了二十年前那决定命运的一天。
![How I coined the term 'open source'](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/hello-name-sticker-badge-tag.png?itok=fAgbMgBb "How I coined the term 'open source'")
图片来自: opensource.com
2 月 3 日是术语“<ruby>[开源软件][6]<rt>open source software</rt></ruby>”创立 20 周年的纪念日。由于开源软件渐受欢迎,并且为这个时代强有力的重要变革提供了动力,我们仔细反思了它的初生到崛起。
我是 “开源软件” 这个词的始作俑者,它是我在<ruby>前瞻协会<rt>Foresight Institute</rt></ruby>担任执行董事时提出的。我不像其它人是个软件开发者,所以感谢 Linux 程序员 Todd Anderson 对这个术语的支持并将它提交小组讨论。
这是我对于它如何想到的,如何提出的,以及后续影响的记叙。当然,还有一些有关该术语的其它记叙,例如 Eric Raymond 和 Richard Stallman 写的,而我的,则写于 2006 年 1 月 2 日。
但直到今天,我才公诸于世。
* * *
推行术语“开源软件”是特别为了让新手和商业人士更加理解这个领域,对它的推广被认为对于更广泛的用户社区很有必要。早期的称呼“<ruby>自由软件<rt>free software</rt></ruby>”不适用并非是因为含有政治意义,而是对于新手来说会误导关注于价格。所以需要一个关注于关键的源代码,而且不会让新用户混淆概念的术语。第一个在正确时间出现并且满足这些要求的术语被迅速接受了:<ruby>开源<rt>open source</rt></ruby>。
这个术语很长一段时间被用在“情报”(即间谍活动)活动中,但据我所知,确实在 1998 年以前软件领域从未使用过该术语。下面这个就是讲述了术语“开源软件”如何流行起来,并且变成了一项产业和一场运动名称的故事。
### 计算机安全会议
在 1997 年的晚些时候,<ruby>前瞻协会<rt>Foresight Institute</rt></ruby>开始举办周会讨论计算机安全问题。这个协会是一个非盈利性智库,它专注于纳米技术和人工智能,而二者的安全性及可靠性取决于软件安全。我们确定了自由软件是一个改进软件安全可靠性且具有发展前景的方法,并将寻找推动它的方式。 对自由软件的兴趣开始在编程社区外开始增长,而且越来越清晰,一个改变世界的机会正在来临。然而,该怎么做我们并不清楚,因为我们当时正在摸索中。
在这些会议中,由于“容易混淆”的因素,我们讨论了采用一个新术语的必要性。观点主要如下:对于那些新接触“自由软件”的人会把 “free” 当成了价格上的 “免费” 。老资格的成员们开始解释,通常像下面所说的:“我们指的是 freedom 中的自由,而不是‘免费啤酒’的免费。”在这一点上,关于软件方面的讨论就会变成了关于酒精饮料价格的讨论。问题不在于解释不了它的含义 —— 问题在于重要概念的术语不应该使新手们感到困惑。所以需要一个更清晰的术语。自由软件一词并没有政治上的问题;问题在于这个术语不能对新人清晰表明其概念。
### 开放的网景
1998 年 2 月 2 日Eric Raymond 访问网景公司,并与它一起计划采用自由软件风格的许可证发布其浏览器的源代码。我们那晚在前瞻协会位于<ruby>罗斯阿尔托斯<rt>Los Altos</rt></ruby>的办公室开会,商讨并完善了我们的计划。除了 Eric 和我,积极参与者还有 Brian Behlendorf、Michael Tiemann、Todd Anderson、Mark S. Miller 和 Ka-Ping Yee。但在那次会议上这一领域仍然被描述成“自由软件”或者用 Brian 的话说, 叫“可获得源代码的” 软件。
在这个镇上Eric 把前瞻协会作为行动的大本营。他访问行程期间,他接到了网景的法律和市场部门人员的电话。当他聊完后,我要求和他们(一男一女,可能是 Mitchell Baker通电话以便我告诉他们一个新的术语的必要性。他们原则上立即同意了但我们在具体术语上并未达成一致。
在那周的会议中,我始终专注于起一个更好的名字并提出了 “开源软件”一词。 虽然不太理想但我觉得足够好了。我找到至少四个人征求意见Eric Drexler、Mark Miller 以及 Todd Anderson 都喜欢它,而一个从事市场公关的朋友觉得术语 “open” 被滥用了,并且觉得我们能找到一个更好。理论上他是对的,可我想不出更好的了,所以我想试着先推广它。事后想起来,我应该直接向 Eric Raymond 提议,但在那时我并不是很了解他,所以我采取了间接的策略。
Todd 强烈同意需要一个新的术语,并提供协助推广它。这很有帮助,因为作为一个非编程人员,我在自由软件社区的影响力很弱。我从事的纳米技术教育是一个加分项,但不足以让我在自由软件问题上非常得到重视。而作为一个 Linux 程序员Todd 的话更容易被倾听。
### 关键性会议
那周稍晚时候1998 年的 2 月 5 日,一伙人在 VA Research 进行头脑风暴商量对策。与会者除了 Eric Raymond、Todd 和我之外,还有 Larry Augustin、Sam Ockman和 Jon Hall “maddog”通过电话参与。
会议的主要议题是推广策略,特别是要联系的公司。 我几乎没说什么,但是一直在寻找机会介绍提议的术语。我觉得我直接说“你们这些技术人员应当开始使用我的新术语了。”没有什么用。大多数与会者不认识我,而且据我所知,他们可能甚至不同意现在就迫切需要一个新术语。
幸运的是Todd 一直留心着。他没有主张社区应该用哪个特定的术语,而是面对社区这些固执的人间接地做了一些事。他仅仅是在其它话题中使用了那个术语 —— 把它放进对话里看看会发生什么。我很紧张,期待得到回应,但是起初什么也没有。讨论继续进行原来的话题。似乎只有他和我注意了这个术语的使用。
不仅如此——模因演化LCTT 译注人类学术语在起作用。几分钟后另一个人使用了这个术语显然没有注意到而在继续进行话题讨论。Todd 和我用眼角互觑了一下:是的,我们都注意到发生了什么。我很激动——它或许有用!但我保持了安静:我在小组中仍然地位不高。可能有些人都奇怪为什么 Eric 会邀请我。
临近会议尾声,可能是 Todd 或 Eric明确提出了[术语问题][8]。Maddog 提及了一个早期的术语“可自由分发的”和一个新的术语“合作开发的”。Eric 列出了“自由软件”、“开源软件”和“软件源”作为主要选项。Todd 提议使用“开源”,然后 Eric 支持了他。我没说太多,就让 Todd 和 Eric轻松、非正式地就“开源”这个名字达成了共识。显然对于大多数与会者改名并不是在这讨论的最重要议题那只是一个次要的相关议题。从我的会议记录中看只有大约 10% 的内容是术语的。
但是我很高兴。在那有许多社区的关键领导人,并且他们喜欢这新名字,或者至少没反对。这是一个好的信号。可能我帮不上什么忙; Eric Raymond 更适合宣传新的名称而且他也这么做了。Bruce Perens 立即表示支持,帮助建立了 [Opensource.org][9] 并在新术语的宣传中发挥了重要作用。
为了让这个名字获得认同Tim O'Reilly 同意在代表社区的多个项目中积极使用它,这是很必要,甚至是非常值得的。并且在官方即将发布的 Netscape Navigator网景浏览器代码中也使用了此术语。 到二月底, O'Reilly & Associates 还有网景公司Netscape 已经开始使用新术语。
### 名字的宣传
在那之后的一段时间,这条术语由 Eric Raymond 向媒体推广,由 Tim O'Reilly 向商业推广,并由二人向编程社区推广,它似乎传播的相当快。
1998 年 4 月 17 日Tim O'Reilly 召集了该领域的一些重要领袖的峰会,宣布为第一次 “[自由软件峰会][10]” ,在 4 月14 日之后,它又被称作首届 “[开源峰会][11]”。
这几个月对于开源来说是相当激动人心的。似乎每周都有一个新公司宣布加入计划。读 SlashdotLCTT 译注:科技资讯网站)已经成了一个必需操作,甚至对于那些像我一样只能外围地参与者亦是如此。我坚信新术语能对快速传播到商业很有帮助,能被公众广泛使用。
尽管在谷歌搜索一下表明“开源”比“自由软件”出现的更多,但后者仍然有大量的使用,在和偏爱它的人们沟通的时候我们应该包容。
### 快乐的感觉
当 Eric Raymond 写的有关术语更改的[早期声明][12]被发布在了<ruby>开源促进会<rt>Open Source Initiative</rt></ruby>的网站上时,我被列在 VA 头脑风暴会议的名单上,但并不是作为术语的创始人。这是我自己的失误,我没告诉 Eric 细节。我的想法就是让它过去吧,我呆在幕后就好,但是 Todd 不这样认为。他认为我总有一天会为被称作“开源软件”这个名词的创造者而高兴。他向 Eric 解释了这个情况Eric 及时更新了网站。
想出这个短语只是一个小贡献,但是我很感激那些把它归功于我的人。每次我听到它(现在经常听到了),它都给我些许的感动。
说服社区的巨大功劳要归功于 Eric Raymond 和 Tim O'Reilly是他们让这一切成为可能。感谢他们对我的归功并感谢 Todd Anderson 所做的一切。以上内容并非完整的开源一词的历史,让我对很多没有提及的关键人士表示歉意。那些寻求更完整讲述的人应该参考本文和网上其他地方的链接。
### 关于作者
[![photo of Christine Peterson](https://opensource.com/sites/default/files/styles/profile_pictures/public/pictures/cp2016_crop2_185.jpg?itok=vUkSjFig)][13]
Christine Peterson 撰写、举办讲座,并向媒体介绍未来强大的技术,特别是在纳米技术,人工智能和长寿方面。她是纳米科技公益组织前瞻协会的共同创始人和前任主席。前瞻协会向公众、技术团体和政策制定者提供未来强大的技术的教育以及告诉它是如何引导他们的长期影响。她服务于[机器智能][2]咨询委员会……[更多关于 Christine Peterson][3]
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/2/coining-term-open-source-software
作者:[Christine Peterson][a]
译者:[fuzheng1998](https://github.com/fuzheng1998)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/christine-peterson
[1]:https://opensource.com/article/18/2/coining-term-open-source-software?rate=HFz31Mwyy6f09l9uhm5T_OFJEmUuAwpI61FY-fSo3Gc
[2]:http://intelligence.org/
[3]:https://opensource.com/users/christine-peterson
[4]:https://opensource.com/users/christine-peterson
[5]:https://opensource.com/user/206091/feed
[6]:https://opensource.com/resources/what-open-source
[7]:https://opensource.org/osd
[8]:https://wiki2.org/en/Alternative_terms_for_free_software
[9]:https://opensource.org/
[10]:http://www.oreilly.com/pub/pr/636
[11]:http://www.oreilly.com/pub/pr/796
[12]:https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Alternative_terms_for_free_software.html
[13]:https://opensource.com/users/christine-peterson
[14]:https://opensource.com/users/christine-peterson
[15]:https://opensource.com/users/christine-peterson
[16]:https://opensource.com/article/18/2/coining-term-open-source-software#comments

View File

@@ -0,0 +1,62 @@
如何检查你的 Linux 系统是否存在 Meltdown 或者 Spectre 漏洞
======
![](https://www.maketecheasier.com/assets/uploads/2018/01/lmc-feat.jpg)
Meltdown 和 Specter 漏洞的最恐怖的现实之一是它们涉及非常广泛。几乎每台现代计算机都会受到一些影响。真正的问题是_你_是否受到了影响每个系统都处于不同的脆弱状态具体取决于已经或者还没有打补丁的软件。
由于 Meltdown 和 Spectre 都是相当新的漏洞,并且事情正在迅速发展,所以告诉你需要注意什么或在系统上修复了什么并非易事。有一些工具可以提供帮助。它们并不完美,但它们可以帮助你找出你需要知道的东西。
### 简单测试
顶级的 Linux 内核开发人员之一提供了一种简单的方式来检查系统在 Meltdown 和 Specter 漏洞方面的状态。它是简单的,也是最简洁的,但它不适用于每个系统。有些发行版不支持它。即使如此,也值得一试。
```
grep . /sys/devices/system/cpu/vulnerabilities/*
```
![Kernel Vulnerability Check][1]
你应该看到与上面截图类似的输出。很有可能你会发现系统中至少有一个漏洞还存在。这的确是真的,因为 Linux 在减轻 Specter v1 影响方面还没有取得任何进展。
### 脚本
如果上面的方法不适合你,或者你希望看到更详细的系统报告,一位开发人员已创建了一个 shell 脚本,它将检查你的系统来查看系统收到什么漏洞影响,还有做了什么来减轻 Meltdown 和 Spectre 的影响。
要得到脚本,请确保你的系统上安装了 Git然后将脚本仓库克隆到一个你不介意运行它的目录中。
```
cd ~/Downloads
git clone https://github.com/speed47/spectre-meltdown-checker.git
```
这不是一个大型仓库,所以它应该只需要几秒钟就克隆完成。完成后,输入新创建的目录并运行提供的脚本。
```
cd spectre-meltdown-checker
./spectre-meltdown-checker.sh
```
你会在终端看到很多输出。别担心它不是太难理解。首先脚本检查你的硬件然后运行三个漏洞检查Specter v1、Spectre v2 和 Meltdown。每个漏洞都有自己的部分。在这之间脚本明确地告诉你是否受到这三个漏洞的影响。
![Meltdown Spectre Check Script Ubuntu][2]
每个部分为你提供了潜在的可用的缓解方案,以及它们是否已被应用。这里需要你的一点常识。它给出的决定可能看起来有冲突。研究一下,看看它所说的修复是否实际上完全缓解了这个问题。
### 这意味着什么
所以,要点是什么?大多数 Linux 系统已经针对 Meltdown 进行了修补。如果你还没有更新,你应该更新一下。 Specter v1 仍然是一个大问题到目前为止还没有取得很大进展。Spectre v2 将取决于你的发行版以及它选择应用的补丁。无论哪种工具都说,没有什么是完美的。做好研究并留意直接来自内核和发行版开发者的信息。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/check-linux-meltdown-spectre-vulnerability/
作者:[Nick Congleton][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.maketecheasier.com/author/nickcongleton/
[1]:https://www.maketecheasier.com/assets/uploads/2018/01/lmc-kernel-check.jpg (Kernel Vulnerability Check)
[2]:https://www.maketecheasier.com/assets/uploads/2018/01/lmc-script.jpg (Meltdown Spectre Check Script Ubuntu)

View File

@@ -0,0 +1,102 @@
如何在 Linux 上运行你自己的公共时间服务器
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/eddington_a._space_time_and_gravitation._fig._9.jpg?itok=KgNqViyZ)
最重要的公共服务之一就是<ruby>报时<rt>timekeeping</rt></ruby>,但是很多人并没有意识到这一点。大多数公共时间服务器都是由志愿者管理,以满足不断增长的需求。这里学习一下如何运行你自己的时间服务器,为基础公共利益做贡献。(查看 [在 Linux 上使用 NTP 保持精确时间][1] 去学习如何设置一台局域网时间服务器)
### 著名的时间服务器滥用事件
就像现实生活中任何一件事情一样,即便是像时间服务器这样的公益项目,也会遭受不称职的或者恶意的滥用。
消费类网络设备的供应商因制造了大混乱而臭名昭著。我回想起的第一件事发生在 2003 年那时NetGear 在它们的路由器中硬编码了威斯康星大学的 NTP 时间服务器地址。使得时间服务器的查询请求突然增加,随着 NetGear 卖出越来越多的路由器,这种情况越发严重。更有意思的是,路由器的程序设置是每秒钟发送一次请求,这将使服务器难堪重负。后来 Netgear 发布了升级固件,但是,升级他们的设备的用户很少,并且他们的其中一些用户的设备,到今天为止,还在不停地每秒钟查询一次威斯康星大学的 NTP 服务器。Netgear 给威斯康星大学捐献了一些钱,以帮助弥补他们带来的成本增加,直到这些路由器全部淘汰。类似的事件还有 D-Link、Snapchat、TP-Link 等等。
对 NTP 协议进行反射和放大,已经成为发起 DDoS 攻击的一个选择。当攻击者使用一个伪造的目标受害者的源地址向时间服务器发送请求,称为反射攻击;攻击者发送请求到多个服务器,这些服务器将回复请求,这样就使伪造的源地址受到轰炸。放大攻击是指一个很小的请求收到大量的回复信息。例如,在 Linux 上,`ntpq` 命令是一个查询你的 NTP 服务器并验证它们的系统时间是否正确的很有用的工具。一些回复,比如,对端列表,是非常大的。组合使用反射和放大,攻击者可以将 10 倍甚至更多带宽的数据量发送到被攻击者。
那么,如何保护提供公益服务的公共 NTP 服务器呢?从使用 NTP 4.2.7p26 或者更新的版本开始,它们可以帮助你的 Linux 发行版不会发生前面所说的这种问题,因为它们都是在 2010 年以后发布的。这个发行版都默认禁用了最常见的滥用攻击。目前,[最新版本是 4.2.8p10][2],它发布于 2017 年。
你可以采用的另一个措施是,在你的网络上启用入站和出站过滤器。阻塞宣称来自你的网络的数据包进入你的网络,以及拦截发送到伪造返回地址的出站数据包。入站过滤器可以帮助你,而出站过滤器则帮助你和其他人。阅读 [BCP38.info][3] 了解更多信息。
### 层级为 0、1、2 的时间服务器
NTP 有超过 30 年的历史了它是至今还在使用的最老的因特网协议之一。它的用途是保持计算机与世界标准时间UTC的同步。NTP 网络是分层组织的,并且同层的设备是对等的。<ruby>层次<rt>Stratum</rt></ruby> 0 包含主报时设备,比如,原子钟。层级 1 的时间服务器与层级 0 的设备同步。层级 2 的设备与层级 1 的设备同步,层级 3 的设备与层级 2 的设备同步。NTP 协议支持 16 个层级,现实中并没有使用那么多的层级。同一个层级的服务器是相互对等的。
过去很长一段时间内,我们都为客户端选择配置单一的 NTP 服务器,而现在更好的做法是使用 [NTP 服务器地址池][4],它使用轮询的 DNS 信息去共享负载。池地址只是为客户端服务的,比如单一的 PC 和你的本地局域网 NTP 服务器。当你运行一台自己的公共服务器时,你不用使用这些池地址。
### 公共 NTP 服务器配置
运行一台公共 NTP 服务器只有两步:设置你的服务器,然后申请加入到 NTP 服务器池。运行一台公共的 NTP 服务器是一种很高尚的行为,但是你得先知道这意味着什么。加入 NTP 服务器池是一种长期责任,因为即使你加入服务器池后,运行了很短的时间马上退出,然后接下来的很多年你仍然会接收到请求。
你需要一个静态的公共 IP 地址,一个至少 512Kb/s 带宽的、可靠的、持久的因特网连接。NTP 使用的是 UDP 的 123 端口。它对机器本身要求并不高很多管理员在其它的面向公共的服务器比如Web 服务器)上顺带架设了 NTP 服务。
配置一台公共的 NTP 服务器与配置一台用于局域网的 NTP 服务器是一样的,只需要几个配置。我们从阅读 [协议规则][5] 开始。遵守规则并注意你的行为;几乎每个时间服务器的维护者都是像你这样的志愿者。然后,从 [StratumTwoTimeServers][6] 中选择 4 到 7 个层级 2 的上游服务器。选择的时候,选取地理位置上靠近(小于 300 英里的)你的因特网服务提供商的上游服务器,阅读他们的访问规则,然后,使用 `ping``mtr` 去找到延迟和跳数最小的服务器。
以下的 `/etc/ntp.conf` 配置示例文件,包括了 IPv4 和 IPv6以及基本的安全防护
```
# stratum 2 server list
server servername_1 iburst
server servername_2 iburst
server servername_3 iburst
server servername_4 iburst
server servername_5 iburst
# access restrictions
restrict -4 default kod noquery nomodify notrap nopeer limited
restrict -6 default kod noquery nomodify notrap nopeer limited
# Allow ntpq and ntpdc queries only from localhost
restrict 127.0.0.1
restrict ::1
```
启动你的 NTP 服务器,让它运行几分钟,然后测试它对远程服务器的查询:
```
$ ntpq -p
remote refid st t when poll reach delay offset jitter
=================================================================
+tock.no-such-ag 200.98.196.212 2 u 36 64 7 98.654 88.439 65.123
+PBX.cytranet.ne 45.33.84.208 3 u 37 64 7 72.419 113.535 129.313
*eterna.binary.n 199.102.46.70 2 u 39 64 7 92.933 98.475 56.778
+time.mclarkdev. 132.236.56.250 3 u 37 64 5 111.059 88.029 74.919
```
目前表现很好。现在从另一台 PC 上使用你的 NTP 服务器名字进行测试。以下的示例是一个正确的输出。如果有不正确的地方,你将看到一些错误信息。
```
$ ntpdate -q yourservername
server 66.96.99.10, stratum 2, offset 0.017690, delay 0.12794
server 98.191.213.2, stratum 1, offset 0.014798, delay 0.22887
server 173.49.198.27, stratum 2, offset 0.020665, delay 0.15012
server 129.6.15.28, stratum 1, offset -0.018846, delay 0.20966
26 Jan 11:13:54 ntpdate[17293]: adjust time server 98.191.213.2 offset 0.014798 sec
```
一旦你的服务器运行的很好,你就可以向 [manage.ntppool.org][7] 申请加入池中。
查看官方的手册 [分布式网络时间服务器NTP][8] 学习所有的命令、配置选项、以及高级特性,比如,管理、查询、和验证。访问以下的站点学习关于运行一台时间服务器所需要的一切东西。
通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”][9] 学习更多 Linux 的知识。
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2018/2/how-run-your-own-public-time-server-linux
作者:[CARLA SCHRODER][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/cschroder
[1]:https://linux.cn/article-9462-1.html
[2]:http://www.ntp.org/downloads.html
[3]:http://www.bcp38.info/index.php/Main_Page
[4]:http://www.pool.ntp.org/en/use.html
[5]:http://support.ntp.org/bin/view/Servers/RulesOfEngagement
[6]:http://support.ntp.org/bin/view/Servers/StratumTwoTimeServers?redirectedfrom=Servers.StratumTwo
[7]:https://manage.ntppool.org/manage
[8]:https://www.eecis.udel.edu/~mills/ntp/html/index.html
[9]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@@ -0,0 +1,190 @@
快捷教程:如何在命令行上编辑文件
======
此次教程中我们将向您展示三种命令行编辑文件的方式。本文一共覆盖了三种命令行编辑器vi或 vim、nano 和 emacs。
### 在命令行上使用 Vi 或 Vim 编辑文件
您可以使用 `vi` 编辑文件。运行如下命令,打开文件:
```
vi /path/to/file
```
现在,您可以看见文件中的内容了(如果文件存在。请注意,如果此文件不存在,该命令会创建文件)。
`vi` 最重要的命令莫过于此:
键入 `i` 进入<ruby>编辑<rt>Insert</rt></ruby>模式。如此,您可以编辑文本。
退出编辑模式请键入 `ESC`
正处于光标之下的字符,使用 `x` 键删除(您千万不要在编辑模式这样做,如果您这样做了,将不会删除光标下的字符,而是会在光标下插入 `x` 字符)。因此,当您仅仅使用 `vi` 打开文本LCTT 译注:此时默认进入指令模式),此时您可以使用 `x` 键立即删除字符。在编辑模式下,您需要键入 `ESC` 退出编辑模式。
如果您做了修改,想要保存文件,请键入 `:x`(同样,您不能在编辑模式执行此操作。请按 `ESC` 退出编辑模式,完成此操作)。
如果您并没有做修改,键入 `:q` 退出文本(您同样不能在编辑模式执行此操作)。
如果您做了修改,但却想不保存文本而之际退出,请键入 `:q!` (同样不能在编辑模式执行此作)。
请注意在上述所有操作中,您都可以使用方向键操控光标在文本中的位置。
以上所有都是 `vi` 编辑器的内容。请注意,`vim` 编辑器或多或少也会支持这些操作,如果您想深层次了解 `vim`,请看 [这里][1]。
### 使用 Nano 命令行编辑器编辑文件
接下来是 Nano 编辑器。您可以执行 `nano` 命令调用它:
```
nano
```
这里是 `nano` 的用户界面:
![Nano 命令行编辑器][3]
您同样可以使用它启动文件。
```
nano [filename]
```
例如:
```
nano test.txt
```
![在 nano 中打开文件][5]
如您所见的用户界面,大致被分成四个部分。编辑器顶部显示编辑器版本、正在编辑的文件和编辑状态。然后是实际编辑区域,在这里,您能看见文件的内容。编辑器下方高亮区展示着重要的信息,最后两行显示能执行基础任务地快捷键,切实地帮助初学者。
这里是您前期应当了解的快捷键快表。
使用方向键浏览文本,退格键删除文本,`Ctrl+O` 保存文件修改。当您尝试保存时,`nano` 会征询您的确认(请参阅截图中主编辑器下方区域):
![在 nano 中保存文件][7]
注意,在这个阶段,您有一个选项,可以保存不同的系统格式。键入 `Alt+D` 选择 DOS 格式,`Atl+M` 选择 Mac 格式。
![以 DOS 格式保存文件][9]
敲回车保存更改。
![文件已经被保存][11]
继续,文本剪切使用 `Ctrl+K`,文本复制使用 `Ctrl+U`。这些快捷键同样可以用来粘贴剪切单个单词,但您需要先选择好单词,通常,您可以通过键入 `Alt+A`(光标在第一个单词下) 然后使用方向键选择完整的单词。
现在来进行搜索操作。使用 `Ctrl+W` 可以执行一个简单的搜索,同时搜索和替换您可以使用 `Ctrl+\\`
![使用 nano 在文件中搜索][13]
这些就是 `nano` 的一些基础功,它能给您带来一些不错的开始,如果您是初次使用 `nano` 编辑器。更多内容,请阅读我们的完整内容,点击 [这里][14]。
### 使用 Emacs 命令行编辑器编辑文件
接下来登场的是 Emacs。如果系统未安装此软件您可以使用下面的命令在您的系统中安装它
```
sudo apt-get install emacs
```
`nano` 一致,您可以使用下面的方式在 `emacs` 中直接打开文件:
```
emacs -nw [filename]
```
注意:`-nw` 选项确保 `emacs` 在本窗口启动,而不是打开一个新窗口,默认情况下,它会打开一个新窗口。
一个实例:
```
emacs -nw test.txt
```
下面是编辑器的用户界面:
![在 emacs 中打开文件][16]
`nano` 一样,`emacs` 的界面同样被分割成了几个部分。第一部分是最上方的菜单区域,和您在图形界面下的应用程序一致。接下来是显示文本(您打开的文件文本)内容的主编辑区域。
编辑区域下方坐落着另一个高亮菜单条,显示了文件名,编辑模式(如截图内的 Text和状态`**` 为已修改,`-` 为未修改,`%%` 为只读)。最后是提供输入指令的区域,同时也能查看输出。
现在开始基础操作,当您做了修改、想要保存时,在 `Ctrl+x` 之后键入 `Ctrl+s`。最后在面板最后一行会向您显示一些信息Wrote ........’。这里有一个例子:
![emascs 中保存文件][18]
现在,如果您放弃修改并且退出时,在 `Ctrl+x` 之后键入`Ctrl+c`。编辑器将会立即询问,如下图:
![emacs 中抛弃修改][20]
输入 `n` 之后键入 `yes`,之后编辑器将会不保存而直接退出。
请注意Emacs 中 `C` 代表 `Ctrl``M` 代表 `Alt`。比如,当你看见 `C-x`,这意味着按下 `Ctrl+x`
至于其他基本编辑器操作,以删除为例,大多数人都会,使用 `Backspace`/`Delete` 键。然而,这里的一些删除快捷键能够提高用户体验。比如,使用 `Ctrl+k` 删除一整行,`Alt+d` 删除一个单词,`Alt+k` 删除一个整句。
在键入 `Ctrl+k` 之后键入 `u` 将撤销操作,输入 `Ctrl+g` 之后输入 `Ctrl+_` 恢复撤销的操作。使用 `Ctrl+s` 向前搜索,`Ctrl+r` 反向搜索。
![使用 emacs 在文件中搜索][22]
继续,使用 `Alt+Shift+%` 执行替换操作。您将被询问要替换单词。回复并回车。之后编辑器将会询问您是否替换。例如,下方截图展示了 `emacs` 询问使用者关于单词 This 的替换操作。
![使用 emacs 替换单词][24]
输入替换文本并回车。每一个替换操作 `emacs` 都会等待询问,下面是首次询问:
![确定文本替换][26]
键入 `y` 之后,单词将会被替换。
![键入 y 确定操作][28]
这些就是几乎所有的基础操作,您在开始使用 `emacs` 时需要了解掌握的。对了,我们忘记讨论如何访问顶部菜单,其实这些可以通过使用 `F10` 访问它们。
![基础编辑器操作][30]
`Esc` 键三次,退出这些菜单。
--------------------------------------------------------------------------------
via: https://www.howtoforge.com/faq/how-to-edit-files-on-the-command-line
作者:[Falko Timme, Himanshu Arora][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.howtoforge.com
[1]:https://www.howtoforge.com/vim-basics
[2]:https://www.howtoforge.com/images/command-tutorial/nano-basic-ui.png
[3]:https://www.howtoforge.com/images/command-tutorial/big/nano-basic-ui.png
[4]:https://www.howtoforge.com/images/command-tutorial/nano-file-open.png
[5]:https://www.howtoforge.com/images/command-tutorial/big/nano-file-open.png
[6]:https://www.howtoforge.com/images/command-tutorial/nano-save-changes.png
[7]:https://www.howtoforge.com/images/command-tutorial/big/nano-save-changes.png
[8]:https://www.howtoforge.com/images/command-tutorial/nano-mac-format.png
[9]:https://www.howtoforge.com/images/command-tutorial/big/nano-mac-format.png
[10]:https://www.howtoforge.com/images/command-tutorial/nano-changes-saved.png
[11]:https://www.howtoforge.com/images/command-tutorial/big/nano-changes-saved.png
[12]:https://www.howtoforge.com/images/command-tutorial/nano-search-replace.png
[13]:https://www.howtoforge.com/images/command-tutorial/big/nano-search-replace.png
[14]:https://www.howtoforge.com/linux-nano-command/
[15]:https://www.howtoforge.com/images/command-tutorial/nano-file-open1.png
[16]:https://www.howtoforge.com/images/command-tutorial/big/nano-file-open1.png
[17]:https://www.howtoforge.com/images/command-tutorial/emacs-save.png
[18]:https://www.howtoforge.com/images/command-tutorial/big/emacs-save.png
[19]:https://www.howtoforge.com/images/command-tutorial/emacs-quit-without-saving.png
[20]:https://www.howtoforge.com/images/command-tutorial/big/emacs-quit-without-saving.png
[21]:https://www.howtoforge.com/images/command-tutorial/emacs-search.png
[22]:https://www.howtoforge.com/images/command-tutorial/big/emacs-search.png
[23]:https://www.howtoforge.com/images/command-tutorial/emacs-search-replace.png
[24]:https://www.howtoforge.com/images/command-tutorial/big/emacs-search-replace.png
[25]:https://www.howtoforge.com/images/command-tutorial/emacs-replace-prompt.png
[26]:https://www.howtoforge.com/images/command-tutorial/big/emacs-replace-prompt.png
[27]:https://www.howtoforge.com/images/command-tutorial/emacs-replaced.png
[28]:https://www.howtoforge.com/images/command-tutorial/big/emacs-replaced.png
[29]:https://www.howtoforge.com/images/command-tutorial/emacs-accessing-menus.png
[30]:https://www.howtoforge.com/images/command-tutorial/big/emacs-accessing-menus.png

View File

@@ -0,0 +1,127 @@
如何使用 Seahorse 管理 PGP 和 SSH 密钥
============================================================
![Seahorse](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fish-1907607_1920.jpg?itok=u07bav4m "Seahorse")
> 学习使用 Seahorse GUI 工具去管理 PGP 和 SSH 密钥。
安全即内心的平静。毕竟,安全是许多用户迁移到 Linux 的最大理由。但是为什么要止步于仅仅采用该平台,你还可以采用多种方法和技术去确保你的桌面或者服务器系统的安全。
其中一项技术涉及到密钥 —— 用在 PGP 和 SSH 中。PGP 密钥允许你去加密和解密电子邮件和文件,而 SSH 密钥允许你使用一个额外的安全层去登入服务器。
当然你可以通过命令行接口CLI来管理这些密钥但是如果你使用一个华丽的 GUI 桌面环境呢?经验丰富的 Linux 用户可能对于脱离命令行来工作感到很不适应,但是,并不是所有用户都具备与他们相同的技术和水平,因此,使用 GUI 吧!
在本文中,我将带你探索如何使用  [Seahorse][14] GUI 工具来管理 PGP 和 SSH 密钥。Seahorse 有非常强大的功能,它可以:
* 加密/解密/签名文件和文本。
* 管理你的密钥和密钥对。
* 同步你的密钥和密钥对到远程密钥服务器。
* 签名和发布密钥。
* 缓存你的密码。
* 备份密钥和密钥对。
* 在任何一个 GDK 支持的格式中添加一个图像作为一个 OpenPGP photo ID。
* 创建、配置、和缓存 SSH 密钥。
对于那些不了解 Seahorse 的人来说,它是一个管理 GNOME 钥匙环中的加密密钥和密码的 GNOME 应用程序。不用担心Seahorse 可以安装在许多的桌面环境上。并且由于 Seahorse 可以在标准的仓库中找到你可以打开你的桌面应用商店比如Ubuntu Software 或者 Elementary OS AppCenter去安装它。你可以在你的发行版的应用商店中点击去安装它。安装完成后你就可以去使用这个很方便的工具了。
我们开始去使用它吧。
### PGP 密钥
我们需要做的第一件事情就是生成一个新的 PGP 密钥。正如前面所述PGP 密钥可以用于加密电子邮件(通过一些工具,像  [Thunderbird][15] 的 [Enigmail][16] 或者使用 [Evolution][17] 内置的加密功能。PGP 密钥也可以用于加密文件。任何人都可以使用你的公钥加密电子邮件和文件发给你LCTT 译注:原文此处“加密”误作“解密”)。没有 PGP 密钥是做不到的。
使用 Seahorse 创建一个新的 PGP 密钥对是非常简单的。以下是操作步骤:
1. 打开 Seahorse 应用程序
2. 在主面板的左上角点击 “+” 按钮
3. 选择 “<ruby>PGP 密钥<rt>PGP Key</rt></ruby>”(如图 1
4. 点击 “<ruby>继续<rt>Continue</rt></ruby>”
5. 当提示时,输入完整的名字和电子邮件地址
6. 点击 “<ruby>创建<rt>Create</rt></ruby>”
![Seahorse](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_1.jpg?itok=khLOYC61 "Seahorse")
*图 1使用 Seahorse 创建一个 PGP 密钥。*
在创建你的 PGP 密钥期间,你可以点击 “<ruby>高级密钥选项<rt>Advanced key options</rt></ruby>” 展开选项部分,在那里你可以为密钥添加注释信息、加密类型、密钥长度、以及过期时间(如图 2
![PGP](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_2.jpg?itok=eWiazwrn "PGP")
*图 2PGP 密钥高级选项*
增加注释部分可以很方便帮你记住密钥的用途(或者其它的信息)。
要使用你创建的 PGP可在密钥列表中双击它。在结果窗口中点击 “<ruby>名字<rt>Names</rt></ruby>” 和 “<ruby>签名<rt>Signatures</rt></ruby>” 选项卡。在这个窗口中,你可以签名你的密钥(表示你信任这个密钥)。点击 “<ruby>签名<rt>Sign</rt></ruby>” 按钮然后(在结果窗口中)指出 “<ruby>你是如何仔细的检查这个密钥的?<rt>how carefully youve checked this key?</rt></ruby>” 和 “<ruby>其他人将如何看到该签名<rt>how others will see the signature</rt></ruby>”(如图 3
![Key signing](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_3.jpg?itok=7USKG9fI "Key signing")
*图 3签名一个密钥表示信任级别。*
当你处理其它人的密钥时,密钥签名是非常重要的,因为一个签名的密钥将确保你的系统(和你)做了这项签名工作并且完全信任这个重要的密钥。
谈到导入的密钥Seahorse 可以允许你很容易地去导入其他人的公钥文件(这个文件以 `.asc` 为后缀。你的系统上有其他人的公钥意味着你可以加密发送给他们的电子邮件和文件LCTT 译注原文将“加密”误作“解密”。然而Seahorse 在很长的一段时间内都存在一个 [已知的 bug][18]。这个问题是Seahorse 导入使用 GPG 版本 1但是显示的是 GPG 版本 2。这意味着在这个存在了很长时间的 bug 被修复之前,导入公钥总是失败的。如果你想导入一个公钥文件到 Seahorse 中,你只能去使用命令行。因此,如果有人发送给你一个文件 `olivia.asc`,你想去导入到 Seahorse 中使用它,你将只能运行命令 `gpg2 --import olivia.asc`。那个密钥将出现在 GnuPG 密钥列表中。你可以打开该密钥,点击 “<ruby>我信任签名<rt>I trust signatures</rt></ruby>” 按钮,然后在问题 “<ruby>你是如何仔细地检查该密钥的?<rt>how carefully youve checked the key</rt></ruby>” 中,点击 “<ruby>签名这个密钥<rt>Sign this key</rt></ruby>” 按钮去签名。
### SSH 密钥
现在我们来谈谈我认为 Seahorse 中最重要的一个方面 — SSH 密钥。Seahorse 不仅可以很容易地生成一个 SSH 密钥,而且它也可以很容易地将生成的密钥发送到服务器上,因此,你可以享受到 SSH 密钥验证的好处。下面是如何生成一个新的密钥以及如何导出它到一个远程服务器上。
1. 打开 Seahorse 应用程序
2. 点击 “+” 按钮
3. 选择 “Secure Shell Key”
4. 点击 “Continue”
5. 提供一个密钥描述信息
6. 点击 “Set Up” 去创建密钥
7. 输入密钥的验证密钥
8. 点击 OK
9. 输入远程服务器地址和服务器上的登录名(如图 4
10. 输入远程用户的密码
11. 点击 OK
![SSH key](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_4.jpg?itok=ZxuxT8ry "SSH key")
*图 4上传一个 SSH 密钥到远程服务器。*
新密钥将上传到远程服务器上以备使用。如果你的服务器已经设置为使用 SSH 密钥验证,那就一切就绪了。
需要注意的是,在创建一个 SSH 密钥期间,你可以点击 “<ruby>高级密钥选项<rt>Advanced key options</rt></ruby>”去展开它,配置加密类型和密钥长度(如图 5
![Advanced options](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/seahorse_5.jpg?itok=vUT7pi0z "Advanced options")
*图 5高级 SSH 密钥选项。*
### Linux 新手必备
任何 Linux 新手用户都可以很快熟悉使用 Seahorse。即便是它有缺陷Seahorse 仍然是为你准备的一个极其方便的工具。有时候,你可能希望(或者需要)去加密或者解密一个电子邮件/文件,或者为使用 SSH 验证来管理 SSH 密钥。如果你想去这样做而不希望使用命令行那么Seahorse 将是非常适合你的工具。
_通过来自 Linux 基金会和 edX 的 ["Linux 入门" ][13] 免费课程学习更多 Linux 的知识。_
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2018/2/how-manage-pgp-and-ssh-keys-seahorse
作者:[JACK WALLEN][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxt](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/jlwallen
[1]:https://www.linux.com/licenses/category/used-permission
[2]:https://www.linux.com/licenses/category/used-permission
[3]:https://www.linux.com/licenses/category/used-permission
[4]:https://www.linux.com/licenses/category/used-permission
[5]:https://www.linux.com/licenses/category/used-permission
[6]:https://www.linux.com/licenses/category/creative-commons-zero
[7]:https://www.linux.com/files/images/seahorse1jpg
[8]:https://www.linux.com/files/images/seahorse2jpg
[9]:https://www.linux.com/files/images/seahorse3jpg
[10]:https://www.linux.com/files/images/seahorse4jpg
[11]:https://www.linux.com/files/images/seahorse5jpg
[12]:https://www.linux.com/files/images/fish-19076071920jpg
[13]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
[14]:https://wiki.gnome.org/Apps/Seahorse
[15]:https://www.mozilla.org/en-US/thunderbird/
[16]:https://enigmail.net/index.php/en/
[17]:https://wiki.gnome.org/Apps/Evolution
[18]:https://bugs.launchpad.net/ubuntu/+source/seahorse/+bug/1577198

View File

@@ -0,0 +1,39 @@
3 种扩展 Kubernetes 能力的方式
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/chen-goldberg-kubecon.png?itok=WR_4i31u)
Google 的工程总监 Chen Goldberg 在最近的奥斯汀 [KubeCon 和 CloudNativeCon][1]上说Kubernetes 的扩展能力是它的秘密武器。
在建立帮助工程师提高工作效率的工具的竞赛中Goldberg 谈到他曾经领导过一个开发这样一个平台的团队。尽管平台最初有用,但它无法扩展,并且修改也很困难。
幸运的是Goldberg 说Kubernetes 没有这些问题。首先Kubernetes 是一个自我修复系统,因为它使用的控制器实现了“<ruby>协调环<rt>Reconciliation Loop</rt></ruby>”。在协调环中,控制器观察系统的当前状态并将其与所需状态进行比较。一旦它确定了这两个状态之间的差异,它就会努力实现所需的状态。这使得 Kubernetes 非常适合动态环境。
### 3 种扩展 Kubernetes 的方式
Goldberg 然后解释说,要建立控制器,你需要资源,也就是说,你需要扩展 Kubernetes。有三种方法可以做到这一点从最灵活但也更困难到最简单的依次是使用 Kube 聚合器、使用 API 服务器构建器或创建<ruby>自定义资源定义<rt>Custom Resource Definition</rt></ruby>CRD
后者甚至可以使用极少的代码来扩展 Kubernetes 的功能。为了演示它是如何完成的Goggle 软件工程师 Anthony Yeh 上台展示了为 Kubernetes 添加一个状态集。 (状态集对象用于管理有状态应用,即需要存储应用状态的程序,跟踪例如用户身份及其个人设置。)使用 _catset_,在一个 100 行 JavaScript 的文件中实现的 CRDYeh 展示了如何将状态集添加到 Kubernetes 部署中。之前的扩展不是 CRD需要 24 个文件和 3000 多行代码。
为解决 CRD 可靠性问题Goldberg 表示Kubernetes 已经启动了一项认证计划,允许公司在 Kubernetes 社区注册和认证其扩展。在一个月内,已有 30 多家公司报名参加该计划。
Goldberg 继续解释 Kubernetes 的可扩展性如何成为今年 KubeCon 的热门话题,以及 Google 和 IBM 如何构建一个使用 CRD 管理和保护微服务的平台。或者一些开发人员如何将机器学习带入 Kubernetes另外展示开放服务代理以及在混合设置上的服务消费。
Goldberg 总结说可扩展性是种增能。而且Kubernetes 的可扩展性使其成为开发者的通用平台,并且易于使用,这使得他们可以运行任何应用程序。
你可以在下面观看整个视频:
https://www.youtube.com/embed/1kjgwXP_N7A?enablejsapi=1
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/event/kubecon/2018/2/3-ways-extend-power-kubernetes
作者:[PAUL BROWN][a]
译者:[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/bro66
[1]:http://events17.linuxfoundation.org/events/kubecon-and-cloudnativecon-north-america

View File

@@ -0,0 +1,139 @@
如何在 Linux / Unix 上使用 awk 打印文件名
=================
Q我想在 Linux / 类Unix 系统上使用 awk 打印文件名。 如何使用 awk 的 `BEGIN` 特殊模式打印文件名? 我可以使用 gawk/awk 打印当前输入文件的名称吗LCTT 译注:读者最好能有一些 awk 的背景知识,否则阅读本文的时候会有一些困惑)
`FILENAME` 变量中存放着当前输入文件的名称。 您可以使用 `FILENAME` 显示或打印当前输入文件名,如果在命令行中未指定文件,则 `FILENAME` 的值为 `-` 标准输入LCTT 译注:多次按下回车键即可看到效果)。 但是,除非由 `getline` 设置,否则 `FILENAME``BEGIN` 特殊模式中未定义。
### 使用 awk 打印文件名
使用语法如下:
```
awk '{ print FILENAME }' fileNameHere
awk '{ print FILENAME }' /etc/hosts
```
因 awk 逐行读取文件因此你可能看到多个文件名为了避免这个情况你可以使用如下的命令LCTT 译注:`FNR` 表示当前记录数,只在文件中有效)
```
awk 'FNR == 1{ print FILENAME } ' /etc/passwd
awk 'FNR == 1{ print FILENAME } ' /etc/hosts
```
![](https://www.cyberciti.biz/media/new/faq/2018/02/How-to-print-filename-using-awk-on-Linux-or-Unix.jpg)
### 使用 awk 的 BEGIN 特殊规则打印文件名
使用下面的语法LCTT 译注:`ARGV[I]` 表示输入的第 i 个参数)
```
awk 'BEGIN{print ARGV[1]}' fileNameHere
awk 'BEGIN{print ARGV[1]}{ print "someting or do something on data" }END{}' fileNameHere
awk 'BEGIN{print ARGV[1]}' /etc/hosts
```
示例输出:
```
/etc/hosts
```
然而,`ARGV[1]` 并不是每一次都能奏效,例如:
```
ls -l /etc/hosts | awk 'BEGIN{print ARGV[1]} { print }'
```
你需要将它修改如下(假设 `ls -l` 只产生一行输出):
```
ls -l /etc/hosts | awk '{ print "File: " $9 ", Owner:" $3 ", Group: " $4 }'
```
示例输出:
```
File: /etc/hosts, Owner:root, Group: root
```
### 处理由通配符指定的多个文件名
使用如下的示例语法:
```
awk '{ print FILENAME; nextfile } ' *.c
awk 'BEGIN{ print "Starting..."} { print FILENAME; nextfile }END{ print "....DONE"} ' *.conf
```
示例输出:
```
Starting...
blkid.conf
cryptconfig.conf
dhclient6.conf
dhclient.conf
dracut.conf
gai.conf
gnome_defaults.conf
host.conf
idmapd.conf
idnalias.conf
idn.conf
insserv.conf
iscsid.conf
krb5.conf
ld.so.conf
logrotate.conf
mke2fs.conf
mtools.conf
netscsid.conf
nfsmount.conf
nscd.conf
nsswitch.conf
openct.conf
opensc.conf
request-key.conf
resolv.conf
rsyncd.conf
sensors3.conf
slp.conf
smartd.conf
sysctl.conf
vconsole.conf
warnquota.conf
wodim.conf
xattr.conf
xinetd.conf
yp.conf
....DONE
```
`nextfile` 告诉 awk 停止处理当前的输入文件。 下一个输入记录读取来自下一个输入文件。 更多信息,请参见 awk/[gawk][1] 命令手册页:
```
man awk
man gawk
```
### 关于作者
作者是 nixCraft 的创立者,也是经验丰富的系统管理员和 Linux/Unix shell 脚本的培训师。 他曾与全球各行各业的客户合作,涉及 IT教育国防和空间研究以及非营利部门等多个行业。 您可以在 [Twitter][2][Facebook][3] 和 [Google+][4]上关注他。 可以通过订阅我的 [RSS][5] 来获取更多的关于**系统管理Linux/Unix ,和开源主题**的相关资料。
-------------
via: https://www.cyberciti.biz/faq/how-to-print-filename-with-awk-on-linux-unix/
作者:[Vivek Gite][a]
译者:[amwps290](https://github.com/amwps290)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz/
[1]:https://www.gnu.org/software/gawk/manual/
[2]:https://twitter.com/nixcraft
[3]:https://facebook.com/nixcraft
[4]:https://plus.google.com/+CybercitiBiz
[5]:https://www.cyberciti.biz/atom/atom.xml

View File

@@ -0,0 +1,89 @@
如何检查你的计算机使用的是 UEFI 还是 BIOS
======
**简介:这是一个快速的教程,来告诉你的系统使用的是现代 UEFI 或者传统 BIOS。同时提供 Windows 和 Linux 的说明。**
当你尝试[双启动 Linux 和 Windows][1] 时,你需要知道系统上是否有 UEFI 或 BIOS 启动模式。它可以帮助你决定安装 Linux 的分区。
我不打算在这里讨论[什么是 BIOS][2]。不过,我想通过 BIOS 告诉你一些 [UEFI][3] 的优点。
UEFI 即(<ruby>统一可扩展固件接口<rt>Unified Extensible Firmware Interface</rt></ruby>)旨在克服 BIOS 的某些限制。它增加了使用大于 2TB 磁盘的能力,并具有独立于 CPU 的体系结构和驱动程序。采用模块化设计,即使没有安装操作系统,也可以支持远程诊断和修复,以及灵活的无操作系统环境(包括网络功能)。
### UEFI 优于 BIOS 的地方
* UEFI 在初始化硬件时速度更快。
* 提供安全启动,这意味着你在加载操作系统之前加载的所有内容都必须签名。这为你的系统提供了额外的保护层。
* BIOS 不支持超过 2TB 的分区。
* 最重要的是,如果你是双引导,那么建议始终在相同的引导模式下安装两个操作系统。
![How to check if system has UEFI or BIOS][4]
如果试图查看你的系统运行的是 UEFI 还是 BIOS这并不难。首先让我从 Windows 开始,然后看看如何在 Linux 系统上查看用的是 UEFI 还是 BIOS。
### 在 Windows 中检查使用的是 UEFI 还是 BIOS
在 Windows 中,在“开始”面板中的“系统信息”中,在 BIOS 模式下,可以找到启动模式。如果它显示的是 Legacy那么你的系统是 BIOS。如果显示 UEFI那么它是 UEFI。
![][5]
**另一个方法**:如果你使用 Windows 10可以打开文件资源管理器并进入到 `C:\Windows\Panther` 来查看你使用的是 UEFI 还是 BIOS。打开文件 setupact.log 并搜索下面的字符串。
```
Detected boot environment
```
我建议在 notepad++ 中打开这个文件,因为这是一个很大的文件,记事本很可能挂起(至少它对我来说是 6GB !)。
你会看到几行有用的信息。
```
2017-11-27 09:11:31, Info IBS Callback_BootEnvironmentDetect:FirmwareType 1.
2017-11-27 09:11:31, Info IBS Callback_BootEnvironmentDetect: Detected boot environment: BIOS
```
### 在 Linux 中检查使用的是 UEFI 还是 BIOS
最简单地找出使用的是 UEFI 还是 BIOS 的方法是查找 `/sys/firmware/efi` 文件夹。如果使用的 BIOS 那么该文件夹不存在。
![Find if system uses UEFI or BIOS on Ubuntu Linux][6]
**另一种方法**:安装名为 efibootmgr 的软件包。
在基于 Debian 和 Ubuntu 的发行版中,你可以使用以下命令安装 efibootmgr 包:
```
sudo apt install efibootmgr
```
完成后,输入以下命令:
```
sudo efibootmgr
```
如果你的系统支持 UEFI它会输出不同的变量。如果没有你将看到一条消息指出 EFI 变量不支持。
![][7]
### 最后的话
查看你的系统使用的是 UEFI 还是 BIOS 很容易。一方面,像快速和安全的引导为 UEFI 提供了优势,如果你使用的是 BIOS 也不必担心太多,除非你打算使用 2TB 硬盘。
--------------------------------------------------------------------------------
via: https://itsfoss.com/check-uefi-or-bios/
作者:[Ambarish Kumar][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/ambarish/
[1]:https://itsfoss.com/guide-install-linux-mint-16-dual-boot-windows/
[2]:https://www.lifewire.com/bios-basic-input-output-system-2625820
[3]:https://www.howtogeek.com/56958/htg-explains-how-uefi-will-replace-the-bios/
[4]:https://itsfoss.com/wp-content/uploads/2018/02/uefi-or-bios-800x450.png
[5]:https://itsfoss.com/wp-content/uploads/2018/01/BIOS-800x491.png
[6]:https://itsfoss.com/wp-content/uploads/2018/02/uefi-bios.png
[7]:https://itsfoss.com/wp-content/uploads/2018/01/bootmanager.jpg

View File

@@ -0,0 +1,61 @@
LKRG用于运行时完整性检查的可加载内核模块
======
![LKRG logo][1]
开源社区的人们正在致力于一个 Linux 内核的新项目,它可以让内核更安全。命名为 Linux 内核运行时防护Linux Kernel Runtime Guard简称LKRG它是一个在 Linux 内核执行运行时完整性检查的可加载内核模块LKM
它的用途是检测对 Linux 内核的已知的或未知的安全漏洞利用企图,以及去阻止这种攻击企图。
LKRG 也可以检测正在运行的进程的提权行为,在漏洞利用代码运行之前杀掉这个运行进程。
### 这个项目开发始于 2011 年,首个版本已经发布
因为这个项目开发的较早LKRG 的当前版本仅仅是通过内核消息去报告违反内核完整性的行为,但是随着这个项目的成熟,将会部署一个完整的漏洞利用缓减系统。
LKRG 的成员 Alexander Peslyak 解释说,这个项目从 2011 年启动,并且 LKRG 已经经历了一个“重新开发"阶段。
LKRG 的首个公开版本是 LKRG v0.0,它现在可以从 [这个页面][2] 下载使用。[这里][3] 是这个项目的维基,为支持这个项目,它也有一个 [Patreon 页面][4]。
虽然 LKRG 仍然是一个开源项目LKRG 的维护者也计划做一个 LKRG Pro 版本,这个版本将包含一个专用的 LKRG 发行版,它将支持对特定漏洞利用的检测,比如,容器泄漏。开发团队计划从 LKRG Pro 基金中提取部分资金用于保证项目的剩余工作。
### LKRG 是一个内核模块而不是一个补丁。
一个类似的项目是<ruby>附加内核监视器<rt>Additional Kernel Observer</rt></ruby>AKO但是 LKRG 与 AKO 是不一样的,因为 LKRG 是一个内核加载模块而不是一个补丁。LKRG 开发团队决定将它设计为一个内核模块是因为,在内核上打补丁对安全性、系统稳定性以及性能都有很直接的影响。
而以内核模块的方式提供,可以在每个系统上更容易部署 LKRG而不必去修改核心的内核代码修改核心的内核代码非常复杂并且很容易出错。
LKRG 内核模块在目前主流的 Linux 发行版上都可以使用比如RHEL7、OpenVZ 7、Virtuozzo 7、以及 Ubuntu 16.04 到最新的主线版本。
### 它并非是一个完美的解决方案
LKRG 的创建者警告用户,他们并不认为 LKRG 是一个完美的解决方案,它**提供不了**坚不可摧和 100% 的安全。他们说LKRG 是 “设计为**可旁通**的”,并且仅仅提供了“多元化安全” 的**一个**方面。
> 虽然 LKRG 可以防御许多已有的 Linux 内核漏洞利用,而且也有可能会防御将来许多的(包括未知的)未特意设计去绕过 LKRG 的安全漏洞利用。它是设计为可旁通的(尽管有时候是以更复杂和/或低可利用为代价的)。因此,他们说 LKRG 通过多元化提供安全,就像运行一个不常见的操作系统内核一样,也就不会有真实运行一个不常见的操作系统的可用性弊端。
LKRG 有点像基于 Windows 的防病毒软件它也是工作于内核级别去检测漏洞利用和恶意软件。但是LKRG 团队说,他们的产品比防病毒软件以及其它终端安全软件更加安全,因为它的基础代码量比较小,所以在内核级别引入新 bug 和漏洞的可能性就更小。
### 运行当前版本的 LKRG 大约会带来 6.5% 的性能损失
Peslyak 说 LKRG 是非常适用于 Linux 机器的它在修补内核的安全漏洞后不需要重启动机器。LKRG 允许用户持续运行带有安全措施的机器,直到在一个计划的维护窗口中测试和部署关键的安全补丁为止。
经测试显示,安装 LKRG v0.0 后大约会产生 6.5% 性能影响但是Peslyak 说将在后续的开发中持续降低这种影响。
测试也显示LKRG 检测到了 CVE-2014-9322 (BadIRET)、CVE-2017-5123 (waitid(2) missing access_ok)、以及 CVE-2017-6074 (use-after-free in DCCP protocol) 的漏洞利用企图,但是没有检测到 CVE-2016-5195 (Dirty COW) 的漏洞利用企图。开发团队说由于前面提到的“可旁通”的设计策略LKRG 没有检测到 Dirty COW 提权攻击。
> 在 Dirty COW 的测试案例中,由于 bug 机制的原因,使得 LKRG 发生了 “旁通”,并且这也是一种利用方法,它也是将来类似的以用户空间为目标的绕过 LKRG 的一种方法。这样的漏洞利用是否会是普通情况(不太可能!除非 LKRG 或者类似机制的软件流行起来),以及对它的可用性的(负面的)影响是什么?(对于那些直接目标是用户空间的内核漏洞来说,这不太重要,也并不简单)。
--------------------------------------------------------------------------------
via: https://www.bleepingcomputer.com/news/linux/lkrg-linux-to-get-a-loadable-kernel-module-for-runtime-integrity-checking/
作者:[Catalin Cimpanu][a]
译者:[qhwdw](https://github.com/qhwdw)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.bleepingcomputer.com/author/catalin-cimpanu/
[1]:https://www.bleepstatic.com/content/posts/2018/02/04/LKRG-logo.png
[2]:http://www.openwall.com/lkrg/
[3]:http://openwall.info/wiki/p_lkrg/Main
[4]:https://www.patreon.com/p_lkrg

View File

@@ -0,0 +1,132 @@
初识 PythonHello World 和字符串操作
======
![](https://process.filestackapi.com/cache=expiry:max/resize=width:700/compress/eadkmsrBTcWSyCeA4qti)
开始之前,说一下本文中的[代码][1]和[视频][2]可以在我的 GitHub 上找到。
那么,让我们开始吧!如果你糊涂了,我建议你在单独的选项卡中打开下面的视频。
- [Python 的 Hello World 和字符串操作视频][2]
### 开始 (先决条件)
首先在你的操作系统上安装 Anaconda Python。你可以从[官方网站][4]下载 anaconda 并自行安装,或者你可以按照以下这些 anaconda 安装教程进行安装。
- 在 Windows 上安装 Anaconda [链接[5]
- 在 Mac 上安装 Anaconda [链接][6]
- 在 Ubuntu (Linux) 上安装 Anaconda[链接][7]
### 打开一个 Jupyter Notebook
打开你的终端Mac或命令行并输入以下内容[请参考视频中的 1:16 处][8])来打开 Jupyter Notebook
```
jupyter notebook
```
### 打印语句/Hello World
在 Jupyter 的单元格中输入以下内容并按下 `shift + 回车`来执行代码。
```
# This is a one line comment
print('Hello World!')
```
![](https://cdn-images-1.medium.com/max/1600/1*tRRBPYjREydsRIcKFa9NPQ.png)
*打印输出 “Hello World!”*
### 字符串和字符串操作
字符串是 Python 类的一种特殊类型。作为对象,在类中,你可以使用 `.methodName()` 来调用字符串对象的方法。字符串类在 Python 中默认是可用的,所以你不需要 `import` 语句来使用字符串对象接口。
```
# Create a variable
# Variables are used to store information to be referenced
# and manipulated in a computer program.
firstVariable = 'Hello World'
print(firstVariable)
```
![](https://cdn-images-1.medium.com/max/1600/1*f0aXyvLgXb7PCV1Xao_D8Q.png)
*输出打印变量 firstVariable*
```
# Explore what various string methods
print(firstVariable.lower())
print(firstVariable.upper())
print(firstVariable.title())
```
![](https://cdn-images-1.medium.com/max/1600/1*8dZfNBBABBSTuXxqE9mI3g.png)
*使用 .lower()、.upper() 和 title() 方法输出*
```
# Use the split method to convert your string into a list
print(firstVariable.split(' '))
```
![](https://cdn-images-1.medium.com/max/1600/1*gG7KFXpkNjbYjQgZwgtGTQ.png)
*使用 split 方法输出(此例中以空格分隔)*
```
# You can add strings together.
a = "Fizz" + "Buzz"
print(a)
```
![](https://cdn-images-1.medium.com/max/1600/1*p7y9qCsQmXAbae7Cf9t_3w.png)
*字符串连接*
### 查询方法的功能
对于新程序员他们经常问你如何知道每种方法的功能。Python 提供了两种方法来实现。
1、在不在 Jupyter Notebook 中都可用)使用 `help` 查询每个方法的功能。
![](https://cdn-images-1.medium.com/max/1600/1*3Mz8PtPFypNrptb9JqyOqA.png)
*查询每个方法的功能*
2.Jupyter Notebook 专用)你也可以通过在方法之后添加问号来查找方法的功能。
```
# To look up what each method does in jupyter (doesnt work outside of jupyter)
firstVariable.lower?
```
![](https://cdn-images-1.medium.com/max/1600/1*VrLofndKpFcsKNAsv5vz9Q.png)
*在 Jupyter 中查找每个方法的功能*
### 结束语
如果你对本文或在 [YouTube 视频][2]的评论部分有任何疑问,请告诉我们。文章中的代码也可以在我的 [GitHub][1] 上找到。本系列教程的第 2 部分是[简单的数学操作][10]。
--------------------------------------------------------------------------------
via: https://www.codementor.io/mgalarny/python-hello-world-and-string-manipulation-gdgwd8ymp
作者:[Michael][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.codementor.io/mgalarny
[1]:https://github.com/mGalarnyk/Python_Tutorials/blob/master/Python_Basics/Intro/Python3Basics_Part1.ipynb
[2]:https://www.youtube.com/watch?v=JqGjkNzzU4s
[3]:https://www.youtube.com/watch?v=kApPBm1YsqU
[4]:https://www.continuum.io/downloads
[5]:https://medium.com/@GalarnykMichael/install-python-on-windows-anaconda-c63c7c3d1444
[6]:https://medium.com/@GalarnykMichael/install-python-on-mac-anaconda-ccd9f2014072
[7]:https://medium.com/@GalarnykMichael/install-python-on-ubuntu-anaconda-65623042cb5a
[8]:https://youtu.be/JqGjkNzzU4s?t=1m16s
[9]:data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
[10]:https://medium.com/@GalarnykMichael/python-basics-2-simple-math-4ac7cc928738

View File

@@ -0,0 +1,93 @@
Zsync一个仅下载文件新的部分的传输工具
======
![](https://www.ostechnix.com/wp-content/uploads/2018/02/Linux-1-720x340.png)
就算是网费每天变得越来越便宜,你也不应该重复下载相同的东西来浪费你的流量。一个很好的例子就是下载 Ubuntu 或任何 Linux 镜像的开发版本。如你所知Ubuntu 开发人员每隔几个月就会发布一次日常构建、alpha、beta 版 ISO 镜像以供测试。在过去,一旦发布我就会下载这些镜像,并审查每个版本。现在不用了!感谢 Zsync 文件传输程序。现在可以仅下载 ISO 镜像新的部分。这将为你节省大量时间和 Internet 带宽。不仅时间和带宽,它将为你节省服务端和客户端的资源。
Zsync 使用与 Rsync 相同​​的算法,如果你会得到一份已有文件旧版本,它只下载该文件新的部分。 Rsync 主要用于在计算机之间同步数据,而 Zsync 则用于分发数据。简单地说,可以使用 Zsync 将中心的一个文件分发给数千个下载者。它在 Artistic License V2 许可证下发布,完全免费且开源。
### 安装 Zsync
Zsync 在大多数 Linux 发行版的默认仓库中有。
在 Arch Linux 及其衍生版上,使用命令安装它:
```
$ sudo pacman -S zsync
```
在 Fedora 上,启用 Zsync 仓库:
```
$ sudo dnf copr enable ngompa/zsync
```
并使用命令安装它:
```
$ sudo dnf install zsync
```
在 Debian、Ubuntu、Linux Mint 上:
```
$ sudo apt-get install zsync
```
对于其他发行版,你可以从 [Zsync 下载页面][1]下载二进制打包文件,并手动编译安装它,如下所示。
```
$ wget http://zsync.moria.org.uk/download/zsync-0.6.2.tar.bz2
$ tar xjf zsync-0.6.2.tar.bz2
$ cd zsync-0.6.2/
$ configure
$ make
$ sudo make install
```
### 用法
请注意,只有当人们提供 zsync 下载方式时zsync 才有用。目前Debian、Ubuntu所有版本的 ISO 镜像都有 .zsync 下载链接。例如,请访问以下链接。
你可能注意到Ubuntu 18.04 LTS 每日构建版有直接的 ISO 和 .zsync 文件。如果你下载 .ISO 文件,则必须在 ISO 更新时下载完整的 ISO 文件。但是,如果你下载的是 .zsync 文件,那么 Zsync 以后仅会下载新的更改。你不需要每次都下载整个 ISO 映像。
.zsync 文件包含 zsync 程序所需的元数据。该文件包含 rsync 算法的预先计算的校验和。它在服务器上生成一次,然后由任意数量的下载器使用。要使用 Zsync 客户端程序下载 .zsync 文件,你只需执行以下操作:
```
$ zsync <.zsync-file-URL>
```
例如:
```
$ zsync http://cdimage.ubuntu.com/ubuntu/daily-live/current/bionic-desktop-amd64.iso.zsync
```
如果你的系统中已有以前的镜像文件,那么 Zsync 将计算远程服务器中旧文件和新文件之间的差异,并仅下载新的部分。你将在终端看见计算过程一系列的点或星星。
如果你下载的文件的旧版本存在于当前工作目录,那么 Zsync 将只下载新的部分。下载完成后,你将看到两个镜像,一个你刚下载的镜像和以 .iso.zs-old 为扩展名的旧镜像。
如果没有找到相关的本地数据Zsync 会下载整个文件。
![](http://www.ostechnix.com/wp-content/uploads/2018/02/Zsync-1.png)
你可以随时按 `CTRL-C` 取消下载过程。
试想一下,如果你直接下载 .ISO 文件或使用 torrent每当你下载新镜像时你将损失约 1.4GB 流量。因此Zsync 不会下载整个 Alpha、beta 和日常构建映像,而只是在你的系统上下载了 ISO 文件的新部分,并在系统中有一个旧版本的拷贝。
今天就到这里。希望对你有帮助。我将很快另外写一篇有用的指南。在此之前,请保持关注!
干杯!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/zsync-file-transfer-utility-download-new-parts-file/
作者:[SK][a]
译者:[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]:http://zsync.moria.org.uk/downloads

View File

@@ -0,0 +1,104 @@
在你的网络中使用树莓派和 Pi-hole 拦截广告
======
> 痛恨上网时看到广告?学习这篇教程来设置 Pi-hole。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/pi-hole-banner.png?itok=1TXcp3hm)
有一个闲置的树莓派?在浏览网页时讨厌广告?[Pi-hole][1] 是一个拦截广告的开源软件项目,它可以将你的家庭网络上的所有广告路由到一个不存在的地方,从而实现在你的设备上拦截广告的目的。这么好的方法只需要花几钟的时间来设置,你就可以使用它了。
Pi-hole 拦截了超过 100,000 个提供广告的域名,它可以拦截任何设备(包括移动设备、平板电脑、以及个人电脑)上的广告,并且它是完整的拦截了广告,而不是仅将它们隐藏起来,这样做可以提升总体的网络性能(因为广告不需要下载)。你可以在一个 web 界面上、或者也可以使用一个 API 来监视性能和统计数据。
### 你需要:
* 树莓派 + SD 卡
* USB 电源线
* 以太网线
![](https://opensource.com/sites/default/files/u128651/raspberry-pi.png)
![](https://opensource.com/sites/default/files/u128651/noobs-card.png)
![](https://opensource.com/sites/default/files/u128651/power-supply.png)
![](https://opensource.com/sites/default/files/u128651/ethernet-cable.png)
你不需要使用一个最新型号的树莓派 — 一个老款足够完成这项工作,只要它的内存不小于 512MB 就可以 — 因此一个一代树莓派 Model Brev 2就足够一个 Model B+、或者二代的或者三代的树莓派都可以。你可以使用 Pi Zero但需要一个 USB micro 以太网适配器。你可以使用一个带 WiFi 的 Pi Zero W 而不是以太网。但是,作为你的网络基础设施的一部分,我建议你使用一个性能良好、稳定的有线连接来代替 WiFi 连接。
### 准备 SD 卡
开始的第一步,你可能需要将 Raspbian Stretch Lite 安装到一个 SD 卡上。SD 卡至少需要 4GB 大小(完整的桌面版 Raspbian 镜像至少要 8GB但是 Lite 版镜像更小更轻量化,足够完成这项工作)。如果你喜欢,也可以使用完整的 Raspbian 桌面版镜像,但是作为一个去运行简单应用程序的树莓派,你没必要做更多的事情。
![](https://opensource.com/sites/default/files/u128651/raspbian-downloads.png)
使用你的个人电脑,从树莓派的网站上下载 Raspbian Stretch Lite 镜像。解压它并提取出里面的 `.img` 文件,然后将这个 `.img` 文件写入到你的 SD 卡。不论你的 SD 卡是否是空白的,这一步都不会有什么麻烦,因为在写入前它会清空上面的数据。
如果你使用的是 Linux写入镜像文件更简单的办法是使用命令行工具 `dd`。或者,你也可以使用跨平台的软件 [Etcher][2] (可以去参考 Les Pounder 写的指南 “[如何为树莓派准备 SD 卡][3]“)。
![](https://opensource.com/sites/default/files/etcher-win-520px.png)
SD 卡准备完成之后,你可以将它插入到你的树莓派,连接上键盘、显示器和以太网,然后为树莓派接上电源。在初始化设置之后,这个树莓派就不需要键盘或显示器了。如果你有使用“<ruby>无末端<rt>headless</rt></ruby>”树莓派工作的经验,你可以 [启用 SSH][4] 然后去设置它 [启用远程连接][5]。
### 安装 Pi-hole
在你的树莓派引导完成之后,用缺省用户名(`pi`)和密码(`raspberry`)登入。现在你就可以运行命令行了,可以去安装 Pi-hole 了。简单地输入下列命令并回车:
```
curl -sSL https://install.pi-hole.net | bash
```
这个命令下载了 Pi-hole 安装脚本然后去运行它。你可以在你的电脑浏览器中输入 `https://install.pi-hole.net` 来查看它的内容,你将会看到这个脚本做了些什么。它为你生成了一个**管理员密码**,并和其它安装信息一起显示在你的屏幕上。
就是这么简单,几分钟之后,你的树莓派将准备好为你拦截广告。
在你断开树莓派连接之前,你需要知道它的 IP 地址和你的路由器的 IP 地址。(如果你不知道),在你的终端中输入 `hostname -I` 来查看你的树莓派的 IP 地址,输入 `ip route | grep default` 来找到你的路由器的 IP 地址。你看到的将是像 `192.168.1.1` 这样的地址。
### 配置你的路由器
你的树莓派现在运行着一个 DNS 服务器,接下来你需要告诉你的路由器去使用 Pi-hole 作为它的 DNS 服务器而不是你的 ISP 提供给你的缺省 DNS。进入路由器的管理控制台 web 界面。这个界面一般是输入你的路由器的 IP 地址来进入的。
找到 LAN 设置下面的 DHCP/DNS 设置,然后将你的主 DNS 服务器的 IP 地址设置为你的 Pi-hole 的 IP 地址。设置完成之后,它应该你下图的样子:
![](https://opensource.com/sites/default/files/u128651/pi-hole-dns.png)
关于这一步的更多信息,可以查看 [Pi-hole discourse][6]。
你还需要确保你的 Pi-hole 始终保持相同的 IP 地址,因此,你需要去查看 DHCP 设置,将你的树莓派的 IP 地址条目添加到保留地址中。
### 外部测试
现在,在命令行下输入 `sudo halt` 关闭运行的树莓派,并断开它的电源。你可以拔掉显示器连接线和键盘,然后将你的树莓派放置到一个合适的固定的地方 — 或许应该将它放在你的路由器附近。确保连接着以太网线,然后重新连接电源以启动它。
在你的个人电脑上导航到一个网站(强烈建议访问 [Opensource.com][7] 网站),或者用你的 WiFi 中的一个设备去检查你的因特网访问是否正常(如果不能正常访问,可能是你的 DNS 配置错误)。如果在浏览器中看到了预期的结果,说明它的工作正常。现在,你浏览网站时,应该再也看不到广告了!甚至在你的 app 中提供的广告也无法出现在你的移动设备中!祝你“冲浪”愉快!
如果你想去测试一下你的广告拦截的新功能,你可以去这个 [测试页面][8] 尝试浏览一些内置广告的网站。
现在你可以在你的电脑浏览器上输入 Pi-hole 的 IP 地址来访问它的 web 界面(比如,`http://192.168.1.4/admin` 或者 `http://pi.hole/admin` 也可能会工作)。你将看到 Pi-hole 管理面板和一些统计数据(在这时可能数字比较小)。在你输入(在安装时显示在屏幕上的)密码后,你将看到更漂亮的图形界面:
![](https://opensource.com/sites/default/files/u128651/pi-hole-web.png)
你也可以微调你的 Pi-hole 的设置,像域名的白名单和黑名单、永久和临时禁止、访问拦截统计信息等等。
个别情况下,你可能需要去升级你的 Pi-hole 安装。当软件需要更新时,这个 web 界面会出现一个更新提示。如果你启用了 SSH你可以远程登入否则那你只能再次连接键盘和显示器。远程登入之后输入 `pihole -up`命令来更新它。
![](https://opensource.com/sites/default/files/u128651/pi-hole-update.png)
如果你使用过 Pi-hole 或者其它的开源广告拦截器,请在下面的评论区把你的经验共享出来。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/2/block-ads-raspberry-pi
作者:[Ben Nuttall][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/bennuttall
[1]:https://pi-hole.net/
[2]:https://etcher.io/
[3]:https://opensource.com/article/17/3/how-write-sd-cards-raspberry-pi
[4]:https://www.raspberrypi.org/blog/a-security-update-for-raspbian-pixel/
[5]:https://www.raspberrypi.org/documentation/remote-access/ssh/README.md
[6]:https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245
[7]:https://opensource.com/
[8]:https://pi-hole.net/pages-to-test-ad-blocking-performance/

View File

@@ -0,0 +1,97 @@
Linux 新用户?来试试这 8 款重要的软件
======
![](https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-00-Featured.png)
即便您不是计算机的新手,刚接触 Linux 时,通常都会面临选择使用应用软件的问题。在数百万 Linux 应用程序中,做起选择来并不轻松。本文中,您将能发现八个重要的 Linux 应用,帮助您快速选择应用程序。
下面这些应用程序大多不是 Linux 独有的。如果有过使用 Windows/Mac 的经验,您很可能会熟悉其中一些软件。根据兴趣和需求,下面的程序可能不全符合您的要求,但是在我看来,清单里大多数甚至全部的软件,对于新用户开启 Linux 之旅都是有帮助的。
**相关链接** : [每一个 Linux 用户都应该使用的 11 个可移植软件][1]
### 1. Chromium 网页浏览器
![linux-apps-01-chromium][2]
几乎不会不需要使用网页浏览器的用户。您可以看到陈旧的 Linux 发行版几乎都会附带 Firefox火狐浏览器或者其他 [Linux 浏览器][3],关于浏览器,强烈建议您尝试 [Chromium][4]。它是谷歌浏览器的开源版。Chromium 的主要优点是速度和安全性。它同样拥有大量的附加组件。
### 2. LibreOffice
![linux-apps-02-libreoffice][5]
[LibreOffice][6] 是一个开源办公套件其包括文字处理Writer、电子表格Calc、演示Impress、数据库Base、公式编辑器Math、矢量图和流程图Draw应用程序。它与 Microsoft Office 文档兼容,如果其基本功能不能满足需求,您可以使用 [LibreOffice 拓展][7]。
LibreOffice 显然是 Linux 应用中至关重要的一员,如果您使用 Linux 的计算机,安装它是有必要的。
### 3. GIMP<ruby>GUN 图像处理程序<rt>GNU Image Manipulation Program</rt></ruby>
![linux-apps-03-gimp][8]
[GIMP][9] 是一款非常强大的开源图片处理程序,它类似于 Photoshop。通过 GIMP您可以编辑或是创建用于 Web 或是打印的光栅图位图。如果您对专业的图片处理没有概念Linux 自然提供有更简单的图像编辑器GIMP 看上去可能会复杂一点。GIMP 并不单纯提供图片裁剪和大小调整,它更覆盖了图层、滤镜、遮罩、路径和其他一些高级功能。
### 4. VLC 媒体播放器
![linux-apps-04-vlc][10]
[VLC][11] 也许就是最好的影音播放器了。它是跨平台的,所以您可能在 Windows 上也听说过它。VLC 最特殊的地方是其拥有大量解码器(并不是所有的解码器都开放源代码),所以它几乎可以播放所有的影音文件。
### 5. Jitsy
![linux-apps-05-jitsi][12]
[Jitsy][13] 完全是关于通讯的。您可以借助它使用 Google talk、Facebook chat、Yahoo、ICQ 和 XMPP。它是用于音视频通话包括电话会议<ruby>桌面流<rt>desktop streaming</rt></ruby>和群组聊天的多用户工具。会话会被加密。Jistsy 同样能帮助您传输文件或记录电话。
### 6. Synaptic
![linux-apps-06-synaptic][14]
[Synaptic][15] 是一款基于 Debian 系统发行版的另一款应用程序安装程序。并不是所有基于 Debian 的 Linux 都安装有它,如果您使用基于 Debian 的 Linux 操作系统没有预装也许您可以试一试。Synaptic 是一款用于添加或移除系统应用的 GUI 工具,甚至相对于许多发行版默认安装的 [软件中心包管理器][16] ,经验丰富的 Linux 用户更亲睐于 Sunaptic。
**相关链接** : [10 款您没听说过的 Linux 生产力应用程序][17]
### 7. VirtualBox
![linux-apps-07-virtualbox][18]
[VirtualBox][19] 能支持您在计算机上运行虚拟机。当您想在当前 Linux 发行版上安装其他发行版或操作系统时,使用虚拟机会方便许多。您同样可以通过它运行 Windows 应用程序,性能可能会稍弱,但是如果您有一台强大的计算机,就不会那么糟。
### 8. AisleRiot Solitaire纸牌游戏
![linux-apps-08-aisleriot][20]
对于 Linux 的新用户来说,一款纸牌游戏并不是刚需,但是它真的太有趣了。当您进入这款纸牌游戏,您会发现,这是一款极好的纸牌游戏包。[AisleRiot][21] 是 Linux 标志性的应用程序,原因是 - 它涵盖超过八十种纸牌游戏,包括流行的 Klondike、Bakers Dozen、Camelot 等等,作为预警 - 它是会上瘾的,您可能会花很长时间沉迷于此!
根据您所使用的发行版,这些软件会有不同的安装方法。但是大多数都可以通过您使用的发行版中的包管理器安装使用,甚至它们可能会预装在您的发行版上。安装并且尝试它们想必是最好的,如果不合您的胃口,您可以轻松地删除它们。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/essential-linux-apps/
作者:[Ada Ivanova][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.maketecheasier.com/author/adaivanoff/
[1]:https://www.maketecheasier.com/portable-apps-for-linux/ (11 Portable Apps Every Linux User Should Use)
[2]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-01-Chromium.jpg (linux-apps-01-chromium)
[3]:https://www.maketecheasier.com/linux-browsers-you-probably-havent-heard-of/
[4]:http://www.chromium.org/
[5]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-02-LibreOffice.jpg (linux-apps-02-libreoffice)
[6]:https://www.libreoffice.org/
[7]:https://www.maketecheasier.com/best-libreoffice-extensions/
[8]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-03-GIMP.jpg (linux-apps-03-gimp)
[9]:https://www.gimp.org/
[10]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-04-VLC.jpg (linux-apps-04-vlc)
[11]:http://www.videolan.org/
[12]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-05-Jitsi.jpg (linux-apps-05-jitsi)
[13]:https://jitsi.org/
[14]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-06-Synaptic.jpg (linux-apps-06-synaptic)
[15]:http://www.nongnu.org/synaptic/
[16]:https://www.maketecheasier.com/are-linux-gui-software-centers-any-good/
[17]:https://www.maketecheasier.com/free-linux-productivity-apps-you-havent-heard-of/ (10 Free Linux Productivity Apps You Havent Heard Of)
[18]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-07-VirtualBox.jpg (linux-apps-07-virtualbox)
[19]:https://www.virtualbox.org/
[20]:https://www.maketecheasier.com/assets/uploads/2018/01/Linux-apps-08-AisleRiot.jpg (linux-apps-08-aisleriot)
[21]:https://wiki.gnome.org/Aisleriot

View File

@@ -0,0 +1,93 @@
如何在 Linux 中轻松修正拼写错误的 Bash 命令
======
![](https://www.ostechnix.com/wp-content/uploads/2018/02/Correct-Misspelled-Bash-Commands-720x340.png)
我知道你可以按下向上箭头来调出你运行过的命令,然后使用左/右键移动到拼写错误的单词,并更正拼写错误的单词,最后按回车键再次运行它,对吗?可是等等。还有一种更简单的方法可以纠正 GNU/Linux 中拼写错误的 Bash 命令。这个教程解释了如何做到这一点。请继续阅读。
### 在 Linux 中纠正拼写错误的 Bash 命令
你有没有运行过类似于下面的错误输入命令?
```
$ unme -r
bash: unme: command not found
```
你注意到了吗?上面的命令中有一个错误。我在 `uname` 命令缺少了字母 `a`
我在很多时候犯过这种愚蠢的错误。在我知道这个技巧之前,我习惯按下向上箭头来调出命令,并转到命令中拼写错误的单词,纠正拼写错误,然后按回车键再次运行该命令。但相信我。下面的技巧非常易于纠正你刚刚运行的命令中的任何拼写错误。
要轻松更正上述拼写错误的命令,只需运行:
```
$ ^nm^nam^
```
这会将 `uname` 命令中将 `nm` 替换为 `nam`。很酷,是吗?它不仅纠正错别字,而且还能运行命令。查看下面的截图。
![][2]
当你在命令中输入错字时使用这个技巧。请注意,它仅适用于 Bash shell。
**额外提示:**
你有没有想过在使用 `cd` 命令时如何自动纠正拼写错误?没有么?没关系!下面的技巧将解释如何做到这一点。
这个技巧只能纠正使用 `cd` 命令时的拼写错误。
比如说,你想使用命令切换到 `Downloads` 目录:
```
$ cd Donloads
bash: cd: Donloads: No such file or directory
```
哎呀!没有名称为 `Donloads` 的文件或目录。是的,正确的名称是 `Downloads`。上面的命令中缺少 `w`
要解决此问题并在使用 `cd` 命令时自动更正错误,请编辑你的 `.bashrc` 文件:
```
$ vi ~/.bashrc
```
最后添加以下行。
```
[...]
shopt -s cdspell
```
输入 `:wq` 保存并退出文件。
最后,运行以下命令更新更改。
```
$ source ~/.bashrc
```
现在,如果在使用 `cd` 命令时路径中存在任何拼写错误,它将自动更正并进入正确的目录。
![][3]
正如你在上面的命令中看到的那样,我故意输错(`Donloads` 而不是 `Downloads`),但 Bash 自动检测到正确的目录名并 `cd` 进入它。
[Fish][4] 和 Zsh shell 内置的此功能。所以,如果你使用的是它们,那么你不需要这个技巧。
然而,这个技巧有一些局限性。它只适用于使用正确的大小写。在上面的例子中,如果你输入的是 `cd donloads` 而不是 `cd Donloads`,它将无法识别正确的路径。另外,如果路径中缺少多个字母,它也不起作用。
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/easily-correct-misspelled-bash-commands-linux/
作者:[SK][a]
译者:[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/
[2]:http://www.ostechnix.com/wp-content/uploads/2018/02/misspelled-command.png
[3]:http://www.ostechnix.com/wp-content/uploads/2018/02/cd-command.png
[4]:https://www.ostechnix.com/install-fish-friendly-interactive-shell-linux/

View File

@@ -0,0 +1,152 @@
Dnsmasq 进阶技巧
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/banner_3.25.47_pm.png?itok=2YaDe86d)
许多人熟知并热爱 Dnsmasq并在他们的本地域名服务上使用它。今天我们将介绍进阶配置文件管理、如何测试你的配置、一些基础的安全知识、DNS 泛域名、快速 DNS 配置,以及其他一些技巧与窍门。下个星期我们将继续详细讲解如何配置 DNS 和 DHCP。
### 测试配置
当你测试新的配置的时候,你应该从命令行运行 Dnsmasq而不是使用守护进程。下面的例子演示了如何不用守护进程运行它同时显示指令的输出并保留运行日志
```
# dnsmasq --no-daemon --log-queries
dnsmasq: started, version 2.75 cachesize 150
dnsmasq: compile time options: IPv6 GNU-getopt
DBus i18n IDN DHCP DHCPv6 no-Lua TFTP conntrack
ipset auth DNSSEC loop-detect inotify
dnsmasq: reading /etc/resolv.conf
dnsmasq: using nameserver 192.168.0.1#53
dnsmasq: read /etc/hosts - 9 addresses
```
在这个小例子中你能看到许多有用的信息,包括版本、编译参数、系统名字服务文件,以及它的监听地址。可以使用 `Ctrl+C` 停止进程。在默认情况下Dnsmasq 没有自己的日志文件,所以日志会被记录到 `/var/log` 目录下的多个地方。你可以使用经典的 `grep` 来找到 Dnsmasq 的日志文件。下面这条指令会递归式地搜索 `/var/log`,在每个匹配的文件名之后显示匹配的行号,并忽略 `/var/log/dist-upgrade` 里的内容:
```
# grep -ir --exclude-dir=dist-upgrade dnsmasq /var/log/
```
使用 `grep --exclude-dir=` 时有一个有趣的小陷阱需要注意:不要使用完整路径,而应该只写目录名称。
你可以使用如下的命令行参数来让 Dnsmasq 使用你指定的文件作为它专属的日志文件:
```
# dnsmasq --no-daemon --log-queries --log-facility=/var/log/dnsmasq.log
```
或者在你的 Dnsmasq 配置文件中加上 `log-facility=/var/log/dnsmasq.log`
### 配置文件
Dnsmasq 的配置文件位于 `/etc/dnsmasq.conf`。你的 Linux 发行版也可能会使用 `/etc/default/dnsmasq``/etc/dnsmasq.d/`,或者 `/etc/dnsmasq.d-available/`(不,我们不能统一标准,因为这违反了 <ruby>Linux 七嘴八舌秘密议会<rt>Linux Cat Herd Ruling Cabal</rt></ruby>的旨意)。你有很多自由来随意安置你的配置文件。
`/etc/dnsmasq.conf` 是德高望重的老大。Dnsmasq 在启动时会最先读取它。`/etc/dnsmasq.conf` 可以使用 `conf-file=` 选项来调用其他的配置文件,例如 `conf-file=/etc/dnsmasqextrastuff.conf`,或使用 `conf-dir=` 选项来调用目录下的所有文件,例如 `conf-dir=/etc/dnsmasq.d`
每当你对配置文件进行了修改,你都必须重启 Dnsmasq。
你也可以根据扩展名来包含或忽略配置文件。星号表示包含,不加星号表示排除:
```
conf-dir=/etc/dnsmasq.d/, *.conf, *.foo
conf-dir=/etc/dnsmasq.d, .old, .bak, .tmp
```
你可以用 `--addn-hosts=` 选项来把你的主机配置分布在多个文件中。
Dnsmasq 包含了一个语法检查器:
```
$ dnsmasq --test
dnsmasq: syntax check OK.
```
### 实用配置
永远加入这几行:
```
domain-needed
bogus-priv
```
它们可以避免含有格式出错的域名或私有 IP 地址的数据包离开你的网络。
让你的名字服务只使用 Dnsmasq而不去使用 `/etc/resolv.conf` 或任何其他的名字服务文件:
```
no-resolv
```
使用其他的域名服务器。第一个例子是只对于某一个域名使用不同的域名服务器。第二个和第三个例子是 OpenDNS 公用服务器:
```
server=/fooxample.com/192.168.0.1
server=208.67.222.222
server=208.67.220.220
```
你也可以将某些域名限制为只能本地解析,但不影响其他域名。这些被限制的域名只能从 `/etc/hosts` 或 DHCP 解析:
```
local=/mehxample.com/
local=/fooxample.com/
```
限制 Dnsmasq 监听的网络接口:
```
interface=eth0
interface=wlan1
```
Dnsmasq 在默认设置下会读取并使用 `/etc/hosts`。这是一个又快又好的配置大量域名的方法,并且 `/etc/hosts` 只需要和 Dnsmasq 在同一台电脑上。你还可以让这个过程再快一些,可以在 `/etc/hosts` 文件中只写主机名,然后用 Dnsmasq 来添加域名。`/etc/hosts` 看上去是这样的:
```
127.0.0.1 localhost
192.168.0.1 host2
192.168.0.2 host3
192.168.0.3 host4
```
然后把下面这几行写入 `dnsmasq.conf`(当然,要换成你自己的域名):
```
expand-hosts
domain=mehxample.com
```
Dnsmasq 会自动把这些主机名扩展为完整的域名,比如 `host2` 会变为 `host2.mehxample.com`
### DNS 泛域名
一般来说,使用 DNS 泛域名不是一个好习惯,因为它们太容易被误用了。但它们有时会很有用,比如在你的局域网的严密保护之下的时候。一个例子是使用 DNS 泛域名会让 Kubernetes 集群变得容易管理许多,除非你喜欢给你成百上千的应用写 DNS 记录。假设你的 Kubernetes 域名是 mehxample.com那么下面这行配置可以让 Dnsmasq 解析所有对 mehxample.com 的请求:
```
address=/mehxample.com/192.168.0.5
```
这里使用的地址是你的集群的公网 IP 地址。这会响应对 mehxample.com 的所有主机名和子域名的请求,除非请求的目标地址已经在 DHCP 或者 `/etc/hosts` 中配置过。
下星期我们将探索更多的管理 DNS 和 DHCP 的细节,包括对不同的子网络使用不同的设置,以及提供权威域名服务器。
### 更多参考
* [使用 Dnsmasq 进行 DNS 伪装][1]
* [使用 Dnsmasq 配置简单的局域网域名服务][2]
* [Dnsmasq][3]
--------------------------------------------------------------------------------
via: https://www.linux.com/learn/intro-to-linux/2018/2/advanced-dnsmasq-tips-and-tricks
作者:[CARLA SCHRODER][a]
译者:[yixunx](https://github.com/yixunx)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/cschroder
[1]:https://www.linux.com/learn/intro-to-linux/2017/7/dns-spoofing-dnsmasq
[2]:https://www.linux.com/learn/dnsmasq-easy-lan-name-services
[3]:http://www.thekelleys.org.uk/dnsmasq/doc.html

View File

@@ -0,0 +1,47 @@
去掉了 chrome-gnome-shell 的 Gnome
======
新的笔记本有触摸屏,它可以折叠成平板电脑,我听说 gnome-shell 将是桌面环境的一个很好的选择,我设法调整它以按照现有的习惯使用。
然而,我发现一个很大的问题,它怎么会鼓励人们从互联网上下载随机扩展,并将它们作为整个桌面环境的一部分运行呢? 一个更大的问题是,[gnome-core][1] 对 [chrome-gnome-shell] [2] 有强制依赖,这个插件如果不用 root 用户编辑 `/etc` 下的文件则无法禁用,这会给将我的桌面环境暴露给网站。
访问[这个网站][3],它会知道你已经安装了哪些扩展,并且能够安装更多。我不信任它,我不需要那样,我不想那样。我为此感到震惊。
[我想出了一个临时解决方法][4]。LCTT 译注:作者做了一个空的依赖包来满足依赖,而不会做任何可能危害你的隐私和安全的操作。)
人们会在 firefox 中如何做呢?
### 描述
chrome-gnome-shell 是 gnome-core 的一个强制依赖项,它安装了一个你可能不需要的浏览器插件,并强制它使用系统级的 chrome 策略。
我认为使用 chrome-gnome-shell 会不必要地增加系统的攻击面,我作为主要用户,它会获取下载和执行随机未经审查代码的可疑特权。
(我做的)这个包满足了 chrome-gnome-shell 的依赖,但不会安装任何东西。
请注意,在安装此包之后,如果先前安装了 chrome-gnome-shell则需要清除 chrome-gnome-shell以使其在 `/etc/chromium` 中删除 chromium 策略文件。
### 说明
```
apt install equivs
equivs-build contain-gnome-shell
sudo dpkg -i contain-gnome-shell_1.0_all.deb
sudo dpkg --purge chrome-gnome-shell
```
--------------------------------------------------------------------------------
via: http://www.enricozini.org/blog/2018/debian/gnome-without-chrome-gnome-shell/
作者:[Enrico Zini][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://www.enricozini.org/
[1]:https://packages.debian.org/gnome-core
[2]:https://packages.debian.org/chrome-gnome-shell
[3]:https://extensions.gnome.org/
[4]:https://salsa.debian.org/enrico/contain-gnome-shell

View File

@@ -0,0 +1,158 @@
如何在 Debian Linux 上设置和配置网桥
=====
Q我是一个新 Debian Linux 用户,我想为 Debian Linux 上运行的虚拟化环境KVM设置网桥。那么我该如何在 Debian Linux 9.x 服务器上的 `/etc/network/interfaces` 中设置桥接网络呢?
如何你想为你的虚拟机分配 IP 地址并使其可从你的局域网访问,则需要设置网络桥接器。默认情况下,虚拟机使用 KVM 创建的专用网桥。但你需要手动设置接口,避免与网络管理员发生冲突。
### 怎样安装 brctl
输入以下 [apt-get 命令][1]
```
$ sudo apt install bridge-utils
```
### 怎样在 Debian Linux 上设置网桥
你需要编辑 `/etc/network/interface` 文件。不过,我建议在 `/etc/network/interface.d/` 目录下放置一个全新的配置。在 Debian Linux 配置网桥的过程如下:
#### 步骤 1 - 找出你的物理接口
使用 [ip 命令][2]
```
$ ip -f inet a s
```
示例输出如下:
```
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.2.23/24 brd 192.168.2.255 scope global eno1
valid_lft forever preferred_lft forever
```
`eno1` 是我的物理网卡。
#### 步骤 2 - 更新 /etc/network/interface 文件
确保只有 `lo`loopback 在 `/etc/network/interface` 中处于活动状态LCTT 译注loopback 指本地环回接口,也称为回送地址)删除与 `eno1` 相关的任何配置。这是我使用 [cat 命令][3] 打印的配置文件:
```
$ cat /etc/network/interface
```
```
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
 
source /etc/network/interfaces.d/*
 
# The loopback network interface
auto lo
iface lo inet loopback
```
#### 步骤 3 - 在 /etc/network/interfaces.d/br0 中配置网桥br0
使用文本编辑器创建一个文本文件,比如 `vi` 命令:
```
$ sudo vi /etc/network/interfaces.d/br0
```
在其中添加配置:
```
## static ip config file for br0 ##
auto br0
iface br0 inet static
address 192.168.2.23
broadcast 192.168.2.255
netmask 255.255.255.0
gateway 192.168.2.254
# If the resolvconf package is installed, you should not edit
# the resolv.conf configuration file manually. Set name server here
#dns-nameservers 192.168.2.254
# If you have muliple interfaces such as eth0 and eth1
# bridge_ports eth0 eth1
bridge_ports eno1
bridge_stp off # disable Spanning Tree Protocol
bridge_waitport 0 # no delay before a port becomes available
bridge_fd 0 # no forwarding delay
```
如果你想使用 DHCP 来获得 IP 地址:
```
## DHCP ip config file for br0 ##
auto br0
 
# Bridge setup
iface br0 inet dhcp
bridge_ports eno1
```
[在 vi/vim 中保存并关闭文件][4]。
#### 步骤 4 - 重新启动网络服务
在重新启动网络服务之前,请确保防火墙已关闭。防火墙可能会引用较老的接口,例如 `eno1`。一旦服务重新启动,你必须更新 `br0` 接口的防火墙规则。键入以下命令重新启动防火墙:
```
$ sudo systemctl restart network-manager
```
确认服务已经重新启动:
```
$ systemctl status network-manager
```
借助 [ip 命令][2]寻找新的 `br0` 接口和路由表:
```
$ ip a s $ ip r $ ping -c 2 cyberciti.biz
```
示例输出:
![](https://www.cyberciti.biz/media/new/faq/2018/02/How-to-setup-and-configure-network-bridge-on-Debian-Linux.jpg)
你可以使用 brctl 命令查看网桥有关信息:
```
$ brctl show
```
显示当前网桥:
```
$ bridge link
```
![](https://www.cyberciti.biz/media/new/faq/2018/02/Show-current-bridges-and-what-interfaces-they-are-connected-to-on-Linux.jpg)
### 关于作者
作者是 nixCraft 的创建者也是经验丰富的系统管理员DevOps 工程师以及 Linux 操作系统/ Unix shell 脚本的培训师。通过订阅 [RSS/XML 流][6] 或者 [每周邮件推送][7]获得关于 SysAdmin, Linux/Unix 和开源主题的最新教程。
--------------------------------------------------------------------------------
via: https://www.cyberciti.biz/faq/how-to-configuring-bridging-in-debian-linux/
作者:[Vivek GIte][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.cyberciti.biz/
[1]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
[2]:https://www.cyberciti.biz/faq/linux-ip-command-examples-usage-syntax/ (See Linux/Unix ip command examples for more info)
[3]:https://www.cyberciti.biz/faq/linux-unix-appleosx-bsd-cat-command-examples/ (See Linux/Unix cat command examples for more info)
[4]:https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/
[5]:https://www.cyberciti.biz/faq/linux-restart-network-interface/
[6]:https://www.cyberciti.biz/atom/atom.xml
[7]:https://www.cyberciti.biz/subscribe-to-weekly-linux-unix-newsletter-for-sysadmin/

View File

@@ -0,0 +1,117 @@
RStudio IDE 入门
======
> 用于统计技术的 R 项目是分析数据的有力方式,而 RStudio IDE 则可使这一切更加容易。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/code_development_programming_screen.png?itok=BgcSm5Pl)
从我记事起,我就一直喜欢摆弄数字。作为 20 世纪 70 年代后期的大学生,我上过统计学的课程,学习了如何检查和分析数据以揭示其意义。
那时候,我有一部科学计算器,它让统计计算变得比以往更容易。在 90 年代早期,作为一名从事 <ruby>t 检验<rt>t-test</rt></ruby>、相关性以及 [ANOVA][1] 研究的教育心理学研究生,我开始通过精心编写输入到 IBM 主机的文本文件来进行计算。这个主机远超我的手持计算器,但是一个小的空格错误就会导致整个过程无效,而且这个过程仍然有点乏味。
撰写论文时,尤其是我的毕业论文,我需要一种方法能够根据我的数据来创建图表,并将它们嵌入到文字处理文档中。我着迷于 Microsoft Excel 及其数字运算能力以及可以用计算结果创建出的大量图表。但这条路每一步都有成本。在 20 世纪 90 年代,除了 Excel还有其他专有软件包比如 SAS 和 SPSS+,但对于我那已经满满的研究生时间表来说,学习曲线是一项艰巨的任务。
### 快速回到现在
最近,由于我对数据科学的兴趣浓厚,加上对 Linux 和开源软件感兴趣,我阅读了大量的数据科学文章,并在 Linux 会议上听了许多数据科学演讲者谈论他们的工作。因此,我开始对编程语言 R一种开源的统计计算软件非常感兴趣。
起初,这只是一个偶发的一个想法。当我和我的朋友 Michael J. Gallagher 博士谈论他如何在他的 [博士论文][2] 研究中使用 R 时,这个火花便增大了。最后,我访问了 [R 项目][3] 的网站,并了解到我可以轻松地安装 [R for Linux][4]。游戏开始!
### 安装 R
根据你的操作系统和发行版情况,安装 R 会稍有不同。请参阅 [Comprehensive R Archive Network][5] CRAN网站上的安装指南。CRAN 提供了在 [各种 Linux 发行版][6][FedoraRHEL及其衍生版][7][MacOS][8] 和 [Windows][9] 上的安装指示。
我在使用 Ubuntu按照 CRAN 的指示,将以下行加入到我的 `/etc/apt/sources.list` 文件中:
```
deb https://<my.favorite.cran.mirror>/bin/linux/ubuntu artful/
```
接着我在终端运行下面命令:
```
$ sudo apt-get update
$ sudo apt-get install r-base
```
根据 CRAN 说明,“需要从源码编译 R 的用户[如包的维护者,或者任何通过 `install.packages()` 安装包的用户]也应该安装 `r-base-dev` 的包。”
### 使用 R 和 RStudio
安装好了 R我就准备了解更多关于使用这个强大的工具的信息。Gallagher 博士推荐了 [DataCamp][10] 上的 “R 语言入门”,并且我也在 [Code School][11] 找到了适用于 R 新手的免费课程。两门课程都帮助我学习了 R 的命令和语法。我还参加了 [Udemy][12] 上的 R 在线编程课程,并从 [No Starch 出版社][14] 上购买了 [R 之书][13]。
在阅读更多内容并观看 YouTube 视频后,我意识到我还应该安装 [RStudio][15]。Rstudio 是 R 语言的开源 IDE易于在 [Debian、Ubuntu、 Fedora 和 RHEL][16] 上安装。它也可以安装在 MacOS 和 Windows 上。
根据 RStudio 网站的说明,可以根据你的偏好对 IDE 进行自定义,具体方法是选择工具菜单,然后从中选择全局选项。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/r_global-options.png?itok=un6-SvS-)
R 提供了一些很棒的演示例子,可以通过在提示符处输入 `demo()` 从控制台访问。`demo(plotmath)``demo(perspective)` 选项为 R 强大的功能提供了很好的例证。我尝试过一些简单的 [vectors][17] 并在 R 控制台的命令行中绘制,如下所示。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/r_plotting-vectors.png?itok=9T7UV8p2)
你可能想要开始学习如何将 R 和一些样本数据结合起来使用,然后将这些知识应用到自己的数据上得到描述性统计。我自己没有丰富的数据来分析,但我搜索了可以使用的数据集 [datasets][18];有一个这样的数据集(我并没有用这个例子)是由圣路易斯联邦储备银行提供的 [经济研究数据][19]。我对一个题为“美国商业航空公司的乘客里程1937-1960”很感兴趣因此我将它导入 RStudio 以测试 IDE 的功能。RStudio 可以接受各种格式的数据,包括 CSV、Excel、SPSS 和 SAS。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/rstudio-import.png?itok=1yJKQei1)
数据导入后,我使用 `summary(AirPassengers)` 命令获取数据的一些初始描述性统计信息。按回车键后,我得到了 1949-1960 年的每月航空公司旅客的摘要以及其他数据,包括飞机乘客数量的最小值、最大值、四分之一位数、四分之三位数、中位数以及平均数。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/r_air-passengers.png?itok=RCJMLIb3)
我从摘要统计信息中知道航空乘客样本的均值为 280.3。在命令行中输入 `sd(AirPassengers)` 会得到标准偏差,在 RStudio 控制台中可以看到:
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/r_sd-air-passengers.png?itok=d-25fQoz)
接下来,我生成了一个数据直方图,通过输入 `hist(AirPassengers);` 得到这会以图形的方式显示此数据集RStudio 可以将数据导出为 PNG、PDF、JPEG、TIFF、SVG、EPS 或 BMP。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/r_histogram-air-passengers.png?itok=0HWsseQE)
除了生成统计数据和图形数据外R 还记录了我所有的历史操作。这使得我能够返回先前的操作,并且我可以保存此历史记录以供将来参考。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/r_history.png?itok=50jaFPU4)
在 RStudio 的脚本编辑器中,我可以编写我发出的所有命令的脚本,然后保存该脚本以便在我的数据更改后能再次运行,或者想重新访问它。
![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/r_script-editor.png?itok=eiE1_bnX)
### 获得帮助
在 R 提示符下输入 `help()` 可以很容易找到帮助信息。输入你正在寻找的信息的特定主题可以找到具体的帮助信息,例如 `help(sd)` 可以获得有关标准差的帮助。通过在提示符处输入 `contributors()` 可以获得有关 R 项目贡献者的信息。您可以通过在提示符处输入 `citation()` 来了解如何引用 R。通过在提示符出输入 `license()` 可以很容易地获得 R 的许可证信息。
R 是在 GNU General Public License1991 年 6 月的版本 2或者 2007 年 6 月的版本 3的条款下发布的。有关 R 许可证的更多信息,请参考 [R 项目官网][20]。
另外RStudio 在 GUI 中提供了完美的帮助菜单。该区域包括 RStudio 快捷表(可作为 PDF 下载),[RStudio][21]的在线学习、RStudio 文档、支持和 [许可证信息][22]。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/2/getting-started-RStudio-IDE
作者:[Don Watkins][a]
译者:[szcf-weiya](https://github.com/szcf-weiya)
校对:[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/Analysis_of_variance
[2]:https://www.michael-j-gallagher.com/high-performance-computing
[3]:https://www.r-project.org/
[4]:https://cran.r-project.org/index.html
[5]:https://cran.r-project.org/
[6]:https://cran.r-project.org/bin/linux/
[7]:https://cran.r-project.org/bin/linux/redhat/README
[8]:https://cran.r-project.org/bin/macosx/
[9]:https://cran.r-project.org/bin/windows/
[10]:https://www.datacamp.com/onboarding/learn?from=home&technology=r
[11]:http://tryr.codeschool.com/levels/1/challenges/1
[12]:https://www.udemy.com/r-programming
[13]:https://nostarch.com/bookofr
[14]:https://opensource.com/article/17/10/no-starch
[15]:https://www.rstudio.com/
[16]:https://www.rstudio.com/products/rstudio/download/
[17]:http://www.r-tutor.com/r-introduction/vector
[18]:https://vincentarelbundock.github.io/Rdatasets/datasets.html
[19]:https://fred.stlouisfed.org/
[20]:https://www.r-project.org/Licenses/
[21]:https://www.rstudio.com/online-learning/#R
[22]:https://support.rstudio.com/hc/en-us/articles/217801078-What-license-is-RStudio-available-under-

View File

@@ -0,0 +1,95 @@
简单介绍 ldd 命令
=========================================
如果您的工作涉及到 Linux 中的可执行文件和共享库的知识,则需要了解几种命令行工具。其中之一是 `ldd` ,您可以使用它来访问共享对象依赖关系。在本教程中,我们将使用一些易于理解的示例来讨论此实用程序的基础知识。
请注意,这里提到的所有示例都已在 Ubuntu 16.04 LTS 上进行了测试。
### Linux ldd 命令
正如开头已经提到的,`ldd` 命令打印共享对象依赖关系。以下是该命令的语法:
```
ldd [option]... file...
```
下面是该工具的手册页对它作出的解释:
> ldd 会输出命令行指定的每个程序或共享对象所需的共享对象(共享库)。
以下使用问答的方式让您更好地了解ldd的工作原理。
### 问题一、 如何使用 ldd 命令?
`ldd` 的基本用法非常简单,只需运行 `ldd` 命令以及可执行文件或共享对象的文件名称作为输入。
```
ldd [object-name]
```
例如:
```
ldd test
```
[![How to use ldd](https://www.howtoforge.com/images/command-tutorial/ldd-basic.png)](https://www.howtoforge.com/images/command-tutorial/big/ldd-basic.png)
所以你可以看到所有的共享库依赖已经在输出中产生了。
### Q2、 如何使 ldd 在输出中生成详细的信息?
如果您想要 `ldd` 生成详细信息,包括符号版本控制数据,则可以使用 `-v` 命令行选项。例如,该命令
```
ldd -v test
```
当使用 `-v` 命令行选项时,在输出中产生以下内容:
[![How to make ldd produce detailed information in output](https://www.howtoforge.com/images/command-tutorial/ldd-v-option.png)](https://www.howtoforge.com/images/command-tutorial/big/ldd-v-option.png)
### Q3、 如何使 ldd 产生未使用的直接依赖关系?
对于这个信息,使用 `-u` 命令行选项。这是一个例子:
```
ldd -u test
```
[![How to make ldd produce unused direct dependencies](https://www.howtoforge.com/images/command-tutorial/ldd-u-test.png)](https://www.howtoforge.com/images/command-tutorial/big/ldd-u-test.png)
### Q4、 如何让 ldd 执行重定位?
您可以在这里使用几个命令行选项:`-d``-r`。 前者告诉 `ldd` 执行数据重定位,后者则使 `ldd` 为数据对象和函数执行重定位。在这两种情况下,该工具都会报告丢失的 ELF 对象(如果有的话)。
```
ldd -d
ldd -r
```
### Q5、 如何获得关于ldd的帮助
`--help` 命令行选项使 `ldd` 为该工具生成有用的用法相关信息。
```
ldd --help
```
[![How get help on ldd](https://www.howtoforge.com/images/command-tutorial/ldd-help-option.png)](https://www.howtoforge.com/images/command-tutorial/big/ldd-help-option.png)
### 总结
`ldd` 不像 `cd``rm``mkdir` 这样的工具类别。这是因为它是为特定目的而构建的。该实用程序提供了有限的命令行选项,我们在这里介绍了其中的大部分。要了解更多信息,请前往 `ldd` 的[手册页](https://linux.die.net/man/1/ldd)。
---------
via: [https://www.howtoforge.com/linux-ldd-command/](https://www.howtoforge.com/linux-ldd-command/)
作者: [Himanshu Arora](https://www.howtoforge.com/)
选题: [lujun9972](https://github.com/lujun9972)
译者: [MonkeyDEcho](https://github.com/MonkeyDEcho)
校对: [wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出

View File

@@ -0,0 +1,149 @@
有用的 Bash 快捷键清单
======
![](https://www.ostechnix.com/wp-content/uploads/2018/02/Bash-720x340.jpg)
现如今,我在终端上花的时间更多,尝试在命令行完成比在图形界面更多的工作。随着时间推移,我学了许多 BASH 的技巧。这是一份每个 Linux 用户都应该知道的 BASH 快捷键,这样在终端做事就会快很多。我不会说这是一份完全的 BASH 快捷键清单,但是这足够让你的 BASH shell 操作比以前更快了。学习更快地使用 BASH 不仅节省了更多时间,也让你因为学到了有用的知识而感到自豪。那么,让我们开始吧。
### ALT 快捷键
1. `ALT+A` 光标移动到行首。
2. `ALT+B` 光标移动到所在单词词首。
3. `ALT+C` 终止正在运行的命令/进程。与 `CTRL+C` 相同。
4. `ALT+D` 关闭空的终端(也就是它会关闭没有输入的终端)。也删除光标后的全部字符。
5. `ALT+F` 移动到光标所在单词词末。
6. `ALT+T` 交换最后两个单词。
7. `ALT+U` 将单词内光标后的字母转为大写。
8. `ALT+L` 将单词内光标后的字母转为小写。
9. `ALT+R` 撤销对从历史记录中带来的命令的修改。
正如你在上面输出所见,我使用反向搜索拉取了一个指令,并更改了那个指令的最后一个字母,并使用 `ALT+R` 撤销了更改。
10. `ALT+.` (注意末尾的点号) 使用上一条命令的最后一个单词。
如果你想要对多个命令进行相同的操作的话,你可以使用这个快捷键来获取前几个指令的最后一个单词。例如,我需要使用 `ls -r` 命令输出以文件名逆序排列的目录内容。同时,我也想使用 `uname -r` 命令来查看我的内核版本。在这两个命令中,相同的单词是 `-r` 。这就是需要 `ALT+.` 的地方。快捷键很顺手。首先运行 `ls -r` 来按文件名逆序输出,然后在其他命令,比如 `uname` 中使用最后一个单词 `-r`
### CTRL 快捷键
1. `CTRL+A` 快速移动到行首。
我们假设你输入了像下面这样的命令。当你在第 N 行时,你发现在行首字符有一个输入错误
```
$ gind . -mtime -1 -type
```
注意到了吗?上面的命令中我输入了 `gind` 而不是 `find` 。你可以通过一直按着左箭头键定位到第一个字母然后用 `g` 替换 `f` 。或者,仅通过 `CTRL+A` 或 `HOME` 键来立刻定位到行首,并替换拼错的单词。这将节省你几秒钟的时间。
2. `CTRL+B` 光标向前移动一个字符。
这个快捷键可以使光标向前移动一个字符,即光标前的一个字符。或者,你可以使用左箭头键来向前移动一个字符。
3. `CTRL+C` 停止当前运行的命令。
如果一个命令运行时间过久,或者你误运行了,你可以通过使用 `CTRL+C` 来强制停止或退出。
4. `CTRL+D` 删除光标后的一个字符。
如果你的系统退格键无法工作的话,你可以使用 `CTRL+D` 来删除光标后的一个字符。这个快捷键也可以让你退出当前会话,和 exit 类似。
5. `CTRL+E` 移动到行末。
当你修正了行首拼写错误的单词,按下 `CTRL+E` 来快速移动到行末。或者,你也可以使用你键盘上的 `END` 键。
6. `CTRL+F` 光标向后移动一个字符。
如果你想将光标向后移动一个字符的话,按 `CTRL+F` 来替代右箭头键。
7. `CTRL+G` 退出历史搜索模式,不运行命令。
正如你在上面的截图看到的,我进行了反向搜索,但是我执行命令,并退出了历史搜索模式。
8. `CTRL+H` 删除光标签的一个字符,和退格键相同。
9. `CTRL+J` 和 ENTER/RETURN 键相同。
回车键不工作?没问题! `CTRL+J` 或 `CTRL+M` 可以用来替换回车键。
10. `CTRL+K` 删除光标后的所有字符。
你不必一直按着删除键来删除光标后的字符。只要按 `CTRL+K` 就能删除光标后的所有字符。
11. `CTRL+L` 清空屏幕并重新显示当前行。
别输入 `clear` 来清空屏幕了。只需按 `CTRL+M` 即可清空并重新显示当前行。
12. `CTRL+M` 和 `CTRL+J` 或 RETURN键相同。
13. `CTRL+N` 在命令历史中显示下一行。
你也可以使用下箭头键。
14. `CTRL+O` 运行你使用反向搜索时发现的命令,即 CTRL+R。
15. `CTRL+P` 显示命令历史的上一条命令。
你也可以使用上箭头键。
16. `CTRL+R` 向后搜索历史记录(反向搜索)。
17. `CTRL+S` 向前搜索历史记录。
18. `CTRL+T` 交换最后两个字符。
这是我最喜欢的一个快捷键。假设你输入了 `sl` 而不是 `ls` 。没问题!这个快捷键会像下面这张截图一样交换字符。
![][2]
19. `CTRL+U` 删除光标前的所有字符(从光标后的点删除到行首)。
这个快捷键立刻删除前面的所有字符。
20. `CTRL+V` 逐字显示输入的下一个字符。
21. `CTRL+W` 删除光标前的一个单词。
不要和 CTRL+U 弄混了。CTRL+W 不会删除光标前的所有东西,而是只删除一个单词。
![][3]
22. `CTRL+X` 列出当前单词可能的文件名补全。
23. `CTRL+XX` 移动到行首位置(再移动回来)。
24. `CTRL+Y` 恢复你上一个删除或剪切的条目。
记得吗,我们在第 21 个命令用 `CTRL+W` 删除了单词“-al”。你可以使用 `CTRL+Y` 立刻恢复。
![][4]
看见了吧?我没有输入“-al”。取而代之我按了 `CTRL+Y` 来恢复它。
25. `CTRL+Z` 停止当前的命令。
你也许很了解这个快捷键。它终止了当前运行的命令。你可以在前台使用 `fg` 或在后台使用 `bg` 来恢复它。
26. `CTRL+[` 和 `ESC` 键等同。
### 杂项
1. `!!` 重复上一个命令。
2. `ESC+t` 交换最后两个单词。
这就是我所能想到的了。将来我遇到 Bash 快捷键时我会持续添加的。如果你觉得文章有错的话,请在下方的评论区留言。我会尽快更新。
Cheers!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/list-useful-bash-keyboard-shortcuts/
作者:[SK][a]
译者:[heart4lor](https://github.com/heart4lor)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.ostechnix.com/author/sk/
[2]:http://www.ostechnix.com/wp-content/uploads/2018/02/CTRLT-1.gif
[3]:http://www.ostechnix.com/wp-content/uploads/2018/02/CTRLW-1.gif
[4]:http://www.ostechnix.com/wp-content/uploads/2018/02/CTRLY-1.gif

View File

@@ -0,0 +1,69 @@
Linux 如何成为我的工作
======
> IBM 工程师 Phil Estes 分享了他的 Linux 爱好如何使他成为了一位开源领袖、贡献者和维护者。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/linux_penguin_green.png?itok=ENdVzW22)
从很早很早以前起,我就一直使用开源软件。那个时候,没有所谓的社交媒体。没有火狐,没有谷歌浏览器(甚至连谷歌也没有),没有亚马逊,甚至几乎没有互联网。事实上,那个时候最热门的是最新的 Linux 2.0 内核。当时的技术挑战是什么?嗯,是 Linux 发行版本中旧的 [a.out][2] 格式被 [ELF 格式][1]代替,导致升级一些 [Linux][3] 的安装可能有些棘手。
我如何将我自己对这个初出茅庐的年轻操作系统的兴趣转变为开源事业是一个有趣的故事。
### Linux 为乐趣为生,而非利益
1994 年我大学毕业时,计算机实验室是 UNIX 系统的小型网络如果你幸运的话它们会连接到这个叫做互联网的新东西上。我知道这难以置信那时“Web”就是所知道的那个大多是手写的 HTML`cgi-bin` 目录是启用动态 Web 交互的一个新平台。我们许多人对这些新技术感到兴奋,我们还自学了 shell 脚本、[Perl][4]、HTML以及所有我们在父母的 Windows 3.1 PC 上从没有见过的简短的 UNIX 命令。
毕业后,我加入 IBM工作在一个不能访问 UNIX 系统的 PC 操作系统上,不久,我的大学切断了我通往工程实验室的远程通道。我该如何继续通过 [Pine][6] 使用 `vi``ls` 读我的电子邮件的呢?我一直听说开源 Linux但我还没有时间去研究它。
1996 年,我在德克萨斯大学奥斯丁分校开始读硕士学位。我知道这将涉及编程和写论文,不知道还有什么,但我不想使用专有的编辑器,编译器或者文字处理器。我想要的是我的 UNIX 体验!
所以我拿了一个旧电脑,找到了一个 Linux 发行版本 Slackware 3.0,在我的 IBM 办公室下载了一张又一张的软盘。可以说我在第一次安装 Linux 后就没有回过头了。在最初的那些日子里,我学习了很多关于 Makefile 和 `make` 系统、构建软件、补丁还有源码控制的知识。虽然我开始使用 Linux 只是为了兴趣和个人知识,但它最终改变了我的职业生涯。
虽然我是一个愉快的 Linux 用户,但我认为开源开发仍然是其他人的工作;我觉得在线邮件列表都是神秘的 [UNIX][7] 极客的。我很感激像 Linux HOWTO 这样的项目,它们在我尝试添加软件包、升级 Linux 版本,或者安装新硬件和新 PC 的设备驱动程序撞得鼻青脸肿时帮助了我。但是要处理源代码并进行修改或提交到上游……那是别人的事,不是我。
### Linux 如何成为我的工作
1999 年,我终于有理由把我对 Linux 的个人兴趣与我在 IBM 的日常工作结合起来了。我接了一个研究项目,将 IBM 的 Java 虚拟机JVM移植到 Linux 上。为了确保我们在法律上是安全的IBM 购买了一个塑封的盒装的 Red Hat Linux 6.1 副本来完成这项工作。在 IBM 东京研究实验室工作时,为了编写我们的 JVM 即时编译器JIT参考了 AIX JVM 源代码和 Windows 及 OS/2 的 JVM 源代码,我们在几周内就有了一个可以工作在 Linux 上的 JVM击败了 SUN 公司官方宣告花了几个月才把 Java 移植到 Linux。既然我在 Linux 平台上做得了开发,我就更喜欢它了。
到 2000 年IBM 使用 Linux 的频率迅速增加。由于 [Dan Frye][8] 的远见和坚持IBM 在 Linux 上下了“[一亿美元的赌注][9]”,在 1999 年创建了 Linux 技术中心LTC。在 LTC 里面有内核开发者、开源贡献者、IBM 硬件设备的驱动程序编写者,以及各种各样的针对 Linux 的开源工作。比起留在与 LTC 联系不大的部门,我更想要成为这个令人兴奋的 IBM 新天地的一份子。
从 2003 年到 2013 年我深度参与了 IBM 的 Linux 战略和 Linux 发行版(在 IBM 内部)的使用,最终组成了一个团队成为大约 60 个产品的信息交换所Linux 的使用涉及了 IBM 每个部门。我参与了收购,期望每个设备、管理系统和虚拟机或者基于物理设备的中间件都能运行 Linux。我开始熟悉 Linux 发行版的构建,包括打包、选择上游来源、开发发行版维护的补丁集、做定制,并通过我们的发行版合作伙伴提供支持。
由于我们的下游供应商,我很少提交补丁到上游,但我通过配合 [Ulrich Drepper][10] (将一个小补丁提交到 glibc和改变[时区数据库][11]的工作贡献了自己的力量Arthur David Olson 在 NIH 的 FTP 站点维护它的时候接受了这个改变)。但我仍然没有把开源项目的正式贡献者的工作来当做我的工作的一部分。是该改变这种情况的时候了。
在 2013 年末,我加入了 IBM 在开源社区的云组织,并正在寻找一个上游社区参与进来。我会在 Cloud Foundry 工作,还是会加入 IBM 为 OpenStack 贡献的大组中呢?都不是,因为在 2014 年 Docker 席卷了全球IBM 要我们几个参与到这个热门的新技术。我在接下来的几个月里,经历了许多的第一次:使用 GitHub比起只是 `git clone` [学习了关于 Git 的更多知识][12],做过 Pull Request 的审查,用 Go 语言写代码,等等。在接下来的一年中,我在 Docker 引擎项目上成为一个维护者,为 Dockr 创造下一版的镜像规范(支持多个架构),并在一个关于容器技术的会议上出席和讲话。
### 如今的我
一晃几年过去,我已经成为了包括 CNCF 的 [containerd][13] 项目在内的开源项目的维护者。我还创建了项目(如 [manifest-tool][14] 和 [bucketbench][15])。我也通过 OCI 参与了开源治理我现在是技术监督委员会的成员而在Moby 项目我是技术指导委员会的成员。我乐于在世界各地的会议、沙龙、IBM 内部发表关于开源的演讲。
开源现在是我在 IBM 职业生涯的一部分。我与工程师、开发人员和行业领袖的联系可能比我在 IBM 内认识的人的联系还要多。虽然开源与专有开发团队和供应商合作伙伴有许多相同的挑战,但据我的经验,开源与全球各地的人们的关系和联系远远超过困难。随着不同的意见、观点和经验的不断优化,可以对软件和涉及的在其中的人产生一种不断学习和改进的文化。
这个旅程 —— 从我第一次使用 Linux 到今天成为一个领袖、贡献者,和现在云原生开源世界的维护者 —— 我获得了极大的收获。我期待着与全球各地的人们长久的进行开源协作和互动。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/2/my-open-source-story-phil-estes
作者:[Phil Estes][a]
译者:[ranchong](https://github.com/ranchong)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/estesp
[1]:https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
[2]:https://en.wikipedia.org/wiki/A.out
[3]:https://opensource.com/node/19796
[4]:https://opensource.com/node/25456
[5]:https://opensource.com/node/35141
[6]:https://opensource.com/article/17/10/alpine-email-client
[7]:https://opensource.com/node/22781
[8]:https://www.linkedin.com/in/danieldfrye/
[9]:http://www-03.ibm.com/ibm/history/ibm100/us/en/icons/linux/
[10]:https://www.linkedin.com/in/ulrichdrepper/
[11]:https://en.wikipedia.org/wiki/Tz_database
[12]:https://linux.cn/article-9319-1.html
[13]:https://github.com/containerd/containerd
[14]:https://github.com/estesp/manifest-tool
[15]:https://github.com/estesp/bucketbench

View File

@@ -0,0 +1,113 @@
使用 Zim 在你的 Linux 桌面上创建一个维基
======
> 用强大而小巧的 Zim 在桌面上像维基一样管理信息。
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/OSDC_bees_network.png?itok=NFNRQpJi)
不可否认<ruby>维基<rt>wiki</rt></ruby>的用处,即使对于一个极客来说也是如此。你可以用它做很多事——写笔记和手稿,协作项目,建立完整的网站。还有更多的事。
这些年来,我已经使用了几个维基,要么是为了我自己的工作,要么就是为了我接到的各种合同和全职工作。虽然传统的维基很好,但我真的喜欢[桌面版维基][1] 这个想法。它们体积小,易于安装和维护,甚至更容易使用。而且,正如你可能猜到的那样,有许多可以用在 Linux 中的桌面版维基。
让我们来看看更好的桌面版的 维基 之一: [Zim][2]。
### 开始吧
你可以从 Zim 的官网[下载][3]并安装 Zim或者通过发行版的软件包管理器轻松地安装。
安装好了 Zim就启动它。
在 Zim 中的一个关键概念是<ruby>笔记本<rt>notebook</rt></ruby>,它们就像某个单一主题的维基页面的集合。当你第一次启动 Zim 时它要求你为你的笔记本指定一个文件夹和笔记本的名称。Zim 建议用 `Notes` 来表示文件夹的名称和指定文件夹为 `~/Notebooks/`。如果你愿意,你可以改变它。我是这么做的。
![](https://opensource.com/sites/default/files/u128651/zim1.png)
在为笔记本设置好名称和指定好文件夹后,单击 “OK” 。你得到的本质上是你的维基页面的容器。
![](https://opensource.com/sites/default/files/u128651/zim2.png)
### 将页面添加到笔记本
所以你有了一个容器。那现在怎么办?你应该开始往里面添加页面。当然,为此,选择 “File > New Page”。
![](https://opensource.com/sites/default/files/u128651/zim3.png)
输入该页面的名称,然后单击 “OK”。从那里开始你可以开始输入信息以向该页面添加信息。
![](https://opensource.com/sites/default/files/u128651/zim4.png)
这一页可以是你想要的任何内容:你正在选修的课程的笔记、一本书或者一片文章或论文的大纲,或者是你的书的清单。这取决于你。
Zim 有一些格式化的选项,其中包括:
* 标题
* 字符格式
* 圆点和编号清单
* 核对清单
你可以添加图片和附加文件到你的维基页面,甚至可以从文本文件中提取文本。
### Zim 的维基语法
你可以使用工具栏向一个页面添加格式。但这不是唯一的方法。如果你像我一样是个老派人士,你可以使用维基标记来进行格式化。
[Zim 的标记][4] 是基于在 [DokuWiki][5] 中使用的标记。它本质上是有一些小变化的 [WikiText][6] 。例如,要创建一个子弹列表,输入一个星号(`*`)。用两个星号包围一个单词或短语来使它加黑。
### 添加链接
如果你在笔记本上有一些页面,很容易将它们联系起来。有两种方法可以做到这一点。
第一种方法是使用 [驼峰命名法][7] 来命名这些页面。假设我有个叫做 “Course Notes” 的笔记本。我可以通过输入 “AnalysisCourse” 来重命名为我正在学习的数据分析课程。 当我想从笔记本的另一个页面链接到它时,我只需要输入 “AnalysisCourse” 然后按下空格键。即时超链接。
第二种方法是点击工具栏上的 “Insert link” 按钮。 在 “Link to” 中输入你想要链接到的页面的名称,从显示的列表中选择它,然后点击 “Link”。
![](https://opensource.com/sites/default/files/u128651/zim5.png)
我只能在同一个笔记本中的页面之间进行链接。每当我试图连接到另一个笔记本中的一个页面时,这个文件(有 .txt 的后缀名)总是在文本编辑器中被打开。
### 输出你的维基页面
也许有一天你会想在别的地方使用笔记本上的信息 —— 比如,在一份文件或网页上。你可以将笔记本页面导出到以下格式中的任何一种。而不是复制和粘贴(和丢失格式):
* HTML
* LaTeX
* Markdown
* ReStructuredText
为此,点击你想要导出的维基页面。然后,选择 “File > Export”。决定是要导出整个笔记本还是一个页面然后点击 “Forward”。
![](https://opensource.com/sites/default/files/u128651/zim6.png)
选择要用来保存页面或笔记本的文件格式。使用 HTML 和 LaTeX你可以选择一个模板。 随便看看什么最适合你。 例如,如果你想把你的维基页面变成 HTML 演示幻灯片,你可以在 “Template” 中选择 “SlideShow s5”。 如果你想知道,这会产生由 [S5 幻灯片框架][8]驱动的幻灯片。
![](https://opensource.com/sites/default/files/u128651/zim7.png)
点击 “Forward”如果你在导出一个笔记本你可以选择将页面作为单个文件或一个文件导出。 你还可以指向要保存导出文件的文件夹。
![](https://opensource.com/sites/default/files/u128651/zim8.png)
### Zim 能做的就这些吗?
远远不止这些,还有一些 [插件][9] 可以扩展它的功能。它甚至包含一个内置的 Web 服务器,可以让你将你的笔记本作为静态的 HTML 文件。这对于在内部网络上分享你的页面和笔记本是非常有用的。
总的来说Zim 是一个用来管理你的信息的强大而又紧凑的工具。这是我使用过的最好的桌面版维基,而且我一直在使用它。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/2/create-wiki-your-linux-desktop-zim
作者:[Scott Nesbitt][a]
译者:[Auk7F7](https://github.com/Auk7F7)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/scottnesbitt
[1]:https://opensource.com/article/17/2/3-desktop-wikis
[2]:http://zim-wiki.org/
[3]:http://zim-wiki.org/downloads.html
[4]:http://zim-wiki.org/manual/Help/Wiki_Syntax.html
[5]:https://www.dokuwiki.org/wiki:syntax
[6]:http://en.wikipedia.org/wiki/Wikilink
[7]:https://en.wikipedia.org/wiki/Camel_case
[8]:https://meyerweb.com/eric/tools/s5/
[9]:http://zim-wiki.org/manual/Plugins.html

View File

@@ -0,0 +1,142 @@
可以运行在 Windows 10 中的最实用的 Linux 命令
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-commands.png?itok=91oEXdO8)
在本系列早先的文章中,我们讨论了关于如何在 [Windows 10 上开启 WSL 之旅][1] 的内容。作为本系列的最后一篇文章,我们准备探讨一些能在 Windows 10 上广泛使用的 Linux 命令。
话题深入之前,请先让我们明确本教程所适用的人群。本文适用于使用 Windows 10 系统,但是又想在 Azure、AWS 或是私有云平台上学习 Linux 的初级开发者。换句话说,就是为了帮助初次接触 Linux 系统的 Windows 10 用户。
您的工作任务决定了您所需要的命令,而我的需求可能和您的不一样。本文旨在帮助您在 Windwos 10 上舒服的使用 Linux。不过请牢记WSL 并不提供硬件访问的功能比如声卡、GPU至少官方是这么描述的。但是这可能并不能阻止 Linux 用户的折腾精神。很多用户不仅完成了硬件访问,甚至已经在 Windows 10 上安装上了 Linux 桌面程序。但是本文并不会涉及这些内容,我们可能会讨论这些,但不是现在。
下面是我们需要着手的任务。
### 如何让您的 Linux 系统保持到最新的版本
因为 Linux 运行在了 Windows 系统中,所以您将被剥夺 Linux 系统所提供的所有安全特性。另外,如果不及时给 Linux 系统打补丁,你的 Windows 设备将被迫暴露在外界威胁中,所以还请保持您的 Linux 为最新版本。
WSL 官方支持 openSUSE/SUSE Linux Enterprise 和 Ubuntu。您也可以安装其他发行版但是我只需要它们当中的二者之一就可以完成我的所有工作毕竟我只需要访问一些 Linux 基础程序。
**更新 openSUSE Leap**
```
sudo zypper up
```
如果您想升级系统,您可以运行下面的命令:
```
sudo zypper dup
```
**更新 Ubuntu**
```
sudo apt-get update
sudo apt-get dist-upgrade
```
这样你就安全了,由于 Linux 系统的更新是渐进式的,所以更新系统成为了我的日常。不像 Windows 10 的更新通常需要重启系统,而 Linux 不同,一般只有 KB 或是 MB 级的更新,无需重启。
### 管理文件目录
系统更新之后,我们来看看一些或普通或不太普通的任务。
系统更新之外的第二重要的任务是使用 Linux 管理本地和远程文件。我承认我更青睐图形界面程序,但是终端能提供更可靠、更有价值的服务。要不你使用资源管理器移动 1 TB 的文件试试?我通常使用 `rsync` 命令来移动大量文件。如果中断任务,`rsync` 可以在上次停止的位置继续工作。
虽然您可能更习惯使用 `cp` 或是 `mv` 命令复制、移动文件,但是我还是喜欢灵活的 `rsync` 命令,了解 `rsync` 对远程文件传输也有帮助。使用 `rsync` 大半为了完成下面三个任务:
**使用 rsync 复制整个目录:**
```
rsync -avzP /source-directory /destination directory
```
**使用 rsync 移动文件:**
```
rsync --remove-source-files -avzP /source-directory /destination-directory
```
在成功复制目标目录之后,此命令将删除源文件。
**使用 rsync 同步文件:**
我的文件可能在多处存储。但是,我只会在主要位置中增加或是删除。如果不使用专业的软件,同步文件可能会给用户带来挑战,而 `rsync` 刚好可以简化这个过程。这个命令可以让两个目录文件内容同步。不过要注意,这是一个单向同步,即从源位置同步到目标位置。
```
rsync --delete -avzP /source-directory /destination-directory
```
如果源目录中没有找到文件,上述命令将删除目标目录中的文件。换言之,它创建了源目录的一个镜像。
### 文件自动备份
保持文件备份是一项乏味的工作。为了保持我的设备的完全同步,我运行了一个 cron 作业在夜间保持我的所有目录同步。不过我会留一个外部驱动器,基本上每周我都会手动同步一次。由于可能删掉我不想删除的文件,所以我并没有使用 `--delete` 选项。我会根据情况手动决定是否使用这个选项。
**创建 cron 作业,打开 crontab**
```
crontab -e
```
移动大文件时,我会选择在系统空闲的深夜执行该命令。此命令将在每天早上 1 点运行,您大概可以这样修改它:
```
# 0 1 * * * rsync -avzP /source-directory /destination-directory
```
这是使用 crontab 的定时作业的命令结构:
```
# m h dom mon dow command
```
在此,`m` = 分钟,`h` = 小时,`dom` = 本月的某天,`mon` = 月,`dow` = 本周的某天。
我们将在每天早上 1 点运行这条命令。您可以选择 `dow` 或是 `dom`(比如,每月 5 号)等。您可以在 [这里][2] 阅读更多相关内容。
### 管理远程服务器
在 Windows 系统上使用 WSL 的优势之一就是能方便管理云上的 Linux 服务器WSL 能提供原生的 Linux 工具给您。首先,您需要使用 `ssh` 命令登录远程 Linux 服务器。
比如,我的服务器 ip 是 192.168.0.112;端口为 2018不是默认的 22 端口Linux 用户名是 swapnil密码是 “就不告诉你”。
```
ssh -p2018 swapnil@192.168.0.112
```
它会向您询问用户密码,然后您就可以登录到 Linux 服务器了。现在您可以在 Linux 服务器上执行任意您想执行的所有操作了。不需使用 PuTTY 程序了。
使用 `rsync` ,您可以很轻易的在本地机器和远程机器之间传输文件。源目录还是目标目录取决于您是上传文件到服务器,还是下载文件到本地目录,您可以使用 `username@IP-address-of-server:/path-of-directory` 来指定目录。
如果我想复制一些文本内容到服务器的 home 目录,命令如下:
```
rsync -avzP /source-directory-on-local-machine ssh -p2018 swapnil@192.168.0.112:/home/swapnil/Documents/
```
这将会复制这些文件到远程服务器中 `Documents` 目录。
### 总结
本教程主要是为了证明您可以在 Windows 10 系统上通过 WSL 完成 Linux 方面的很大一部分的任务。通常来说它提高了生产效率。现在Linux 的世界已经向 Windwos 10 系统张开怀抱了,尽情探索吧。如果您有任何疑问,或是想了解 WSL 涉及到的其他层面,欢迎在下方的评论区分享您的想法。
在 [Administering Linux on Azure (LFS205)][4] 课程中了解更多,可以在 [这里][5] 注册。
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/learn/2018/3/most-useful-linux-commands-you-can-run-windows-10
作者:[SAPNIL BHARTIYA][a]
译者:[CYLeft](https://github.com/CYLeft)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/arnieswap
[1]:https://www.linux.com/blog/learn/2018/2/how-get-started-using-wsl-windows-10
[2]:http://www.adminschoice.com/crontab-quick-reference
[3]:mailto:username@IP
[4]:https://training.linuxfoundation.org/linux-courses/system-administration-training/administering-linux-on-azure
[5]:http://bit.ly/2FpFtPg

View File

@@ -0,0 +1,127 @@
通过玩命令行游戏来测试你的 BASH 技能
=====
![](https://www.ostechnix.com/wp-content/uploads/2018/03/Test-your-bash-skills-1-720x340.png)
如果我们经常在实际场景中使用 Linux 命令,我们就会更有效的学习和记忆它们。除非你经常使用 Linux 命令,否则你可能会在一段时间内忘记它们。无论你是新手还是老手,总会有一些趣味的方法来测试你的 BASH 技能。在本教程中,我将解释如何通过玩命令行游戏来测试你的 BASH 技能。其实从技术上讲,这些并不是像 Super TuxKart、极品飞车或 CS 等真正的游戏。这些只是 Linux 命令培训课程的游戏化版本。你将需要根据游戏本身的某些指示来完成一个任务。
现在,我们来看看几款能帮助你实时学习和练习 Linux 命令的游戏。这些游戏不是消磨时间或者令人惊诧的,这些游戏将帮助你获得终端命令的真实体验。请继续阅读:
### 使用 “Wargames” 来测试 BASH 技能
这是一个在线游戏,所以你必须联网。这些游戏可以帮助你以充满乐趣的游戏形式学习和练习 Linux 命令。Wargames 是一个 shell 游戏的集合,每款游戏有很多关卡。只有通过解决先前的关卡才能访问下一个关卡。不要担心!每个游戏都提供了有关如何进入下一关的清晰简洁说明。
要玩 Wargames请点击以下链接[Wargames][1] 。
![][2]
如你所见,左边列出了许多 shell 游戏。每个 shell 游戏都有自己的 SSH 端口。所以,你必须通过本地系统配置 SSH 连接到游戏,你可以在 Wargames 网站的左上角找到关于如何使用 SSH 连接到每个游戏的信息。
例如,让我们来玩 Bandit 游戏吧。为此,单击 Wargames 主页上的 Bandit 链接。在左上角,你会看到 Bandit 游戏的 SSH 信息。
![][3]
正如你在上面的屏幕截图中看到的,有很多关卡。要进入每个关卡,请单机左侧列中的相应链接。此外,右侧还有适合初学者的说明。如果你对如何玩此游戏有任何疑问,请阅读它们。
现在,让我们点击它进入关卡 0。在下一个屏幕中你将获得该关卡的 SSH 信息。
![][4]
正如你在上面的屏幕截图中看到的,你需要配置 SSH 端口 2220 连接 `bandit.labs.overthewire.org`,用户名是 `bandit0`,密码是 `bandit0`
让我们连接到 Bandit 游戏关卡 0。
```
$ ssh bandit0@bandit.labs.overthewire.org -p 2220
```
输入密码 `bandit0`
示例输出将是:
![][5]
登录后,输入 `ls` 命令查看内容或者进入关卡 1 页面,了解如何通过关卡 1 等等。建议的命令列表已在每个关卡提供。所以,你可以选择和使用任何合适的命令来解决每个关卡。
我必须承认Wargames 是令人上瘾的,并且解决每个关卡是非常有趣的。 尽管有些关卡确实很具挑战性,你可能需要谷歌才能知道如何解决问题。 试一试,你会很喜欢它。
### 使用 “Terminus” 来测试 BASH 技能
这是另一个基于浏览器的在线 CLI 游戏,可用于改进或测试你的 Linux 命令技能。要玩这个游戏,请打开你的 web 浏览器并导航到以下 URL[Play Terminus Game][9]
一旦你进入游戏,你会看到有关如何玩游戏的说明。与 Wargames 不同你不需要连接到它们的游戏服务器来玩游戏。Terminus 有一个内置的 CLI你可以在其中找到有关如何使用它的说明。
你可以使用命令 `ls` 查看周围的环境,使用命令 `cd 位置` 移动到新的位置,返回使用命令 `cd ..`,与这个世界进行交互使用命令 `less 项目` 等等。要知道你当前的位置,只需输入 `pwd`
![][6]
### 使用 “clmystery” 来测试 BASH 技能
与上述游戏不同,你可以在本地玩这款游戏。你不需要连接任何远程系统,这是完全离线的游戏。
相信我,这家伙是一个有趣的游戏。按照给定的说明,你将扮演一个侦探角色来解决一个神秘案件。
首先,克隆仓库:
```
$ git clone https://github.com/veltman/clmystery.git
```
或者,从 [这里][7] 将其作为 zip 文件下载。解压缩并切换到下载文件的地方。最后,通过阅读 `instructions` 文件来开启宝箱。
```
[sk@sk]: clmystery-master>$ ls
cheatsheet.md cheatsheet.pdf encoded hint1 hint2 hint3 hint4 hint5 hint6 hint7 hint8 instructions LICENSE.md mystery README.md solution
```
这里是玩这个游戏的说明:
终端城发生了一起谋杀案TCPD 需要你的帮助。你需要帮助它们弄清楚是谁犯罪了。
为了查明是谁干的,你需要到 `mystery` 子目录并从那里开始工作。你可能需要查看犯罪现场的所有线索( `crimescene` 文件)。现场的警官相当谨慎,所以他们在警官报告中写下了一切。幸运的是,警官以全部大写的 “CLUE” 一词把真正的线索标记了出来。
如果里遇到任何问题,请打开其中一个提示文件,例如 “hint1”“hint2” 等。你可以使用下面的 `cat` 命令打开提示文件。
```
$ cat hint1
$ cat hint2
```
要检查你的答案或找出解决方案,请在 `clmystery` 目录中打开文件 `solution`
```
$ cat solution
```
要了解如何使用命令行,请参阅 `cheatsheet.md``cheatsheet.pdf` (在命令行中,你可以输入 nano cheatsheet.md。请勿使用文本编辑器查看除 `instructions``cheatsheet``hint` 以外的任何文件。
有关更多详细信息,请参阅 [clmystery GitHub][8] 页面。
推荐阅读:
而这就是我现在所知道的。如果将来遇到任何问题,我会继续添加更多游戏。将此链接加入书签并不时访问。如果你知道其他类似的游戏,请在下面的评论部分告诉我,我将测试和更新本指南。
还有更多好东西,敬请关注!
干杯!
--------------------------------------------------------------------------------
via: https://www.ostechnix.com/test-your-bash-skills-by-playing-command-line-games/
作者:[SK][a]
译者:[MjSeven](https://github.com/MjSeven)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.ostechnix.com/author/sk/
[1]:http://overthewire.org/wargames/
[2]:http://www.ostechnix.com/wp-content/uploads/2018/03/Wargames-1.png
[3]:http://www.ostechnix.com/wp-content/uploads/2018/03/Bandit-game.png
[4]:http://www.ostechnix.com/wp-content/uploads/2018/03/Bandit-level-0.png
[5]:http://www.ostechnix.com/wp-content/uploads/2018/03/Bandit-level-0-ssh-1.png
[6]:http://www.ostechnix.com/wp-content/uploads/2018/03/Terminus.png
[7]:https://github.com/veltman/clmystery/archive/master.zip
[8]:https://github.com/veltman/clmystery
[9]:http://web.mit.edu/mprat/Public/web/Terminus/Web/main.html

View File

@@ -0,0 +1,99 @@
解读 ip 命令展示的网络连接信息
======
![](https://images.idgesg.net/images/article/2018/03/network-connections-100751906-large.jpg)
`ip` 命令可以告诉你很多网络连接配置和状态的信息,但是所有这些词和数字意味着什么? 让我们深入了解一下,看看所有显示的值都试图告诉你什么。
当您使用 `ip a`(或 `ip addr`)命令获取系统上所有网络接口的信息时,您将看到如下所示的内容:
```
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:1e:4f:c8:43:fc brd ff:ff:ff:ff:ff:ff
inet 192.168.0.24/24 brd 192.168.0.255 scope global dynamic enp0s25
valid_lft 57295sec preferred_lft 57295sec
inet6 fe80::2c8e:1de0:a862:14fd/64 scope link
valid_lft forever preferred_lft forever
```
这个系统上的两个接口 - 环回(`lo`)和网络(`enp0s25`)——显示了很多统计数据。 `lo` 接口显然是<ruby>环回地址<rt>loolback</rt></ruby>。 我们可以在列表中看到环回 IPv4 地址(`127.0.0.1`)和环回 IPv6`::1`)。 而普通的网络接口更有趣。
### 为什么是 enp0s25 而不是 eth0
如果你想知道为什么它在这个系统上被称为 `enp0s25`,而不是可能更熟悉的 `eth0`,那我们可以稍微解释一下。
新的命名方案被称为“<ruby>可预测的网络接口<rt>Predictable Network Interface</rt></ruby>”。 它已经在基于systemd 的 Linux 系统上使用了一段时间了。 接口名称取决于硬件的物理位置。 `en` 仅仅就是 “ethernet” 的意思,就像 “eth” 用于对应 `eth0`,一样。 `p` 是以太网卡的总线编号,`s` 是插槽编号。 所以 `enp0s25` 告诉我们很多我们正在使用的硬件的信息。
`<BROADCAST,MULTICAST,UP,LOWER_UP>` 这个配置串告诉我们:
```
BROADCAST 该接口支持广播
MULTICAST 该接口支持多播
UP 网络接口已启用
LOWER_UP 网络电缆已插入,设备已连接至网络
```
列出的其他值也告诉了我们很多关于接口的知识,但我们需要知道 `brd``qlen` 这些词代表什么意思。 所以,这里显示的是上面展示的 `ip` 信息的其余部分的翻译。
```
mtu 1500 最大传输单位数据包大小为1,500字节
qdisc pfifo_fast 用于数据包排队
state UP 网络接口已启用
group default 接口组
qlen 1000 传输队列长度
link/ether 00:1e:4f:c8:43:fc 接口的 MAC硬件地址
brd ff:ff:ff:ff:ff:ff 广播地址
inet 192.168.0.24/24 IPv4 地址
brd 192.168.0.255 广播地址
scope global 全局有效
dynamic enp0s25 地址是动态分配的
valid_lft 80866sec IPv4 地址的有效使用期限
preferred_lft 80866sec IPv4 地址的首选生存期
inet6 fe80::2c8e:1de0:a862:14fd/64 IPv6 地址
scope link 仅在此设备上有效
valid_lft forever IPv6 地址的有效使用期限
preferred_lft forever IPv6 地址的首选生存期
```
您可能已经注意到,`ifconfig` 命令提供的一些信息未包含在 `ip a` 命令的输出中 —— 例如传输数据包的统计信息。 如果您想查看发送和接收的数据包数量以及冲突数量的列表,可以使用以下 `ip` 命令:
```
$ ip -s link show enp0s25
2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:1e:4f:c8:43:fc brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
224258568 418718 0 0 0 84376
TX: bytes packets errors dropped carrier collsns
6131373 78152 0 0 0 0
```
另一个 `ip` 命令提供有关系统路由表的信息。
```
$ ip route show
default via 192.168.0.1 dev enp0s25 proto static metric 100
169.254.0.0/16 dev enp0s25 scope link metric 1000
192.168.0.0/24 dev enp0s25 proto kernel scope link src 192.168.0.24 metric 100
```
`ip` 命令是非常通用的。 您可以从 `ip` 命令及其来自[Red Hat][1]的选项获得有用的备忘单。
--------------------------------------------------------------------------------
via: https://www.networkworld.com/article/3262045/linux/checking-your-network-connections-on-linux.html
作者:[Sandra Henry-Stocker][a]
译者:[Flowsnow](https://github.com/Flowsnow)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/
[1]:https://access.redhat.com/sites/default/files/attachments/rh_ip_command_cheatsheet_1214_jcs_print.pdf

View File

@@ -0,0 +1,113 @@
chkservice在 Linux 终端管理 systemd 单元的工具
================
systemd 意即<ruby>系统守护进程<rt>system daemon</rt></ruby>,是一个新的初始化系统和系统管理工具,它现在非常流行,大部分的 Linux 发行版开始使用这种新的初始化系统。
`systemctl` 是一个 systemd 的工具,它可以帮助我们管理 systemd 守护进程。 它控制系统的启动程序和服务,使用并行化方式,为启动的服务激活套接字和 D-Bus提供守护进程的按需启动使用 Linux 控制组跟踪进程,维护挂载和自动挂载点。
此外,它还提供了日志守护进程、用于控制基本系统配置的功能,如主机名、日期、地区、维护已登录用户列表和运行容器和虚拟机、系统帐户、运行时目录和设置,以及管理简单网络配置、网络时间同步、日志转发和名称解析的守护进程。
### 什么是 chkservice
[chkservice][1] 是一个基于 ncurses 的在终端中管理 systemd 单元的工具。它提供了一个非常全面的 systemd 服务的视图,使得它们非常容易修改。
只有拥有超级管理权限才能够改变 systemd 单元的状态和 sysv 系统启动脚本。
### 在 Linux 安装 chkservice
我们可以通过两种方式安装 `chkservice`,通过包安装或者手动安装。
对于 Debian/Ubuntu使用 [APT-GET 命令][2] 或 [APT 命令][3] 安装 `chkservice`
```
$ sudo add-apt-repository ppa:linuxenko/chkservice
$ sudo apt-get update
$ sudo apt-get install chkservice
```
对于 Arch Linux 系的系统,使用 [Yaourt 命令][4] 或 [Packer 命令][5] 从 AUR 库安装 `chkservice`
```
$ yaourt -S chkservice
$ packer -S chkservice
```
对于 Fedora使用 [DNF 命令][6] 安装 `chkservice`
```
$ sudo dnf copr enable srakitnican/default
$ sudo dnf install chkservice
```
对于 Debian 系系统,使用 [DPKG 命令][7] 安装 `chkservice`
```
$ wget https://github.com/linuxenko/chkservice/releases/download/0.1/chkservice_0.1.0-amd64.deb
$ sudo dpkg -i chkservice_0.1.0-amd64.deb
```
对于 RPM 系的系统,使用 [DNF 命令][8] 安装 `chkservice`
```
$ sudo yum install https://github.com/linuxenko/chkservice/releases/download/0.1/chkservice_0.1.0-amd64.rpm
```
### 如何使用 chkservice
只需输入以下命令即可启动 `chkservice` 工具。 输出分为四部分。
* **第一部分:** 这一部分显示了守护进程的状态,比如可用的 `[X]` 或者不可用的 `[ ]` 或者静态的 `[s]` 或者被掩藏的 `-m-`
* **第二部分:** 这一部分显示守护进程的状态例如开始 `>` 或者停止 `=`
* **第三部分:** 这一部分显示单元的名称
* **第四部分:** 这一部分简短地显示了守护进程的一些信息
```
$ sudo chkservice
```
![][10]
要查看帮助页面,按下 `?`。 这将向您显示管理 systemd 服务的可用选项。
![][11]
选择要启用或禁用的守护进程,然后点击空格键。
![][12]
选择你想开始或停止的守护进程,然后按下 `s`
![][13]
选择要重新启动的守护进程,然后按下 `r`,之后,您可以在顶部看到更新的提示。
![][14]
按下 `q` 退出。
--------------------------------------------------------------------------------
via: https://www.2daygeek.com/chkservice-a-tool-for-managing-systemd-units-from-linux-terminal/
作者:[Ramya Nuvvula][a]
译者:[amwps290](https://github.com/amwps290)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.2daygeek.com/author/ramya/
[1]:https://github.com/linuxenko/chkservice
[2]:https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/
[3]:https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/
[4]:https://www.2daygeek.com/install-yaourt-aur-helper-on-arch-linux/
[5]:https://www.2daygeek.com/install-packer-aur-helper-on-arch-linux/
[6]:https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/
[7]:https://www.2daygeek.com/dpkg-command-to-manage-packages-on-debian-ubuntu-linux-mint-systems/
[8]:https://www.2daygeek.com/rpm-command-examples/
[9]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
[10]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-1.png
[11]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-2.png
[12]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-3.png
[13]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-4.png
[14]:https://www.2daygeek.com/wp-content/uploads/2018/03/chkservice-to-manage-systemd-units-5.png