diff --git a/published/20090211 Page Cache the Affair Between Memory and Files.md b/published/20090211 Page Cache the Affair Between Memory and Files.md new file mode 100644 index 0000000000..726ea23041 --- /dev/null +++ b/published/20090211 Page Cache the Affair Between Memory and Files.md @@ -0,0 +1,86 @@ +页面缓存、内存和文件之间的那些事 +============================================================ + + +上一篇文章中我们学习了内核怎么为一个用户进程 [管理虚拟内存][2],而没有提及文件和 I/O。这一篇文章我们将专门去讲这个重要的主题 —— 页面缓存。文件和内存之间的关系常常很不好去理解,而它们对系统性能的影响却是非常大的。 + +在面对文件时,有两个很重要的问题需要操作系统去解决。第一个是相对内存而言,慢的让人发狂的硬盘驱动器,[尤其是磁盘寻道][3]。第二个是需要将文件内容一次性地加载到物理内存中,以便程序间*共享*文件内容。如果你在 Windows 中使用 [进程浏览器][4] 去查看它的进程,你将会看到每个进程中加载了大约 ~15MB 的公共 DLL。我的 Windows 机器上现在大约运行着 100 个进程,因此,如果不共享的话,仅这些公共的 DLL 就要使用高达 ~1.5 GB 的物理内存。如果是那样的话,那就太糟糕了。同样的,几乎所有的 Linux 进程都需要 ld.so 和 libc,加上其它的公共库,它们占用的内存数量也不是一个小数目。 + +幸运的是,这两个问题都用一个办法解决了:页面缓存 —— 保存在内存中的页面大小的文件块。为了用图去说明页面缓存,我捏造出一个名为 `render` 的 Linux 程序,它打开了文件 `scene.dat`,并且一次读取 512 字节,并将文件内容存储到一个分配到堆中的块上。第一次读取的过程如下: + +![Reading and the page cache](http://static.duartes.org/img/blogPosts/readFromPageCache.png) + +1. `render` 请求 `scene.dat` 从位移 0 开始的 512 字节。 +2. 内核搜寻页面缓存中 `scene.dat` 的 4kb 块,以满足该请求。假设该数据没有缓存。 +3. 内核分配页面帧,初始化 I/O 请求,将 `scend.dat` 从位移 0 开始的 4kb 复制到分配的页面帧。 +4. 内核从页面缓存复制请求的 512 字节到用户缓冲区,系统调用 `read()` 结束。 + +读取完 12KB 的文件内容以后,`render` 程序的堆和相关的页面帧如下图所示: + +![Non-mapped file read](http://static.duartes.org/img/blogPosts/nonMappedFileRead.png) + +它看起来很简单,其实这一过程做了很多的事情。首先,虽然这个程序使用了普通的读取(`read`)调用,但是,已经有三个 4KB 的页面帧将文件 scene.dat 的一部分内容保存在了页面缓存中。虽然有时让人觉得很惊奇,但是,**普通的文件 I/O 就是这样通过页面缓存来进行的**。在 x86 架构的 Linux 中,内核将文件认为是一系列的 4KB 大小的块。如果你从文件中读取单个字节,包含这个字节的整个 4KB 块将被从磁盘中读入到页面缓存中。这是可以理解的,因为磁盘通常是持续吞吐的,并且程序一般也不会从磁盘区域仅仅读取几个字节。页面缓存知道文件中的每个 4KB 块的位置,在上图中用 `#0`、`#1` 等等来描述。Windows 使用 256KB 大小的视图view,类似于 Linux 的页面缓存中的页面page。 + +不幸的是,在一个普通的文件读取中,内核必须拷贝页面缓存中的内容到用户缓冲区中,它不仅花费 CPU 时间和影响 [CPU 缓存][6],**在复制数据时也浪费物理内存**。如前面的图示,`scene.dat` 的内存被存储了两次,并且,程序中的每个实例都用另外的时间去存储内容。我们虽然解决了从磁盘中读取文件缓慢的问题,但是在其它的方面带来了更痛苦的问题。内存映射文件是解决这种痛苦的一个方法: + +![Mapped file read](http://static.duartes.org/img/blogPosts/mappedFileRead.png) + +当你使用文件映射时,内核直接在页面缓存上映射你的程序的虚拟页面。这样可以显著提升性能:[Windows 系统编程][7] 报告指出,在相关的普通文件读取上运行时性能提升多达 30% ,在 [Unix 环境中的高级编程][8] 的报告中,文件映射在 Linux 和 Solaris 也有类似的效果。这取决于你的应用程序类型的不同,通过使用文件映射,可以节约大量的物理内存。 + +对高性能的追求是永恒不变的目标,[测量是很重要的事情][9],内存映射应该是程序员始终要使用的工具。这个 API 提供了非常好用的实现方式,它允许你在内存中按字节去访问一个文件,而不需要为了这种好处而牺牲代码可读性。在一个类 Unix 的系统中,可以使用 [mmap][11] 查看你的 [地址空间][10],在 Windows 中,可以使用 [CreateFileMapping][12],或者在高级编程语言中还有更多的可用封装。当你映射一个文件内容时,它并不是一次性将全部内容都映射到内存中,而是通过 [页面故障][13] 来按需映射的。在 [获取][15] 需要的文件内容的页面帧后,页面故障句柄 [映射你的虚拟页面][14] 到页面缓存上。如果一开始文件内容没有缓存,这还将涉及到磁盘 I/O。 + +现在出现一个突发的状况,假设我们的 `render` 程序的最后一个实例退出了。在页面缓存中保存着 `scene.dat` 内容的页面要立刻释放掉吗?人们通常会如此考虑,但是,那样做并不是个好主意。你应该想到,我们经常在一个程序中创建一个文件,退出程序,然后,在第二个程序去使用这个文件。页面缓存正好可以处理这种情况。如果考虑更多的情况,内核为什么要清除页面缓存的内容?请记住,磁盘读取的速度要慢于内存 5 个数量级,因此,命中一个页面缓存是一件有非常大收益的事情。因此,只要有足够大的物理内存,缓存就应该保持全满。并且,这一原则适用于所有的进程。如果你现在运行 `render` 一周后, `scene.dat` 的内容还在缓存中,那么应该恭喜你!这就是什么内核缓存越来越大,直至达到最大限制的原因。它并不是因为操作系统设计的太“垃圾”而浪费你的内存,其实这是一个非常好的行为,因为,释放物理内存才是一种“浪费”。(LCTT 译注:释放物理内存会导致页面缓存被清除,下次运行程序需要的相关数据,需要再次从磁盘上进行读取,会“浪费” CPU 和 I/O 资源)最好的做法是尽可能多的使用缓存。 + +由于页面缓存架构的原因,当程序调用 [write()][16] 时,字节只是被简单地拷贝到页面缓存中,并将这个页面标记为“脏”页面。磁盘 I/O 通常并**不会**立即发生,因此,你的程序并不会被阻塞在等待磁盘写入上。副作用是,如果这时候发生了电脑死机,你的写入将不会完成,因此,对于至关重要的文件,像数据库事务日志,要求必须进行 [fsync()][17](仍然还需要去担心磁盘控制器的缓存失败问题),另一方面,读取将被你的程序阻塞,直到数据可用为止。内核采取预加载的方式来缓解这个矛盾,它一般提前预读取几个页面并将它加载到页面缓存中,以备你后来的读取。在你计划进行一个顺序或者随机读取时(请查看 [madvise()][18]、[readahead()][19]、[Windows 缓存提示][20] ),你可以通过提示hint帮助内核去调整这个预加载行为。Linux 会对内存映射的文件进行 [预读取][21],但是我不确定 Windows 的行为。当然,在 Linux 中它可能会使用 [O_DIRECT][22] 跳过预读取,或者,在 Windows 中使用 [NO_BUFFERING][23] 去跳过预读,一些数据库软件就经常这么做。 + +一个文件映射可以是私有的,也可以是共享的。当然,这只是针对内存中内容的**更新**而言:在一个私有的内存映射上,更新并不会提交到磁盘或者被其它进程可见,然而,共享的内存映射,则正好相反,它的任何更新都会提交到磁盘上,并且对其它的进程可见。内核使用写时复制copy on write(CoW)机制,这是通过页面表条目page table entry(PTE)来实现这种私有的映射。在下面的例子中,`render` 和另一个被称为 `render3d` 的程序都私有映射到 `scene.dat` 上。然后 `render` 去写入映射的文件的虚拟内存区域: + +![The Copy-On-Write mechanism](http://static.duartes.org/img/blogPosts/copyOnWrite.png) + +1. 两个程序私有地映射 `scene.dat`,内核误导它们并将它们映射到页面缓存,但是使该页面表条目只读。 +2. `render` 试图写入到映射 `scene.dat` 的虚拟页面,处理器发生页面故障。 +3. 内核分配页面帧,复制 `scene.dat` 的第二块内容到其中,并映射故障的页面到新的页面帧。 +4. 继续执行。程序就当做什么都没发生。 + +上面展示的只读页面表条目并不意味着映射是只读的,它只是内核的一个用于共享物理内存的技巧,直到尽可能的最后一刻之前。你可以认为“私有”一词用的有点不太恰当,你只需要记住,这个“私有”仅用于更新的情况。这种设计的重要性在于,要想看到被映射的文件的变化,其它程序只能读取它的虚拟页面。一旦“写时复制”发生,从其它地方是看不到这种变化的。但是,内核并不能保证这种行为,因为它是在 x86 中实现的,从 API 的角度来看,这是有意义的。相比之下,一个共享的映射只是将它简单地映射到页面缓存上。更新会被所有的进程看到并被写入到磁盘上。最终,如果上面的映射是只读的,页面故障将触发一个内存段失败而不是写到一个副本。 + +动态加载库是通过文件映射融入到你的程序的地址空间中的。这没有什么可奇怪的,它通过普通的 API 为你提供与私有文件映射相同的效果。下面的示例展示了映射文件的 `render` 程序的两个实例运行的地址空间的一部分,以及物理内存,尝试将我们看到的许多概念综合到一起。 + +![Mapping virtual memory to physical memory](http://static.duartes.org/img/blogPosts/virtualToPhysicalMapping.png) + +这是内存架构系列的第三部分的结论。我希望这个系列文章对你有帮助,对理解操作系统的这些主题提供一个很好的思维模型。 + +-------------------------------------------------------------------------------- + +via:https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ + +作者:[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://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ +[2]:https://linux.cn/article-9393-1.html +[3]:https://manybutfinite.com/post/what-your-computer-does-while-you-wait +[4]:http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx +[5]:http://ld.so +[6]:https://manybutfinite.com/post/intel-cpu-caches +[7]:http://www.amazon.com/Windows-Programming-Addison-Wesley-Microsoft-Technology/dp/0321256190/ +[8]:http://www.amazon.com/Programming-Environment-Addison-Wesley-Professional-Computing/dp/0321525949/ +[9]:https://manybutfinite.com/post/performance-is-a-science +[10]:https://manybutfinite.com/post/anatomy-of-a-program-in-memory +[11]:http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html +[12]:http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx +[13]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2678 +[14]:http://lxr.linux.no/linux+v2.6.28/mm/memory.c#L2436 +[15]:http://lxr.linux.no/linux+v2.6.28/mm/filemap.c#L1424 +[16]:http://www.kernel.org/doc/man-pages/online/pages/man2/write.2.html +[17]:http://www.kernel.org/doc/man-pages/online/pages/man2/fsync.2.html +[18]:http://www.kernel.org/doc/man-pages/online/pages/man2/madvise.2.html +[19]:http://www.kernel.org/doc/man-pages/online/pages/man2/readahead.2.html +[20]:http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx#caching_behavior +[21]:http://lxr.linux.no/linux+v2.6.28/mm/filemap.c#L1424 +[22]:http://www.kernel.org/doc/man-pages/online/pages/man2/open.2.html +[23]:http://msdn.microsoft.com/en-us/library/cc644950(VS.85).aspx \ No newline at end of file diff --git a/published/20100419 10 Tools To Add Some Spice To Your UNIX-Linux Shell Scripts.md b/published/20100419 10 Tools To Add Some Spice To Your UNIX-Linux Shell Scripts.md new file mode 100644 index 0000000000..022f9229bd --- /dev/null +++ b/published/20100419 10 Tools To Add Some Spice To Your UNIX-Linux Shell Scripts.md @@ -0,0 +1,408 @@ +10 个增加 UNIX/Linux Shell 脚本趣味的工具 +====== + +有些误解认为 shell 脚本仅用于 CLI 环境。实际上在 KDE 或 Gnome 桌面下,你可以有效的使用各种工具编写 GUI 或者网络(socket)脚本。shell 脚本可以使用一些 GUI 组件(菜单、警告框、进度条等),你可以控制终端输出、光标位置以及各种输出效果等等。利用下面的工具,你可以构建强壮的、可交互的、对用户友好的 UNIX/Linux bash 脚本。 + +制作 GUI 应用不是一项困难的任务,但需要时间和耐心。幸运的是,UNIX 和 Linux 都带有大量编写漂亮 GUI 脚本的工具。以下工具是基于 FreeBSD 和 Linux 操作系统做的测试,而且也适用于其他类 UNIX 操作系统。 + +### 1、notify-send 命令 + +`notify-send` 命令允许你借助通知守护进程发送桌面通知给用户。这种避免打扰用户的方式,对于通知桌面用户一个事件或显示一些信息是有用的。在 Debian 或 Ubuntu 上,你需要使用 [apt 命令][1] 或 [apt-get 命令][2] 安装的包: + +```bash +sudo apt-get install libnotify-bin +``` + +CentOS/RHEL 用户使用下面的 [yum 命令][3]: + +```bash +sudo yum install libnotify +``` + +Fedora Linux 用户使用下面的 dnf 命令: + +```bash +`$ sudo dnf install libnotify` +In this example, send simple desktop notification from the command line, enter: +### 发送一些通知 ### +notify-send "rsnapshot done :)" +``` + +示例输出: + +![Fig:01: notify-send in action ][4] + +下面是另一个附加选项的代码: + +```bash +... +alert=18000 +live=$(lynx --dump http://money.rediff.com/ | grep 'BSE LIVE' | awk '{ print $5}' | sed 's/,//g;s/\.[0-9]*//g') +[ $notify_counter -eq 0 ] && [ $live -ge $alert ] && { notify-send -t 5000 -u low -i "BSE Sensex touched 18k"; notify_counter=1; } +... +``` + +示例输出: + +![Fig.02: notify-send with timeouts and other options][5] + +这里: + + * `-t 5000`:指定超时时间(毫秒) (5000 毫秒 = 5 秒) + * `-u low`: 设置紧急等级 (如:低、普通、紧急) + * `-i gtk-dialog-info`: 设置要显示的图标名称或者指定的图标(你可以设置路径为:`-i /path/to/your-icon.png`) + +关于更多使用 `notify-send` 功能的信息,请参考 man 手册。在命令行下输入 `man notify-send` 即可看见: + +```bash +man notify-send +``` + +### 2、tput 命令 + +`tput` 命令用于设置终端特性。通过 `tput` 你可以设置: + + * 在屏幕上移动光标。 + * 获取终端信息。 + * 设置颜色(背景和前景)。 + * 设置加粗模式。 + * 设置反转模式等等。 + +下面有一段示例代码: + +```bash +#!/bin/bash + +# clear the screen +tput clear + +# Move cursor to screen location X,Y (top left is 0,0) +tput cup 3 15 + +# Set a foreground colour using ANSI escape +tput setaf 3 +echo "XYX Corp LTD." +tput sgr0 + +tput cup 5 17 +# Set reverse video mode +tput rev +echo "M A I N - M E N U" +tput sgr0 + +tput cup 7 15 +echo "1. User Management" + +tput cup 8 15 +echo "2. Service Management" + +tput cup 9 15 +echo "3. Process Management" + +tput cup 10 15 +echo "4. Backup" + +# Set bold mode +tput bold +tput cup 12 15 +read -p "Enter your choice [1-4] " choice + +tput clear +tput sgr0 +tput rc +``` + +示例输出: + +![Fig.03: tput in action][6] + +关于 `tput` 命令的详细信息,参见手册: + +```bash +man 5 terminfo +man tput +``` + +### 3、setleds 命令 + +`setleds` 命令允许你设置键盘灯。下面是打开数字键灯的示例: + +```bash +setleds -D +num +``` + +关闭数字键灯,输入: + +```bash +setleds -D -num +``` + + * `-caps`:关闭大小写锁定灯 + * `+caps`:打开大小写锁定灯 + * `-scroll`:关闭滚动锁定灯 + * `+scroll`:打开滚动锁定灯 + +查看 `setleds` 手册可看见更多信息和选项 `man setleds`。 + +### 4、zenity 命令 + +[zenity 命令显示 GTK+ 对话框][7],并且返回用户输入。它允许你使用各种 Shell 脚本向用户展示或请求信息。下面是一个 `whois` 指定域名目录服务的 GUI 客户端示例。 + +```bash +#!/bin/bash +# Get domain name +_zenity="/usr/bin/zenity" +_out="/tmp/whois.output.$$" +domain=$(${_zenity} --title "Enter domain" \ + --entry --text "Enter the domain you would like to see whois info" ) + +if [ $? -eq 0 ] +then + # Display a progress dialog while searching whois database + whois $domain | tee >(${_zenity} --width=200 --height=100 \ + --title="whois" --progress \ + --pulsate --text="Searching domain info..." \ + --auto-kill --auto-close \ + --percentage=10) >${_out} + + # Display back output + ${_zenity} --width=800 --height=600 \ + --title "Whois info for $domain" \ + --text-info --filename="${_out}" +else + ${_zenity} --error \ + --text="No input provided" +fi +``` + +示例输出: + +![Fig.04: zenity in Action][8] + +参见手册获取更多 `zenity` 信息以及其他支持 GTK+ 的组件: + +```bash +zenity --help +man zenity +``` + +### 5、kdialog 命令 + +`kdialog` 命令与 `zenity` 类似,但它是为 KDE 桌面和 QT 应用设计。你可以使用 `kdialog` 展示对话框。下面示例将在屏幕上显示信息: + +```bash +kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found." +``` + +示例输出: + +![Fig.05: Suppressing the display of a dialog ][9] + +参见 《[KDE 对话框 Shell 脚本编程][10]》 教程获取更多信息。 + +### 6、Dialog + +[Dialog 是一个使用 Shell 脚本的应用][11],显示用户界面组件的文本。它使用 curses 或者 ncurses 库。下面是一个示例代码: + +```bash +#!/bin/bash +dialog --title "Delete file" \ +--backtitle "Linux Shell Script Tutorial Example" \ +--yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60 + +# Get exit status +# 0 means user hit [yes] button. +# 1 means user hit [no] button. +# 255 means user hit [Esc] key. +response=$? +case $response in + 0) echo "File deleted.";; + 1) echo "File not deleted.";; + 255) echo "[ESC] key pressed.";; +esac +``` + +参见 `dialog` 手册获取详细信息:`man dialog`。 + +#### 关于其他用户界面工具的注意事项 + +UNIX、Linux 提供了大量其他工具来显示和控制命令行中的应用程序,shell 脚本可以使用一些 KDE、Gnome、X 组件集: + + * `gmessage` - 基于 GTK xmessage 的克隆 + * `xmessage` - 在窗口中显示或询问消息(基于 X 的 /bin/echo) + * `whiptail` - 显示来自 shell 脚本的对话框 + * `python-dialog` - 用于制作简单文本或控制台模式用户界面的 Python 模块 + +### 7、logger 命令 + +`logger` 命令将信息写到系统日志文件,如:`/var/log/messages`。它为系统日志模块 syslog 提供了一个 shell 命令行接口: + +```bash +logger "MySQL database backup failed." +tail -f /var/log/messages +logger -t mysqld -p daemon.error "Database Server failed" +tail -f /var/log/syslog +``` + +示例输出: + +```bash +Apr 20 00:11:45 vivek-desktop kernel: [38600.515354] CPU0: Temperature/speed normal +Apr 20 00:12:20 vivek-desktop mysqld: Database Server failed +``` + +参见 《[如何写消息到 syslog 或 日志文件][12]》 获得更多信息。此外,你也可以查看 logger 手册获取详细信息:`man logger` + +### 8、setterm 命令 + +`setterm` 命令可设置不同的终端属性。下面的示例代码会强制屏幕在 15 分钟后变黑,监视器则 60 分钟后待机。 + +```bash +setterm -blank 15 -powersave powerdown -powerdown 60 +``` + +下面的例子将 xterm 窗口中的文本以下划线展示: + +```bash +setterm -underline on; +echo "Add Your Important Message Here" +setterm -underline off +``` + +另一个有用的选项是打开或关闭光标显示: + +```bash +setterm -cursor off +``` + +打开光标: + +```bash +setterm -cursor on +``` + +参见 setterm 命令手册获取详细信息:`man setterm` + +### 9、smbclient:给 MS-Windows 工作站发送消息 + +`smbclient` 命令可以与 SMB/CIFS 服务器通讯。它可以向 MS-Windows 系统上选定或全部用户发送消息。 + +```bash +smbclient -M WinXPPro </dev/tcp/localhost/25) &>/dev/null && echo "TCP port 25 open" || echo "TCP port 25 close" +``` + +下面的代码片段,你可以利用 [bash 循环找出已打开的端口][14]: + +```bash +echo "Scanning TCP ports..." +for p in {1..1023} +do + (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open" +done +``` + +示例输出: + +```bash +Scanning TCP ports... +22 open +53 open +80 open +139 open +445 open +631 open +``` + +下面的示例中,你的 bash 脚本将像 HTTP 客户端一样工作: + +```bash +#!/bin/bash +exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80 + +printf "GET / HTTP/1.0\r\n" >&3 +printf "Accept: text/html, text/plain\r\n" >&3 +printf "Accept-Language: en\r\n" >&3 +printf "User-Agent: nixCraft_BashScript v.%s\r\n" "${BASH_VERSION}" >&3 +printf "\r\n" >&3 + +while read LINE <&3 +do + # do something on $LINE + # or send $LINE to grep or awk for grabbing data + # or simply display back data with echo command + echo $LINE +done +``` + +参见 bash 手册获取更多信息:`man bash` + +### 关于 GUI 工具和 cron 任务的注意事项 + +如果你 [使用 crontab][15] 来启动你的脚本,你需要使用 `export DISPLAY=[用户机器]:0` 命令请求本地显示或输出服务。举个例子,使用 `zenity` 工具调用 `/home/vivek/scripts/monitor.stock.sh`: + +``` +@hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh +``` + +你有喜欢的可以增加 shell 脚本趣味的 UNIX 工具么?请在下面的评论区分享它吧。 + +### 关于作者 + +本文作者是 nixCraft 创始人、一个老练的系统管理员、Linux 操作系统和 UNIX shell 编程培训师。他服务来自全球的客户和不同的行业,包括 IT 、教育、防务和空间探索、还有非营利组织。你可以在 [Twitter][16],[Facebook][17],[Google+][18] 上面关注他。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/tips/spice-up-your-unix-linux-shell-scripts.html + +作者:[Vivek Gite][a] +译者:[pygmalion666](https://github.com/pygmalion666) +校对:[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/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info) +[4]:https://www.cyberciti.biz/media/new/tips/2010/04/notify-send.png (notify-send: Shell Script Get Or Send Desktop Notifications ) +[5]:https://www.cyberciti.biz/media/new/tips/2010/04/notify-send-with-icons-timeout.png (Linux / UNIX: Display Notifications From Your Shell Scripts With notify-send) +[6]:https://www.cyberciti.biz/media/new/tips/2010/04/tput-options.png (Linux / UNIX Script Colours and Cursor Movement With tput) +[7]:https://bash.cyberciti.biz/guide/Zenity:_Shell_Scripting_with_Gnome +[8]:https://www.cyberciti.biz/media/new/tips/2010/04/zenity-outputs.png (zenity: Linux / UNIX display Dialogs Boxes From The Shell Scripts) +[9]:https://www.cyberciti.biz/media/new/tips/2010/04/KDialog.png (Kdialog: Suppressing the display of a dialog ) +[10]:http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs +[11]:https://bash.cyberciti.biz/guide/Bash_display_dialog_boxes +[12]:https://www.cyberciti.biz/tips/howto-linux-unix-write-to-syslog.html +[13]:https://www.cyberciti.biz/tips/freebsd-sending-a-message-to-windows-workstation.html +[14]:https://www.cyberciti.biz/faq/bash-for-loop/ +[15]:https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/ +[16]:https://twitter.com/nixcraft +[17]:https://facebook.com/nixcraft +[18]:https://plus.google.com/+CybercitiBiz \ No newline at end of file diff --git a/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md b/published/20150703 Let-s Build A Simple Interpreter. Part 2..md similarity index 68% rename from translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md rename to published/20150703 Let-s Build A Simple Interpreter. Part 2..md index a22a94bae0..e9591cddd1 100644 --- a/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md +++ b/published/20150703 Let-s Build A Simple Interpreter. Part 2..md @@ -1,9 +1,9 @@ -让我们做个简单的解释器(2) +让我们做个简单的解释器(二) ====== -在一本叫做 《高效思考的 5 要素》 的书中,作者 Burger 和 Starbird 讲述了一个关于他们如何研究 Tony Plog 的故事,一个举世闻名的交响曲名家,为一些有才华的演奏者开创了一个大师班。这些学生一开始演奏复杂的乐曲,他们演奏的非常好。然后他们被要求演奏非常基础简单的乐曲。当他们演奏这些乐曲时,与之前所演奏的相比,听起来非常幼稚。在他们结束演奏后,老师也演奏了同样的乐曲,但是听上去非常娴熟。差别令人震惊。Tony 解释道,精通简单符号可以让人更好的掌握复杂的部分。这个例子很清晰 - 要成为真正的名家,必须要掌握简单基础的思想。 +在一本叫做 《高效思考的 5 要素》 的书中,作者 Burger 和 Starbird 讲述了一个关于他们如何研究 Tony Plog 的故事,他是一位举世闻名的交响曲名家,为一些有才华的演奏者开创了一个大师班。这些学生一开始演奏复杂的乐曲,他们演奏的非常好。然后他们被要求演奏非常基础简单的乐曲。当他们演奏这些乐曲时,与之前所演奏的相比,听起来非常幼稚。在他们结束演奏后,老师也演奏了同样的乐曲,但是听上去非常娴熟。差别令人震惊。Tony 解释道,精通简单音符可以让人更好的掌握复杂的部分。这个例子很清晰 —— 要成为真正的名家,必须要掌握简单基础的思想。 -故事中的例子明显不仅仅适用于音乐,而且适用于软件开发。这个故事告诉我们不要忽视繁琐工作中简单基础的概念的重要性,哪怕有时候这让人感觉是一种倒退。尽管熟练掌握一门工具或者框架非常重要,了解他们背后的原理也是极其重要的。正如 Palph Waldo Emerson 所说: +故事中的例子明显不仅仅适用于音乐,而且适用于软件开发。这个故事告诉我们不要忽视繁琐工作中简单基础的概念的重要性,哪怕有时候这让人感觉是一种倒退。尽管熟练掌握一门工具或者框架非常重要,了解它们背后的原理也是极其重要的。正如 Palph Waldo Emerson 所说: > “如果你只学习方法,你就会被方法束缚。但如果你知道原理,就可以发明自己的方法。” @@ -15,11 +15,11 @@ 2. 识别输入字符串中的多位整数 3. 做两个整数之间的减法(目前它仅能加减整数) - 新版本计算器的源代码在这里,它可以做到上述的所有事情: + ``` # 标记类型 -# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成 INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF' @@ -168,9 +168,10 @@ if __name__ == '__main__': main() ``` -把上面的代码保存到 calc2.py 文件中,或者直接从 [GitHub][2] 上下载。试着运行它。看看它是不是正常工作:它应该能够处理输入中任意位置的空白符;能够接受多位的整数,并且能够对两个整数做减法和加法。 +把上面的代码保存到 `calc2.py` 文件中,或者直接从 [GitHub][2] 上下载。试着运行它。看看它是不是正常工作:它应该能够处理输入中任意位置的空白符;能够接受多位的整数,并且能够对两个整数做减法和加法。 这是我在自己的笔记本上运行的示例: + ``` $ python calc2.py calc> 27 + 3 @@ -182,21 +183,21 @@ calc> 与 [第一部分][1] 的版本相比,主要的代码改动有: - 1. get_next_token 方法重写了很多。增加指针位置的逻辑之前是放在一个单独的方法中。 - 2. 增加了一些方法:skip_whitespace 用于忽略空白字符,integer 用于处理输入字符的多位整数。 - 3. expr 方法修改成了可以识别 “整数 -> 减号 -> 整数” 词组和 “整数 -> 加号 -> 整数” 词组。在成功识别相应的词组后,这个方法现在可以解释加法和减法。 + 1. `get_next_token` 方法重写了很多。增加指针位置的逻辑之前是放在一个单独的方法中。 + 2. 增加了一些方法:`skip_whitespace` 用于忽略空白字符,`integer` 用于处理输入字符的多位整数。 + 3. `expr` 方法修改成了可以识别 “整数 -> 减号 -> 整数” 词组和 “整数 -> 加号 -> 整数” 词组。在成功识别相应的词组后,这个方法现在可以解释加法和减法。 -[第一部分][1] 中你学到了两个重要的概念,叫做 **标记** 和 **词法分析**。现在我想谈一谈 **词法**, **解析**,和**解析器**。 +[第一部分][1] 中你学到了两个重要的概念,叫做 标记token词法分析lexical analyzer。现在我想谈一谈词法lexeme解析parsing解析器parser。 -你已经知道标记。但是为了让我详细的讨论标记,我需要谈一谈词法。词法是什么?**词法** 是一个标记中的字符序列。在下图中你可以看到一些关于标记的例子,还好这可以让它们之间的关系变得清晰: +你已经知道了标记。但是为了让我详细的讨论标记,我需要谈一谈词法。词法是什么?词法lexeme是一个标记token中的字符序列。在下图中你可以看到一些关于标记的例子,这可以让它们之间的关系变得清晰: ![][3] -现在还记得我们的朋友,expr 方法吗?我之前说过,这是数学表达式实际被解释的地方。但是你要先识别这个表达式有哪些词组才能解释它,比如它是加法还是减法。expr 方法最重要的工作是:它从 get_next_token 方法中得到流,并找出标记流的结构然后解释已经识别出的词组,产生数学表达式的结果。 +现在还记得我们的朋友,`expr` 方法吗?我之前说过,这是数学表达式实际被解释的地方。但是你要先识别这个表达式有哪些词组才能解释它,比如它是加法还是减法。`expr` 方法最重要的工作是:它从 `get_next_token` 方法中得到流,并找出该标记流的结构,然后解释已经识别出的词组,产生数学表达式的结果。 -在标记流中找出结构的过程,或者换种说法,识别标记流中的词组的过程就叫 **解析**。解释器或者编译器中执行这个任务的部分就叫做 **解析器**。 +在标记流中找出结构的过程,或者换种说法,识别标记流中的词组的过程就叫解析parsing。解释器或者编译器中执行这个任务的部分就叫做解析器parser。 -现在你知道 expr 方法就是你的解释器的部分,**解析** 和 **解释** 都在这里发生 - expr 方法首先尝试识别(**解析**)标记流里的 “整数 -> 加法 -> 整数” 或者 “整数 -> 减法 -> 整数” 词组,成功识别后 (**解析**) 其中一个词组,这个方法就开始解释它,返回两个整数的和或差。 +现在你知道 `expr` 方法就是你的解释器的部分,解析parsing解释interpreting都在这里发生 —— `expr` 方法首先尝试识别(解析)标记流里的 “整数 -> 加法 -> 整数” 或者 “整数 -> 减法 -> 整数” 词组,成功识别后 (解析了) 其中一个词组,这个方法就开始解释它,返回两个整数的和或差。 又到了练习的时间。 @@ -206,15 +207,12 @@ calc> 2. 扩展这个计算器,让它能够计算两个整数的除法 3. 修改代码,让它能够解释包含了任意数量的加法和减法的表达式,比如 “9 - 5 + 3 + 11” - - **检验你的理解:** 1. 词法是什么? 2. 找出标记流结构的过程叫什么,或者换种说法,识别标记流中一个词组的过程叫什么? 3. 解释器(编译器)执行解析的部分叫什么? - 希望你喜欢今天的内容。在该系列的下一篇文章里你就能扩展计算器从而处理更多复杂的算术表达式。敬请期待。 -------------------------------------------------------------------------------- @@ -223,12 +221,12 @@ via: https://ruslanspivak.com/lsbasi-part2/ 作者:[Ruslan Spivak][a] 译者:[BriFuture](https://github.com/BriFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://ruslanspivak.com -[1]:http://ruslanspivak.com/lsbasi-part1/ (Part 1) +[1]:https://linux.cn/article-9399-1.html [2]:https://github.com/rspivak/lsbasi/blob/master/part2/calc2.py [3]:https://ruslanspivak.com/lsbasi-part2/lsbasi_part2_lexemes.png [4]:https://ruslanspivak.com/lsbasi-part2/lsbasi_part2_exercises.png diff --git a/translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md b/published/20150812 Let-s Build A Simple Interpreter. Part 3..md similarity index 83% rename from translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md rename to published/20150812 Let-s Build A Simple Interpreter. Part 3..md index d50e5ce8f4..a70c10f9b0 100644 --- a/translated/tech/20150812 Let-s Build A Simple Interpreter. Part 3..md +++ b/published/20150812 Let-s Build A Simple Interpreter. Part 3..md @@ -1,11 +1,11 @@ -让我们做个简单的解释器(3) +让我们做个简单的解释器(三) ====== 早上醒来的时候,我就在想:“为什么我们学习一个新技能这么难?” 我不认为那是因为它很难。我认为原因可能在于我们花了太多的时间,而这件难事需要有丰富的阅历和足够的知识,然而我们要把这样的知识转换成技能所用的练习时间又不够。 -拿游泳来说,你可以花上几天时间来阅读很多有关游泳的书籍,花几个小时和资深的游泳者和教练交流,观看所有可以获得的训练视频,但你第一次跳进水池的时候,仍然会像一个石头那样沉入水中, +拿游泳来说,你可以花上几天时间来阅读很多有关游泳的书籍,花几个小时和资深的游泳者和教练交流,观看所有可以获得的训练视频,但你第一次跳进水池的时候,仍然会像一个石头那样沉入水中, 要点在于:你认为自己有多了解那件事都无关紧要 —— 你得通过练习把知识变成技能。为了帮你练习,我把训练放在了这个系列的 [第一部分][1] 和 [第二部分][2] 了。当然,你会在今后的文章中看到更多练习,我保证 :) @@ -17,7 +17,7 @@ ![][3] -什么是语法图? **语法图** 是对一门编程语言中的语法规则进行图像化的表示。基本上,一个语法图就能告诉你哪些语句可以在程序中出现,哪些不能出现。 +什么是语法图syntax diagram? **语法图** 是对一门编程语言中的语法规则进行图像化的表示。基本上,一个语法图就能告诉你哪些语句可以在程序中出现,哪些不能出现。 语法图很容易读懂:按照箭头指向的路径。某些路径表示的是判断,有些表示的是循环。 @@ -28,9 +28,7 @@ * 它们用图形的方式表示一个编程语言的特性(语法)。 * 它们可以用来帮你写出解析器 —— 你可以根据下列简单规则把图片转换成代码。 - - -你已经知道,识别出记号流中的词组的过程就叫做 **解析**。解释器或者编译器执行这个任务的部分叫做 **解析器**。解析也称为 **语法分析**,并且解析器这个名字很合适,你猜的对,就是 **语法分析**。 +你已经知道,识别出记号流中的词组的过程就叫做 **解析**。解释器或者编译器执行这个任务的部分叫做 **解析器**。解析也称为 **语法分析**,并且解析器这个名字很合适,你猜的对,就是 **语法分析器**。 根据上面的语法图,下面这些表达式都是合法的: @@ -38,9 +36,8 @@ * 3 + 4 * 7 - 3 + 2 - 1 - - 因为算术表达式的语法规则在不同的编程语言里面是很相近的,我们可以用 Python shell 来“测试”语法图。打开 Python shell,运行下面的代码: + ``` >>> 3 3 @@ -53,6 +50,7 @@ 意料之中。 表达式 “3 + ” 不是一个有效的数学表达式,根据语法图,加号后面必须要有个 term (整数),否则就是语法错误。然后,自己在 Python shell 里面运行: + ``` >>> 3 + File "", line 1 @@ -63,9 +61,10 @@ SyntaxError: invalid syntax 能用 Python shell 来做这样的测试非常棒,让我们把上面的语法图转换成代码,用我们自己的解释器来测试,怎么样? -从之前的文章里([第一部分][1] 和 [第二部分][2])你知道 expr 方法包含了我们的解析器和解释器。再说一遍,解析器仅仅识别出结构,确保它与某些特性对应,而解释器实际上是在解析器成功识别(解析)特性之后,就立即对表达式进行评估。 +从之前的文章里([第一部分][1] 和 [第二部分][2])你知道 `expr` 方法包含了我们的解析器和解释器。再说一遍,解析器仅仅识别出结构,确保它与某些特性对应,而解释器实际上是在解析器成功识别(解析)特性之后,就立即对表达式进行评估。 以下代码片段显示了对应于图表的解析器代码。语法图里面的矩形方框(term)变成了 term 方法,用于解析整数,expr 方法和语法图的流程一致: + ``` def term(self): self.eat(INTEGER) @@ -85,9 +84,10 @@ def expr(self): self.term() ``` -你能看到 expr 首先调用了 term 方法。然后 expr 方法里面的 while 循环可以执行 0 或多次。在循环里面解析器基于标记做出判断(是加号还是减号)。花一些时间,你就知道,上述代码确实是遵循着语法图的算术表达式流程。 +你能看到 `expr` 首先调用了 `term` 方法。然后 `expr` 方法里面的 `while` 循环可以执行 0 或多次。在循环里面解析器基于标记做出判断(是加号还是减号)。花一些时间,你就知道,上述代码确实是遵循着语法图的算术表达式流程。 + +解析器并不解释任何东西:如果它识别出了一个表达式,它就静默着,如果没有识别出来,就会抛出一个语法错误。改一下 `expr` 方法,加入解释器的代码: -解析器并不解释任何东西:如果它识别出了一个表达式,它就静默着,如果没有识别出来,就会抛出一个语法错误。改一下 expr 方法,加入解释器的代码: ``` def term(self): """Return an INTEGER token value""" @@ -113,14 +113,16 @@ def expr(self): return result ``` -因为解释器需要评估一个表达式, term 方法被改成返回一个整型值,expr 方法被改成在合适的地方执行加法或减法操作,并返回解释的结果。尽管代码很直白,我建议花点时间去理解它。 +因为解释器需要评估一个表达式, `term` 方法被改成返回一个整型值,`expr` 方法被改成在合适的地方执行加法或减法操作,并返回解释的结果。尽管代码很直白,我建议花点时间去理解它。 + 进行下一步,看看完整的解释器代码,好不? -这时新版计算器的源代码,它可以处理包含有任意多个加法和减法运算的有效的数学表达式。 +这是新版计算器的源代码,它可以处理包含有任意多个加法和减法运算的有效的数学表达式。 + ``` # 标记类型 # -# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成 INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF' @@ -265,9 +267,10 @@ if __name__ == '__main__': main() ``` -把上面的代码保存到 calc3.py 文件中,或者直接从 [GitHub][4] 上下载。试着运行它。看看它能不能处理我之前给你看过的语法图里面派生出的数学表达式。 +把上面的代码保存到 `calc3.py` 文件中,或者直接从 [GitHub][4] 上下载。试着运行它。看看它能不能处理我之前给你看过的语法图里面派生出的数学表达式。 这是我在自己的笔记本上运行的示例: + ``` $ python calc3.py calc> 3 @@ -297,15 +300,13 @@ Traceback (most recent call last): Exception: Invalid syntax ``` - -记得我在文章开始时提过的练习吗:他们在这儿,我保证过的:) +记得我在文章开始时提过的练习吗:它们在这儿,我保证过的:) ![][5] * 画出只包含乘法和除法的数学表达式的语法图,比如 “7 * 4 / 2 * 3”。认真点,拿只钢笔或铅笔,试着画一个。 修改计算器的源代码,解释只包含乘法和除法的数学表达式。比如 “7 * 4 / 2 * 3”。 - * 从头写一个可以处理像 “7 - 3 + 2 - 1” 这样的数学表达式的解释器。用你熟悉的编程语言,不看示例代码自己思考着写出代码。做的时候要想一想这里面包含的组件:一个 lexer,读取输入并转换成标记流,一个解析器,从 lexer 提供的记号流中取食,并且尝试识别流中的结构,一个解释器,在解析器成功解析(识别)有效的数学表达式后产生结果。把这些要点串起来。花一点时间把你获得的知识变成一个可以运行的数学表达式的解释器。 - + * 从头写一个可以处理像 “7 - 3 + 2 - 1” 这样的数学表达式的解释器。用你熟悉的编程语言,不看示例代码自己思考着写出代码。做的时候要想一想这里面包含的组件:一个词法分析器,读取输入并转换成标记流,一个解析器,从词法分析器提供的记号流中获取,并且尝试识别流中的结构,一个解释器,在解析器成功解析(识别)有效的数学表达式后产生结果。把这些要点串起来。花一点时间把你获得的知识变成一个可以运行的数学表达式的解释器。 **检验你的理解。** @@ -314,8 +315,6 @@ Exception: Invalid syntax 3. 什么是语法分析器? - - 嘿,看!你看完了所有内容。感谢你们坚持到今天,而且没有忘记练习。:) 下次我会带着新的文章回来,尽请期待。 -------------------------------------------------------------------------------- @@ -323,14 +322,14 @@ Exception: Invalid syntax via: https://ruslanspivak.com/lsbasi-part3/ 作者:[Ruslan Spivak][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[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]:http://ruslanspivak.com/lsbasi-part1/ (Part 1) -[2]:http://ruslanspivak.com/lsbasi-part2/ (Part 2) +[1]:https://linux.cn/article-9399-1.html +[2]:https://linux.cn/article-9520-1.html [3]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_syntax_diagram.png [4]:https://github.com/rspivak/lsbasi/blob/master/part3/calc3.py [5]:https://ruslanspivak.com/lsbasi-part3/lsbasi_part3_exercises.png diff --git a/sources/tech/20170101 How to resolve mount.nfs- Stale file handle error.md b/published/20170101 How to resolve mount.nfs- Stale file handle error.md similarity index 50% rename from sources/tech/20170101 How to resolve mount.nfs- Stale file handle error.md rename to published/20170101 How to resolve mount.nfs- Stale file handle error.md index d57280df28..056c9bf450 100644 --- a/sources/tech/20170101 How to resolve mount.nfs- Stale file handle error.md +++ b/published/20170101 How to resolve mount.nfs- Stale file handle error.md @@ -1,14 +1,15 @@ -How to resolve mount.nfs: Stale file handle error +如何解决 “mount.nfs: Stale file handle”错误 ====== -Learn how to resolve mount.nfs: Stale file handle error on Linux platform. This is Network File System error can be resolved from client or server end. + +> 了解如何解决 Linux 平台上的 `mount.nfs: Stale file handle` 错误。这个 NFS 错误可以在客户端或者服务端解决。 _![][1]_ -When you are using Network File System in your environment, you must have seen`mount.nfs: Stale file handle` error at times. This error denotes that NFS share is unable to mount since something has changed since last good known configuration. +当你在你的环境中使用网络文件系统时,你一定不时看到 `mount.nfs:Stale file handle` 错误。此错误表示 NFS 共享无法挂载,因为自上次配置后有些东西已经更改。 -Whenever you reboot NFS server or some of the NFS processes are not running on client or server or share is not properly exported at server; these can be reasons for this error. Moreover its irritating when this error comes to previously mounted NFS share. Because this means configuration part is correct since it was previously mounted. In such case once can try following commands: +无论是你重启 NFS 服务器或某些 NFS 进程未在客户端或服务器上运行,或者共享未在服务器上正确输出,这些都可能是导致这个错误的原因。此外,当这个错误发生在先前挂载的 NFS 共享上时,它会令人不快。因为这意味着配置部分是正确的,因为是以前挂载的。在这种情况下,可以尝试下面的命令: -Make sure NFS service are running good on client and server. +确保 NFS 服务在客户端和服务器上运行良好。 ``` # service nfs status @@ -18,9 +19,7 @@ nfsd (pid 12009 12008 12007 12006 12005 12004 12003 12002) is running... rpc.rquotad (pid 11988) is running... ``` -> Stay connected to your favorite windows applications from anywhere on any device with [ windows 7 cloud desktop ][2] from CloudDesktopOnline.com. Get Office 365 with expert support and free migration from [ Apps4Rent.com ][3]. - -If NFS share currently mounted on client, then un-mount it forcefully and try to remount it on NFS client. Check if its properly mounted by `df` command and changing directory inside it. +如果 NFS 共享目前挂载在客户端上,则强制卸载它并尝试在 NFS 客户端上重新挂载它。通过 `df` 命令检查它是否正确挂载,并更改其中的目录。 ``` # umount -f /mydata_nfs @@ -32,9 +31,9 @@ If NFS share currently mounted on client, then un-mount it forcefully and try to server:/nfs_share 41943040 892928 41050112 3% /mydata_nfs ``` -In above mount command, server can be IP or [hostname ][4]of NFS server. +在上面的挂载命令中,服务器可以是 NFS 服务器的 IP 或[主机名][4]。 -If you are getting error while forcefully un-mounting like below : +如果你在强制取消挂载时遇到像下面错误: ``` # umount -f /mydata_nfs @@ -43,7 +42,8 @@ umount: /mydata_nfs: device is busy umount2: Device or resource busy umount: /mydata_nfs: device is busy ``` -Then you can check which all processes or users are using that mount point with `lsof` command like below: + +然后你可以用 `lsof` 命令来检查哪个进程或用户正在使用该挂载点,如下所示: ``` # lsof |grep mydata_nfs @@ -55,9 +55,9 @@ bash 20092 oracle11 cwd unknown bash 25040 oracle11 cwd unknown /mydata_nfs/MUYR (stat: Stale NFS file handle) ``` -If you see in above example that 4 PID are using some files on said mount point. Try killing them off to free mount point. Once done you will be able to un-mount it properly. +如果你在上面的示例中看到共有 4 个 PID 正在使用该挂载点上的某些文件。尝试杀死它们以释放挂载点。完成后,你将能够正确卸载它。 -Sometimes it still give same error for mount command. Then try mounting after restarting NFS service at client using below command. +有时 `mount` 命令会有相同的错误。接着使用下面的命令在客户端重启 NFS 服务后挂载。 ``` # service nfs restart @@ -71,19 +71,19 @@ Starting NFS mountd: [ OK ] Starting NFS daemon: [ OK ] ``` -Also read : [How to restart NFS step by step in HPUX][5] +另请阅读:[如何在 HPUX 中逐步重启 NFS][5] -Even if this didnt solve your issue, final step is to restart services at NFS server. Caution! This will disconnect all NFS shares which are exported from NFS server. All clients will see mount point disconnect. This step is where 99% you will get your issue resolved. If not then [NFS configurations][6] must be checked, provided you have changed configuration and post that you started seeing this error. +即使这没有解决你的问题,最后一步是在 NFS 服务器上重启服务。警告!这将断开从该 NFS 服务器输出的所有 NFS 共享。所有客户端将看到挂载点断开。这一步将 99% 解决你的问题。如果没有,请务必检查 [NFS 配置][6],提供你修改的配置并发布你启动时看到的错误。 -Outputs in above post are from RHEL6.3 server. Drop us your comments related to this post. +上面文章中的输出来自 RHEL6.3 服务器。请将你的评论发送给我们。 -------------------------------------------------------------------------------- via: https://kerneltalks.com/troubleshooting/resolve-mount-nfs-stale-file-handle-error/ 作者:[KernelTalks][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20170201 Prevent Files And Folders From Accidental Deletion Or Modification In Linux.md b/published/20170201 Prevent Files And Folders From Accidental Deletion Or Modification In Linux.md new file mode 100644 index 0000000000..0af616dccd --- /dev/null +++ b/published/20170201 Prevent Files And Folders From Accidental Deletion Or Modification In Linux.md @@ -0,0 +1,296 @@ + +如何在 Linux 系统中防止文件和目录被意外的删除或修改 +====== + +![](https://www.ostechnix.com/wp-content/uploads/2017/02/Prevent-Files-And-Folders-From-Accidental-Deletion-Or-Modification-In-Linux-720x340.jpg) + +有时,我会不小心的按下 `SHIFT+DELETE`来删除我的文件数据。是的,我是个笨蛋,没有再次确认下我实际准备要删除的东西。而且我太笨或者说太懒,没有备份我的文件数据。结果呢?数据丢失了!在一瞬间就丢失了。 + +这种事时不时就会发生在我身上。如果你和我一样,有个好消息告诉你。有个简单又有用的命令行工具叫`chattr`(**Ch**ange **Attr**ibute 的缩写),在类 Unix 等发行版中,能够用来防止文件和目录被意外的删除或修改。 + +通过给文件或目录添加或删除某些属性,来保证用户不能删除或修改这些文件和目录,不管是有意的还是无意的,甚至 root 用户也不行。听起来很有用,是不是? + +在这篇简短的教程中,我们一起来看看怎么在实际应用中使用 `chattr` 命令,来防止文件和目录被意外删除。 + +### Linux中防止文件和目录被意外删除和修改 + +默认,`chattr` 命令在大多数现代 Linux 操作系统中是可用的。 + +默认语法是: + +``` +chattr [operator] [switch] [file] +``` + +`chattr` 具有如下操作符: + + * 操作符 `+`,追加指定属性到文件已存在属性中 + * 操作符 `-`,删除指定属性 + * 操作符 `=`,直接设置文件属性为指定属性 + +`chattr` 提供不同的属性,也就是 `aAcCdDeijsStTu`。每个字符代表一个特定文件属性。 + + * `a` – 只能向文件中添加数据 + * `A` – 不更新文件或目录的最后访问时间 + * `c` – 将文件或目录压缩后存放 + * `C` – 不适用写入时复制机制(CoW) + * `d` – 设定文件不能成为 `dump` 程序的备份目标 + * `D` – 同步目录更新 + * `e` – extend 格式存储 + * `i` – 文件或目录不可改变 + * `j` – 设定此参数使得当通过 `mount` 参数:`data=ordered` 或者 `data=writeback` 挂载的文件系统,文件在写入时会先被记录在日志中 + * `P` – project 层次结构 + * `s` – 安全删除文件或目录 + * `S` – 即时更新文件或目录 + * `t` – 不进行尾部合并 + * `T` – 顶层目录层次结构 + * `u` – 不可删除 + +在本教程中,我们将讨论两个属性的使用,即 `a`、`i` ,这个两个属性可以用于防止文件和目录的被删除。这是我们今天的主题,对吧?来开始吧! + +### 防止文件被意外删除和修改 + +我先在我的当前目录创建一个`file.txt`文件。 + +``` +$ touch file.txt +``` + +现在,我将给文件应用 `i` 属性,让文件不可改变。就是说你不能删除或修改这个文件,就算你是文件的拥有者和 root 用户也不行。 + +``` +$ sudo chattr +i file.txt +``` + +使用`lsattr`命令检查文件已有属性: + +``` +$ lsattr file.txt +``` + +输出: + +``` +----i---------e---- file.txt +``` + +现在,试着用普通用户去删除文件: + +``` +$ rm file.txt +``` + +输出: + +``` +# 不能删除文件,非法操作 +rm: cannot remove 'file.txt': Operation not permitted +``` + +我来试试 `sudo` 特权: + +``` +$ sudo rm file.txt +``` + +输出: + +``` +# 不能删除文件,非法操作 +rm: cannot remove 'file.txt': Operation not permitted +``` + +我们试试追加写内容到这个文本文件: + +``` +$ echo 'Hello World!' >> file.txt +``` + +输出: + +``` +# 非法操作 +bash: file.txt: Operation not permitted +``` + +试试 `sudo` 特权: + +``` +$ sudo echo 'Hello World!' >> file.txt +``` + +输出: + +``` +# 非法操作 +bash: file.txt: Operation not permitted +``` + +你应该注意到了,我们不能删除或修改这个文件,甚至 root 用户或者文件所有者也不行。 + +要撤销属性,使用 `-i` 即可。 + +``` +$ sudo chattr -i file.txt +``` + +现在,这不可改变属性已经被删除掉了。你现在可以删除或修改这个文件了。 + +``` +$ rm file.txt +``` + +类似的,你能够限制目录被意外删除或修改,如下一节所述。 + +### 防止目录被意外删除和修改 + +创建一个 `dir1` 目录,放入文件 `file.txt`。 + +``` +$ mkdir dir1 && touch dir1/file.txt +``` + +现在,让目录及其内容(`file.txt` 文件)不可改变: + +``` +$ sudo chattr -R +i dir1 +``` + +命令中, + + * `-R` – 递归使 `dir1` 目录及其内容不可修改 + * `+i` – 使目录不可修改 + + +现在,来试试删除这个目录,要么用普通用户,要么用 `sudo` 特权。 + +``` +$ rm -fr dir1 +$ sudo rm -fr dir1 +``` + +你会看到如下输出: + +``` +# 不可删除'dir1/file.txt':非法操作 +rm: cannot remove 'dir1/file.txt': Operation not permitted +``` + +尝试用 `echo` 命令追加内容到文件,你成功了吗?当然,你做不到。 + +撤销此属性,输入: + +``` +$ sudo chattr -R -i dir1 +``` + +现在你就能想平常一样删除或修改这个目录内容了。 + +### 防止文件和目录被意外删除,但允许追加操作 + +我们现已知道如何防止文件和目录被意外删除和修改了。接下来,我们将防止文件被删除但仅仅允许文件被追加内容。意思是你不可以编辑修改文件已存在的数据,或者重命名这个文件或者删除这个文件,你仅可以使用追加模式打开这个文件。 + +为了设置追加属性到文件或目录,我们像下面这么操作: + +针对文件: + +``` +$ sudo chattr +a file.txt +``` + +针对目录: + +``` +$ sudo chattr -R +a dir1 +``` + +一个文件或目录被设置了 `a` 这个属性就仅仅能够以追加模式打开进行写入。 + +添加些内容到这个文件以测试是否有效果。 + +``` +$ echo 'Hello World!' >> file.txt +$ echo 'Hello World!' >> dir1/file.txt +``` + +查看文件内容使用cat命令 + +``` +$ cat file.txt +$ cat dir1/file.txt +``` + +输出: + +``` +Hello World! +``` + +你将看到你现在可以追加内容。就表示我们可以修改这个文件或目录。 + +现在让我们试试删除这个文件或目录。 + +``` +$ rm file.txt +``` + +输出: + +``` +# 不能删除文件'file.txt':非法操作 +rm: cannot remove 'file.txt': Operation not permitted +``` + +让我们试试删除这个目录: + +``` +$ rm -fr dir1/ +``` + +输出: + +``` +# 不能删除文件'dir1/file.txt':非法操作 +rm: cannot remove 'dir1/file.txt': Operation not permitted +``` + +删除这个属性,执行下面这个命令: + +针对文件: + +``` +$ sudo chattr -R -a file.txt +``` + +针对目录: + +``` +$ sudo chattr -R -a dir1/ +``` + +现在,你可以想平常一样删除或修改这个文件和目录了。 + +更多详情,查看 man 页面。 + +``` +man chattr +``` + +### 总结 + +保护数据是系统管理人员的主要工作之一。市场上有众多可用的免费和收费的数据保护软件。幸好,我们已经拥有这个内置命令可以帮助我们去保护数据被意外的删除和修改。在你的 Linux 系统中,`chattr` 可作为保护重要系统文件和数据的附加工具。 + +然后,这就是今天所有内容了。希望对大家有所帮助。接下来我将会在这提供其他有用的文章。在那之前,敬请期待。再见! + + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/prevent-files-folders-accidental-deletion-modification-linux/ + +作者:[SK][a] +译者:[yizhuoyan](https://github.com/yizhuoyan) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.ostechnix.com/author/sk/ diff --git a/translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md b/published/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md similarity index 88% rename from translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md rename to published/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md index 5af00db0f9..6b31355f02 100644 --- a/translated/tech/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md +++ b/published/20170508 Ansible Tutorial- Intorduction to simple Ansible commands.md @@ -39,7 +39,7 @@ $ ansible -m setup -a "filter=ansible_distribution" ### 传输文件 -对于传输文件,我们使用模块 “copy” ,完整的命令是这样的: +对于传输文件,我们使用模块 `copy` ,完整的命令是这样的: ``` $ ansible -m copy -a "src=/home/dan dest=/tmp/home" @@ -47,7 +47,7 @@ $ ansible -m copy -a "src=/home/dan dest=/tmp/home" ### 管理用户 -要管理已连接主机上的用户,我们使用一个名为 “user” 的模块,并如下使用它。 +要管理已连接主机上的用户,我们使用一个名为 `user` 的模块,并如下使用它。 #### 创建新用户 @@ -65,7 +65,7 @@ $ ansible -m user -a "name=testuser state=absent" ### 更改权限和所有者 -要改变已连接主机文件的所有者,我们使用名为 ”file“ 的模块,使用如下。 +要改变已连接主机文件的所有者,我们使用名为 `file` 的模块,使用如下。 #### 更改文件权限 @@ -81,7 +81,7 @@ $ ansible -m file -a "dest=/home/dan/file1.txt mode=777 owner=dan group= ### 管理软件包 -我们可以通过使用 ”yum“ 和 ”apt“ 模块来管理所有已连接主机的软件包,完整的命令如下: +我们可以通过使用 `yum` 和 `apt` 模块来管理所有已连接主机的软件包,完整的命令如下: #### 检查包是否已安装并更新 @@ -109,7 +109,7 @@ $ ansible -m yum -a "name=ntp state=absent" ### 管理服务 -要管理服务,我们使用模块 “service” ,完整命令如下: +要管理服务,我们使用模块 `service` ,完整命令如下: #### 启动服务 @@ -129,7 +129,7 @@ $ ansible -m service -a "name=httpd state=stopped" $ ansible -m service -a "name=httpd state=restarted" ``` -这样我们简单的,单行 Ansible 命令的教程就完成了。此外,在未来的教程中,我们将学习创建 playbook,来帮助我们更轻松高效地管理主机。 +这样我们简单的、单行 Ansible 命令的教程就完成了。此外,在未来的教程中,我们将学习创建 playbook,来帮助我们更轻松高效地管理主机。 -------------------------------------------------------------------------------- diff --git a/published/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md b/published/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md new file mode 100644 index 0000000000..43c2c988f6 --- /dev/null +++ b/published/20170915 Deep learning wars- Facebook-backed PyTorch vs Google-s TensorFlow.md @@ -0,0 +1,81 @@ +深度学习战争:Facebook 支持的 PyTorch 与 Google 的 TensorFlow +====== + +![](https://hub.packtpub.com/wp-content/uploads/2018/03/iStock-621901930-1068x832.jpg) + +有一个令人震惊的事实,即人工智能和机器学习的工具和技术在近期迅速兴起。深度学习,或者说“注射了激素的机器学习”,数据科学家和机器学习专家在这个领域有数不胜数等可用的库和框架。很多这样的框架都是基于 Python 的,因为 Python 是一个更通用,相对简单的语言。[Theano] [1]、[Keras] [2]、 [TensorFlow] [3] 是几个基于 Python 构建的流行的深度学习库,目的是使机器学习专家更轻松。 + +Google 的 TensorFlow 是一个被广泛使用的机器学习和深度学习框架。 TensorFlow 开源于 2015 年,得到了机器学习专家社区的广泛支持,TensorFlow 已经迅速成长为许多机构根据其机器学习和深度学习等需求而选择的框架。 另一方面,PyTorch 是由 Facebook 最近开发的用于训练神经网络的 Python 包,改编自基于 Lua 的深度学习库 Torch。 PyTorch 是少数可用的深度学习框架之一,它使用基于磁带的自动梯度系统tape-based autograd system,以快速和灵活的方式构建动态神经网络。 + +在这篇文章中,我们将 PyTorch 与 TensorFlow 进行不同方面的比较。 + +让我们开始吧! + +### 什么编程语言支持 PyTorch 和 TensorFlow? + +虽然主要是用 C++ 和 CUDA 编写的,但 TensorFlow 包含一个位于核心引擎上的 Python API,使得更便于被Python 支持者Pythonistas使用。 除了 Python,它还包括 C++、Haskell、Java、Go 和 Rust 等其他 API,这意味着开发人员可以用他们的首选语言进行编码。 + +虽然 PyTorch 是一个 Python 软件包,但你也可以提供使用基本的 C/C++ 语言的 API 进行编码。 如果你习惯使用 Lua 编程语言,你也可以使用 Torch API 在 PyTorch 中编写神经网络模型。 + +### PyTorch 和 TensorFlow 有多么易于使用? + +如果将 TensorFlow 作为一个独立的框架使用,它可能会有点复杂,并且会给深度学习模型的训练带来一些困难。 为了减少这种复杂性,可以使用位于 TensorFlow 复杂引擎之上的 Keras 封装,以简化深度学习模型的开发和训练。 TensorFlow 也支持 PyTorch 目前没有的[分布式培训] [4]。 由于包含 Python API,TensorFlow 也可以在生产环境中使用,即可用于培训练和部署企业级深度学习模型。 + +PyTorch 由于 Torch 的复杂用 Python 重写。 这使得 PyTorch 对于开发人员更为原生。 它有一个易于使用的框架,提供最大化的灵活和速度。 它还允许在训练过程中快速更改代码而不妨碍其性能。 如果你已经有了一些深度学习的经验,并且以前使用过 Torch,那么基于它的速度、效率和易用性,你会更喜欢 PyTorch。 PyTorch 包含定制的 GPU 分配器,这使得深度学习模型具有更高的内存效率。 由此,训练大型深度学习模型变得更容易。 因此,Pytorch +在 Facebook、Twitter、Salesforce 等大型组织广受欢迎。 + +### 用 PyTorch 和 TensorFlow 训练深度学习模型 + +PyTorch 和 TensorFlow 都可以用来建立和训练神经网络模型。 + +TensorFlow 工作于 SCG(静态计算图)上,包括在模型开始执行之前定义静态图。 但是,一旦开始执行,在模型内的调整更改的唯一方法是使用 [tf.session and tf.placeholder tensors][5]。 + +PyTorch 非常适合训练 RNN(递归神经网络),因为它们在 [PyTorch] [6] 中比在 TensorFlow 中运行得更快。 它适用于 DCG(动态计算图),可以随时在模型中定义和更改。 在 DCG 中,每个模块可以单独调试,这使得神经网络的训练更简单。 + +TensorFlow 最近提出了 TensorFlow Fold,这是一个旨在创建 TensorFlow 模型的库,用于处理结构化数据。 像 PyTorch 一样,它实现了 DCG,在 CPU 上提供高达 10 倍的计算速度,在 GPU 上提供超过 100 倍的计算速度! 在 [Dynamic Batching] [7] 的帮助下,你现在可以执行尺寸和结构都不相同的深度学习模型。 + +### GPU 和 CPU 优化的比较 + +TensorFlow 的编译时间比 PyTorch 短,为构建真实世界的应用程序提供了灵活性。 它可以从 CPU、GPU、TPU、移动设备到 Raspberry Pi(物联网设备)等各种处理器上运行。 + +另一方面,PyTorch 包括张量tensor计算,可以使用 GPU 将深度神经网络模型加速到 [50 倍或更多] [8]。 这些张量可以停留在 CPU 或 GPU 上。 CPU 和 GPU 都是独立的库, 无论神经网络大小如何,PyTorch 都可以高效地利用。 + +### 社区支持 + +TensorFlow 是当今最流行的深度学习框架之一,由此也给它带来了庞大的社区支持。 它有很好的文档和一套详细的在线教程。 TensorFlow 还包括许多预先训练过的模型,这些模型托管和提供于 [GitHub] [9]。 这些模型提供给热衷于使用 TensorFlow 开发者和研究人员一些现成的材料来节省他们的时间和精力。 + +另一方面,PyTorch 的社区相对较小,因为它最近才发展起来。 与 TensorFlow 相比,文档并不是很好,代码也不是很容易获得。 然而,PyTorch 确实允许个人与他人分享他们的预训练模型。 + +### PyTorch 和 TensorFlow —— 力量悬殊的故事 + +就目前而言,由于各种原因,TensorFlow 显然比 PyTorch 更受青睐。 + +TensorFlow 很大,经验丰富,最适合实际应用。 是大多数机器学习和深度学习专家明显的选择,因为它提供了大量的功能,最重要的是它在市场上的成熟应用。 它具有更好的社区支持以及多语言 API 可用。 它有一个很好的文档库,由于从准备到使用的代码使之易于生产。 因此,它更适合想要开始深度学习的人,或者希望开发深度学习模型的组织。 + +虽然 PyTorch 相对较新,社区较小,但它速度快,效率高。 总之,它给你所有的优势在于 Python 的有用性和易用性。 由于其效率和速度,对于基于研究的小型项目来说,这是一个很好的选择。 如前所述,Facebook、Twitter 等公司正在使用 PyTorch 来训练深度学习模型。 但是,使用它尚未成为主流。 PyTorch 的潜力是显而易见的,但它还没有准备好去挑战这个 TensorFlow 野兽。 然而,考虑到它的增长,PyTorch 进一步优化并提供更多功能的日子并不遥远,直到与 TensorFlow可以 比较。 + +作者: Savia Lobo,非常喜欢数据科学。 喜欢更新世界各地的科技事件。 喜欢歌唱和创作歌曲。 相信才智上的艺术。 + +-------------------------------------------------------------------------------- + +via: https://datahub.packtpub.com/deep-learning/dl-wars-pytorch-vs-tensorflow/ + +作者:[Savia Lobo][a] +译者:[Wuod3n](https://github.com/Wuod3n) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://datahub.packtpub.com/author/savial/ +[1]:https://www.packtpub.com/web-development/deep-learning-theano +[2]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-keras +[3]:https://www.packtpub.com/big-data-and-business-intelligence/deep-learning-tensorflow +[4]:https://www.tensorflow.org/deploy/distributed +[5]:https://www.tensorflow.org/versions/r0.12/get_started/basic_usage +[6]:https://www.reddit.com/r/MachineLearning/comments/66rriz/d_rnns_are_much_faster_in_pytorch_than_tensorflow/ +[7]:https://arxiv.org/abs/1702.02181 +[8]:https://github.com/jcjohnson/pytorch-examples#pytorch-tensors +[9]:https://github.com/tensorflow/models + + + diff --git a/published/20170927 Best Linux Distros for the Enterprise.md b/published/20170927 Best Linux Distros for the Enterprise.md new file mode 100644 index 0000000000..516a01ef58 --- /dev/null +++ b/published/20170927 Best Linux Distros for the Enterprise.md @@ -0,0 +1,81 @@ +面向企业的最佳 Linux 发行版 +==== + +在这篇文章中,我将分享企业环境下顶级的 Linux 发行版。其中一些发行版用于服务器和云环境以及桌面任务。所有这些可选的 Linux 具有的一个共同点是它们都是企业级 Linux 发行版 —— 所以你可以期待更高程度的功能性,当然还有支持程度。 + +### 什么是企业级的 Linux 发行版? + +企业级的 Linux 发行版可以归结为以下内容 —— 稳定性和支持。在企业环境中,使用的 Linux 版本必须满足这两点。稳定性意味着所提供的软件包既稳定又可用,同时仍然保持预期的安全性。 + +企业级的支持因素意味着有一个可靠的支持机制。有时这是单一的(官方)来源,如公司。在其他情况下,它可能是一个非营利性的治理机构,向优秀的第三方支持供应商提供可靠的建议。很明显,前者是最好的选择,但两者都可以接受。 + +### Red Hat 企业级 Linux(RHEL) + +[Red Hat][1] 有很多很棒的产品,都有企业级的支持来保证可用。其核心重点如下: + +- Red Hat 企业级 Linux 服务器:这是一组服务器产品,包括从容器托管到 SAP 服务的所有内容,还有其他衍生的服务器。 +- Red Hat 企业级 Linux 桌面:这些是严格控制的用户环境,运行 Red Hat Linux,提供基本的桌面功能。这些功能包括访问最新的应用程序,如 web 浏览器、电子邮件、LibreOffice 等。 +- Red Hat 企业级 Linux 工作站:这基本上是 Red Hat 企业级 Linux 桌面,但针对高性能任务进行了优化。它也非常适合于大型部署和持续管理。 + +#### 为什么选择 Red Hat 企业级 Linux? + +Red Hat 是一家非常成功的大型公司,销售围绕 Linux 的服务。基本上,Red Hat 从那些想要避免供应商锁定和其他相关问题的公司赚钱。这些公司认识到聘用开源软件专家和管理他们的服务器和其他计算需求的价值。一家公司只需要购买订阅来让 Red Hat 做支持工作就行。 + +Red Hat 也是一个可靠的社会公民。他们赞助开源项目以及像 OpenSource.com 这样的 FoSS 支持网站(LCTT 译注:FoSS 是 Free and Open Source Software 的缩写,意为自由及开源软件),并为 Fedora 项目提供支持。Fedora 不是由 Red Hat 所有的,而是由它赞助开发的。这使 Fedora 得以发展,同时也使 Red Hat 受益匪浅。Red Hat 可以从 Fedora 项目中获得他们想要的,并将其用于他们的企业级 Linux 产品中。 就目前来看,Fedora 充当了红帽企业 Linux 的上游渠道。 + +### SUSE Linux 企业版本 + +[SUSE][2] 是一家非常棒的公司,为企业用户提供了可靠的 Linux 选择。SUSE 的产品类似于 Red Hat,桌面和服务器都是该公司所关注的。从我自己使用 SUSE 的经验来看,我相信 YaST 已经证明了,对于希望在工作场所使用 Linux 操作系统的非 Linux 管理员而言,它拥有巨大的优势。YaST 为那些需要一些基本的 Linux 命令行知识的任务提供了一个友好的 GUI。 + +SUSE 的核心重点如下: + +- SUSE Linux 企业级服务器(SLES):包括任务特定的解决方案,从云到 SAP,以及任务关键计算和基于软件的数据存储。 +- SUSE Linux 企业级桌面:对于那些希望为员工提供可靠的 Linux 工作站的公司来说,SUSE Linux 企业级桌面是一个不错的选择。和 Red Hat 一样,SUSE 通过订阅模式来对其提供支持。你可以选择三个不同级别的支持。 + +#### 为什么选择 SUSE Linux 企业版? + +SUSE 是一家围绕 Linux 销售服务的公司,但他们仍然通过专注于简化操作来实现这一目标。从他们的网站到其提供的 Linux 发行版,重点是易用性,而不会牺牲安全性或可靠性。尽管在美国毫无疑问 Red Hat 是服务器的标准,但 SUSE 作为公司和开源社区的贡献成员都做得很好。 + +我还会继续说,SUSE 不会太严肃,当你在 IT 领域建立联系的时候,这是一件很棒的事情。从他们关于 Linux 的有趣音乐视频到 SUSE 贸易展位中使用的 Gecko 以获得有趣的照片机会,SUSE 将自己描述成简单易懂和平易近人的形象。 + +### Ubuntu LTS Linux + +[Ubuntu Long Term Release][3] (LTS) Linux 是一个简单易用的企业级 Linux 发行版。Ubuntu 看起来比上面提到的其他发行版更新更频繁(有时候也更不稳定)。但请不要误解,Ubuntu LTS 版本被认为是相当稳定的,不过,我认为一些专家可能不太同意它们是安全可靠的。 + +#### Ubuntu 的核心重点如下: + +- Ubuntu 桌面版:毫无疑问,Ubuntu 桌面非常简单,可以快速地学习并运行。也许在高级安装选项中缺少一些东西,但这使得其更简单直白。作为额外的奖励,Ubuntu 相比其他版本有更多的软件包(除了它的父亲,Debian 发行版)。我认为 Ubuntu 真正的亮点在于,你可以在网上找到许多销售 Ubuntu 的厂商,包括服务器、台式机和笔记本电脑。 +- Ubuntu 服务器版:这包括服务器、云和容器产品。Ubuntu 还提供了 Juju 云“应用商店”这样一个有趣的概念。对于任何熟悉 Ubuntu 或 Debian 的人来说,Ubuntu 服务器都很有意义。对于这些人来说,它就像手套一样,为你提供了你已经熟知并喜爱的命令行工具。 +- Ubuntu IoT:最近,Ubuntu 的开发团队已经把目标瞄准了“物联网”(IoT)的创建解决方案。包括数字标识、机器人技术和物联网网关。我的猜测是,我们将在 Ubuntu 中看到大量增长的物联网用户来自企业,而不是普通家庭用户。 + +#### 为什么选择 Ubuntu LTS? + +社区是 Ubuntu 最大的优点。除了在已经拥挤的服务器市场上的巨大增长之外,它还与普通用户在一起。Ubuntu 的开发和用户社区是坚如磐石的。因此,虽然它可能被认为比其他企业版更不稳定,但是我发现将 Ubuntu LTS 安装锁定到 “security updates only” 模式下提供了非常稳定的体验。 + +### CentOS 或者 Scientific Linux 怎么样呢? + +首先,让我们把 [CentOS][4] 作为一个企业发行版,如果你有自己的内部支持团队来维护它,那么安装 CentOS 是一个很好的选择。毕竟,它与 Red Hat 企业级 Linux 兼容,并提供了与 Red Hat 产品相同级别的稳定性。不幸的是,它不能完全取代 Red Hat 支持订阅。 + +那么 [Scientific Linux][5] 呢?它的发行版怎么样?好吧,它就像 CentOS,它是基于 Red Hat Linux 的。但与 CentOS 不同的是,它与 Red Hat 没有任何隶属关系。 Scientific Linux 从一开始就有一个目标 —— 为世界各地的实验室提供一个通用的 Linux 发行版。今天,Scientific Linux 基本上是 Red Hat 减去所包含的商标资料。 + +这两种发行版都不能真正地与 Red Hat 互换,因为它们缺少 Red Hat 支持组件。 + +哪一个是顶级企业发行版?我认为这取决于你需要为自己确定的许多因素:订阅范围、可用性、成本、服务和提供的功能。这些是每个公司必须自己决定的因素。就我个人而言,我认为 Red Hat 在服务器上获胜,而 SUSE 在桌面环境中轻松获胜,但这只是我的意见 —— 你不同意?点击下面的评论部分,让我们来谈谈它。 + + +-------------------------------------------------------------------------------- + +via: https://www.datamation.com/open-source/best-linux-distros-for-the-enterprise.html + +作者:[Matt Hartley][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.datamation.com/author/Matt-Hartley-3080.html +[1]:https://www.redhat.com/en +[2]:https://www.suse.com/ +[3]:http://releases.ubuntu.com/16.04/ +[4]:https://www.centos.org/ +[5]:https://www.scientificlinux.org/ diff --git a/published/20170927 Linux directory structure- -lib explained.md b/published/20170927 Linux directory structure- -lib explained.md new file mode 100644 index 0000000000..66ec8e41f4 --- /dev/null +++ b/published/20170927 Linux directory structure- -lib explained.md @@ -0,0 +1,105 @@ +Linux 目录结构:/lib 分析 +====== + +[![linux 目录 lib][1]][1] + +我们在之前的文章中已经分析了其他重要系统目录,比如 `/bin`、`/boot`、`/dev`、 `/etc` 等。可以根据自己的兴趣进入下列链接了解更多信息。本文中,让我们来看看 `/lib` 目录都有些什么。 + +- [目录结构分析:/bin 文件夹][2] +- [目录结构分析:/boot 文件夹][3] +- [目录结构分析:/dev 文件夹][4] +- [目录结构分析:/etc 文件夹][5] +- [目录结构分析:/lost+found 文件夹][6] +- [目录结构分析:/home 文件夹][7] + +### Linux 中,/lib 文件夹是什么? + +`/lib` 文件夹是 **库文件目录** ,包含了所有对系统有用的库文件。简单来说,它是应用程序、命令或进程正确执行所需要的文件。在 `/bin` 或 `/sbin` 目录中的命令的动态库文件正是在此目录中。内核模块同样也在这里。 + +以 `pwd` 命令执行为例。执行它需要调用一些库文件。让我们来探索一下 `pwd` 命令执行时都发生了什么。我们需要使用 [strace 命令][8] 找出调用的库文件。 + +示例: + +``` +root@linuxnix:~# strace -e open pwd +open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 +open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 +open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 +/root ++++ exited with 0 +++ +root@linuxnix:~# +``` + +如果你注意到的话,会发现我们使用的 `pwd` 命令的执行需要调用两个库文件。 + +### Linux 中 /lib 文件夹内部信息 + +正如之前所说,这个文件夹包含了目标文件和一些库文件,如果能了解这个文件夹的一些重要子文件,想必是极好的。下面列举的内容是基于我自己的系统,对于你的来说,可能会有所不同。 + +``` +root@linuxnix:/lib# find . -maxdepth 1 -type d +./firmware +./modprobe.d +./xtables +./apparmor +./terminfo +./plymouth +./init +./lsb +./recovery-mode +./resolvconf +./crda +./modules +./hdparm +./udev +./ufw +./ifupdown +./systemd +./modules-load.d +``` + +`/lib/firmware` - 这个文件夹包含了一些硬件、固件Firmware代码。 + +> **硬件和固件之间有什么不同?** + +> 为了使硬件正常运行,很多设备软件由两部分软件组成。加载到实际硬件的代码部分就是固件,用于在固件和内核之间通讯的软件被称为驱动程序。这样一来,内核就可以直接与硬件通讯,并确保硬件完成内核指派的工作。 + +`/lib/modprobe.d` - modprobe 命令的配置目录。 + +`/lib/modules` - 所有的可加载内核模块都存储在这个目录下。如果你有多个内核,你会在这个目录下看到代表美国内核的目录。 + +`/lib/hdparm` - 包含 SATA/IDE 硬盘正确运行的参数。 + +`/lib/udev` - 用户空间 /dev 是 Linux 内核设备管理器。这个文件夹包含了所有的 udev 相关的文件和文件夹,例如 `rules.d` 包含了 udev 规范文件。 + +### /lib 的姊妹文件夹:/lib32 和 /lib64 + +这两个文件夹包含了特殊结构的库文件。它们几乎和 `/lib` 文件夹一样,除了架构级别的差异。 + +### Linux 其他的库文件 + +`/usr/lib` - 所有软件的库都安装在这里。但是不包含系统默认库文件和内核库文件。 + +`/usr/local/lib` - 放置额外的系统文件。这些库能够用于各种应用。 + +`/var/lib` - 存储动态数据的库和文件,例如 rpm/dpkg 数据和游戏记录。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxnix.com/linux-directory-structure-lib-explained/ + +作者:[Surendra Anne][a] +译者:[CYLeft](https://github.com/CYLeft) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxnix.com/author/surendra/ +[1]:https://www.linuxnix.com/wp-content/uploads/2017/09/The-lib-folder-explained.png +[2]:https://www.linuxnix.com/linux-directory-structure-explained-bin-folder/ +[3]:https://www.linuxnix.com/linux-directory-structure-explained-boot-folder/ +[4]:https://www.linuxnix.com/linux-directory-structure-explained-dev-folder/ +[5]:https://www.linuxnix.com/linux-directory-structure-explainedetc-folder/ +[6]:https://www.linuxnix.com/lostfound-directory-linuxunix/ +[7]:https://www.linuxnix.com/linux-directory-structure-home-root-folders/ +[8]:https://www.linuxnix.com/10-strace-command-examples-linuxunix/ diff --git a/published/20170928 Process Monitoring.md b/published/20170928 Process Monitoring.md new file mode 100644 index 0000000000..b8654a1a42 --- /dev/null +++ b/published/20170928 Process Monitoring.md @@ -0,0 +1,55 @@ +对进程的监视 +====== + +由于复刻了 mon 项目到 [etbemon][1] 中,我花了一些时间做监视脚本。事实上监视一些事情通常很容易,但是决定监视什么才是困难的部分。进程监视脚本 `ps.monitor` 是我重新设计过的一个。 + +对于进程监视我有一些思路。如果你对进程监视如何做的更好有任何建议,请通过评论区告诉我。 + +给不使用 mon 的人介绍一下,如果一切 OK 该监视脚本就返回 0,而如果有问题它会返回 1,并使用标准输出显示错误信息。虽然我并不知道有谁将 mon 脚本挂进一个不同的监视系统中,但是,那样做其实很容易实现。我计划去做的一件事情就是,将来实现 mon 和其它的监视系统如 Nagios 之间的互操作性。 + +### 基本监视 + +``` +ps.monitor tor:1-1 master:1-2 auditd:1-1 cron:1-5 rsyslogd:1-1 dbus-daemon:1- sshd:1- watchdog:1-2 +``` + +我现在计划重写该进程监视脚本的某些部分。现在的功能是在命令行上列出进程名字,它包含了要监视的进程的最小和最大实例数量。上面的示例是一个监视的配置。在这里有一些限制,在这个实例中的 `master` 进程指的是 Postfix 的主进程,但是其它的守护进程使用了相同的进程名(这是那些错误的名字之一,因为它太直白了)。一个显而易见的解决方案是,给一个指定完整路径的选项,这样,那个 `/usr/lib/postfix/sbin/master` 就可以与其它命名为 `master` 的程序区分开了。 + +下一个问题是那些可能以多个用户身份运行的进程。比如 `sshd`,它有一个以 root 身份运行的单独的进程去接受新的连接请求,以及在每个登入用户的 UID 下运行的进程。因此,作为 root 用户运行的 sshd 进程的数量将比 root 登录会话的数量大 1。这意味着如果一个系统管理员直接以 root 身份通过 `ssh` 登入系统(这是有争议的,但它不是本文的主题—— 只是有些人需要这样做,所以我们必须支持这种情形),然后 master 进程崩溃了(或者系统管理员意外或者故意杀死了它),这时对于该进程丢失并不会产生警报。当然正确的做法是监视 22 号端口,查找字符串 `SSH-2.0-OpenSSH_`。有时候,守护进程的多个实例运行在需要单独监视的不同 UID 下面。因此,我们需要通过 UID 监视进程的能力。 + +在许多情形中,进程监视可以被替换为对服务端口的监视。因此,如果在 25 号端口上监视,那么有可能意味着,Postfix 的 `master` 在运行着,不用去理会其它的 `master` 进程。但是对于我而言,我可以在方便地进行多个监视,如果我得到一个关于无法向一个服务器发送邮件的 Jabber 消息,我可以通过这个来自服务器的 Jabber 消息断定 `master` 没有运行,而不需要挨个查找才能发现问题所在。 + +### SE Linux + +我想要的一个功能就是,监视进程的 SE Linux 上下文,就像监视 UID 一样。虽然我对为其它安全系统编写一个测试不感兴趣,但是,我很乐意将别人写好的代码包含进去。因此,不管我做什么,都希望它能与多个安全系统一起灵活地工作。 + +### 短暂进程 + +大多数守护进程在进程启动期间都有一个相同名字的次级进程second process。这意味着如果你为了精确地监视一个进程的一个实例,当 `logrotate` 或者类似的守护进程重启时,你或许会收到一个警报说有两个进程运行。如果在重启期间,恰好在一个错误的时间进行检查,你也或许会收到一个警报说,有 0 个实例。我现在处理这种情况的方法是,在与 `alertafter 2` 指令一起的次级进程失败事件之前我的服务器不发出警报。当监视处于一个失败的状态时,`failure_interval` 指令允许指定检查的时间间隔,将其设置为一个较低值时,意味着在等待一个次级进程失败结果时并不会使提示延迟太多。 + +为处理这种情况,我考虑让 `ps.monitor` 脚本在一个指定的延迟后再次进行自动检查。我认为使用一个单个参数的监视脚本来解决这个问题比起使用两个配置指令的 mon 要好一些。 + +### CPU 使用 + +mon 现在有一个 `loadavg.monitor` 脚本,它用于检查平均负载。但是它并不能捕获一个单个进程使用了太多的 CPU 时间而没有使系统平均负载上升的情况。同样,也没有捕获一个渴望获得 CPU 的进程进入沉默(例如,SETI at Home 停止运行)(LCTT 译注:SETI,由加州大学伯克利分校创建的一项利用全球的联网计算机的空闲计算资源来搜寻地外文明的科学实验计划),而其它的进程进入一个无限循环状态的情况。解决这种问题的一个方法是,让 `ps.monitor` 脚本也配置另外的一个选项去监视 CPU 的使用,但是这也可能会让人产生迷惑。另外的选择是,使用一个独立的脚本,它用来报警任何在它的生命周期或者最后几秒中,使用 CPU 时间超过指定百分比的进程,除非它在一个豁免这种检查的进程或用户的白名单中。或者每个普通用户都应该豁免这种检查,因为你压根就不知道他们什么时候运行一个文件压缩程序。也应该有一个包含排除的守护进程(像 BOINC)和系统进程(像 gzip,有几个定时任务会运行它)的简短列表。 + +### 对例外的监视 + +一个常见的编程错误是在 `setgid()` 之前调用 `setuid()`,这意味着那个程序没有权限去调用 `setgid()`。如果没有检查返回代码(而犯这种低级错误的人往往不会去检查返回代码),那么进程会保持较高的权限。检查以 GID 0 而不是 UID 0 运行的进程是很方便的。顺利说一下,对一个 Debian/Testing 工作站运行的一个快速检查显示,一个使用 GID 0 的进程并没有获得较高的权限,但是可以使用一个 `chmod 770` 命令去改变它。 + +在一个 SE Linux 系统上,应该只有一个进程与 `init_t` 域一起运行。目前在运行守护进程(比如,mysqld 和 tor)的 Debian Stretch 系统中,并不会发生策略与守护进程服务文件所请求的 systemd 的最新功能不匹配的情况。这样的问题将会不断发生,我们需要对它进行自动化测试。 + +对配置错误的自动测试可能会影响系统安全,这是一个很大的问题,我将来或许写一篇关于这方面的单独的博客文章。 + +-------------------------------------------------------------------------------- + +via: https://etbe.coker.com.au/2017/09/28/process-monitoring/ + +作者:[Andrew][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://etbe.coker.com.au +[1]:https://doc.coker.com.au/projects/etbe-mon/ diff --git a/translated/tech/20171002 Linux Gunzip Command Explained with Examples.md b/published/20171002 Linux Gunzip Command Explained with Examples.md similarity index 99% rename from translated/tech/20171002 Linux Gunzip Command Explained with Examples.md rename to published/20171002 Linux Gunzip Command Explained with Examples.md index 9d509c56e5..fb6a25bcba 100644 --- a/translated/tech/20171002 Linux Gunzip Command Explained with Examples.md +++ b/published/20171002 Linux Gunzip Command Explained with Examples.md @@ -74,7 +74,6 @@ gunzip -c file1.gz > /home/himanshu/file1 > `gunzip` 在命令行接受一系列的文件,并且将每个文件内容以正确的魔法数开始,且后缀名为 `.gz`、`-gz`、`.z`、`-z` 或 `_z` (忽略大小写)的压缩文件,用未压缩的文件替换它,并删除其原扩展名。 `gunzip` 也可识别一些特殊扩展名的压缩文件,如 `.tgz` 和 `.taz` 分别是 `.tar.gz` 和 `.tar.Z` 的缩写。在压缩时,`gzip` 在必要情况下使用 `.tgz` 作为扩展名,而不是只截取掉 `.tar` 后缀。 > `gunzip` 目前可以解压 `gzip`、`zip`、`compress`、`compress -H`(`pack`)产生的文件。`gunzip` 自动检测输入文件格式。在使用前两种压缩格式时,`gunzip` 会检验 32 位循环冗余校验码(CRC)。对于 pack 包,`gunzip` 会检验压缩长度。标准压缩格式在设计上不允许相容性检测。不过 `gunzip` 有时可以检测出坏的 `.Z` 文件。如果你解压 `.Z` 文件时出错,不要因为标准解压没报错就认为 `.Z` 文件一定是正确的。这通常意味着标准解压过程不检测它的输入,而是直接产生一个错误的输出。SCO 的 `compress -H` 格式(lzh 压缩方法)不包括 CRC 校验码,但也允许一些相容性检查。 -``` ### 结语 diff --git a/sources/tech/20171010 How to test internet speed in Linux terminal.md b/published/20171010 How to test internet speed in Linux terminal.md similarity index 58% rename from sources/tech/20171010 How to test internet speed in Linux terminal.md rename to published/20171010 How to test internet speed in Linux terminal.md index 85c1832153..066d473d69 100644 --- a/sources/tech/20171010 How to test internet speed in Linux terminal.md +++ b/published/20171010 How to test internet speed in Linux terminal.md @@ -1,21 +1,21 @@ -Translating by FelixYFZ -How to test internet speed in Linux terminal +如何在Linux的终端测试网速 ====== -Learn how to use speedtest cli tool to test internet speed in Linux terminal. Also includes one liner python command to get speed details right away. -![test internet speed in linux terminal][1] +> 学习如何在 Linux 终端使用命令行工具 `speedtest` 测试网速,或者仅用一条 python 命令立刻获得网速的测试结果。 -Most of us check the internet bandwidth speed whenever we connect to new network or wifi. So why not our servers! Here is a tutorial which will walk you through to test internet speed in Linux terminal. +![在Linux终端测试网速][1] -Everyone of us generally uses [Speedtest by Ookla][2] to check internet speed. Its pretty simple process for a desktop. Goto their website and just click GO button. It will scans your location and speed test with nearest server. If you are on mobile, they have their app for you. But if you are on terminal with command line interface things are little different. Lets see how to check internet speed from Linux terminal. +我们都会在连接到一个新的网络或者 WIFI 的时候去测试网络带宽。 为什么不用我们自己的服务器!下面将会教你如何在 Linux 终端测试网速。 -If you want to speed check only once and dont want to download tool on server, jump here and see one liner command. +我们多数都会使用 [Ookla 的 Speedtest][2] 来测试网速。 这在桌面上是很简单的操作,访问他们的网站点击“Go”浏览即可。它将使用最近的服务器来扫描你的本地主机来测试网速。 如果你使用的是移动设备,他们有对应的移动端 APP。但如果你使用的是只有命令行终端,界面的则会有些不同。下面让我们一起看看如何在Linux的终端来测试网速。 -### Step 1 : Download speedtest cli tool +如果你只是想偶尔的做一次网速测试而不想去下载测试工具,那么请往下看如何使用命令完成测试。 -First of all, you have to download speedtest CLI tool from [github repository][3]. Now a days, its also included in many well known Linux repositories as well. If its their in yours then you can directly [install that package on your Linux distro][4]. +### 第一步:下载网速测试命令行工具。 -Lets proceed with Github download and install process. [Install git package][4] depending on your distro. Then clone Github repo of speedtest like belwo : +首先,你需要从 [GitHub][3] 上下载 `speedtest` 命令行工具。现在,它也被包含在许多其它的 Linux 仓库中,如果已经在你的库中,你可以直接[在你的 Linux 发行版上进行安装][4]。 + +让我们继续下载和安装过程,安装的 git 包取决于你的 Linux 发行版。然后按照下面的方法来克隆 Github speedtest 存储库 ``` [root@kerneltalks ~]# git clone https://github.com/sivel/speedtest-cli.git @@ -24,10 +24,9 @@ remote: Counting objects: 913, done. remote: Total 913 (delta 0), reused 0 (delta 0), pack-reused 913 Receiving objects: 100% (913/913), 251.31 KiB | 143.00 KiB/s, done. Resolving deltas: 100% (518/518), done. - ``` -It will be cloned to your present working directory. New directory named `speedtest-cli` will be created. You can see below files in it. +它将会被克隆到你当前的工作目录,新的名为 `speedtest-cli` 的目录将会被创建,你将在新的目录下看到如下的文件。 ``` [root@kerneltalks ~]# cd speedtest-cli @@ -45,13 +44,13 @@ total 96 -rw-r--r--. 1 root root 333 Oct 7 16:55 tox.ini ``` -The python script `speedtest.py` is the one we will be using to check internet speed. +名为 `speedtest.py` 的 Python 脚本文件就是用来测试网速的。 -You can link this script for a command in /usr/bin so that all users on server can use it. Or you can even create [command alias][5] for it and it will be easy for all users to use it. +你可以将这个脚本链接到 `/usr/bin` 下,以便这台机器上的所有用户都能使用。或者你可以为这个脚本创建一个[命令别名][5],这样就能让所有用户很容易使用它。 -### Step 2 : Run python script +### 运行 Python 脚本 -Now, run python script without any argument and it will search nearest server and test your internet speed. +现在,直接运行这个脚本,不需要添加任何参数,它将会搜寻最近的服务器来测试你的网速。 ``` [root@kerneltalks speedtest-cli]# python speedtest.py @@ -66,13 +65,13 @@ Testing upload speed............................................................ Upload: 323.95 Mbit/s ``` -Oh! Dont amaze with speed. 😀 I am on [AWS EC2 Linux server][6]. Thats the bandwidth of Amazon data center! 🙂 +Oh! 不要被这个网速惊讶道。我在 AWE EX2 的服务器上。那是亚马逊数据中心的网速! -### Different options with script +### 这个脚本可以添加有不同的选项。 -Few options which might be useful are as below : +下面的几个选项对这个脚本可能会很有用处: - **To search speedtest servers** nearby your location use `--list` switch and `grep` for your location name. +**要搜寻你附近的网路测试服务器**,使用 `--list` 和 `grep` 加上地名来列出所有附近的服务器。 ``` [root@kerneltalks speedtest-cli]# python speedtest.py --list | grep -i mumbai @@ -90,11 +89,11 @@ Few options which might be useful are as below : 6403) YOU Broadband India Pvt Ltd., Mumbai (Mumbai, India) [1.15 km] ``` -You can see here, first column is server identifier followed by name of company hosting that server, location and finally its distance from your location. +然后你就能从搜寻结果中看到,第一列是服务器识别号,紧接着是公司的名称和所在地,最后是离你的距离。 - **To test internet speed using specific server** use `--server` switch and server identifier from previous output as argument. +**如果要使用指定的服务器来测试网速**,后面跟上 `--server` 加上服务器的识别号。 -``` +``` [root@kerneltalks speedtest-cli]# python speedtest.py --server 2827 Retrieving speedtest.net configuration... Testing from Amazon (35.154.184.126)... @@ -107,7 +106,7 @@ Testing upload speed............................................................ Upload: 69.25 Mbit/s ``` -**To get share link of your speed test** , use `--share` switch. It will give you URL of your test hosted on speedtest website. You can share this URL. +**如果想得到你的测试结果的分享链接**,使用 `--share`,你将会得到测试结果的链接。 ``` [root@kerneltalks speedtest-cli]# python speedtest.py --share @@ -121,24 +120,23 @@ Download: 621.00 Mbit/s Testing upload speed................................................................................................ Upload: 367.37 Mbit/s Share results: http://www.speedtest.net/result/6687428141.png - ``` -Observe last line which includes URL of your test result. If I download that image its the one below : +输出中的最后一行就是你的测试结果的链接。下载下来的图片内容如下 : ![Speedtest result on Linux][7] -Thats it! But hey if you dont want all this technical jargon, you can even use below one liner to get speed test done right away. +这就是全部的过程!如果你不想了解这些技术细节,你也可以使用如下的一行命令迅速测出你的网速。 -### Internet speed test using one liner in terminal +### 要想在终端使用一条命令测试网速。 -We are going to use [curl tool ][8]to fetch above said python script online and supply it to python for execution on the go! +我们将使用 `curl` 工具来在线抓取上面使用的 Python 脚本然后直接用 Python 执行脚本。 ``` [root@kerneltalks ~]# curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python - ``` -Above command will run the script and show you result on screen! +上面的脚本将会运行脚本输出结果到屏幕上。 ``` [root@kerneltalks speedtest-cli]# curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python - @@ -153,24 +151,24 @@ Testing upload speed............................................................ Upload: 355.84 Mbit/s ``` -I tested this tool on RHEL 7 server but process is same on Ubuntu, Debian, Fedora or CentOS. +这是在 RHEL 7 上执行的结果,在 Ubuntu、Debian、Fedora 或者 CentOS 上一样可以执行。 -------------------------------------------------------------------------------- via: https://kerneltalks.com/tips-tricks/how-to-test-internet-speed-in-linux-terminal/ 作者:[Shrikant Lavhate][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[FelixYFZ](https://github.com/FelixYFZ) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://kerneltalks.com -[1]:https://c1.kerneltalks.com/wp-content/uploads/2017/10/check-internet-speed-from-Linux.png +[1]:https://a1.kerneltalks.com/wp-content/uploads/2017/10/check-internet-speed-from-Linux.png [2]:http://www.speedtest.net/ [3]:https://github.com/sivel/speedtest-cli [4]:https://kerneltalks.com/tools/package-installation-linux-yum-apt/ [5]:https://kerneltalks.com/commands/command-alias-in-linux-unix/ [6]:https://kerneltalks.com/howto/install-ec2-linux-server-aws-with-screenshots/ -[7]:https://c3.kerneltalks.com/wp-content/uploads/2017/10/speedtest-on-linux.png +[7]:https://a3.kerneltalks.com/wp-content/uploads/2017/10/speedtest-on-linux.png [8]:https://kerneltalks.com/tips-tricks/4-tools-download-file-using-command-line-linux/ diff --git a/translated/tech/20171014 Proxy Models in Container Environments.md b/published/20171014 Proxy Models in Container Environments.md similarity index 53% rename from translated/tech/20171014 Proxy Models in Container Environments.md rename to published/20171014 Proxy Models in Container Environments.md index 4e5b329d68..3592ce567e 100644 --- a/translated/tech/20171014 Proxy Models in Container Environments.md +++ b/published/20171014 Proxy Models in Container Environments.md @@ -1,41 +1,43 @@ 容器环境中的代理模型 ============================================================ -### 我们大多数人都熟悉代理如何工作,但在基于容器的环境中有什么不同?看看有什么改变。 +> 我们大多数人都熟悉代理如何工作,但在基于容器的环境中有什么不同?让我们来看看有什么改变。 -内联,side-arm,反向和前向。这些曾经是我们用来描述网络代理架构布局的术语。 +内联、侧臂side-arm、反向和前向。这些曾经是我们用来描述网络代理架构布局的术语。 如今,容器使用一些相同的术语,但它们正在引入新的东西。这对我是个机会来阐述我最爱的所有主题:代理。 -云的主要驱动之一(我们曾经有过成果控制的白日梦)就是可扩展性。在过去五年中,扩展在各种调查中面临着敏捷性的挑战(有时甚至获胜),因为这是机构在云计算环境中部署应用的最大追求。 +云的主要驱动之一(我们曾经有过成本控制的白日梦)就是可扩展性。在过去五年中,扩展在各种调查中面临着敏捷性的挑战(有时甚至获胜),因为这是机构在云计算环境中部署应用的最大追求。 -这在一定程度上是因为在数字经济 (我们现在运营的) 中,应用已经成为数字等同于实体店的“开放/关闭”的标志和数字客户援助的体现。缓慢、无响应的应用程序等同于把灯关闭或者商店人员不足。 +这在一定程度上是因为在(我们现在运营的)数字经济中,应用已经成为像实体店的“营业/休息”的标牌和导购一样的东西。缓慢、无响应的应用如同商店关灯或缺少营业人员一样。 -应用程序需要可用且响应满足需求。扩展是实现这一业务目标的技术响应。云不仅提供了扩展的能力,而且还提供了_自动_扩展的能力。要做到这一点,需要一个负载均衡器。因为这就是我们扩展应用程序的方式 - 使用代理负载均衡流量/请求。 + [![](https://devcentral.f5.com/Portals/0/Users/038/38/38/unavailable_is_closed_thumb.png?ver=2017-09-12-082119-957)][4] + +应用需要随时可用且能够满足需求。扩展是实现这一业务目标的技术响应。云不仅提供了扩展的能力,而且还提供了_自动_扩展的能力。要做到这一点,需要一个负载均衡器。因为这就是我们扩展应用程序的方式 :使用代理来负载均衡流量/请求。 -容器在扩展上与预期没有什么不同。容器必须进行扩展 - 并自动扩展 - 这意味着使用负载均衡器(代理)。 +容器在扩展上与预期没有什么不同。容器必须进行扩展(并自动扩展)这意味着使用负载均衡器(代理)。 -如果你使用的是本机,则你正在基于 TCP/UDP 进行基本的负载平衡。一般来说,基于容器的代理实现在 HTTP 或其他应用层协议中不流畅,除了一般的旧的负载均衡([POLB][1])之外,不提供其他功能。这通常足够好,因为容器扩展是在一个克隆的水平预置环境中进行的 - 要扩展一个应用程序,添加另一个副本并在其上分发请求。在入口处(在[入口控制器][2]和 API 网关中)可以找到第 7 层(HTTP)路由功能,并且可以使用尽可能多(或更多)的应用程序路由来扩展应用程序。 +如果你使用的是原有的代理机制,那就是采用基于 TCP/UDP 进行基本的负载平衡。一般来说,基于容器的代理的实现在 HTTP 或其他应用层协议中并不流畅,并不能在旧式的负载均衡([POLB][1])之外提供其他功能。这通常足够了,因为容器扩展是在一个克隆的、假定水平扩展的环境中进行的:要扩展一个应用程序,就添加另一个副本并在其上分发请求。在入口处(在[入口控制器][2]和 API 网关中)可以找到第 7 层(HTTP)路由功能,并且可以使用尽可能多(或更多)的应用路由来扩展应用程序。 -然而,在某些情况下,这还不够。如果你希望(或需要)更多以应用程序为中心的扩展或插入其他服务的能力,那么你将获得更健壮的产品,可提供可编程性或以应用程序为中心的可伸缩性,或者两者兼而有之。 +然而,在某些情况下,这还不够。如果你希望(或需要)更多以应用程序为中心的扩展或插入其他服务的能力,那么你就可以获得更健壮的产品,可提供可编程性或以应用程序为中心的可伸缩性,或者两者兼而有之。 -这意味着[插入代理][3]。你正在使用的容器编排环境在很大程度上决定了代理的部署模型,无论它是反向代理还是前向代理。为了让事情有趣,还有第三个模型 - sidecar - 这是由新兴的服务网格实现支持的可扩展性的基础。 +这意味着[插入代理][3]。你正在使用的容器编排环境在很大程度上决定了代理的部署模型,无论它是反向代理还是前向代理。更有趣的是,还有第三个模型挎斗模式 ,这是由新兴的服务网格实现支持的可扩展性的基础。 ### 反向代理 - [![Image title](https://devcentral.f5.com/Portals/0/Users/038/38/38/unavailable_is_closed_thumb.png?ver=2017-09-12-082119-957 "Image title")][4] +![](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-app_reverse_proxy.jpg) -反向代理最接近于传统模型,在这种模型中,虚拟服务器接受所有传入请求,并将其分发到资源池(服务器中心,集群)中。 +反向代理最接近于传统模型,在这种模型中,虚拟服务器接受所有传入请求,并将其分发到资源池(服务器中心、集群)中。 -每个“应用程序”有一个代理。任何想要连接到应用程序的客户端连接到代理,代理然后选择并转发请求到适当的实例。如果绿色应用想要与蓝色应用通信,它会向蓝色代理发送请求,蓝色代理会确定蓝色应用的两个实例中的哪一个应该响应该请求。 +每个“应用程序”有一个代理。任何想要连接到应用程序的客户端都连接到代理,代理然后选择并转发请求到适当的实例。如果绿色应用想要与蓝色应用通信,它会向蓝色代理发送请求,蓝色代理会确定蓝色应用的两个实例中的哪一个应该响应该请求。 在这个模型中,代理只关心它正在管理的应用程序。蓝色代理不关心与橙色代理关联的实例,反之亦然。 ### 前向代理 - [![Image title](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-node_forward_proxy_thumb.jpg?ver=2017-09-14-072422-213)][5] + [![](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-node_forward_proxy.jpg?ver=2017-09-14-072422-213)][5] -这种模式更接近传统出站防火墙的模式。 +这种模式更接近传统的出站防火墙的模式。 在这个模型中,每个容器 **节点** 都有一个关联的代理。如果客户端想要连接到特定的应用程序或服务,它将连接到正在运行的客户端所在的容器节点的本地代理。代理然后选择一个适当的应用实例,并转发客户端的请求。 @@ -43,31 +45,31 @@ 在这个模型中,每个代理必须知道每个应用,以确保它可以将请求转发给适当的实例。 -### sidecar 代理 +### 挎斗代理 - [![Image title](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-pod_sidecar_proxy_thumb.jpg?ver=2017-09-14-072425-620)][6] + [![](https://devcentral.f5.com/Portals/0/Users/038/38/38/per-pod_sidecar_proxy.jpg?ver=2017-09-14-072425-620)][6] 这种模型也被称为服务网格路由。在这个模型中,每个**容器**都有自己的代理。 -如果客户想要连接到一个应用,它将连接到 sidecar 代理,它会选择一个合适的应用程序实例并转发客户端的请求。此行为与_前向代理_模型相同。 +如果客户想要连接到一个应用,它将连接到挎斗代理,它会选择一个合适的应用程序实例并转发客户端的请求。此行为与_前向代理_模型相同。 -sidecar 和前向代理之间的区别在于,sidecar 代理不需要修改容器编排环境。例如,为了插入一个前向代理到 k8s,你需要代理_和_一个 kube-proxy 的替代。sidecar 代理不需要此修改,因为应用会自动连接到 “sidecar” 代理而不是通过代理路由。 +挎斗代理和前向代理之间的区别在于,挎斗代理不需要修改容器编排环境。例如,为了插入一个前向代理到 k8s,你需要代理_和_一个 kube-proxy 的替代。挎斗代理不需要这种修改,因为应用会自动连接到 “挎斗” 代理而不是通过代理路由。 ### 总结 -每种模式都有其优点和缺点。三者共同依赖环境数据(远程监控和配置变化),以及融入生态系统的需求。有些模型是根据你选择的环境预先确定的,因此需要仔细考虑将来的需求 - 服务插入、安全性、网络复杂性 - 在建立模型之前需要进行评估。 +每种模式都有其优点和缺点。三者共同依赖环境数据(远程监控和配置变化),以及融入生态系统的需求。有些模型是根据你选择的环境预先确定的,因此需要仔细考虑将来的需求(服务插入、安全性、网络复杂性)在建立模型之前需要进行评估。 在容器及其在企业中的发展方面,我们还处于早期阶段。随着它们继续延伸到生产环境中,了解容器化环境发布的应用程序的需求以及它们在代理模型实现上的差异是非常重要的。 -我是急性写下这篇文章的。现在就这么多。 +这篇文章是匆匆写就的。现在就这么多。 -------------------------------------------------------------------------------- via: https://dzone.com/articles/proxy-models-in-container-environments -作者:[Lori MacVittie ][a] +作者:[Lori MacVittie][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171016 5 SSH alias examples in Linux.md b/published/20171016 5 SSH alias examples in Linux.md new file mode 100644 index 0000000000..bcfc643750 --- /dev/null +++ b/published/20171016 5 SSH alias examples in Linux.md @@ -0,0 +1,210 @@ +Linux 中的 5 个 SSH 别名例子 +====== + +[![][1]][1] + +作为一个 Linux 用户,我们常用 [ssh 命令][2] 来登入远程机器。`ssh` 命令你用得越多,你在键入一些重要的命令上花的时间也越多。我们可以用 [定义在你的 .bashrc 文件里的别名][3] 或函数来大幅度缩减花在命令行界面(CLI)的时间。但这不是最佳解决之道。最佳办法是在 `ssh` 配置文件中使用 **SSH 别名** 。 + +这里是我们能把 `ssh` 命令用得更好的几个例子。 + +ssh 登入到 AWS(译注:Amazon Web Services,亚马逊公司旗下云计算服务平台)实例的连接是一种痛。仅仅输入以下命令,每次也完全是浪费你时间。 + +``` +ssh -p 3000 -i /home/surendra/mysshkey.pem ec2-user@ec2-54-20-184-202.us-west-2.compute.amazonaws.com +``` + +缩短到: + +``` +ssh aws1 +``` + +调试时连接到系统。 + +``` +ssh -vvv the_good_user@red1.taggle.abc.com.au +``` + +缩短到: + +``` +ssh xyz +``` + +在本篇中,我们将看到如何不使用 bash 别名或函数实现 `ssh` 命令的缩短。`ssh` 别名的主要优点是所有的 `ssh` 命令快捷方式都存储在一个单一文件,如此就易于维护。其他优点是 **对于类似于 SSH 和 SCP 的命令** 我们能用相同的别名。 + +在我们进入实际配置之前,我们应该知道 `/etc/ssh/ssh_config`、`/etc/ssh/sshd_config` 和 `~/.ssh/config` 文件三者的区别。以下是对这些文件的解释。 + +### /etc/ssh/ssh_config 和 ~/.ssh/config 间的区别 + +系统级别的 SSH 配置项存放在 `/etc/ssh/ssh_config`,而用户级别的 SSH 配置项存放在 `~/.ssh/config` 文件中。 + +### /etc/ssh/ssh_config 和 /etc/ssh/sshd_config 间的区别 + +系统级别的 SSH 配置项是在 `/etc/ssh/ssh_config` 文件中,而系统级别的 SSH **服务端**配置项存放在 `/etc/ssh/sshd_config` 文件。 + +### 在 ~/.ssh/config 文件里配置项的语法 + +`~/.ssh/config` 文件内容的语法: + +``` +配置项 值 +配置项 值1 值2 +``` + +**例 1:** 创建主机(www.linuxnix.com)的 SSH 别名 + +编辑 `~/.ssh/config` 文件写入以下内容: + +``` +Host tlj + User root + HostName 18.197.176.13 + port 22 +``` + +保存此文件。 + +以上 ssh 别名用了 + + 1. `tlj` 作为一个别名的名称 + 2. `root` 作为将要登入的用户 + 3. `18.197.176.13` 作为主机的 IP 地址 + 4. `22` 作为访问 SSH 服务的端口 + +输出: + +``` +sanne@Surendras-MacBook-Pro:~ > ssh tlj +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + Get cloud support with Ubuntu Advantage Cloud Guest: + http://www.ubuntu.com/business/services/cloud +Last login: Sat Oct 14 01:00:43 2017 from 20.244.25.231 +root@linuxnix:~# exit +logout +Connection to 18.197.176.13 closed. +``` + +**例 2:** 不用密码用 ssh 密钥登到系统要用 `IdentityFile` 。 + +例: + +``` +Host aws + User ec2-users + HostName ec2-54-200-184-202.us-west-2.compute.amazonaws.com + IdentityFile ~/Downloads/surendra.pem + port 22 +``` + +**例 3:** 对同一主机使用不同的别名。在下例中,我们对同一 IP/主机 18.197.176.13 用了 `tlj`、 `linuxnix`、`linuxnix.com` 三个别名。 + +~/.ssh/config 文件内容 +``` +Host tlj linuxnix linuxnix.com + User root + HostName 18.197.176.13 + port 22 +``` + +**输出:** + +``` +sanne@Surendras-MacBook-Pro:~ > ssh tlj +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) +* Documentation: https://help.ubuntu.com +* Management: https://landscape.canonical.com +* Support: https://ubuntu.com/advantage +Get cloud support with Ubuntu Advantage Cloud Guest: +http://www.ubuntu.com/business/services/cloud +Last login: Sat Oct 14 01:00:43 2017 from 220.244.205.231 +root@linuxnix:~# exit +logout +Connection to 18.197.176.13 closed. +sanne@Surendras-MacBook-Pro:~ > ssh linuxnix.com +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) +* Documentation: https://help.ubuntu.com +* Management: https://landscape.canonical.com +* Support: https://ubuntu.com/advantage +``` +``` +Get cloud support with Ubuntu Advantage Cloud Guest: +http://www.ubuntu.com/business/services/cloud +Last login: Sun Oct 15 20:31:08 2017 from 1.129.110.13 +root@linuxnix:~# exit +logout +Connection to 138.197.176.103 closed. +[6571] sanne@Surendras-MacBook-Pro:~ > ssh linuxnix +Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64) +* Documentation: https://help.ubuntu.com +* Management: https://landscape.canonical.com +* Support: https://ubuntu.com/advantage +Get cloud support with Ubuntu Advantage Cloud Guest: +http://www.ubuntu.com/business/services/cloud +Last login: Sun Oct 15 20:31:20 2017 from 1.129.110.13 +root@linuxnix:~# exit +logout +Connection to 18.197.176.13 closed. +``` + +**例 4:** 用相同的 SSH 别名复制文件到远程系统 + +语法: + +``` +scp <文件名> :<位置> +``` + +例子: + +``` +sanne@Surendras-MacBook-Pro:~ > scp abc.txt tlj:/tmp +abc.txt 100% 12KB 11.7KB/s 00:01 +sanne@Surendras-MacBook-Pro:~ > +``` + +若我们已经将 ssh 主机设置好一个别名,由于 `ssh` 和 `scp` 两者用几乎相同的语法和选项,`scp` 也可以轻易使用。 + +请在下面尝试从本机 `scp` 一个文件到远程机器。 + +**例 5:** 解决 Linux 中的 SSH 超时问题。默认情况,如果你不积极地使用终端,你的 ssh 登入就会超时 + +[SSH 超时问题][5] 是一个更痛的点意味着你在一段时间后不得不重新登入到远程机器。我们能在 `~/.ssh/config` 文件里边恰当地设置 SSH 超时时间来使你的会话不管在什么时间总是激活的。我们将用 2 个能保持会话存活的 SSH 选项来实现这一目的。之一是 `ServerAliveInterval` 保持你会话存活的秒数和 `ServerAliveCountMax` 在(经历了一个)给定数值的会话之后初始化会话。 + +``` +ServerAliveInterval A +ServerAliveCountMax B +``` + +**例:** + +``` +Host tlj linuxnix linuxnix.com + User root + HostName 18.197.176.13 + port 22 + ServerAliveInterval 60 + ServerAliveCountMax 30 +``` + +在下篇中我们将会看到一些其他的退出方式。 + +-------------------------------------------------------------------------------- + +via: https://www.linuxnix.com/5-ssh-alias-examples-using-ssh-config-file/ + +作者:[SURENDRA ANNE][a] +译者:[ch-cn](https://github.com/ch-cn) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linuxnix.com +[1]:https://www.linuxnix.com/wp-content/uploads/2017/10/SSH-alias-1.png +[2]:https://www.linuxnix.com/ssh-access-remote-linux-server/ +[3]:https://www.linuxnix.com/linux-alias-command-explained-with-examples/ +[4]:/cdn-cgi/l/email-protection +[5]:https://www.linuxnix.com/how-to-auto-logout/ diff --git a/published/20171018 Install a Centralized Log Server with Rsyslog in Debian 9.md b/published/20171018 Install a Centralized Log Server with Rsyslog in Debian 9.md new file mode 100644 index 0000000000..f13a69acab --- /dev/null +++ b/published/20171018 Install a Centralized Log Server with Rsyslog in Debian 9.md @@ -0,0 +1,258 @@ +在 Debian 9 上使用 Rsyslog 安装一台中央日志服务器 +====== + +在 Linux 上,日志文件包含了系统功能的信息,系统管理员经常使用日志来确认机器上的问题所在。日志可以帮助管理员还原在过去的时间中在系统中发生的事件。一般情况下,Linux 中所有的日志文件都保存在 `/var/log` 目录下。在这个目录中,有保存着各种信息的几种类型的日志文件。比如,记录系统事件的日志文件、记录安全相关信息的日志文件、内核专用的日志文件、用户或者 cron 作业使用的日志文件。日志文件的主要作用是系统调试。Linux 中的大部分的日志文件都由 rsyslogd 服务来管理。在最新的 Linux 发行版中,日志文件也可能是由 journald 系统服务来管理和控制的。journald 服务是 systemd 初始化程序的一部分。journald 以二进制的格式存储日志,以易失性的方式写入到内存和 `/run/log/journal/` 中的环状缓冲区中,但是,journald 也可以配置为永久存储到 syslog 中。 + +在 Linux 中,可以配置运行一个 Rsyslog 服务器来中央化管理日志,在流行的服务端—客户端模式中,通过 TCP 或者 UDP 传输协议基于网络来发送日志信息,或者从网络设备、服务器、路由器、交换机、以及其它系统或嵌入式设备中接受生成的日志。 + +Rsyslog 守护程序可以被同时配置为以客户端或者服务端方式运行。配置作为服务器时,Rsyslog 将缺省监听 TCP 和 UDP 的 514 端口,来收集远程系统基于网络发送的日志信息。配置为客户端运行时,Rsyslog 将通过相同的 TCP 或 UDP 端口基于网络来发送内部日志信息。 + +Rsyslog 可以根据选定的属性和动作来过滤 syslog 信息。Rsyslog 拥有的过滤器如下: + + 1. 设备或者优先级过滤器 + 2. 基于特性的过滤器 + 3. 基于表达式的过滤器 + +设备过滤器代表了生成日志的 Linux 内部子系统。它们目前的分类如下: + + * `auth/authpriv` = 由验证进程产生的信息 + * `cron` = cron 任务相关的日志 + * `daemon` = 正在运行的系统服务相关的信息 + * `kernel` = Linux 内核信息 + * `mail` = 邮件服务器信息 + * `syslog` = syslog 或者其它守护程序(DHCP 服务器发送的日志在这里)相关的信息 + * `lpr` = 打印机或者打印服务器信息 + * `local0` ~ `local7` = 管理员控制下的自定义信息 + +优先级或者严重程度级别分配如下所述的一个关键字或者一个数字。 + + * `emerg` = 紧急 - 0 + * `alert` = 警报 - 1 + * `err` = 错误 - 3 + * `warn` = 警告 - 4 + * `notice` = 提示 - 5 + * `info` = 信息 - 6 + * `debug` = 调试 - 7 (最高级别) + +此外也有一些 Rsyslog 专用的关键字,比如星号(`*`)可以用来定义所有的设备和优先级,`none` 关键字更具体地表示没有优先级,等号(`=`)表示仅那个优先级,感叹号(`!`)表示取消这个优先级。 + +Rsyslog 的动作部分由声明的目的地来表示。日志信息的目的地可以是:存储在文件系统中的一个文件、 `/var/log/` 目录下的一个文件、通过命名管道或者 FIFO 作为输入的另一个本地进程。日志信息也可以直达用户,或者丢弃到一个“黑洞”(`/dev/null`)中、或者发送到标准输出、或者通过一个 TCP/UDP 协议发送到一个远程 syslog 服务器。日志信息也可以保存在一个数据库中,比如 MySQL 或者 PostgreSQL。 + +### 配置 Rsyslog 为服务器 + +在大多数 Linux 发行版中 Rsyslog 守护程序是自动安装的。如果你的系统中没有安装 Rsyslog,你可以根据你的系统发行版执行如下之一的命令去安装这个服务。_运行这个命令必须有 root 权限_。 + +在基于 Debian 的发行版中: + +``` +sudo apt-get install rsyslog +``` + +在基于 RHEL 的发行版中,比如像 CentOS: + +``` +sudo yum install rsyslog +``` + +验证 Rsyslog 守护进程是否在你的系统中运行,根据发行版不同,可以选择运行下列的命令: + +在新的使用 systemd 的 Linux 发行版中: + +``` +systemctl status rsyslog.service +``` + +在老的使用 init 的 Linux 发行版中: + +``` +service rsyslog status +``` + +或 + +``` +/etc/init.d/rsyslog status +``` + +启动 rsyslog 守护进程运行如下的命令。 + +在使用 init 的老的 Linux 版本: + +``` +service rsyslog start +``` + +或 + +``` +/etc/init.d/rsyslog start +``` + +在最新的 Linux 发行版: + +``` +systemctl start rsyslog.service +``` + +安装一个 rsyslog 程序运行为服务器模式,可以编辑主要的配置文件 `/etc/rsyslog.conf` 。可以使用下列所示的命令去改变它。 + +``` +sudo vi /etc/rsyslog.conf +``` + +为了允许在 UDP 的 514 端口上接收日志信息,找到并删除下列行前面的井号(`#`)以取消注释。缺省情况下,UDP 端口用于 syslog 去接收信息。 + +``` +$ModLoad imudp +$UDPServerRun 514 +``` + +因为在网络上使用 UDP 协议交换数据并不可靠,你可以设置 Rsyslog 使用 TCP 协议去向远程服务器输出日志信息。为了启用 TCP 协议去接受日志信息,打开 `/etc/rsyslog.conf` 文件并删除如下行前面的井号(`#`)以取消注释。这将允许 rsyslog 守护程序去绑定并监听 TCP 协议的 514 端口。 + +``` +$ModLoad imtcp +$InputTCPServerRun 514 +``` + +_在 rsyslog 上可以**同时**启用两种协议_。 + +如果你想去指定哪个发送者被允许访问 rsyslog 守护程序,可以在启用协议行的后面添加如下的行: + +``` +$AllowedSender TCP, 127.0.0.1, 10.110.50.0/24, *.yourdomain.com +``` + +在接收入站日志信息之前,你需要去创建一个 rsyslog 守护程序解析日志的新模板,这个模板将指示本地 Rsyslog 服务器在哪里保存入站的日志信息。在 `$AllowedSender` 行后以如下示例去创建一个合适的模板。 + +``` +$template Incoming-logs,"/var/log/%HOSTNAME%/%PROGRAMNAME%.log"  +*.*  ?Incoming-logs +& ~ +``` + +为了仅接收内核生成的日志信息,可以使用如下的语法。 + +``` +kern.*   ?Incoming-logs +``` + +接收到的日志由上面的模板来解析,它将保存在本地文件系统的 `/var/log/` 目录的文件中,之后的是以客户端主机名客户端设备名命名的日志文件名字:`%HOSTNAME%` 和 `%PROGRAMNAME%` 变量。 + +下面的 `& ~` 重定向规则,配置 Rsyslog 守护程序去保存入站日志信息到由上面的变量名字指定的文件中。否则,接收到的日志信息将被进一步处理,并将保存在本地的日志文件中,比如,`/var/log/syslog` 文件中。 + +为添加一个规则去丢弃所有与邮件相关的日志信息,你可以使用下列的语法。 + +``` +mail.* ~ +``` + +可以在输出文件名中使用的其它变量还有:`%syslogseverity%`、`%syslogfacility%`、`%timegenerated%`、`%HOSTNAME%`、`%syslogtag%`、`%msg%`、`%FROMHOST-IP%`、`%PRI%`、`%MSGID%`、`%APP-NAME%`、`%TIMESTAMP%`、%$year%、`%$month%`、`%$day%`。 + +从 Rsyslog 版本 7 开始,将使用一个新的配置格式,在一个 Rsyslog 服务器中声明一个模板。 + +一个版本 7 的模板应该看起来是如下行的样子。 + +``` +template(name="MyTemplate" type="string" +         string="/var/log/%FROMHOST-IP%/%PROGRAMNAME:::secpath-replace%.log" +        ) +``` + +另一种模式是,你也可以使用如下面所示的样子去写上面的模板: + +``` +template(name="MyTemplate" type="list") { +    constant(value="/var/log/") +    property(name="fromhost-ip") +    constant(value="/") +    property(name="programname" SecurePath="replace") +    constant(value=".log") +    } +``` + +为了让 Rsyslog 配置文件的变化生效,你必须重启守护程序来加载新的配置。 + +``` +sudo service rsyslog restart +``` + +``` +sudo systemctl restart rsyslog +``` + +在 Debian Linux 系统上去检查它监听哪个套接字,你可以用 root 权限去运行 `netstat` 命令。将输出传递给一个过滤程序,比如 `grep`。 + +``` +sudo netstat -tulpn | grep rsyslog +``` + +请注意: 为了允许建立入站连接,你必须在防火墙上打开 Rsyslog 的端口。 + +在使用 Firewalld 的基于 RHEL 的发行版上,运行如下的命令: + +``` +firewall-cmd --permanent --add-port=514/tcp +firewall-cmd --permanent --add-port=514/tcp +firewall-cmd -reload +``` + +在使用 UFW 的基于 Debian 的发行版上,运行如下的命令: + +``` +ufw allow 514/tcp +ufw allow 514/udp +``` + +Iptables 防火墙规则: + +``` +iptables -A INPUT -p tcp -m tcp --dport 514 -j ACCEPT +iptables -A INPUT -p udp --dport 514 -j ACCEPT +``` + +### 配置 Rsyslog 作为一个客户端 + +启用 Rsyslog 守护程序以客户端模式运行,并将输出的本地日志信息发送到远程 Rsyslog 服务器,编辑 `/etc/rsyslog.conf` 文件并增加下列的行: + +``` +*. * @IP_REMOTE_RSYSLOG_SERVER:514 +*. * @FQDN_RSYSLOG_SERVER:514 +``` + +这个行启用了 Rsyslog 服务,并将输出的所有内部日志发送到一个远处的 UDP 的 514 端口上运行的 Rsyslog 服务器上。 + +为了使用 TCP 协议去发送日志信息,使用下列的模板: + +``` +*. *  @@IP_reomte_syslog_server:514 +``` + +输出所有优先级的、仅与 cron 相关的日志信息到一个 Rsyslog 服务器上,使用如下的模板: + +``` +cron.* @ IP_reomte_syslog_server:514 +``` + +在 `/etc/rsyslog.conf` 文件中添加下列行,可以在 Rsyslog 服务器无法通过网络访问时,临时将客户端的日志信息存储在它的一个磁盘缓冲文件中,当网络或者服务器恢复时,再次进行发送。 + +``` +$ActionQueueFileName queue +$ActionQueueMaxDiskSpace 1g +$ActionQueueSaveOnShutdown on +$ActionQueueType LinkedList +$ActionResumeRetryCount -1 +``` + +为使上述规则生效,需要重新 Rsyslog 守护程序,以激活为客户端模式。 + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/tutorial/rsyslog-centralized-log-server-in-debian-9/ + +作者:[Matt Vas][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.howtoforge.com diff --git a/published/20171027 Scary Linux commands for Halloween.md b/published/20171027 Scary Linux commands for Halloween.md new file mode 100644 index 0000000000..4f88023a72 --- /dev/null +++ b/published/20171027 Scary Linux commands for Halloween.md @@ -0,0 +1,106 @@ +可怕的万圣节 Linux 命令 +====== + +![](https://images.idgesg.net/images/article/2017/10/animal-skeleton-100739983-large.jpg) + +虽然现在不是万圣节,也可以关注一下 Linux 可怕的一面。什么命令可能会显示鬼、巫婆和僵尸的图像?哪个会鼓励“不给糖果就捣蛋”的精神? + +### crypt + +好吧,我们一直看到 `crypt`。尽管名称不同,crypt 不是一个地窖,也不是垃圾文件的埋葬坑,而是一个加密文件内容的命令。现在,`crypt` 通常用一个脚本实现,通过调用一个名为 `mcrypt` 的二进制文件来模拟以前的 `crypt` 命令来完成它的工作。直接使用 `mycrypt` 命令是更好的选择。 + +``` +$ mcrypt x +Enter the passphrase (maximum of 512 characters) +Please use a combination of upper and lower case letters and numbers. +Enter passphrase: +Enter passphrase: + +File x was encrypted. +``` + +请注意,`mcrypt` 命令会创建第二个扩展名为 `.nc` 的文件。它不会覆盖你正在加密的文件。 + +`mcrypt` 命令有密钥大小和加密算法的选项。你也可以再选项中指定密钥,但 `mcrypt` 命令不鼓励这样做。 + +### kill + +还有 `kill` 命令 - 当然并不是指谋杀,而是用来强制和非强制地结束进程,这取决于正确终止它们的要求。当然,Linux 并不止于此。相反,它有各种 `kill` 命令来终止进程。我们有 `kill`、`pkill`、`killall`、`killpg`、`rfkill`、`skill`()读作 es-kill)、`tgkill`、`tkill` 和 `xkill`。 + +``` +$ killall runme +[1] Terminated ./runme +[2] Terminated ./runme +[3]- Terminated ./runme +[4]+ Terminated ./runme +``` + +### shred + +Linux 系统也支持一个名为 `shred` 的命令。`shred` 命令会覆盖文件以隐藏其以前的内容,并确保使用硬盘恢复工具无法恢复它们。请记住,`rm` 命令基本上只是删除文件在目录文件中的引用,但不一定会从磁盘上删除内容或覆盖它。`shred` 命令覆盖文件的内容。 + +``` +$ shred dupes.txt +$ more dupes.txt +▒oΛ▒▒9▒lm▒▒▒▒▒o▒1־▒▒f▒f▒▒▒i▒▒h^}&▒▒▒{▒▒ +``` + +### 僵尸 + +虽然不是命令,但僵尸在 Linux 系统上是很顽固的存在。僵尸基本上是没有完全清理掉的死亡进程的遗骸。进程_不应该_这样工作 —— 让死亡进程四处游荡,而不是简单地让它们死亡并进入数字天堂,所以僵尸的存在表明了让他们遗留于此的进程有一些缺陷。 + +一个简单的方法来检查你的系统是否有僵尸进程遗留,看看 `top` 命令的标题行。 + +``` +$ top +top - 18:50:38 up 6 days, 6:36, 2 users, load average: 0.00, 0.00, 0.00 +Tasks: 171 total, 1 running, 167 sleeping, 0 stopped, 3 zombie `< ==` +%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.9 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st +KiB Mem : 2003388 total, 250840 free, 545832 used, 1206716 buff/cache +KiB Swap: 9765884 total, 9765764 free, 120 used. 1156536 avail Mem +``` + +可怕!上面显示有三个僵尸进程。 + +### at midnight + +有时会在万圣节这么说,死者的灵魂从日落开始游荡直到午夜。Linux 可以通过 `at midnight` 命令跟踪它们的离开。用于安排在下次到达指定时间时运行的作业,`at` 的作用类似于一次性的 cron。 + +``` +$ at midnight +warning: commands will be executed using /bin/sh +at> echo 'the spirits of the dead have left' +at> +job 3 at Thu Oct 31 00:00:00 2017 +``` + +### 守护进程 + +Linux 系统也高度依赖守护进程 —— 在后台运行的进程,并提供系统的许多功能。许多守护进程的名称以 “d” 结尾。这个 “d” 代表守护进程daemon,表明这个进程一直运行并支持一些重要功能。有的会用单词 “daemon” 。 + +``` +$ ps -ef | grep sshd +root 1142 1 0 Oct19 ? 00:00:00 /usr/sbin/sshd -D +root 25342 1142 0 18:34 ? 00:00:00 sshd: shs [priv] +$ ps -ef | grep daemon | grep -v grep +message+ 790 1 0 Oct19 ? 00:00:01 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation +root 836 1 0 Oct19 ? 00:00:02 /usr/lib/accountsservice/accounts-daemon +``` + +### 万圣节快乐! + +在 [Facebook][1] 和 [LinkedIn][2] 上加入 Network World 社区来对主题进行评论。 + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3235219/linux/scary-linux-commands-for-halloween.html + +作者:[Sandra Henry-Stocker][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[1]:https://www.facebook.com/NetworkWorld/ +[2]:https://www.linkedin.com/company/network-world diff --git a/sources/tech/20171109 How to record statistics about a Linux machine-s uptime.md b/published/20171109 How to record statistics about a Linux machine-s uptime.md similarity index 65% rename from sources/tech/20171109 How to record statistics about a Linux machine-s uptime.md rename to published/20171109 How to record statistics about a Linux machine-s uptime.md index 1a5be11efa..f1684bc9c8 100644 --- a/sources/tech/20171109 How to record statistics about a Linux machine-s uptime.md +++ b/published/20171109 How to record statistics about a Linux machine-s uptime.md @@ -1,27 +1,37 @@ -How to record statistics about a Linux machine’s uptime -====== -Linux/Unix sysadmins have a weird obsession with server uptime. There is a xkcd comic devoted to this subject where a good sysadmin is an unstoppable force that it stands between the forces of darkness and your cat blog's servers. +如何记录 Linux 的系统运行时间的统计信息 +===== + +Linux/Unix 系统管理员对服务器的系统运行时间有一种奇怪的痴迷。这里有一个关于这个主题的 xkcd 漫画,一个好的系统管理员是一股不可阻挡的力量,他伫立在你家猫咪博客的服务器之前,对抗黑暗势力。 + [![Fig.01: Devotion to Duty https://xkcd.com/705/][1]][1] -One can tell how long the Linux system has been running using the uptime command or [w command][2] or top command. I can get [a report of the historical and statistical running time of the system][3], keeping it between restarts using tuptime tool. -Like uptime command but with the more impressive output. Recently I discovered another tool called uptimed that records statistics about a machine's uptime. Let us see how to get uptime record statistics using uptimed and uprecords on Linux operating system. +我们可以使用 `uptime` 命令或 [w 命令][2] 或 `top` 命令来判断 Linux 系统运行了多久。我可以使用 `tuptime` 工具保留每次重新启动的运行时间,以[获得系统运行时间的历史和统计报告][3]。 + +这就像 `uptime` 命令一样,但输出结果更令人印象深刻。最近我发现了另一种称为 `uptimed` 的工具,用于记录关于机器的系统运行时间和统计信息。让我们看看如何使用 Linux 操作系统上的 `uptimed` 和 `uprecords` 来获得运行时间的记录统计信息。 + +查找系统运行时间非常简单,只需在基于 Linux 的系统上键入以下命令即可: -Finding uptime is pretty easy, just type the following on your Linux based system: ``` -$ **uptime -p** +$ uptime -p up 2 weeks, 4 days, 7 hours, 28 minutes ``` -To keep historical stats about uptime use either [tuptime][3] or uptimed tool. -## uptimed installation +要保留有关 `uptime` 的历史统计信息,请使用 [tuptime][3] 或 `uptimed` 工具。 -The simplest way to install uptimed locally is through your package managers such as apt/apt-get/yum and friends as per your Linux distro. +### 安装 uptimed -### Install uptimed on a Debian/Ubuntu Linux +安装 `uptimed` 的最简单的方式是通过你的软件包管理器,比如 apt/apt-get/yum 这些你的 Linux 发行版的朋友。 + +#### 在 Debian/Ubuntu Linux 上安装 uptimed + +键入以下 [apt 命令][4]/[apt-get 命令][5]: + +``` +$ sudo apt-get install uptimed +``` + +示例输出: -Type the following [apt command][4]/[apt-get command][5]: -`$ sudo apt-get install uptimed` -Sample outputs: ``` Reading package lists... Done Building dependency tree @@ -55,13 +65,22 @@ Processing triggers for systemd (229-4ubuntu21) ... Processing triggers for ureadahead (0.100.0-19) ... ``` -### Install uptimed on a CentOS/RHEL/Fedora/Oracle/Scientific Linux +#### 在 CentOS/RHEL/Fedora/Oracle/Scientific Linux 上安装 uptimed + +首先 [在 CentOS/RHEL 使用 EPEL 仓库][6]: + +``` +$ sudo yum -y install epel-release +``` + +然后,键入以下 [yum 命令][7]: + +``` +$ sudo yum install uptimed +``` + +示例输出: -First [enable EPEL repo on a CentOS/RHEL][6]: -`$ sudo yum -y install epel-release` -Next, type the following [yum command][7]: -`$ sudo yum install uptimed` -Sample outputs: ``` Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile @@ -104,35 +123,53 @@ Installed: Complete! ``` -If you are using **a Fedora Linux** , run the following dnf command: -`$ sudo dnf install uptimed` +如果你正在使用 Fedora Linux,运行以下 `dnf` 命令: -### Install uptimed on an Arch Linux +``` +$ sudo dnf install uptimed +``` -Type the following pacman command: -`$ sudo pacman -S uptimed` +#### 在 Arch Linux 上安装 uptimed -### Install uptimed on a Gentoo Linux +键入以下 `pacman` 命令: -Type the following emerge command: -`$ sudo emerge --ask uptimed` +``` +$ sudo pacman -S uptimed +``` -## How to configure uptimed +#### 在 Gentoo Linux 上安装 uptimed + +键入以下 `emerge` 命令: + +``` +$ sudo emerge --ask uptimed +``` + +### 如何配置 uptimed + +使用文本编辑器编辑 `/etc/uptimed.conf` 文件,例如 `vim` 命令: + +``` +$ sudo vim /etc/uptimed.conf +``` + +最少设置一个 email 地址来发送记录。假定有个兼容 sendmail 的 MTA 安装在 `/usr/lib/sendmail`。 -Edit the file /etc/uptimed.conf using a text editor such as vim command: -`$ sudo vim /etc/uptimed.conf` -At least set an email address to mail milestones/records to. Assumes sendmail compatible MTA installed as /usr/lib/sendmail. ``` EMAIL=vivek@server1.cyberciti.biz ``` -Save and close the file. -### How do I enable uptimed service at boot time? +保存并关闭文件。 -Enable uptimed service using the systemctl command: -`$ sudo systemctl enable uptimed` +### 如何在系统启动时启动 uptimed 服务? -### How do I start/stop/restart or view status of uptimed service? +使用 `systemctl` 命令启动 `uptimed` 服务: + +``` +$ sudo systemctl enable uptimed +``` + +### 我该如何 启动/停止/重启 或者查看 uptimed 服务的状态? ``` $ sudo systemctl start uptimed ## start it ## @@ -140,7 +177,9 @@ $ sudo systemctl stop uptimed ## stop it ## $ sudo systemctl restart uptimed ## restart it ## $ sudo systemctl status uptimed ## view status ## ``` -Sample outputs: + +示例输出: + ``` ● uptimed.service - uptime record daemon Loaded: loaded (/lib/systemd/system/uptimed.service; enabled; vendor preset: enabled) @@ -152,19 +191,26 @@ Sample outputs: Nov 09 17:49:14 gfs04 systemd[1]: Started uptime record daemon. ``` -## How to see uptime record +### 如何查看 uptime 记录 + +只需键入以下命令即可查看 `uptimed(8)` 程序的统计信息: -Simply type the following command to see statistics from the uptimed(8) program: ``` $ uprecords ``` -Sample outputs: + +示例输出: + [![Fig.02: uprecords in action][9]][9] -uprecords has a few more option: + +`uprecords` 有一些选项: + ``` $ uprecords -? ``` -Sample outputs: + +示例输出: + ``` usage: uprecords [OPTION]... @@ -185,19 +231,19 @@ usage: uprecords [OPTION]... -v version information ``` -## Conclusion +### 结论 + +这是一个极好的小工具,可以显示服务器正常运行时间的记录,以证明机器正常运行时间和你的业务连续性。在相关说明中,你可以看到官方的 [XKCD 系统管理员 T恤][10] 因为漫画被制作成衬衫,其中包括背面的新插图。 -This is an excellent little tool to show your server uptime records to prove your uptime and business continuity. On a related note, you should get the official [XKCD sysadmin t-shirt][10] as comic was made into a shirt, which includes a new illustration on the back. [![Fig.03: Sysadmin XKCD shirt features the original comic on the front and a new illustration on the back.][11]][11] - -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/hardware/see-records-statistics-about-a-linux-servers-uptime/ -作者:[][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +作者:[Vivek Gite][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171113 My Adventure Migrating Back To Windows.md b/published/20171113 My Adventure Migrating Back To Windows.md new file mode 100644 index 0000000000..4d2017bf8d --- /dev/null +++ b/published/20171113 My Adventure Migrating Back To Windows.md @@ -0,0 +1,121 @@ +我的冒险旅程之迁移回 Windows +====== + +我已经主要使用 Linux 大约 10 年了,而且主要是 Ubuntu。但在最新发布的版本中,我决定重新回到我通常不喜欢的操作系统: Windows 10。 + +![Ubuntu On Windows][1] + +我一直是 Linux 的粉丝,我最喜欢的两个发行版是 Debian 和 Ubuntu。现今作为一个服务器操作系统,Linux 是完美无暇的,但在桌面上一直存在不同程度的问题。 + +最近一系列的问题让我意识到,我不需要使用 Linux 作为我的桌面操作系统,我仍然是一个 Linux 粉丝,但基于我安装 Ubuntu 17.10 的经验,我已经决定回到 Windows。 + +### 什么使我选择了回归 + +问题是,当 Ubuntu 17.10 出来后,我像往常一样进行全新安装,但遇到了一些非常奇怪的新问题。 + +* Dell D3100 Dock 不再工作(包括临时规避方案也没用) +* Ubuntu 意外死机(随机) +* 双击桌面上的图标没反应 +* 使用 HUD 搜索诸如“tweaks”之类的程序会尝试安装 META 桌面版本 +* GUI 比标准的 GNOME 感觉更糟糕 + +现在我确实考虑回到使用 Ubuntu 16.04 或另一个发行版,但是我觉得 Unity 7 是最精致的桌面环境,而另外唯一一个优雅且稳定的是 Windows 10。 + +除此之外,使用 Linux 而不是使用 Windows 也有一些固有的问题,如: + +* 大多数商用软件不可用,E.G Maya、 PhotoShop、 Microsoft Office(大多数情况下,替代品并不相同)等等。 +* 大多数游戏都没有移植到 Linux 上,包括来自 EA、 Rockstar Ect. 等主要工作室的游戏。 +* 对于大多数硬件来说,其 Linux 驱动程序是厂商的次要考虑。 + +在决定使用 Windows 之前,我确实考虑过其他发行版和操作系统。 + +与此同时,我看到了更多的“微软爱 Linux ”的行动,并且了解了 WSL。他们的新开发者的关注角度对我来说很有意思,于是我试了一下。 + +### 我在 Windows 找到了什么 + +我使用计算机主要是为了编程,我也使用虚拟机、git 和 ssh,并且大部分工作依赖于 bash。我偶尔也会玩游戏,观看 netflix 和一些轻松的办公室工作。 + +总之,我期待在 Ubuntu 中保留当前的工作流程并将其移植到 Windows 上。我也想利用 Windows 的优点。 + +* 所有的 PC 游戏支持 Windows +* 大多数程序是原生的 +* 微软办公软件 + +虽然使用 Windows 有很多坑,但是我打算正确对待它,所以我不担心一般的 Windows 故障,例如病毒和恶意软件。 + +### Windows 的子系统 Linux(Windows 上的 Ubuntu 中的 Bash) + +微软与 Canonical 的密切合作将 Ubuntu 带到了 Windows 上。在经过快速设置和启动程序之后,你将拥有非常熟悉的 bash 界面。 + +我一直在研究其局限性,但是在写这篇文章时我碰到的唯一真正的限制是它从硬件中抽象了出来。例如,`lsblk` 不会显示你有什么分区,因为子系统里的 Ubuntu 没有提供这些信息。 + +但是除了访问底层工具之外,我发现其体验非常熟悉,也很棒。 + +我在下面的工作流程中使用了它。 + +* 生成 SSH 密钥对 +* 使用 Git 和 Github 来管理我的仓库 +* SSH 到几个服务器,包括不用密码 +* 为本地数据库运行 MySQL +* 监视系统资源 +* 使用 Vim 编辑配置文件 +* 运行 Bash 脚本 +* 运行本地 Web 服务器 +* 运行 PHP、NodeJS + +到目前为止,它已经被证明是非常强大的工具。除了是在 Windows 10 用户界面之中,我的工作流程感觉和我在 Ubuntu 上几乎一样。尽管我的多数工作可以在 WSL 中处理,但我仍然打算通过虚拟机进行更深入的工作,这可能超出了 WSL 的范围。 + +### 不需要用 Wine + +我遇到的另一个主要问题是兼容性问题。我很少使用 Wine 来使用 Windows 软件。(LCTT 译注:Wine 是可以使 Linux 上运行 Windows 应用的软件)但是有时它是必需的,尽管通常体验不是很好。 + +#### HeidiSQL + +我首先安装的程序之一是 HeidiSQL,它是我最喜欢的数据库客户端之一。它可以在 Wine 下工作,但是感觉很不好,所以我在 Linux 下丢掉它而使用了 MySQL Workbench。回到了 Windows 中,就像一个可靠的老朋友回来了。 + +#### 游戏平台 / Steam + +没有游戏的 Windows 电脑是无法想象的。我从 Steam 的网站上安装了它,我的 Linux 游戏,加上我的 Windows 游戏就变大了 5 倍,并且包括 GTA V (LCTT 译注: GTA V 是一款名叫侠盗飞车的游戏) 等 AAA 级游戏。而这些我在 Ubuntu 中只能梦想。 + +我对 SteamOS 有很大的期望,并且一直会持续如此。但是我认为在可预见的将来,它不会在任何地方的游戏市场中崭露头角。所以如果你想在 PC 上玩游戏,你确实需要 Windows。 + +还有一点需要注意的是, 你的 nvidia 显卡的驱动程序会得到很好的支持,这使得像 TF2 (LCTT 译注: 这是一款名叫军团要塞 2 的游戏)这样的一些 Linux 原生游戏运行的稍好一些。 + +**Windows 在游戏方面总是优越的,所以这并不令人感到意外。** + +### 从 USB 硬盘运行,为什么 + +我在我的主固态硬盘上运行 Linux,但在过去,我是从 usb 棒和 usb 硬盘运行它的。我习惯了 Linux 的这种持久性,这让我可以在不丢失主要操作系统的情况下长期尝试多个版本。现在我尝试将 Windows 安装到 USB 连接的硬盘上时,它无法工作也不可能工作。所以当我将 Windows 硬盘分区的克隆作为备份时,我很惊讶我可以通过 USB 启动它。 + +这对我来说已经成为一个方便的选择,因为我打算将我的工作笔记本电脑迁移回 Windows,但如果不想冒险,那就把它扔在那里吧。 + +所以我在过去的几天里,我使用 USB 来运行它,除了一些错误的消息外,我没有通过 USB 运行发现它真正的缺点。 + +这样做主要的问题是: + +* 较慢的启动速度 +* 恼人的信息:不要拔掉你的 USB +* 无法激活它 + +**我可能会写一篇关于 USB 驱动器上的 Windows 的文章,这样我们可以有更详细的了解。** + +### 那么结论是什么? + +我使用 Windows 10 大约两周了,并没有注意到它对我的工作流程有任何的负面影响。尽管过程会有一些小问题,但我需要的所以工具都在手边,并且操作系统一般都在运行。 + +### 我会留在 Windows吗? + +虽然现在还为时尚早,但我想在可见的未来我会坚持使用 Windows。 + +-------------------------------------------------------------------------------- + +via: [https://www.chris-shaw.com/blog/my-adventure-migrating-back-to-windows](https://www.chris-shaw.com/blog/my-adventure-migrating-back-to-windows) + +作者:[Christopher Shaw][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.chris-shaw.com +[1]:https://winaero.com/blog/wp-content/uploads/2016/07/Ubutntu-on-Windows-10-logo-banner.jpg diff --git a/published/20171113 The big break in computer languages.md b/published/20171113 The big break in computer languages.md new file mode 100644 index 0000000000..720100a600 --- /dev/null +++ b/published/20171113 The big break in computer languages.md @@ -0,0 +1,90 @@ +计算机语言的巨变 +==================================================== + +我的上一篇博文《[与 C 语言长别离][3]》引来了我的老朋友,一位 C++ 专家的评论。在评论里,他推荐把 C++ 作为 C 的替代品。这是不可能发生的,如果 C++ 代替 C 是趋势的话,那么 Go 和 Rust 也就不会出现了。 + +![](https://static1.squarespace.com/static/586bd48d03596e5605450cee/t/5880d61b29687f4fd5a5712d/1484838431523/) + +但是我不能只给我的读者一个光秃秃的看法(LCTT 译注:此处是双关语)。所以,在这篇文章中,我来讲述一下为什么我不再碰 C++ 的故事。这是关于计算机语言设计经济学专题文章的起始点。这篇文章会讨论为什么一些真心不好的决策会被做出来,然后进入语言的基础设计之中,以及我们该如何修正这些问题。 + +在这篇文章中,我会一点一点的指出人们(当然也包括我)自从 20 世纪 80 年代以来就存在的关于未来的编程语言的预见失误。直到最近,我们才找到了证明我们错了的证据。 + +我记得我第一次学习 C++ 是因为我需要使用 GNU eqn 输出 MathXML,而 eqn 是使用 C++ 写的。那个项目不错。在那之后,21 世纪初,我在韦诺之战Battle For Wesnoth那边当了多年的资深开发人生,并且与 C++ 相处甚欢。 + +在那之后啊,有一天我们发现一个不小心被我们授予提交权限的人已经把游戏的 AI 核心搞崩掉了。显然,在团队中只有我是不那么害怕查看代码的。最终,我把一切都恢复正常了 —— 我折腾了整整两周。再那之后,我就发誓我再也不靠近 C++ 了。 + +在那次经历过后,我发现这个语言的问题就是它在尝试使得本来就复杂的东西更加复杂,来粗陋补上因为基础概念的缺失造成的漏洞。对于裸指针这样东西,它说“别这样做”,这没有问题。对于小规模的个人项目(比如我的魔改版 eqn),遵守这些规定没有问题。 + +但是对于大型项目,或者开发者水平参差不齐的多人项目(这是我经常要处理的情况)就不能这样。随着时间的推移以及代码行数的增加,有的人就会捅篓子。当别人指出有 BUG 时,因为诸如 STL 之类的东西给你增加了一层复杂度,你处理这种问题所需要的精力就比处理同等规模的 C 语言的问题就要难上很多。我在韦诺之战时,我就知道了,处理这种问题真的相当棘手。 + +我给 Stell Heller(我的老朋友,C++ 的支持者)写代码时不会发生的问题在我与非 Heller 们合作时就被放大了,我和他们合作的结局可能就是我得给他们擦屁股。所以我就不用 C++ ,我觉得不值得为了其花时间。 C 是有缺陷的,但是 C 有 C++ 没有的优点 —— 如果你能在脑内模拟出硬件,那么你就能很简单的看出程序是怎么运行的。如果 C++ 真的能解决 C 的问题(也就是说,C++ 是类型安全以及内存安全的),那么失去其透明性也是值得的。但是,C++ 并没有这样。 + +我们判断 C++ 做的还不够的方法之一是想象一个 C++ 已经搞得不错的世界。在那个世界里,老旧的 C 语言项目会被迁移到 C++ 上来。主流的操作系统内核会是 C++ 写就,而现存的内核实现,比如 Linux 会渐渐升级成那样。在现实世界,这些都没有发生。C++ 不仅没有打消语言设计者设想像 D、Go 以及 Rust 那样的新语言的想法,它甚至都没有取代它的前辈。不改变 C++ 的核心思想,它就没有未来,也因此,C++ 的抽象泄露leaky abstraction也不会消失。 + +既然我刚刚提到了 D 语言,那我就说说为什么我不把 D 视为一个够格的 C 语言竞争者的原因吧。尽管它比 Rust 早出现了八年(和 Rust 相比是九年)Walter Bright 早在那时就有了构建那样一个语言的想法。但是在 2001 年,以 Python 和 Perl 为首的语言的出现已经确定了,专有语言能和开源语言抗衡的时代已经过去。官方 D 语言库/运行时和 Tangle 的无谓纷争也打击了其发展。它从未修正这些错误。 + +然后就是 Go 语言(我本来想说“以及 Rust”。但是如前文所述,我认为 Rust 还需要几年时间才能有竞争力)。它_的确是_类型安全以及内存安全的(好吧,是在大多数时候是这样,但是如果你要使用接口的话就不是如此了,但是自找麻烦可不是正常人的做法)。我的一位好友,Mark Atwood,曾指出过 Go 语言是脾气暴躁的老头子因为愤怒而创造出的语言,主要是 _C 语言的作者之一_(Ken Thompson) 因为 C++ 的混乱臃肿造成的愤怒,我深以为然。 + +我能理解 Ken 恼火的原因。这几十年来我就一直认为 C++ 搞错了需要解决的问题。C 语言的后继者有两条路可走。其一就是 C++ 那样,接受 C 的抽象泄漏、裸指针等等,以保证兼容性。然后以此为基础,构建一个最先进的语言。还有一条道路,就是从根源上解决问题 —— _修正_ C语言的抽象泄露。这一来就会破环其兼容性,但是也会杜绝 C/C++ 现有的问题。 + +对于第二条道路,第一次严谨的尝试就是 1995 年出现的 Java。Java 搞得不错,但是在语言解释器上构建这门语言使其不适合系统编程。这就在系统编程那留下一个巨大的洞,在 Go 以及 Rust 出现之前的 15 年里,都没有语言来填补这个空白。这也就是我的 GPSD 和 NTPsec 等软件在 2017 年仍然主要用 C 写成的原因,尽管 C 的问题也很多。 + +在许多方面这都是很糟糕的情况。尽管由于缺少足够多样化的选择,我们很难认识到 C/C++ 做的不够好的地方。我们都认为在软件里面出现缺陷以及基于安全方面考虑的妥协是理所当然的,而不是想想这其中多少是真的由于语言的设计问题导致的,就像缓存区溢出漏洞一样。 + +所以,为什么我们花了这么长时间才开始解决这个问题?从 C 1972 年面世到 Go 2009 年出现,这其中隔了 37 年;Rust 也是在其仅仅一年之前出现。我想根本原因还是经济。 + +从最早的计算机语言开始,人们就已经知道,每种语言的设计都体现了程序员时间与机器资源的相对价值的权衡。在机器这端,就是汇编语言,以及之后的 C 语言,这些语言以牺牲开发人员的时间为代价来提高性能。 另一方面,像 Lisp 和(之后的)Python 这样的语言则试图自动处理尽可能多的细节,但这是以牺牲机器性能为代价的。 + +广义地说,这两端的语言的最重要的区别就是有没有自动内存管理。这与经验一致,内存管理缺陷是以机器为中心的语言中最常见的一类缺陷,程序员需要手动管理资源。 + +当相对价值断言与软件开发在某个特定领域的实际成本动因相匹配时,这个语言就是在经济上可行的。语言设计者通过设计一个适合处理现在或者不远的将来出现的情况的语言,而不是使用现有的语言来解决他们遇到的问题。 + +随着时间的推移,时兴的编程语言已经渐渐从需要手动管理内存的语言变为带有自动内存管理以及垃圾回收(GC)机制的语言。这种变化对应了摩尔定律导致的计算机硬件成本的降低,使得程序员的时间与之前相比更加的宝贵。但是,除了程序员的时间以及机器效率的变化之外,至少还有两个维度与这种变化相关。 + +其一就是距离底层硬件的距离。底层软件(内核与服务代码)的低效率会被成倍地扩大。因此我们可以发现,以机器为中心的语言向底层推进,而以程序员为中心的语言向着高级发展。因为大多数情况下面向用户的语言仅仅需要以人类的反应速度(0.1 秒)做出回应即可。 + +另一个维度就是项目的规模。由于程序员抽象发生的问题的漏洞以及自身的疏忽,任何语言都会有可预期的每千行代码的出错率。这个比率在以机器为中心的语言上很高,而在程序员为中心的带有 GC 的语言里就大大降低。随着项目规模的增大,带有 GC 的语言作为一个防止出错率不堪入目的策略就显得愈发重要起来。 + +当我们使用这三种维度来看当今的编程语言的形势 —— C 语言在底层,蓬勃发展的带有 GC 的语言在上层,我们会发现这基本上很合理。但是还有一些看似不合理的是 —— C 语言的应用不合理地广泛。 + +我为什么这么说?想想那些经典的 Unix 命令行工具吧。那些小程序通常都可以使用带有完整的 POSIX 支持的脚本语言快速实现出来。重新编码那些程序将使得它们调试、维护和拓展起来都会更加简单。 + +但是为什么还是使用 C (或者某些像 eqn 的项目,使用 C++)?因为有转换成本。就算是把相当小、相当简单的程序使用新的语言重写并且确认你已经忠实地保留了所有非错误行为都是相当困难的。笼统地说,在任何一个领域的应用编程或者系统编程在一种语言的权衡过时之后,仍然坚持使用它。 + +这就是我和其他预测者犯的大错。 我们认为,降低机器资源成本(增加程序员时间的相对成本)本身就足以取代 C 语言(以及没有 GC 的语言)。 在这个过程中,我们有一部分或者甚至一大部分都是错误的 —— 自 20 世纪 90 年代初以来,脚本语言、Java 以及像 Node.js 这样的东西的兴起显然都是这样兴起的。 + +但是,竞争系统编程语言的新浪潮并非如此。 Rust 和 Go 都明确地回应了_增加项目规模_ 这一需求。 脚本语言是先是作为编写小程序的有效途径,并逐渐扩大规模,而 Rust 和 Go 从一开始就定位为减少_大型项目_中的缺陷率。 比如 Google 的搜索服务和 Facebook 的实时聊天复用。 + +我认为这就是对 “为什么不再早点儿” 这个问题的回答。Rust 和 Go 实际上并不算晚,它们相对迅速地回应了一个直到最近才被发现低估的成本动因问题。 + +好,说了这么多理论上的问题。按照这些理论我们能预言什么?它告诉我们在 C 之后会出现什么? + +推动 GC 语言发展的趋势还没有扭转,也不要期待其扭转。这是大势所趋。因此:最终我们*将*拥有具有足够低延迟的 GC 技术,可用于内核和底层固件,这些技术将以语言实现方式被提供。 这些才是真正结束 C 长期统治的语言应有的特性。 + +我们能从 Go 语言开发团队的工作文件中发现端倪,他们正朝着这个方向前进 —— 可参见关于并发 GC 的学术研究 —— 从未停止研究。 如果 Go 语言自己没有选择这么做,其他的语言设计师也会这样。 但我认为他们会这么做 —— 谷歌推动他们的项目的能力是显而易见的(我们从 “Android 的发展”就能看出来)。 + +在我们拥有那么理想的 GC 之前,我把能替换 C 语言的赌注押在 Go 语言上。因为其 GC 的开销是可以接受的 —— 也就是说不只是应用,甚至是大部分内核外的服务都可以使用。原因很简单: C 的出错率无药可医,转化成本还很高。 + +上周我尝试将 C 语言项目转化到 Go 语言上,我发现了两件事。其一就是这活很简单, C 的语言和 Go 对应的很好。还有就是写出的代码相当简单。由于 GC 的存在以及把集合视为首要的数据结构,人们会预期代码减少,但是我意识到我写的代码比我最初期望的减少的更多,比例约为 2:1 —— 和 C 转 Python 类似。 + +抱歉呐,Rust 粉们。你们在内核以及底层固件上有着美好的未来,但是你们在别的 C 领域被 Go 压的很惨。没有 GC ,再加上难以从 C 语言转化过来,还有就是 API 的标准部分还是不够完善。(我的 `select(2)` 又哪去了啊?)。 + +对你们来说,唯一的安慰就是,C++ 粉比你们更糟糕 —— 如果这算是安慰的话。至少 Rust 还可以在 Go 顾及不到的 C 领域内大展宏图。C++ 可不能。 + +-------------------------------------------------------------------------------- + +via: http://esr.ibiblio.org/?p=7724 + +作者:[Eric Raymond][a] +译者:[name1e5s](https://github.com/name1e5s) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://esr.ibiblio.org/?author=2 +[1]:http://esr.ibiblio.org/?author=2 +[2]:http://esr.ibiblio.org/?p=7724 +[3]:https://linux.cn/article-9268-1.html +[4]:http://esr.ibiblio.org/?cat=13 +[5]:http://esr.ibiblio.org/?author=2 +[6]:http://esr.ibiblio.org/?p=7724 diff --git a/published/20171123 Why microservices are a security issue.md b/published/20171123 Why microservices are a security issue.md new file mode 100644 index 0000000000..816baaba85 --- /dev/null +++ b/published/20171123 Why microservices are a security issue.md @@ -0,0 +1,93 @@ +为什么微服务是一个安全问题 +============================================================ + +> 你可能并不想把所有的遗留应用全部分解为微服务,或许你可以考虑从安全功能开始。 + +![Why microservices are a security issue](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003601_05_mech_osyearbook2016_security_cc.png?itok=3V07Lpko) + +Image by : Opensource.com + +我为了给这篇文章起个标题,使出 “洪荒之力”,也很担心这会变成标题党。如果你点击它,是因为它激起了你的好奇,那么我表示抱歉 ^[注1][5] 。我当然是希望你留下来阅读的 ^[注2][6] :我有很多有趣的观点以及很多 ^[注3][7] 脚注。我不是故意提出微服务会导致安全问题——尽管如同很多组件一样都有安全问题。当然,这些微服务是那些安全方面的人员的趣向所在。进一步地说,我认为对于那些担心安全的人来说,它们是优秀的架构。 + +为什么这样说?这是个好问题,对于我们这些有[系统安全][16] 经验的人来说,此时这个世界才是一个有趣的地方。我们看到随着带宽便宜了并且延迟降低了,分布式系统在增长。加上部署到云愈加便利,越来越多的架构师们开始意识到应用是可以分解的,不只是分成多个层,并且层内还能分为多个组件。当然,均衡负载可以用于让一个层内的各个组件协同工作,但是将不同的服务输出为各种小组件的能力导致了微服务在设计、实施和部署方面的增长。 + +所以,[到底什么是微服务呢][23]?我同意[维基百科的定义][24],尽管没有提及安全性方面的内容^[注4][17] 。 我喜欢微服务的一点是,经过精心设计,其符合 Peter H. Salus 描述的 [UNIX 哲学][25] 的前俩点: + +1. 程序应该只做一件事,并尽可能把它做好。 +2. 让程序能够互相协同工作。 +3. 应该让程序处理文本数据流,因为这是一个通用的接口。 + +三者中最后一个有点不太相关,因为 UNIX 哲学通常被用来指代独立应用,它常有一个实例化的命令。但是,它确实包含了微服务的基本要求之一:必须具有“定义明确”的接口。 + +这里的“定义明确”,我指的不仅仅是可外部访问的 API 的方法描述,也指正常的微服务输入输出操作——以及,如果有的话,还有其副作用。就像我之前的文章描述的,“[良好的系统架构的五个特征][18]”,如果你能够去设计一个系统,数据和主体描述是至关重要的。在此,在我们的微服务描述上,我们要去看看为什么这些是如此重要。因为对我来说,微服务架构的关键定义是可分解性。如果你要分解 ^[注5][8] 你的架构,你必须非常、非常地清楚每个细节(“组件”)要做什么。 + +在这里,就要开始考虑安全了。特定组件的准确描述可以让你: + +* 审查您的设计 +* 确保您的实现符合描述 +* 提出可重用测试单元来审查功能 +* 跟踪实施中的错误并纠正错误 +* 测试意料之外的产出 +* 监视不当行为 +* 审核未来可能的实际行为 + +现在,这些微服务能用在一个大型架构里了吗?是的。但如果实体是在更复杂的配置中彼此链接或组合在一起,它们会随之越来越难。当你让一小部分可以彼此配合工作时,确保正确的实施和行为是非常、非常容易的。并且如果你不能确定单个组件正在做它们应该作的,那么确保其衍生出来的复杂系统的正确行为及不正确行为就困难的多了。 + +而且还不止于此。如我已经在许多[以往场合][19]提过的,写足够安全的代码是困难的^[注7][9] ,证实它应该做的更加困难。因此,有理由限制有特定安全要求的代码——密码检测、加密、加密密钥管理、授权等等——将它们变成小而定义明确的代码块。然后你就可以执行我上面提及所有工作,以确保正确完成。 + +还有,我们都知道并不是每个人都擅长于编写与安全相关的代码。通过分解你的体系架构,将安全敏感的代码限制到定义明确的组件中,你就可以把你最棒的安全人员放到这方面,并限制了 J.佛系.码奴 ^[注8][10] 绕过或降级一些关键的安全控制措施的危险。 + +它可以作为学习的机会:它对于设计/实现/测试/监视的兄弟们都是好的,而且给他们说:“听、读、标记、学习,并且引为己用 ^[注9][11] 。这是应该做的。” + +是否应该将所有遗留应用程序分解为微服务? 不一定。 但是考虑到其带来的好处,你可以考虑从安全入手。 + +* * * + +- 注1、有一点——有读者总是好的。 +- 注2、这是我写下文章的意义。 +- 注3、可能没那么有趣。 +- 注4、在我写这篇文章时。我或你们中的一个可能会去编辑改变它。 +- 注5、这很有趣,听起来想一个园艺术语。并不是说我很喜欢园艺,但仍然... ^[注6][12] +- 注6、有意思的是,我最先写的 “如果你要分解你的架构....” 听起来想是一个 IT 主题的谋杀电影标题。 +- 注7、长期读者可能会记得提到的优秀电影 “The Thick of It” +- 注8、其他的什么人:请随便选择。 +- 注9、不是加密摘要digest:我不认同原作者的想法。 + +这篇文章最初出在[爱丽丝、伊娃与鲍伯](https://zh.wikipedia.org/zh-hans/%E6%84%9B%E9%BA%97%E7%B5%B2%E8%88%87%E9%AE%91%E4%BC%AF)——一个安全博客上,并被许可转载。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/11/microservices-are-security-issue + +作者:[Mike Bursell][a] +译者:[erlinux](https://itxdm.me) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/mikecamel +[1]:https://blog.openshift.com/microservices-how-to-explain-them-to-your-ceo/?intcmp=7016000000127cYAAQ&amp;amp;amp;amp;amp;amp;amp;src=microservices_resource_menu1 +[2]:https://www.openshift.com/promotions/microservices.html?intcmp=7016000000127cYAAQ&amp;amp;amp;amp;amp;amp;amp;src=microservices_resource_menu2 +[3]:https://opensource.com/business/16/11/secured-devops-microservices?src=microservices_resource_menu3 +[4]:https://opensource.com/article/17/11/microservices-are-security-issue?rate=GDH4xOWsgYsVnWbjEIoAcT_92b8gum8XmgR6U0T04oM +[5]:https://opensource.com/article/17/11/microservices-are-security-issue#1 +[6]:https://opensource.com/article/17/11/microservices-are-security-issue#2 +[7]:https://opensource.com/article/17/11/microservices-are-security-issue#3 +[8]:https://opensource.com/article/17/11/microservices-are-security-issue#5 +[9]:https://opensource.com/article/17/11/microservices-are-security-issue#7 +[10]:https://opensource.com/article/17/11/microservices-are-security-issue#8 +[11]:https://opensource.com/article/17/11/microservices-are-security-issue#9 +[12]:https://opensource.com/article/17/11/microservices-are-security-issue#6 +[13]:https://aliceevebob.com/2017/10/31/why-microservices-are-a-security-issue/ +[14]:https://opensource.com/user/105961/feed +[15]:https://opensource.com/tags/security +[16]:https://aliceevebob.com/2017/03/14/systems-security-why-it-matters/ +[17]:https://opensource.com/article/17/11/microservices-are-security-issue#4 +[18]:https://opensource.com/article/17/10/systems-architect +[19]:https://opensource.com/users/mikecamel +[20]:https://opensource.com/users/mikecamel +[21]:https://opensource.com/users/mikecamel +[22]:https://opensource.com/article/17/11/microservices-are-security-issue#comments +[23]:https://opensource.com/resources/what-are-microservices +[24]:https://en.wikipedia.org/wiki/Microservices +[25]:https://en.wikipedia.org/wiki/Unix_philosophy diff --git a/published/20171205 7 rules for avoiding documentation pitfalls.md b/published/20171205 7 rules for avoiding documentation pitfalls.md new file mode 100644 index 0000000000..76cc9b6eaf --- /dev/null +++ b/published/20171205 7 rules for avoiding documentation pitfalls.md @@ -0,0 +1,72 @@ +防止文档陷阱的 7 条准则 +====== +> 让我们了解一下如何使国外读者更容易理解你的技术文章。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-docdish-typewriterkeys-4-series.png?itok=ccZISDxR) + +英语是开源社区的通用语言。为了减少翻译成本,很多团队都改成用英语来写他们的文档。 但奇怪的是,为国际读者写英语并不一定就意味着以英语为母语的人就占据更多的优势。 相反, 他们往往忘记了该文档用的语言可能并不是读者的母语。 + +我们以下面这个简单的句子为例: “Encrypt the password using the `foo bar` command。”语法上来说,这个句子是正确的。 鉴于动名词的 “-ing” 形式在英语中很常见,大多数的母语人士都认为这是一种优雅的表达方式, 他们通常会很自然的写出这样的句子。 但是仔细观察, 这个句子存在歧义因为 “using” 可能指的宾语(“the password”)也可能指的动词(“encrypt”)。 因此这个句子有两种解读方式: + + * “加密使用了 `foo bar` 命令的密码。” + * “使用命令 `foo bar` 来加密密码。” + +如果你有相关的先验知识(密码加密或者 `foo bar` 命令),你可以消除这种不确定性并且明白第二种方式才是真正的意思。 但是若你没有足够深入的知识怎么办呢? 如果你并不是这方面的专家,而只是一个拥有泛泛相关知识的翻译者而已怎么办呢? 再或者,如果你只是个非母语人士且对像动名词这种高级语法不熟悉怎么办呢? + +即使是英语为母语的人也需要经过训练才能写出清晰直接的技术文档。训练的第一步就是提高对文本可用性以及潜在问题的警觉性, 下面让我们来看一下可以帮助避免常见陷阱的 7 条规则。 + +### 1、了解你的目标读者并代入其中。 + +如果你是一名开发者,而写作的对象是最终用户, 那么你需要站在他们的角度来看这个产品。 文档的结构是否反映了用户的目标? [人格面具persona 技术][1] 能帮你专注于目标受众并为你的读者提供合适层次的细节。 + +### 2、遵循 KISS 原则——保持文档简短而简单 + +这个原则适用于多个层次,从语法,句子到单词。 比如: + + * 使用合适的最简单时态。比如, 当提到一个动作的结果时使用现在时: + * " ~~Click 'OK.' The 'Printer Options' dialog will appear.~~ " -> "Click 'OK.' The 'Printer Options' dialog appears." + * 按经验来说,一个句子表达一个主题;然而, 短句子并不一定就容易理解(尤其当这些句子都是由名词组成时)。 有时, 将句子裁剪过度可能会引起歧义,而反过来太多单词则又难以理解。 + * 不常用的以及很长的单词会降低阅读速度,而且可能成为非母语人士的障碍。 使用更简单的替代词语: + * " ~~utilize~~ " -> "use" + * " ~~indicate~~ " -> "show","tell" 或 "say" + * " ~~prerequisite~~ " -> "requirement" + +### 3、不要干扰阅读流 + +将虚词和较长的插入语移到句子的首部或者尾部: + + * " ~~They are not, however, marked as installed.~~ " -> "However, they are not marked as installed." + +将长命令放在句子的末尾可以让自动/半自动的翻译拥有更好的断句。 + +### 4、区别对待两种基本的信息类型 + +描述型信息以及任务导向型信息有必要区分开来。描述型信息的一个典型例子就是命令行参考, 而 HOWTO 则是属于基于任务的信息;(LCTT 译注:HOWTO 文档是 Linux 文档中的一种)然而, 技术写作中都会涉及这两种类型的信息。 仔细观察, 就会发现许多文本都同时包含了两种类型的信息。 然而如果能够清晰地划分这两种类型的信息那必是极好的。 为了更好地区分它们,可以对它们进行分别标记。 标题应该能够反映章节的内容以及信息的类型。 对描述性章节使用基于名词的标题(比如“Types of Frobnicators”),而对基于任务的章节使用口头表达式的标题(例如“Installing Frobnicators”)。 这可以让读者快速定位感兴趣的章节而跳过对他无用的章节。 + +### 5、考虑不同的阅读场景和阅读模式 + +有些读者在阅读产品文档时会由于自己搞不定而感到十分的沮丧。他们在一个嘈杂的环境中工作,也很难专注于阅读。 同时,不要期望你的读者会一页一页的进行阅读,很多人都是快速浏览文本,搜索关键字或者通过表格、索引以及全文搜索的方式来查找主题。 请牢记这一点, 从不同的角度来看待你的文字。 通常需要折中才能找到一种适合多种情况的文本结构。 + +### 6、将复杂的信息分成小块 + +这会让读者更容易记住和吸收信息。例如, 过程不应该超过 7 到 10 个步骤(根据认知心理学中的 [米勒法则][2])。 如果需要更多的步骤, 那么就将任务分拆成不同的过程。 + +### 7、形式遵循功能 + +根据以下问题检查你的文字:某句话/段落/章节的 _目的_(功能)是什么?比如,它是一个指令呢?还是一个结果呢?还是一个警告呢?如果是指令, 使用主动语气: “Configure the system.” 被动语气可能适合于进行描述: “The system is configured automatically.” 将警告放在危险操作的 _前面_ 。 专注于目的还有助于发现冗余的内容,可以清除类似 “basically” 或者 “easily” 这一类的填充词,类似 “~~already~~ existing ” 或“ ~~completely~~ new” 这一类的不必要的修饰, 以及任何与你的目标大众无关的内容。 + +你现在可能已经猜到了,写作就是一个不断重写的过程。 好的写作需要付出努力和练习。 即使你只是偶尔写点东西, 你也可以通过关注目标大众并遵循上述规则来显著地改善你的文字。 文字的可读性越好, 理解就越容易, 这一点对不同语言能力的读者来说都是适合的。 尤其是当进行本地化时, 高质量的原始文本至关重要:“垃圾进, 垃圾出”。 如果原始文本就有缺陷, 翻译所需要的时间就会变长, 从而导致更高的成本。 最坏的情况下, 翻译会导致缺陷成倍增加,需要在不同的语言版本中修正这个缺陷。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/12/7-rules + +作者:[Tanja Roth][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com +[1]:https://en.wikipedia.org/wiki/Persona_(user_experience) +[2]:https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two diff --git a/published/20171205 What DevOps teams really need from a CIO.md b/published/20171205 What DevOps teams really need from a CIO.md new file mode 100644 index 0000000000..b26a62e485 --- /dev/null +++ b/published/20171205 What DevOps teams really need from a CIO.md @@ -0,0 +1,59 @@ +CIO 真正需要 DevOps 团队做什么? +====== + +> DevOps 团队需要 IT 领导者关注三件事:沟通、技术债务和信任。 + +![](https://enterprisersproject.com/sites/default/files/styles/620x350/public/cio_cloud_2.png?itok=wGdeAHVn) + +IT 领导者可以从大量的 [DevOps][1] 材料和 [向 DevOps 转变][2] 所要求的文化挑战中学习。但是,你在一个 DevOps 团队面对长期或短期的团结挑战的调整中 —— 一个 CIO 真正需要他们做的是什么呢? + +在我与 DevOps 团队成员的谈话中,我听到的其中一些内容让你感到非常的意外。DevOps 专家(无论是内部团队的还是外部团队的)都希望将下列的事情放在你的 CIO 优先关注的级别。 + +### 1. 沟通 + +第一个也是最重要的一个,DevOps 专家需要面对面的沟通。一个经验丰富的 DevOps 团队是非常了解当前 DevOps 的趋势,以及成功和失败的经验,并且他们非常乐意去分享这些信息。表达 DevOps 的概念是很困难的,因此,要在这种新的工作关系中保持开放,定期(不用担心,不用每周)讨论有关你的 IT 的当前状态,如何评价你的沟通环境,以及你的整体的 IT 产业。 + +相反,你应该准备好与 DevOps 团队去共享当前的业务需求和目标。业务不再是独立于 IT 的东西:它们现在是驱动 IT 发展的重要因素,并且 IT 决定了你的业务需求和目标运行的效果如何。 + +注重参与而不是领导。在需要做决策的时候,你仍然是最终的决策者,但是,理解这些决策的最好方式是协作,这样,你的 DevOps 团队将有更多的自主权,并因此受到更多激励。 + +### 2. 降低技术债务 + +第二,力争更好地理解技术债务,并在 DevOps 中努力降低它。你的 DevOps 团队都工作于一线。这里,“技术债务”是指在一个庞大的、不可持续发展的环境之中,通过维护和增加新功能而占用的人力资源和基础设备资源(查看 Rube Goldberg)。 + +CIO 常见的问题包括: + + * 为什么我们要用一种新方法去做这件事情? + * 为什么我们要在它上面花费时间和金钱? + * 如果这里没有新功能,只是现有组件实现了自动化,那么我们的收益是什么? + +“如果没有坏,就不要去修理它”,这样的事情是可以理解的。但是,如果你正在路上好好的开车,而每个人都加速超过你,这时候,你的环境就被破坏了。持续投入宝贵的资源去支撑或扩张拼凑起来的环境。 + +选择妥协,并且一个接一个的打补丁,以这种方式去处理每个独立的问题,结果将从一开始就变得很糟糕 —— 在一个不能支撑建筑物的地基上,一层摞一层地往上堆。事实上,这种方法就像不断地在电脑中插入坏磁盘一样。迟早有一天,面对出现的问题你将会毫无办法。在外面持续增加的压力下,整个事情将变得一团糟,完全吞噬掉你的资源。 + +这种情况下,解决方案就是:自动化。使用自动化的结果是良好的可伸缩性 —— 每个维护人员在 IT 环境的维护和增长方面花费更少的努力。如果增加人力资源是实现业务增长的唯一办法,那么,可伸缩性就是白日做梦。 + +自动化降低了你的人力资源需求,并且对持续进行的 IT 提供了更灵活的需求。很简单,对吗?是的,但是你必须为迟到的满意做好心理准备。为了在提高生产力和效率的基础上获得后端经济效益,需要预先投入时间和精力对架构和结构进行变更。为了你的 DevOps 团队能够成功,接受这些挑战,对 IT 领导者来说是非常重要的。 + +### 3. 信任 + +最后,相信你的 DevOps 团队并且一定要理解他们。DevOps 专家也知道这个要求很难,但是他们必须得到你的强大支持和你积极参与的意愿。因为 DevOps 团队持续改进你的 IT 环境,他们自身也在不断地适应这些变化的技术,而这些变化通常正是 “你要去学习的经验”。 + +倾听,倾听,倾听他们,并且相信他们。DevOps 的改变是非常有价值的,而且也是值的去投入时间和金钱的。它可以提高效率、生产力、和业务响应能力。信任你的 DevOps 团队,并且给予他们更多的自由,实现更高效率的 IT 改进。 + +新 CIO 的底线是:将你的 DevOps 团队的潜力最大化,离开你的领导 “舒适区”,拥抱一个 “CIOps" 的转变。通过 DevOps 转变,持续地与你的 DevOps 团队共同成长,以帮助你的组织获得长期的 IT 成功。 + +-------------------------------------------------------------------------------- + +via: https://enterprisersproject.com/article/2017/12/what-devops-teams-really-need-cio + +作者:[John Allessio][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://enterprisersproject.com/user/john-allessio +[1]:https://enterprisersproject.com/tags/devops +[2]:https://www.redhat.com/en/insights/devops?intcmp=701f2000000tjyaAAA +[3]:https://enterprisersproject.com/devops?sc_cid=70160000000h0aXAAQ diff --git a/sources/tech/20171207 How to use KVM cloud images on Ubuntu Linux.md b/published/20171207 How to use KVM cloud images on Ubuntu Linux.md similarity index 56% rename from sources/tech/20171207 How to use KVM cloud images on Ubuntu Linux.md rename to published/20171207 How to use KVM cloud images on Ubuntu Linux.md index 4420807de7..4358b13428 100644 --- a/sources/tech/20171207 How to use KVM cloud images on Ubuntu Linux.md +++ b/published/20171207 How to use KVM cloud images on Ubuntu Linux.md @@ -1,15 +1,16 @@ -How to use KVM cloud images on Ubuntu Linux -====== +如何在 Ubuntu Linux 上使用 KVM 云镜像 +===== -Kernel-based Virtual Machine (KVM) is a virtualization module for the Linux kernel that turns it into a hypervisor. You can create an Ubuntu cloud image with KVM from the command line using Ubuntu virtualisation front-end for libvirt and KVM. +如何下载并使用运行在 Ubuntu Linux 服务器上的 KVM 云镜像?如何在 Ubuntu Linux 16.04 LTS 服务器上无需完整安装即可创建虚拟机?如何在 Ubuntu Linux 上使用 KVM 云镜像? -How do I download and use a cloud image with kvm running on an Ubuntu Linux server? How do I create create a virtual machine without the need of a complete installation on an Ubuntu Linux 16.04 LTS server?Kernel-based Virtual Machine (KVM) is a virtualization module for the Linux kernel that turns it into a hypervisor. You can create an Ubuntu cloud image with KVM from the command line using Ubuntu virtualisation front-end for libvirt and KVM. +基于内核的虚拟机(KVM)是 Linux 内核的虚拟化模块,可将其转变为虚拟机管理程序。你可以在命令行使用 Ubuntu 为 libvirt 和 KVM 提供的虚拟化前端通过 KVM 创建 Ubuntu 云镜像。 -This quick tutorial shows to install and use uvtool that provides a unified and integrated VM front-end to Ubuntu cloud image downloads, libvirt, and cloud-init. +这个快速教程展示了如何安装和使用 uvtool,它为 Ubuntu 云镜像下载,libvirt 和 clout_int 提供了统一的集成虚拟机前端。 -### Step 1 - Install KVM +### 步骤 1 - 安装 KVM + +你必须安装并配置 KVM。使用 [apt 命令][1]/[apt-get 命令][2],如下所示: -You must have kvm installed and configured. Use the [apt command][1]/[apt-get command][2] as follows: ``` $ sudo apt install qemu-kvm libvirt-bin virtinst bridge-utils cpu-checker $ kvm-ok @@ -18,15 +19,19 @@ $ sudo vi /etc/network/interfaces $ sudo systemctl restart networking $ sudo brctl show ``` -See "[How to install KVM on Ubuntu 16.04 LTS Headless Server][4]" for more info. -### Step 2 - Install uvtool +参阅[如何在 Ubuntu 16.04 LTS Headless 服务器上安装 KVM][4] 以获得更多信息。(LCTT 译注:Headless 服务器是指没有本地接口的计算设备,专用于向其他计算机及其用户提供服务。) + +### 步骤 2 - 安装 uvtool + +键入以下 [apt 命令][1]/[apt-get 命令][2]: -Type the following [apt command][1]/[apt-get command][2]: ``` $ sudo apt install uvtool ``` -Sample outputs: + +示例输出: + ``` [sudo] password for vivek: Reading package lists... Done @@ -96,47 +101,68 @@ Processing triggers for man-db (2.7.6.1-2) ... Setting up uvtool-libvirt (0~git122-0ubuntu1) ... ``` +### 步骤 3 - 下载 Ubuntu 云镜像 -### Step 3 - Download the Ubuntu Cloud image +你需要使用 `uvt-simplestreams-libvirt` 命令。它维护一个 libvirt 容量存储池,作为一个简单流simplestreams源的镜像子集的本地镜像,比如 Ubuntu 云镜像。要使用当前所有 amd64 镜像更新 uvtool 的 libvirt 容量存储池,运行: + +``` +$ uvt-simplestreams-libvirt sync arch=amd64 +``` + +要更新/获取 Ubuntu 16.04 LTS (xenial/amd64) 镜像,运行: + +``` +$ uvt-simplestreams-libvirt --verbose sync release=xenial arch=amd64 +``` + +示例输出: -You need to use the uvt-simplestreams-libvirt command. It maintains a libvirt volume storage pool as a local mirror of a subset of images available from a simplestreams source, such as Ubuntu cloud images. To update uvtool's libvirt volume storage pool with all current amd64 images, run: -`$ uvt-simplestreams-libvirt sync arch=amd64` -To just update/grab Ubuntu 16.04 LTS (xenial/amd64) image run: -`$ uvt-simplestreams-libvirt --verbose sync release=xenial arch=amd64` -Sample outputs: ``` Adding: com.ubuntu.cloud:server:16.04:amd64 20171121.1 ``` -Pass the query option to queries the local mirror: -`$ uvt-simplestreams-libvirt query` -Sample outputs: +通过 query 选项查询本地镜像: + +``` +$ uvt-simplestreams-libvirt query +``` + +示例输出: + ``` release=xenial arch=amd64 label=release (20171121.1) ``` -Now, I have an image for Ubuntu xenial and I create the VM. +现在,我为 Ubuntu xenial 创建了一个镜像,接下来我会创建虚拟机。 -### Step 4 - Create the SSH keys +### 步骤 4 - 创建 SSH 密钥 -You need ssh keys for login into KVM VMs. Use the ssh-keygen command to create a new one if you do not have any keys at all. -`$ ssh-keygen` -See "[How To Setup SSH Keys on a Linux / Unix System][5]" and "[Linux / UNIX: Generate SSH Keys][6]" for more info. +你需要使用 SSH 密钥才能登录到 KVM 虚拟机。如果你根本没有任何密钥,请使用 `ssh-keygen` 命令创建一个新的密钥。 -### Step 5 - Create the VM +``` +$ ssh-keygen +``` -It is time to create the VM named vm1 i.e. create an Ubuntu Linux 16.04 LTS VM: -`$ uvt-kvm create vm1` -By default vm1 created using the following characteristics: +参阅“[如何在 Linux / Unix 系统上设置 SSH 密钥][5]” 和 “[Linux / UNIX: 生成 SSH 密钥][6]” 以获取更多信息。 - 1. RAM/memory : 512M - 2. Disk size: 8GiB - 3. CPU: 1 vCPU core +### 步骤 5 - 创建 VM +是时候创建虚拟机了,它叫 vm1,即创建一个 Ubuntu Linux 16.04 LTS 虚拟机: +``` +$ uvt-kvm create vm1 +``` -To control ram, disk, cpu, and other characteristics use the following syntax: -`$ uvt-kvm create vm1 \ +默认情况下 vm1 使用以下配置创建: + + 1. 内存:512M + 2. 磁盘大小:8GiB + 3. CPU:1 vCPU core + +要控制内存、磁盘、CPU 和其他配置,使用以下语法: + +``` +$ uvt-kvm create vm1 \ --memory MEMORY \ --cpu CPU \ --disk DISK \ @@ -145,80 +171,100 @@ To control ram, disk, cpu, and other characteristics use the following syntax: --packages PACKAGES1, PACKAGES2, .. \ --run-script-once RUN_SCRIPT_ONCE \ --password PASSWORD -` -Where, +``` - 1. **\--password PASSWORD** : Set the password for the ubuntu user and allow login using the ubuntu user (not recommended use ssh keys). - 2. **\--run-script-once RUN_SCRIPT_ONCE** : Run RUN_SCRIPT_ONCE script as root on the VM the first time it is booted, but never again. Give full path here. This is useful to run custom task on VM such as setting up security or other stuff. - 3. **\--packages PACKAGES1, PACKAGES2, ..** : Install the comma-separated packages on first boot. +其中 + 1. `--password PASSWORD`:设置 ubuntu 用户的密码和允许使用 ubuntu 的用户登录(不推荐,使用 ssh 密钥)。 + 2. `--run-script-once RUN_SCRIPT_ONCE` : 第一次启动时,在虚拟机上以 root 身份运行 `RUN_SCRIPT_ONCE` 脚本,但再也不会运行。这里给出完整的路径。这对于在虚拟机上运行自定义任务时非常有用,例如设置安全性或其他内容。 + 3. `--packages PACKAGES1, PACKAGES2, ..` : 在第一次启动时安装以逗号分隔的软件包。 +要获取帮助,运行: -To get help, run: ``` $ uvt-kvm -h $ uvt-kvm create -h ``` -#### How do I delete my VM? +#### 如何删除虚拟机? -To destroy/delete your VM named vm1, run (please use the following command with care as there would be no confirmation box): -`$ uvt-kvm destroy vm1` +要销毁/删除名为 vm1 的虚拟机,运行(请小心使用以下命令,因为没有确认框): -#### To find out the IP address of the vm1, run: +``` +$ uvt-kvm destroy vm1 +``` -`$ uvt-kvm ip vm1` +#### 获取 vm1 的 IP 地址,运行: + +``` +$ uvt-kvm ip vm1 192.168.122.52 +``` -#### To list all VMs run +#### 列出所有运行的虚拟机 + +``` +$ uvt-kvm list +``` + +示例输出: -`$ uvt-kvm list` -Sample outputs: ``` vm1 freebsd11.1 - ``` -### Step 6 - How to login to the vm named vm1 +### 步骤 6 - 如何登录 vm1 + +语法是: + +``` +$ uvt-kvm ssh vm1 +``` + +示例输出: -The syntax is: -`$ uvt-kvm ssh vm1` -Sample outputs: ``` Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-101-generic x86_64) - comic core.md Dict.md lctt2014.md lctt2016.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated 选题模板.txt 中文排版指北.md Documentation: https://help.ubuntu.com - comic core.md Dict.md lctt2014.md lctt2016.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated 选题模板.txt 中文排版指北.md Management: https://landscape.canonical.com - comic core.md Dict.md lctt2014.md lctt2016.md LCTT翻译规范.md LICENSE Makefile published README.md sign.md sources translated 选题模板.txt 中文排版指北.md Support: https://ubuntu.com/advantage + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage - Get cloud support with Ubuntu Advantage Cloud Guest: - http://www.ubuntu.com/business/services/cloud + Get cloud support with Ubuntu Advantage Cloud Guest: + http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. -Last login: Thu Dec 7 09:55:06 2017 from 192.168.122.1 - +Last login: Thu Dec 7 09:55:06 2017 from 192.168.122.1 ``` -Another option is to use the regular ssh command from macOS/Linux/Unix/Windows client: -`$ ssh [[email protected]][7] -$ ssh -i ~/.ssh/id_rsa [[email protected]][7]` -Sample outputs: -[![Connect to the running VM using ssh][8]][8] -Once vim created you can use the virsh command as usual: -`$ virsh list` +另一个选择是从 macOS/Linux/Unix/Windows 客户端使用常规的 ssh 命令: +``` +$ ssh ubuntu@192.168.122.52 +$ ssh -i ~/.ssh/id_rsa ubuntu@192.168.122.52 +``` + +示例输出: + +[![Connect to the running VM using ssh][8]][8] + +一旦创建了 vim,你可以照常使用 `virsh` 命令: + +``` +$ virsh list +``` -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/faq/how-to-use-kvm-cloud-images-on-ubuntu-linux/ 作者:[Vivek Gite][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171212 Oh My Fish- Make Your Shell Beautiful.md b/published/20171212 Oh My Fish- Make Your Shell Beautiful.md new file mode 100644 index 0000000000..4920b7c021 --- /dev/null +++ b/published/20171212 Oh My Fish- Make Your Shell Beautiful.md @@ -0,0 +1,283 @@ +Oh My Fish! 让你的 Shell 漂亮起来 +===== + +![](https://www.ostechnix.com/wp-content/uploads/2017/12/oh-my-fish-720x340.jpg) + +几天前,我们讨论了如何[安装 Fish shell][1],这是一个健壮的、完全可用的 shell,带有许多很酷的功能,如自动建议、内置搜索功能、语法高亮显示、基于 web 配置等等。今天,我们将讨论如何使用 Oh My Fish (简称 `omf` ) 让我们的 Fish shell 变得漂亮且优雅。它是一个 Fishshell 框架,允许你安装扩展或更改你的 shell 外观的软件包。它简单易用,快速可扩展。使用 `omf`,你可以根据你的想法,很容易地安装主题,丰富你的外观和安装插件来调整你的 Fish shell。 + +### 安装 Oh My Fish + +安装 omf 很简单。你要做的只是在你的 Fish shell 中运行下面的命令。 + +``` +curl -L https://get.oh-my.fish | fish +``` + +![][3] + +一旦安装完成,你将看到提示符已经自动更改,如上图所所示。另外,你会注意到当前时间在 shell 窗口的右边。 + +就是这样。让我们继续并调整我们的 fish shell。 + +### 现在,让我们将 Fish Shell 变漂亮 + +列出所有的安装包,运行: + +``` +omf list +``` + +这条命令将显示已安装的主题和插件。请注意,包可以是主题或插件。安装包意味着安装主题和插件。 + +所有官方和社区支持的包(包括插件和主题)都托管在 [Omf 主仓库][4] 中。在这个主仓库中,你可以看到大量的仓库,其中包含大量的插件和主题。 + +现在让我们看一下可用的和已安装的主题列表。为此,运行: + +``` +omf theme +``` + +![][5] + +如你所见,我们只有一个已安装的主题,这是默认的,但是还有大量可用的主题。在安装之前,你在[这里][6]可以预览所有可用的主题。这个页面包含了所有的主题细节,特性,每个主题的截图示例,以及哪个主题适合谁。 + +#### 安装一个新主题 + +请允许我安装一个主题,例如 clearance 主题,这是一个极简的 fish shell 主题,供那些经常使用 `git` 的人使用。为此,运行: + +``` +omf install clearance +``` + +![][7] + +如上图所示,在安装新主题后,Fish shell 的提示立即发生了变化。 + +让我浏览一下系统文件,看看它如何显示。 + +![][8] + +看起来不错!这是一个非常简单的主题。它将当前工作目录,文件夹和文件以不同的颜色区分开来。你可能会注意到,它还会在提示符的顶部显示当前工作目录。现在,clearance 是我的默认主题。 + +#### 改变主题 + +就像我之前说的一样,这个主题在安装后被立即应用。如果你有多个主题,你可以使用以下命令切换到另一个不同的主题: + +``` +omf theme +``` + +例如: + +``` +omf theme agnoster +``` + +现在我正在使用 agnoster 主题。 agnoster 就是这样改变了我 shell 的外观。 + +![][9] + +#### 安装插件 + +例如,我想安装一个天气插件。为此,只要运行: + +``` +omf install weather +``` + +天气插件依赖于 [jq][10](LCTT 译注:jq 是一个轻量级且灵活的命令行JSON处理器)。所以,你可能也需要安装 `jq`。它通常在 Linux 发行版的默认仓库中存在。因此,你可以使用默认的包管理器来安装它。例如,以下命令将在 Arch Linux 及其衍生版中安装 `jq`。 + +``` +sudo pacman -S jq +``` + +现在,在 Fish shell 中使用以下命令查看天气: + +``` +weather +``` + +![][11] + +#### 寻找包 + +要搜索主题或插件,请执行以下操作: + +``` +omf search +``` + +例如: + +``` +omf search nvm +``` + +为了限制搜索的主题范围,使用 `-t` 选项。 + +``` +omf search -t chain +``` + +这条命令只会搜索主题名字中包含 “chain” 的主题。 + +为了限制搜索的插件范围,使用 `-p` 选项。 + +``` +omf search -p emacs +``` + +#### 更新包 + +要仅更新核心功能(`omf` 本身),运行: + +``` +omf update omf +``` + +如果是最新的,你会看到以下输出: + +``` +Oh My Fish is up to date. +You are now using Oh My Fish version 6. +Updating https://github.com/oh-my-fish/packages-main master... Done! +``` + +更新所有包: + +``` +omf update +``` + +要有选择地更新软件包,只需包含如下所示的包名称: + +``` +omf update clearance agnoster +``` + +#### 显示关于包的信息 + +当你想知道关于一个主题或插件的信息时,使用以下命令: + +``` +omf describe clearance +``` + +这条命令将显示关于包的信息。 + +``` +Package: clearance +Description: A minimalist fish shell theme for people who use git +Repository: https://github.com/oh-my-fish/theme-clearance +Maintainer: +``` + +#### 移除包 + +移除一个包,例如 emacs,运行: + +``` +omf remove emacs +``` + +#### 管理仓库 + +默认情况下,当你安装了 Oh My Fish 时,会自动添加官方仓库。这个仓库包含了开发人员构建的所有包。要管理用户安装的仓库包,使用这条命令: + +``` +omf repositories [list|add|remove] +``` + +列出所有安装的仓库,运行: + +``` +omf repositories list +``` + +添加一个仓库: + +``` +omf repositories add +``` + +例如: + +``` +omf repositories add https://github.com/ostechnix/theme-sk +``` + +移除一个仓库: + +``` +omf repositories remove +``` + +#### Oh My Fish 排错 + +如果出现了错误,`omf` 足够聪明来帮助你,它可以列出解决问题的方法。例如,我安装了 clearance 包,得到了文件冲突的错误。幸运的是,在继续之前,Oh My Fish 会指示我该怎么做。因此,我只是简单地运行了以下代码来了解如何修正错误。 + +``` +omf doctor +``` + +通过运行以下命令来解决错误: + +``` +rm ~/.config/fish/functions/fish_prompt.fish +``` + +![][12] + +无论你何时遇到问题,只要运行 `omf doctor` 命令,并尝试所有的建议方法。 + +#### 获取帮助 + +显示帮助部分,运行: + +``` +omf -h +``` + +或者 + +``` +omf --help +``` + +#### 卸载 Oh My Fish + +卸载 Oh My Fish,运行以下命令: + +``` +omf destroy +``` + +继续前进,开始自定义你的 fish shell。获取更多细节,请参考项目的 GitHub 页面。 + +这就是全部了。我很快将会在这里开始另一个有趣的指导。在此之前,请继续关注我们! + +干杯! + + +-------------------------------------------------------------------------------- +via: https://www.ostechnix.com/oh-fish-make-shell-beautiful/ + +作者:[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]:https://www.ostechnix.com/install-fish-friendly-interactive-shell-linux/ +[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[3]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-1-1.png() +[4]:https://github.com/oh-my-fish +[5]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-5.png() +[6]:https://github.com/oh-my-fish/oh-my-fish/blob/master/docs/Themes.md +[7]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-3.png() +[8]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-4.png() +[9]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-6.png() +[10]:https://stedolan.github.io/jq/ +[11]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-7.png() +[12]:http://www.ostechnix.com/wp-content/uploads/2017/12/Oh-My-Fish-8.png() diff --git a/translated/tech/20171219 How to generate webpages using CGI scripts.md b/published/20171219 How to generate webpages using CGI scripts.md similarity index 61% rename from translated/tech/20171219 How to generate webpages using CGI scripts.md rename to published/20171219 How to generate webpages using CGI scripts.md index 47d424303a..f8a7861716 100644 --- a/translated/tech/20171219 How to generate webpages using CGI scripts.md +++ b/published/20171219 How to generate webpages using CGI scripts.md @@ -1,28 +1,33 @@ 如何使用 CGI 脚本生成网页 ====== -回到互联网的开端,当我第一次创建了我的第一个商业网站,生活是无比的美好。 +> 通用网关接口(CGI)提供了使用任何语言生成动态网站的简易方法。 -我安装 Apache 并写了一些简单的 HTML 网页,网页上列出了一些关于我的业务的重要信息,比如产品概览以及如何联系我。这是一个静态网站,因为内容很少改变。由于网站的内容很少改变这一性质,因此维护起来也很简单。 +回到互联网的开端,当我第一次创建了我的第一个商业网站,生活是如此的美好。 -## 静态内容 +我安装 Apache 并写了一些简单的 HTML 网页,网页上列出了一些关于我的业务的重要信息,比如产品概览以及如何联系我。这是一个静态网站,因为内容很少改变。由于网站的内容很少发生改变这一性质,因此维护起来也很简单。 -静态内容很简单,同时也很常见。让我们快速的浏览一些静态网页的例子。你不需要一个可运行网站来执行这些小实验,只需要把这些文件放到 home 目录,然后使用浏览器打开。你所看到的内容将和通过 web 服务器提供这一文件看到的内容一样。 +### 静态内容 + +静态内容很简单,同时也很常见。让我们快速的浏览一些静态网页的例子。你不需要一个可运行网站来执行这些小实验,只需要把这些文件放到家目录,然后使用浏览器打开。你所看到的内容将和通过 Web 服务器提供这一文件看到的内容一样。 + +对于一个静态网站,你需要的第一件东西就是 `index.html` 文件,该文件通常放置在 `/var/www/html` 目录下。这个文件的内容可以非常简单,比如可以是像 “Hello, world” 这样一句短文本,没有任何 HTML 标记。它将简单的展示文本串内容。在你的家目录创建 `index.html` 文件,并添加 “hello, world” 作为内容(不需要引号)。在浏览器中通过下面的链接来打开这一文件: -对于一个静态网站,你需要的第一件东西就是 index.html 文件,该文件通常放置在 `/var/www/html` 目录下。这个文件的内容可以非常简单,比如可以是像 "Hello, world" 这样一句短文本,没有任何 HTML 标记。它将简单的展示文本串内容。在你的 home 目录创建 index.html 文件,并添加 "hello, world" 作为内容(不需要引号)。在浏览器中通过下面的链接来打开这一文件: ``` -file:///home//index.html +file:///home/<你的家目录>/index.html ``` 所以 HTML 不是必须的,但是,如果你有大量需要格式化的文本,那么,不用 HTML 编码的网页的结果将会令人难以理解。 所以,下一步就是通过使用一些 HTML 编码来提供格式化,从而使内容更加可读。下面这一命令创建了一个具有 HTML 静态网页所需要的绝对最小标记的页面。你也可以使用你最喜欢的编辑器来创建这一内容。 + ``` echo "

Hello World

" > test1.html ``` -现在,再次查看 index.html 文件,将会看到和刚才有些不同。 +现在,再次查看 `index.html` 文件,将会看到和刚才有些不同。 + +当然,你可以在实际的内容行上添加大量的 HTML 标记,以形成更加完整和标准的网页。下面展示的是更加完整的版本,尽管在浏览器中会看到同样的内容,但这也为更加标准化的网站奠定了基础。继续在 `index.html` 中写入这些内容并通过浏览器查看。 -当然,你可以在实际的内容行上添加大量的 HTML 标记,以形成更加完整和标准的网页。下面展示的是更加完整的版本,尽管在浏览器中会看到同样的内容,但这也为更加标准化的网站奠定了基础。继续在 index.html 中写入这些内容并通过浏览器查看。 ``` @@ -37,24 +42,25 @@ echo "

Hello World

" > test1.html 我使用这些技术搭建了一些静态网站,但我的生活正在改变。 -## 动态网页 +### 动态网页 -我找了一份新工作,这份工作的主要任务就是创建并维护用于一个动态网站的 CGI([公共网关接口][6])代码。字面意思来看,动态意味着在浏览器中生成的网页所需要的 HTML 是由每次访问页面时所访问到的数据生成的。这些数据包括网页表格中的用户输入,以用来在数据库中进行数据查找,结果数据被一些恰当的 HTML 包围着并展示在所请求的浏览器中。但是这不需要非常复杂。 +我找了一份新工作,这份工作的主要任务就是创建并维护用于一个动态网站的 CGI([公共网关接口][6]Common Gateway InterfaceM)代码。字面意思来看,动态意味着在浏览器中生成的网页所需要的 HTML 是由每次访问页面时不同的数据所生成的。这些数据包括网页表单中的用户输入,以用来在数据库中进行数据查找,结果数据被一些恰当的 HTML 包围着并展示在所请求的浏览器中。但是这不需要非常复杂。 通过使用 CGI 脚本,你可以创建一些简单或复杂的交互式程序,通过运行这些程序能够生成基于输入、计算、服务器的当前条件等改变的动态页面。有许多种语言可以用来写 CGI 脚本,在这篇文章中,我将谈到的是 Perl 和 Bash ,其他非常受欢迎的 CGI 语言包括 PHP 和 Python 。 -这篇文章不会介绍 Apache 或其他任何 web 服务器的安装和配置。如果你能够访问一个你可以进行实验的 web 服务器,那么你可以直接查看它们在浏览器中出现的结果。否则,你可以在命令行中运行程序来查看它们所创建的 HTML 文本。你也可以重定向 HTML 输出到一个文件中,然后通过浏览器查看结果文件。 +这篇文章不会介绍 Apache 或其他任何 web 服务器的安装和配置。如果你能够访问一个你可以进行实验的 Web 服务器,那么你可以直接查看它们在浏览器中出现的结果。否则,你可以在命令行中运行程序来查看它们所创建的 HTML 文本。你也可以重定向 HTML 输出到一个文件中,然后通过浏览器查看结果文件。 ### 使用 Perl Perl 是一门非常受欢迎的 CGI 脚本语言,它的优势是强大的文本操作能力。 -为了使 CGI 脚本可执行,你需要在你的网站的 httpd.conf 中添加下面这行内容。这会告诉服务器可执行 CGI 文件的位置。在这次实验中,不必担心这个问题。 +为了使 CGI 脚本可执行,你需要在你的网站的 `httpd.conf` 中添加下面这行内容。这会告诉服务器可执行 CGI 文件的位置。在这次实验中,不必担心这个问题。 + ``` ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" ``` -把下面的 Perl 代码添加到文件 index.cgi,在这次实验中,这个文件应该放在你的 home 目录下。如果你使用 web 服务器,那么应把文件的所有者更改为 apache.apache,同时将文件权限设置为 755,因为无论位于哪,它必须是可执行的。 +把下面的 Perl 代码添加到文件 `index.cgi`,在这次实验中,这个文件应该放在你的家目录下。如果你使用 Web 服务器,那么应把文件的所有者更改为 `apache.apache`,同时将文件权限设置为 755,因为无论位于哪,它必须是可执行的。 ``` #!/usr/bin/perl @@ -67,11 +73,11 @@ print "\n"; 在命令行中运行这个程序并查看结果,它将会展示出它所生成的 HTML 内容 -现在,在浏览器中查看 index.cgi 文件,你所看到的只是文件的内容。浏览器的确将它看做 CGI 内容,但是,Apache 不知道需要将这个文件作为 CGI 程序运行,除非 Apache 的配置中包括上面所展示的 "ScriptAlias" 定义。没有这一配置,Apache 只会简单地将文件中的数据发送给浏览器。如果你能够访问 web 服务器,那么你可以将可执行文件放到 `/var/www/cgi-bin` 目录下。 +现在,在浏览器中查看 `index.cgi` 文件,你所看到的只是文件的内容。浏览器需要将它看做 CGI 内容,但是,Apache 不知道需要将这个文件作为 CGI 程序运行,除非 Apache 的配置中包括上面所展示的 `ScriptAlias` 定义。没有这一配置,Apache 只会简单地将文件中的数据发送给浏览器。如果你能够访问 Web 服务器,那么你可以将可执行文件放到 `/var/www/cgi-bin` 目录下。 如果想知道这个脚本的运行结果在浏览器中长什么样,那么,重新运行程序并把输出重定向到一个新文件,名字可以是任何你想要的。然后使用浏览器来查看这一文件,它包含了脚本所生成的内容。 -上面这个 CGI 程序依旧生成静态内容,因为它总是生成相同的输出。把下面这行内容添加到 CGI 程序中 "Hello, world" 这一行后面。Perl 的 "system" 命令将会执行跟在它后面的 shell 命令,并把结果返回给程序。此时,我们将会通过 `free` 命令获得当前的 RAM 使用量。 +上面这个 CGI 程序依旧生成静态内容,因为它总是生成相同的输出。把下面这行内容添加到 CGI 程序中 “Hello, world” 这一行后面。Perl 的 `system` 命令将会执行跟在它后面的 shell 命令,并把结果返回给程序。此时,我们将会通过 `free` 命令获得当前的内存使用量。 ``` system "free | grep Mem\n"; @@ -83,7 +89,7 @@ system "free | grep Mem\n"; Bash 可能是用于 CGI 脚本中最简单的语言。用 Bash 来进行 CGI 编程的最大优势是它能够直接访问所有的标准 GNU 工具和系统程序。 -把已经存在的 index.cgi 文件重命名为 Perl.index.cgi ,然后创建一个新的 index.cgi 文件并添加下面这些内容。记得设置权限使它可执行。 +把已经存在的 `index.cgi` 文件重命名为 `Perl.index.cgi`,然后创建一个新的 `index.cgi 文件并添加下面这些内容。记得设置权限使它可执行。 ``` #!/bin/bash @@ -105,7 +111,7 @@ exit 0 在命令行中执行这个文件并查看输出,然后再次运行并把结果重定向到一个临时结果文件中。然后,刷新浏览器查看它所展示的网页是什么样子。 -## 结论 +### 结论 创建能够生成许多种动态网页的 CGI 程序实际上非常简单。尽管这是一个很简单的例子,但是现在你应该看到一些可能性了。 @@ -115,7 +121,7 @@ via: https://opensource.com/article/17/12/cgi-scripts 作者:[David Both][a] 译者:[ucasFL](https://github.com/ucasFL) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171219 How to set GNOME to display a custom slideshow.md b/published/20171219 How to set GNOME to display a custom slideshow.md new file mode 100644 index 0000000000..5c9160033c --- /dev/null +++ b/published/20171219 How to set GNOME to display a custom slideshow.md @@ -0,0 +1,111 @@ +如何设置 GNOME 显示自定义幻灯片 +====== + +> 使用一个简单的 XML,你就可以设置 GNOME 能够在桌面上显示一个幻灯片。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_keyboard_laptop_development_blue.png?itok=IfckxN48) + +在 GNOME 中,一个非常酷、但却鲜为人知的特性是它能够将幻灯片显示为墙纸。你可以从 [GNOME 控制中心][1]的 “背景设置” 面板中选择墙纸幻灯片。在预览的右下角显示一个小时钟标志,可以将幻灯片的墙纸与静态墙纸区别开来。 + +一些发行版带有预装的幻灯片壁纸。 例如,Ubuntu 包含了库存的 GNOME 定时壁纸幻灯片,以及 Ubuntu 壁纸大赛胜出的墙纸。 + +如果你想创建自己的自定义幻灯片用作壁纸怎么办?虽然 GNOME 没有为此提供一个用户界面,但是在你的主目录中使用一些简单的 XML 文件来创建一个是非常容易的。 幸运的是,GNOME 控制中心的背景选择支持一些常见的目录路径,这样就可以轻松创建幻灯片,而不必编辑你的发行版所提供的任何内容。 + +### 开始 + +使用你最喜欢的文本编辑器在 `$HOME/.local/share/gnome-background-properties/` 创建一个 XML 文件。 虽然文件名不重要,但目录名称很重要(你可能需要创建该目录)。 举个例子,我创建了带有以下内容的 `/home/ken/.local/share/gnome-background-properties/osdc-wallpapers.xml`: + +``` + + + + + Opensource.com Wallpapers + /home/ken/Pictures/Wallpapers/osdc/osdc.xml + zoom + + +``` + +每一个你需要包含在 GNOME 控制中心的 “背景面板”中的每个幻灯片或静态壁纸,你都要在上面的 XML 文件需要为其增加一个 `` 节点。 + +在这个例子中,我的 `osdc.xml` 文件看起来是这样的: + + +``` + + + + + 30.0 + /home/ken/Pictures/Wallpapers/osdc/osdc_2.png + + + + 0.5 + /home/ken/Pictures/Wallpapers/osdc/osdc_2.png + /home/ken/Pictures/Wallpapers/osdc/osdc_1.png + + + 30.0 + /home/ken/Pictures/Wallpapers/osdc/osdc_1.png + + + 0.5 + /home/ken/Pictures/Wallpapers/osdc/osdc_1.png + /home/ken/Pictures/Wallpapers/osdc/osdc_2.png + + +``` + +上面的 XML 中有几个重要的部分。 XML 中的 `` 节点是你的外部节点。 每个背景都支持多个 `` 和 `` 节点。 + +`` 节点定义用 `` 节点要显示的图像以及用 `` 显示它的持续时间。 + +`` 节点定义 ``(变换时长),`` 和 `` 定义了起止的图像。 + +### 全天更换壁纸 + +另一个很酷的 GNOME 功能是基于时间的幻灯片。 你可以定义幻灯片的开始时间,GNOME 将根据它计算时间。 这对于根据一天中的时间设置不同的壁纸很有用。 例如,你可以将开始时间设置为 06:00,并在 12:00 之前显示一张墙纸,然后在下午和 18:00 再次更改。 + +这是通过在 XML 中定义 `` 来完成的,如下所示: + +``` + + + 2017 + 11 + 21 + 6 + 00 + 00 + +``` + +上述 XML 文件定义于 2017 年 11 月 21 日 06:00 开始动画,时长为 21,600.00,相当于六个小时。 这段时间将显示你的早晨壁纸直到 12:00,12:00 时它会更改为你的下一张壁纸。 你可以继续以这种方式每隔一段时间更换一次壁纸,但确保所有持续时间的总计为 86,400 秒(等于 24 小时)。 + +GNOME 将计算开始时间和当前时间之间的增量,并显示当前时间的正确墙纸。 例如,如果你在 16:00 选择新壁纸,则GNOME 将在 06:00 开始时间之后显示 36,000 秒的适当壁纸。 + +有关完整示例,请参阅大多数发行版中由 gnome-backgrounds 包提供的 adwaita-timed 幻灯片。 它通常位于 `/usr/share/backgrounds/gnome/adwaita-timed.xml` 中。 + + +### 了解更多信息 + +希望这可以鼓励你深入了解创建自己的幻灯片壁纸。 如果你想下载本文中引用的文件的完整版本,那么你可以在 [GitHub][2] 上找到它们。 + +如果你对用于生成 XML 文件的实用程序脚本感兴趣,你可以在互联网上搜索 `gnome-backearth-generator`。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/12/create-your-own-wallpaper-slideshow-gnome + +作者:[Ken Vandine][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/kenvandine +[1]:http://manpages.ubuntu.com/manpages/xenial/man1/gnome-control-center.1.html +[2]:https://github.com/kenvandine/misc/tree/master/articles/osdc/gnome/slide-show-backgrounds/osdc + diff --git a/published/20171228 Testing Ansible Playbooks With Vagrant.md b/published/20171228 Testing Ansible Playbooks With Vagrant.md new file mode 100644 index 0000000000..e05aa98499 --- /dev/null +++ b/published/20171228 Testing Ansible Playbooks With Vagrant.md @@ -0,0 +1,127 @@ +使用 Vagrant 测试 Ansible 剧本 +====== + +我使用 Ansible 来自动部署站点 ([LinuxJobs.fr][1]、[Journal du hacker][2]) 与应用 ([Feed2toot][3]、[Feed2tweet][4])。在本文中将会讲述我是如何配置以实现在本地测试 ansbile 剧本playbook的。 + +![ansible](https://carlchenet.com/wp-content/uploads/2017/12/ansible-300x300.png) + +### 为何要测试 Ansible 剧本 + +我需要一种简单而迅速的方法来在我的本地笔记本上测试 Ansible 剧本的部署情况,尤其在刚开始写一个新剧本的时候,因为直接部署到生产服务器上不仅特别慢而且风险还很大。 + +我使用 [Vagrant][6] 来将剧本部署到 [VirtualBox][5] 虚拟机上而不是部署到远程服务器。这使得修改的结果很快就能看到,以实现快速迭代和修正。 + +责任声明:我并不是专业程序员。我只是描述一种我觉得适合我的,即简单又有效的用来测试 Ansible 剧本的解决方案,但可能还有其他更好的方法。 + +### 我的流程 + + 1. 开始写新的 Ansible 剧本 + 2. 启动一台新的虚拟机(VM)并使用 Vagrantt 将剧本部署到这台虚拟机中 + 3. 修复剧本或应用中的错误 + 4. 重新在虚拟机上部署 + 5. 如果还有问题,回到第三步。否则销毁这台虚拟机,重新创建新虚拟机然后测试一次全新部署 + 6. 若没有问题出现,则标记你的 Ansible 剧本版本,可以在生产环境上发布产品了 + +### 你需要哪些东西 + +首先,你需要 Virtualbox。若你使用的是 [Debian][7] 发行版,[这个链接][8] 描述了安装的方法,可以从 Debian 仓库中安装,也可以通过官网来安装。 + +[![][9]][5] + +其次,你需要 Vagrant。为什么要 Vagrant?因为它是介于开发环境和虚拟机之间的中间件,它允许通过编程的方式重复操作,而且可以很方便地将你的部署环境与虚拟机连接起来。通过下面命令可以安装 Vagrant: +``` +# apt install vagrant +``` + +[![][10]][6] + +### 设置 Vagrant + +Vagrant 的一切信息都存放在 `Vagrantfile` 文件中。这是我的内容: + +``` +Vagrant.require_version ">= 2.0.0" + +Vagrant.configure(1) do |config| + + config.vm.box = "debian/stretch64" + config.vm.provision "shell", inline: "apt install --yes git python3-pip" + config.vm.provision "ansible" do |ansible| + ansible.verbose = "v" + ansible.playbook = "site.yml" + ansible.vault_password_file = "vault_password_file" + end +end +``` + 1. 第一行指明了需要用哪个版本的 Vagrant 来执行 `Vagrantfile`。 + 2. 文件中的第一个循环,你要定义为多少台虚拟机执行下面的操作(这里为 `1`)。 + 3. 第三行指定了用来创建虚拟机的官方 Vagrant 镜像。 + 4. 第四行非常重要:有一些需要的应用没有安装到虚拟机中。这里我们用 `apt` 安装 `git` 和 `python3-pip`。 + 5. 下一行指明了 Ansible 配置开始的地方 + 6. 第六行说明我们想要 Ansible 输出详细信息。 + 7. 第七行,我们定义了 Ansible 剧本的入口。 + 8. 第八行,若你使用 Ansible Vault 加密了一些文件,在这里指定这些文件。 + +当 Vagrant 启动 Ansible 时,类似于执行这样的操作: + +``` +$  ansible-playbook --inventory-file=/home/me/ansible/test-ansible-playbook/.vagrant/provisioners/ansible/inventory -v --vault-password-file=vault_password_file site.yml +``` + +### 执行 Vagrant + +写好 `Vagrantfile` 后,就可以启动虚拟机了。只需要简单地运行下面命令: + +``` +$ vagrant up +``` + +这个操作会很慢,因为它会启动虚拟机,安装 `Vagrantfile` 中定义的附加软件,最终应用你的剧本。你不要太频繁地使用这条命令。 + +Ok,现在你可以快速迭代了。在做出修改后,可以通过下面命令来快速测试你的部署: + +``` +$ vagrant provision +``` + +Ansible 剧本搞定后,通常要经过多次迭代(至少我是这样的),你应该一个全新安装的虚拟机上再测试一次,因为你在迭代的过程中可能会对虚拟机造成修改从而引发意料之外的结果。 + +使用下面命令进行全新测试: + +``` +$ vagrant destroy && vagrant up +``` + +这又是一个很慢的操作。你应该在 Ansible 剧本差不多完成了的情况下才这样做。在全新虚拟机上测试部署之后,就可以发布到生产上去了。至少准备要充分不少了吧 :p + +### 有什么改进意见?请告诉我 + +本文中描述的配置对我自己来说很有用。我可以做到快速迭代(尤其在编写新的剧本的时候),除了剧本外,对我的最新应用,尚未准备好部署到生产环境上的应用也很有帮助。直接部署到远程服务器上对我的生产服务来说不仅缓慢而且很危险。 + +我本也可以使用持续集成(CI)服务器,但这不是本文的主题。如前所述,本文的目的是在编写新的 Ansible 剧本之初尽可能的快速迭代。 + +在编写 Ansible 剧本之初就提交,推送到你的 Git 仓库然后等待 CI 测试的执行结果,这有点太过了,因为这个时期的错误总是很多,你需要一一个地去调试。我觉得 CI 在编写 Ansible 剧本的后期会有用的多,尤其当多个人同时对它进行修改而且你有一整套代码质量规范要遵守的时候。不过,这只是我自己的观念,还有待讨论,再重申一遍,我不是个专业的程序员。 + +如果你有更好的测试 Ansible 剧本的方案或者能对这里描述的方法做出一些改进,请告诉我。你可以把它写到留言框中或者通过社交网络联系我,我会很高兴的。 + +-------------------------------------------------------------------------------- + +via: https://carlchenet.com/testing-ansible-playbooks-with-vagrant/ + +作者:[Carl Chenet][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://carlchenet.com +[1]:https://www.linuxjobs.fr +[2]:https://www.journalduhacker.net +[3]:https://gitlab.com/chaica/feed2toot +[4]:https://gitlab.com/chaica/feed2tweet +[5]:https://www.virtualbox.org/ +[6]:https://www.vagrantup.com/ +[7]:https://www.debian.org +[8]:https://wiki.debian.org/VirtualBox +[9]:https://carlchenet.com/wp-content/uploads/2017/12/virtualbox-150x150.png +[10]:https://carlchenet.com/wp-content/uploads/2017/12/vagrant-300x98.png diff --git a/published/20180102 The Uniq Command Tutorial With Examples For Beginners.md b/published/20180102 The Uniq Command Tutorial With Examples For Beginners.md new file mode 100644 index 0000000000..2ab0c6f81c --- /dev/null +++ b/published/20180102 The Uniq Command Tutorial With Examples For Beginners.md @@ -0,0 +1,174 @@ +为初学者提供的 uniq 命令教程及示例 +===== + +如果你主要是在命令行上工作,并且每天处理大量的文本文件,那么你应该了解下 `uniq` 命令。该命令会帮助你轻松地从文件中找到重复的行。它不仅用于查找重复项,而且我们还可以使用它来删除重复项,显示重复项的出现次数,只显示重复的行,只显示唯一的行等。由于 `uniq` 命令是 GNU coreutils 包的一部分,所以它预装在大多数 Linux 发行版中,让我们不需要费心安装。来看一些实际的例子。 + +请注意,除非重复行是相邻的,否则 `uniq` 不会删除它们。因此,你可能需要先对它们进行排序,或将排序命令与 `uniq` 组合以获得结果。让我给你看一些例子。 + +首先,让我们创建一个带有一些重复行的文件: + +``` +vi ostechnix.txt +``` +``` +welcome to ostechnix +welcome to ostechnix +Linus is the creator of Linux. +Linux is secure by default +Linus is the creator of Linux. +Top 500 super computers are powered by Linux +``` + +正如你在上面的文件中看到的,我们有一些重复的行(第一行和第二行,第三行和第五行是重复的)。 + +### 1、 使用 uniq 命令删除文件中的连续重复行 + +如果你在不使用任何参数的情况下使用 `uniq` 命令,它将删除所有连续的重复行,只显示唯一的行。 + +``` +uniq ostechnix.txt +``` + +示例输出: + +![][2] + +如你所见, `uniq` 命令删除了给定文件中的所有连续重复行。你可能还注意到,上面的输出仍然有第二行和第四行重复了。这是因为 `uniq` 命令只有在相邻的情况下才会删除重复的行,当然,我们也可以删除非连续的重复行。请看下面的第二个例子。 + +### 2、 删除所有重复的行 + +``` +sort ostechnix.txt | uniq +``` + +示例输出: + +![][3] + +看到了吗?没有重复的行。换句话说,上面的命令将显示在 `ostechnix.txt` 中只出现一次的行。我们使用 `sort` 命令与 `uniq` 命令结合,因为,就像我提到的,除非重复行是相邻的,否则 `uniq` 不会删除它们。 + +### 3、 只显示文件中唯一的一行 + +为了只显示文件中唯一的一行,可以这样做: + +``` +sort ostechnix.txt | uniq -u +``` + +示例输出: + +``` +Linux is secure by default +Top 500 super computers are powered by Linux +``` + +如你所见,在给定的文件中只有两行是唯一的。 + +### 4、 只显示重复的行 + +同样的,我们也可以显示文件中重复的行,就像下面这样: + +``` +sort ostechnix.txt | uniq -d +``` + +示例输出: + +``` +Linus is the creator of Linux. +welcome to ostechnix +``` + +这两行在 `ostechnix.txt` 文件中是重复的行。请注意 `-d`(小写 `d`) 将会只打印重复的行,每组显示一个。打印所有重复的行,使用 `-D`(大写 `D`),如下所示: + +``` +sort ostechnix.txt | uniq -D +``` + +在下面的截图中看两个选项的区别: + +![][4] + +### 5、 显示文件中每一行的出现次数 + +由于某种原因,你可能想要检查给定文件中每一行重复出现的次数。要做到这一点,使用 `-c` 选项,如下所示: + +``` +sort ostechnix.txt | uniq -c +``` + +示例输出: + +``` + 2 Linus is the creator of Linux. + 1 Linux is secure by default + 1 Top 500 super computers are powered by Linux + 2 welcome to ostechnix +``` + +我们还可以按照每一行的出现次数进行排序,然后显示,如下所示: + +``` +sort ostechnix.txt | uniq -c | sort -nr +``` + +示例输出: + +``` + 2 welcome to ostechnix + 2 Linus is the creator of Linux. + 1 Top 500 super computers are powered by Linux + 1 Linux is secure by default +``` + +### 6、 将比较限制为 N 个字符 + +我们可以使用 `-w` 选项来限制对文件中特定数量字符的比较。例如,让我们比较文件中的前四个字符,并显示重复行,如下所示: + +``` +uniq -d -w 4 ostechnix.txt +``` + +### 7、 忽略比较指定的 N 个字符 + +像对文件中行的前 N 个字符进行限制比较一样,我们也可以使用 `-s` 选项来忽略比较前 N 个字符。 + +下面的命令将忽略在文件中每行的前四个字符进行比较: + +``` +uniq -d -s 4 ostechnix.txt +``` + +为了忽略比较前 N 个字段(LCTT 译注:即前几列)而不是字符,在上面的命令中使用 `-f` 选项。 + +欲了解更多详情,请参考帮助部分: + +``` +uniq --help +``` + +也可以使用 `man` 命令查看: + +``` +man uniq +``` + +今天就到这里!我希望你现在对 `uniq` 命令及其目的有一个基本的了解。如果你发现我们的指南有用,请在你的社交网络上分享,并继续支持我们。更多好东西要来了,请继续关注! + +干杯! + +-------------------------------------------------------------------------------- + +via: https://www.ostechnix.com/uniq-command-tutorial-examples-beginners/ + +作者:[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 +[1]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[2]:http://www.ostechnix.com/wp-content/uploads/2018/01/uniq-2.png +[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/uniq-1-1.png +[4]:http://www.ostechnix.com/wp-content/uploads/2018/01/uniq-4.png diff --git a/published/20180109 Linux size Command Tutorial for Beginners (6 Examples).md b/published/20180109 Linux size Command Tutorial for Beginners (6 Examples).md new file mode 100644 index 0000000000..fae2306150 --- /dev/null +++ b/published/20180109 Linux size Command Tutorial for Beginners (6 Examples).md @@ -0,0 +1,133 @@ +六个例子带你入门 size 命令 +====== + +正如你所知道的那样,Linux 中的目标文件或着说可执行文件由多个段组成(比如文本段和数据段)。若你想知道每个段的大小,那么确实存在这么一个命令行工具 —— 那就是 `size`。在本教程中,我们将会用几个简单易懂的案例来讲解该工具的基本用法。 + +在我们开始前,有必要先声明一下,本文的所有案例都在 Ubuntu 16.04 LTS 中测试过了。 + +### Linux size 命令 + +`size` 命令基本上就是输出指定输入文件各段及其总和的大小。下面是该命令的语法: + +``` +size [-A|-B|--format=compatibility] +            [--help] +            [-d|-o|-x|--radix=number] +            [--common] +            [-t|--totals] +            [--target=bfdname] [-V|--version] +            [objfile...] +``` + +man 页是这样描述它的: + +> GNU 的 `size` 程序列出参数列表中各目标文件或存档库文件的段大小 — 以及总大小。默认情况下,对每个目标文件或存档库中的每个模块都会产生一行输出。 +> +> `objfile...` 是待检查的目标文件。如果没有指定,则默认为文件 `a.out`。 + +下面是一些问答方式的案例,希望能让你对 `size` 命令有所了解。 + +### Q1、如何使用 size 命令? + +`size` 的基本用法很简单。你只需要将目标文件/可执行文件名称作为输入就行了。下面是一个例子: + +``` +size apl +``` + +该命令在我的系统中的输出如下: + +[![How to use size command][1]][2] + +前三部分的内容是文本段、数据段和 bss 段及其相应的大小。然后是十进制格式和十六进制格式的总大小。最后是文件名。 + +### Q2、如何切换不同的输出格式? + +根据 man 页的说法,`size` 的默认输出格式类似于 Berkeley 的格式。然而,如果你想的话,你也可以使用 System V 规范。要做到这一点,你可以使用 `--format` 选项加上 `SysV` 值。 + +``` +size apl --format=SysV +``` + +下面是它的输出: + +[![How to switch between different output formats][3]][4] + +### Q3、如何切换使用其他的单位? + +默认情况下,段的大小是以十进制的方式来展示。然而,如果你想的话,也可以使用八进制或十六进制来表示。对应的命令行参数分别为 `o` 和 `-x`。 + +[![How to switch between different size units][5]][6] + +关于这些参数,man 页是这么说的: + +> -d + +> -o + +> -x + +> --radix=number + +> 使用这几个选项,你可以让各个段的大小以十进制(`-d` 或 `--radix 10`)、八进制(`-o` 或 `--radix 8`);或十六进制(`-x` 或 `--radix 16`)数字的格式显示。`--radix number` 只支持三个数值参数(8、 10、 16)。总共大小以两种进制给出; `-d` 或 `-x` 的十进制和十六进制输出,或 `-o` 的八进制和十六进制输出。 + +### Q4、如何让 size 命令显示所有对象文件的总大小? + +如果你用 `size` 一次性查找多个文件的段大小,则通过使用 `-t` 选项还可以让它显示各列值的总和。 + +``` +size -t [file1] [file2] ... +``` + +下面是该命令的执行的截屏: + +[![How to make size command show totals of all object files][7]][8] + +`-t` 选项让它多加了最后那一行。 + +### Q5、如何让 size 输出每个文件中公共符号的总大小? + +若你为 `size` 提供多个输入文件作为参数,而且想让它显示每个文件中公共符号(指 common segment 中的 symbol)的大小,则你可以带上 `--common` 选项。 + +``` +size --common [file1] [file2] ... +``` + +另外需要指出的是,当使用 Berkeley 格式时,这些公共符号的大小被纳入了 bss 大小中。 + +### Q6、还有什么其他的选项? + +除了刚才提到的那些选项外,`size` 还有一些一般性的命令行选项,比如 `v` (显示版本信息)和 `-h` (可选参数和选项的汇总)。 + +[![What are the other available command line options][9]][10] + +除此之外,你也可以使用 `@file` 选项来让 `size` 从文件中读取命令行选项。下面是详细的相关说明: + +> 读出来的选项会插入并替代原来的 `@file` 选项。若文件不存在或着无法读取,则该选项不会被替换,而是会以字面意义来解释该选项。文件中的选项以空格分隔。当选项中要包含空格时需要用单引号或双引号将整个选项包起来。通过在字符前面添加一个反斜杠可以将任何字符(包括反斜杠本身)纳入到选项中。文件本身也能包含其他的 `@file` 选项;任何这样的选项都会被递归处理。 + +### 结论 + +很明显,`size` 命令并不适用于所有人。它的目标群体是那些需要处理 Linux 中目标文件/可执行文件结构的人。因此,如果你刚好是目标受众,那么多试试我们这里提到的那些选项,你应该做好每天都使用这个工具的准备。想了解关于 `size` 的更多信息,请阅读它的 [man 页 ][11]。 + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/linux-size-command/ + +作者:[Himanshu Arora][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[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/size-basic-usage.png +[2]:https://www.howtoforge.com/images/command-tutorial/big/size-basic-usage.png +[3]:https://www.howtoforge.com/images/command-tutorial/size-format-option.png +[4]:https://www.howtoforge.com/images/command-tutorial/big/size-format-option.png +[5]:https://www.howtoforge.com/images/command-tutorial/size-o-x-options.png +[6]:https://www.howtoforge.com/images/command-tutorial/big/size-o-x-options.png +[7]:https://www.howtoforge.com/images/command-tutorial/size-t-option.png +[8]:https://www.howtoforge.com/images/command-tutorial/big/size-t-option.png +[9]:https://www.howtoforge.com/images/command-tutorial/size-v-x1.png +[10]:https://www.howtoforge.com/images/command-tutorial/big/size-v-x1.png +[11]:https://linux.die.net/man/1/size diff --git a/published/20180110 8 simple ways to promote team communication.md b/published/20180110 8 simple ways to promote team communication.md new file mode 100644 index 0000000000..0be4c5b53a --- /dev/null +++ b/published/20180110 8 simple ways to promote team communication.md @@ -0,0 +1,72 @@ +八种敏捷团队的提升方法 +====== + +> 在这个列表中,没有项目管理软件,这里不包含清单,也没有与 GitHub 整合,只是几种组织思维和提高团队交流的方法。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/world_remote_teams.png?itok=Wk1yBFv6) + +图片来源:opensource.com + +你也许经常听说下面这句话:工具太多,时间太少。为了节约您的时间,我列出了几款我最常用的提高敏捷团队工作效率的工具。如果你也是一名敏捷主义者,你可能听说过类似的工具,但我这里提到的仅限于开源工具。 + +**请注意!** 这些工具和你想象的可能有点不同。它们并不是项目管理软件——这领域已经有一篇[好文章][1]了。因此这里不包含清单,也没有与 GitHub 整合,只是几种组织思维和提高团队交流的方法。 + +### 组建一个充满积极反馈的团队 + +如果在产业中大部分人都习惯了输出、接收负面消息,就很难有人对同事进行正面反馈的输出。这并不奇怪,当人们乐于给出赞美时,人们就会竞相向别人说“干得漂亮!”、“没有你我们很难完成任务。”赞美别人干的漂亮并不会使你痛苦,它通常能激励大家更好地为团队工作。下面两个软件可以帮助你向同事表达赞扬。 + +* 对开发团队来说,[Management 3.0][2] 是个有着大量[免费资源][3]的宝箱,可以尽情使用。其中 Feedback Wraps 的观念最引人注目(不仅仅是因为它让我们联想到墨西哥卷)。 [Feedback Wraps][4] 是一个经过六步对用户进行反馈的程序,也许你会认为它是为了负面反馈而设计的,但我们发现它在表达积极评论方面十分有效。 +* [Happiness Packets][5] 为用户提供了在开源社区内匿名正面反馈的服务。它尤其适合不太习惯人际交往的用户或是不知道说什么好的情况。Happiness Packets 拥有一份[公开的评论档案][6](这些评论都已经得到授权分享),你可以浏览大家的评论,从中得到灵感,对别人做出暖心的称赞。它还有个特殊功能,能够屏蔽恶意消息。 + +### 思考工作的意义 + +这很难定义。在敏捷领域中,成功的关键包括定义人物角色和产品愿景,还要向整个敏捷团队说明此项工作的意义。产品开发人员和项目负责人能够获得的开源工具数量极为有限,对于这一点我们有些失望。 + +在 Rat Hat 公司,最受尊敬也最为常用于训练敏捷团队的开源工具之一是 Product Vision Board 。它出自产品管理专家 Roman Pichler 之手,Roman Pichler 提供了[大量工具和模版][7]来帮助敏捷团队理解他们工作的意义。(你需要提供电子邮箱地址才能下载这些工具。) + +* [Product Vision Board][8] 的模版通过简单但有效的问题引导团队转变思考方式,将思考工作的意义置于具体工作方法之前。 +* 我们也很喜欢 Roman 的 [Product Management Test][9],它能够通过简便快捷的网页表单,引领团队重新定义产品开发人员的角色,并且找出程序漏洞。我们推荐产品开发团队周期性地完成此项测试,重新分析失败原因。 + +### 对工作内容的直观化 + +你是否曾为一个大案子焦头烂额,连熟悉的步骤也在脑海中乱成一团?我们也遇到过这种情况。使用思维导图可以梳理你脑海中的想法,使其直观化。你不需要一下就想出整件事该怎么进行,你只需要你的头脑,一块白板(或者是思维导图软件)和一些思考的时间。 + +* 在这个领域中我们最喜欢的开源工具是 [Xmind3][10]。它支持多种平台运行(Linux、MacOS 和 Windows),以便与他人共享文件。如果你对工具的要求很高,推荐使用[其更新版本][11],提供电子邮箱地址即可免费下载使用。 +* 如果你很看重灵活性,Eduard Lucena 在 Fedora Magazine 中提供的 [三个附加选项][12] 就十分适合。你可以在 Fedora 杂志上找到这些软件的获取方式,其他信息可以在它们的项目页找到。 + + * [Labyrinth][13] + * [View Your Mind][14] + * [FreeMind][15] + +像我们开头说的一样,提高敏捷团队工作效率的工具有很多,如果你有特别喜欢的相关开源工具,请在评论中与大家分享。 + +### 作者简介 + +Jen Krieger :Red Hat 的首席敏捷架构师,在软件开发领域已经工作超过 20 年,曾在瀑布及敏捷生命周期等领域扮演多种角色。目前在 Red Hat 负责针对 CI/CD 最佳效果的部际 DevOps 活动。最近她在与 Project Atomic & OpenShift 团队合作。她最近在引领公司向着敏捷团队改革,并增加开源项目在公司内的认知度。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/foss-tools-agile-teams + +作者:[Jen Krieger][a] +译者:[Valoniakim](https://github.com/Valoniakim) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/jkrieger +[1]:https://opensource.com/business/16/3/top-project-management-tools-2016 +[2]:https://management30.com/ +[3]:https://management30.com/leadership-resource-hub/ +[4]:https://management30.com/en/practice/feedback-wraps/ +[5]:https://happinesspackets.io/ +[6]:https://www.happinesspackets.io/archive/ +[7]:http://www.romanpichler.com/tools/ +[8]:http://www.romanpichler.com/tools/vision-board/ +[9]:http://www.romanpichler.com/tools/romans-product-management-test/ +[10]:https://sourceforge.net/projects/xmind3/?source=recommended +[11]:http://www.xmind.net/ +[12]:https://fedoramagazine.org/three-mind-mapping-tools-fedora/ +[13]:https://people.gnome.org/~dscorgie/labyrinth.html +[14]:http://www.insilmaril.de/vym/ +[15]:http://freemind.sourceforge.net/wiki/index.php/Main_Page diff --git a/published/20180110 Why isn-t open source hot among computer science students.md b/published/20180110 Why isn-t open source hot among computer science students.md new file mode 100644 index 0000000000..aeca417f66 --- /dev/null +++ b/published/20180110 Why isn-t open source hot among computer science students.md @@ -0,0 +1,86 @@ +为什么开源在计算机专业的学生中不那么流行? +=============== + +> 高中和大学生们或许因先入为主的观念而畏于参与开源项目。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDU_OSDC_OpenClass_520x292_FINAL_JD.png?itok=ly78pMqu) + +图片来自:opensource.com + +年轻程序员的技术悟性和创造力是充满活力的。 + +这一点可以从我参加今年的(美国)国内最大的黑客马拉松 [PennApps][1] 时所目睹的他们勤奋的工作中可以看出。在 48 小时内,我的高中和大学年龄段的同龄人们创建了从[可以通过眨眼来让不能说话或行动不便的人来交流的设备][2] 到 [带有物联网功能的煎饼机][3] 的项目。在整个过程中,开源的精神是切实可见的,不同群体之间建立了共同的愿望,思想和技术诀窍的自由流通,无畏的实验和快速的原型设计,以及热衷于参与的渴望。 + +那么我想知道,为什么在我的这些技术极客伙伴中,开源并不是一个热门话题? + +为了更多地了解大学生在听到“开源”时的想法,我调查了几个大学生,他们都是我所属的专业计算机科学团体的成员。这个社团的所有成员都必须在高中或大学期间申请,并根据他们的计算机科学成就和领导能力进行选择——即是否领导过一个学校的机器人团队,建立过将编码带入资金不足的课堂的非营利组织,或其他一些值得努力的地方。鉴于这些个人在计算机科学方面的成就,我认为他们的观点将有助于理解年轻程序员对开源项目的吸引力(或不吸引人)。 + +我编写和发布的在线调查包括以下问题: + + * 你喜欢编写个人项目吗?您是否曾经参与过开源项目? + * 你觉得自己开发自己的编程项目,还是对现有的开源工作做出贡献会更有益处? + * 你将如何比较为开源软件组织和专有软件的组织编码获得的声望? + +尽管绝大多数人表示,他们至少偶尔会喜欢在业余时间编写个人项目,但大多数人从未参与过开源项目。当我进一步探索这一趋势时,一些关于开源项目和组织的常见的偏见逐渐浮出水面。为了说服我的伙伴们,开源项目值得他们花时间,并且为教育工作者和开源组织提供他们对学生的见解,我将谈谈三个首要的偏见。 + +### 偏见 1:从零开始创建个人项目比为现有的开源项目做贡献更好。 + +在我所调查的大学年龄程序员中,26 人中有 24 人声称,开发自己的个人项目比开源项目更有益。 + +作为一名计算机科学专业的大一新生,我也相信这一点。我经常听到年长的同学说,个人项目会让我成为更有吸引力的实习生。没有人提到过为开源项目做出贡献的可能性——所以在我看来,这是无关紧要的。 + +我现在意识到开源项目为现实世界提供了强大的准备工作。对开源项目的贡献培养了一种意识,即[工具和语言如何拼合在一起][4],而单个项目却不能。而且,开源是一个协调与协作的练习,可以培养[学生的沟通,团队合作和解决问题的专业技能][5]。 + +### 偏见 2:我的编码技能是不够的。 + +一些受访者表示,他们被开源项目吓倒了,不知道该从哪里开始贡献,或者担心项目进展缓慢。不幸的是,自卑感往往也会对女性程序员产生影响,而这种感觉并不止于开源社区。事实上,“冒名顶替综合症”甚至可能会被放大,因为[开源的倡导者通常会拒绝官僚主义][6] —— 而且和官僚主义一样难以在内部流动,它有助于新加入的人了解他们在一个组织中的位置。 + +我还记得第一次在 GitHub 上查看开源项目时,我对阅读贡献指南感到害怕。然而,这些指南并非旨在吓跑别人,而是提供[指导][7]。为此,我认为贡献指南是建立期望而不依赖于等级结构的一种方式。 + +有几个开源项目积极为新的项目贡献者创造了一个地方。[TEAMMATES][8] 是一种教育反馈管理工具,是为初学者们解决了这个问题一个开源项目。在评论中,各种技能水平的程序员都详细阐述了实现的细节,这表明开源项目是属于热切的新程序员和经验丰富的软件老手的地方。对于那些还在犹豫的年轻程序员来说,一些[开源项目][9]已经考虑周全,采用了[冒名顶替综合症的免责声明][10]。 + +### 偏见 3:专有软件公司比开源软件组织做得更好。 + +在接受调查的 26 位受访者中,只有 5 位认为开源组织和专有软件组织在声望上是平等的。这可能是由于“开源”意味着“无利可图”,因此质量低下的误解(查看 [“开源”不只是意味着是免费][11])。 + +然而,开源软件和盈利软件并不相互排斥。事实上,小型和大型企业通常都为免费的开源软件的技术支持服务而付款。正如[红帽公司首席执行官 Jim Whitehurst][12] 所解释的那样:“我们拥有一批工程团队,负责跟踪 Linux 的每一项变更--错误修复、安全性增强等等,确保我们客户的关键任务系统保持最新状态和稳定“。 + +另外,开源的本质是通过使更多的人能够检查源代码来提升而不是阻碍质量的提高。[Mobify 首席执行官 Igor Faletski][13] 写道,Mobify 的 “25 位软件开发人员和专业的质量保证人员团队无法满足世界上所有可能使用 [Mobify 的开源]平台的软件开发者,而他们每个人都是该项目的潜在测试者或贡献者。” + +另一个问题可能是年轻的程序员不知道他们每天使用的开源软件。 我使用了许多工具——包括 MySQL、Eclipse、Atom、Audacity 和 WordPress——几个月甚至几年,却没有意识到它们是开源的。 经常急于下载教学大纲指定软件以完成课堂作业的大学生可能不知道哪个软件是开源的。 这使得开源看起来比现在更加陌生。 + +所以学生们,在尝试之前不要敲开源码。 看看这个[初学者友好的项目][14]列表和这[六个起点][15],开始你的开源之旅。 + +教育工作者们,提醒您的学生开源社区的成功创新的历史,并引导他们走向课堂之外的开源项目。你将帮助培养更敏锐、更有准备、更自信的学生。 + +### 关于作者 + +Susie Choi - Susie 是杜克大学计算机科学专业的本科生。她对技术革新和开放源码原则对教育和社会经济不平等问题的影响非常感兴趣。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/17/12/students-and-open-source-3-common-preconceptions + +作者:[Susie Choi][a] +译者:[amwps290](https://github.com/amwps290) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/susiechoi +[1]:http://pennapps.com/ +[2]:https://devpost.com/software/blink-9o2iln +[3]:https://devpost.com/software/daburrito +[4]:https://hackernoon.com/benefits-of-contributing-to-open-source-2c97b6f529e9 +[5]:https://opensource.com/education/16/8/5-reasons-student-involvement-open-source +[6]:https://opensource.com/open-organization/17/7/open-thinking-curb-bureaucracy +[7]:https://opensource.com/life/16/3/contributor-guidelines-template-and-tips +[8]:https://github.com/TEAMMATES/teammates/issues?q=is%3Aissue+is%3Aopen+label%3Ad.FirstTimers +[9]:https://github.com/adriennefriend/imposter-syndrome-disclaimer/blob/master/examples.md +[10]:https://github.com/adriennefriend/imposter-syndrome-disclaimer +[11]:https://opensource.com/resources/what-open-source +[12]:https://hbr.org/2013/01/yes-you-can-make-money-with-op +[13]:https://hbr.org/2012/10/open-sourcing-may-be-worth +[14]:https://github.com/MunGell/awesome-for-beginners +[15]:https://opensource.com/life/16/1/6-beginner-open-source diff --git a/translated/talk/20180111 AI and machine learning bias has dangerous implications.md b/published/20180111 AI and machine learning bias has dangerous implications.md similarity index 72% rename from translated/talk/20180111 AI and machine learning bias has dangerous implications.md rename to published/20180111 AI and machine learning bias has dangerous implications.md index 3484b21163..ea6723b2f7 100644 --- a/translated/talk/20180111 AI and machine learning bias has dangerous implications.md +++ b/published/20180111 AI and machine learning bias has dangerous implications.md @@ -1,6 +1,8 @@ -AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开源社区做些什么 +AI 和机器学习中暗含的算法偏见 ====== +> 我们又能通过开源社区做些什么? + ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW_goodbadugly.png?itok=ZxaimUWU) 图片来源:opensource.com @@ -9,21 +11,21 @@ AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开 很难想像,我们经常忽略的一点是这二者的交集:计算机算法中存在的偏见。 -与我们大多数人所认为的相反,科技并不是客观的。 AI 算法和它们的决策程序是由它们的研发者塑造的,他们写入的代码,使用的“[训练][1]”数据还有他们对算法进行[应力测试][2] 的过程,都会影响这些算法今后的选择。这意味着研发者的价值观,偏见和人类缺陷都会反映在软件上。如果我只给实验室中的人脸识别算法提供白人的照片,当遇到不是白人照片时,它[不会认为照片中的是人类][3] 。这结论并不意味着 AI 是“愚蠢的”或是“天真的”,它显示的是训练数据的分布偏差:缺乏多种的脸部照片。这会引来非常严重的后果。 +与我们大多数人的认知相反,科技并不是客观的。 AI 算法和它们的决策程序是由它们的研发者塑造的,他们写入的代码,使用的“[训练][1]”数据还有他们对算法进行[应力测试][2] 的过程,都会影响这些算法今后的选择。这意味着研发者的价值观、偏见和人类缺陷都会反映在软件上。如果我只给实验室中的人脸识别算法提供白人的照片,当遇到不是白人照片时,它[不会认为照片中的是人类][3] 。这结论并不意味着 AI 是“愚蠢的”或是“天真的”,它显示的是训练数据的分布偏差:缺乏多种的脸部照片。这会引来非常严重的后果。 -这样的例子并不少。全美范围内的[州法院系统][4] 都使用“黑箱子”对罪犯进行宣判。由于训练数据的问题,[这些算法对黑人有偏见][5] ,他们对黑人罪犯会选择更长的服刑期,因此监狱中的种族差异会一直存在。而这些都发生在科技的客观性伪装下,这是“科学的”选择。 +这样的例子并不少。全美范围内的[州法院系统][4] 都使用“黑盒”对罪犯进行宣判。由于训练数据的问题,[这些算法对黑人有偏见][5] ,他们对黑人罪犯会选择更长的服刑期,因此监狱中的种族差异会一直存在。而这些都发生在科技的客观性伪装下,这是“科学的”选择。 美国联邦政府使用机器学习算法来计算福利性支出和各类政府补贴。[但这些算法中的信息][6],例如它们的创造者和训练信息,都很难找到。这增加了政府工作人员进行不平等补助金分发操作的几率。 -算法偏见情况还不止这些。从 Facebook 的新闻算法到医疗系统再到警方使用的相机,我们作为社会的一部分极有可能对这些算法输入各式各样的偏见,性别歧视,仇外思想,社会经济地位歧视,确认偏误等等。这些被输入了偏见的机器会大量生产分配,将种种社会偏见潜藏于科技客观性的面纱之下。 +算法偏见情况还不止这些。从 Facebook 的新闻算法到医疗系统再到警用携带相机,我们作为社会的一部分极有可能对这些算法输入各式各样的偏见、性别歧视、仇外思想、社会经济地位歧视、确认偏误等等。这些被输入了偏见的机器会大量生产分配,将种种社会偏见潜藏于科技客观性的面纱之下。 这种状况绝对不能再继续下去了。 在我们对人工智能进行不断开发研究的同时,需要降低它的开发速度,小心仔细地开发。算法偏见的危害已经足够大了。 -## 我们能怎样减少算法偏见? +### 我们能怎样减少算法偏见? -最好的方式是从算法训练的数据开始审查,根据 [Microsoft 的研究者][2] 所说,这方法很有效。 +最好的方式是从算法训练的数据开始审查,根据 [微软的研究人员][2] 所说,这方法很有效。 数据分布本身就带有一定的偏见性。编程者手中的美国公民数据分布并不均衡,本地居民的数据多于移民者,富人的数据多于穷人,这是极有可能出现的情况。这种数据的不平均会使 AI 对我们是社会组成得出错误的结论。例如机器学习算法仅仅通过统计分析,就得出“大多数美国人都是富有的白人”这个结论。 @@ -37,7 +39,7 @@ AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开 这些对于 AI 来说是十分复杂的数据,但我们可以通过多项测试对它们进行定义和传达。 -## 为什么开源很适合这项任务? +### 为什么开源很适合这项任务? 开源方法和开源技术都有着极大的潜力改变算法偏见。 @@ -45,17 +47,17 @@ AI 和机器中暗含的算法偏见是怎样形成的,我们又能通过开 调试工具如哥伦比亚大学和理海大学推出的 [DeepXplore][9],增强了 AI 应力测试的强度,同时提高了其操控性。还有 [麻省理工学院的计算机科学和人工智能实验室][10]完成的项目,它开发出敏捷快速的样机研究软件,这些应该会被开源社区采纳。 -开源技术也已经证明了其在审查和分类大组数据方面的能力。最明显的体现在开源工具在数据分析市场的占有率上(Weka , Rapid Miner 等等)。应当由开源社区来设计识别数据偏见的工具,已经在网上发布的大量训练数据组比如 [Kaggle][11]也应当使用这种技术进行识别筛选。 +开源技术也已经证明了其在审查和分类大组数据方面的能力。最明显的体现在开源工具在数据分析市场的占有率上(Weka、Rapid Miner 等等)。应当由开源社区来设计识别数据偏见的工具,已经在网上发布的大量训练数据组比如 [Kaggle][11] 也应当使用这种技术进行识别筛选。 -开源方法本身十分适合消除偏见程序的设计。内部谈话,私人软件开发及非民主的决策制定引起了很多问题。开源社区能够进行软件公开的谈话,进行大众化,维持好与大众的关系,这对于处理以上问题是十分重要的。如果线上社团,组织和院校能够接受这些开源特质,那么由开源社区进行消除算法偏见的机器设计也会顺利很多。 +开源方法本身十分适合消除偏见程序的设计。内部谈话、私人软件开发及非民主的决策制定引起了很多问题。开源社区能够进行软件公开的谈话,进行大众化,维持好与大众的关系,这对于处理以上问题是十分重要的。如果线上社团,组织和院校能够接受这些开源特质,那么由开源社区进行消除算法偏见的机器设计也会顺利很多。 -## 我们怎样才能够参与其中? +### 我们怎样才能够参与其中? -教育是一个很重要的环节。我们身边有很多还没意识到算法偏见的人,但算法偏见在立法,社会公正,政策及更多领域产生的影响与他们息息相关。让这些人知道算法偏见是怎样形成的和它们带来的重要影响是很重要的,因为想要改变目前是局面,从我们自身做起是唯一的方法。 +教育是一个很重要的环节。我们身边有很多还没意识到算法偏见的人,但算法偏见在立法、社会公正、政策及更多领域产生的影响与他们息息相关。让这些人知道算法偏见是怎样形成的和它们带来的重要影响是很重要的,因为想要改变目前的局面,从我们自身做起是唯一的方法。 -对于我们中间那些与人工智能一起工作的人来说,这种沟通尤其重要。不论是人工智能的研发者,警方或是科研人员,当他们为今后设计人工智能时,应当格外意识到现今这种偏见存在的危险性,很明显,想要消除人工智能中存在的偏见,就要从意识到偏见的存在开始。 +对于我们中间那些与人工智能一起工作的人来说,这种沟通尤其重要。不论是人工智能的研发者、警方或是科研人员,当他们为今后设计人工智能时,应当格外意识到现今这种偏见存在的危险性,很明显,想要消除人工智能中存在的偏见,就要从意识到偏见的存在开始。 -最后,我们需要围绕 AI 伦理化建立并加强开源社区。不论是需要建立应力实验训练模型,软件工具,或是从千兆字节的训练数据中筛选,现在已经到了我们利用开源方法来应对数字化时代最大的威胁的时间了。 +最后,我们需要围绕 AI 伦理化建立并加强开源社区。不论是需要建立应力实验训练模型、软件工具,或是从千兆字节的训练数据中筛选,现在已经到了我们利用开源方法来应对数字化时代最大的威胁的时间了。 -------------------------------------------------------------------------------- @@ -63,7 +65,7 @@ via: https://opensource.com/article/18/1/how-open-source-can-fight-algorithmic-b 作者:[Justin Sherman][a] 译者:[Valoniakim](https://github.com/Valoniakim) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180116 Monitor your Kubernetes Cluster.md b/published/20180116 Monitor your Kubernetes Cluster.md new file mode 100644 index 0000000000..d7427bc6e0 --- /dev/null +++ b/published/20180116 Monitor your Kubernetes Cluster.md @@ -0,0 +1,275 @@ +使用 Graylog 和 Prometheus 监视 Kubernetes 集群 +====== + +这篇文章最初发表在 [Kevin Monroe 的博客][1] 上。 + +监视日志和指标状态是集群管理员的重点工作。它的好处很明显:指标能帮你设置一个合理的性能目标,而日志分析可以发现影响你工作负载的问题。然而,困难的是如何找到一个与大量运行的应用程序一起工作的监视解决方案。 + +在本文中,我将使用 [Graylog][2] (用于日志)和 [Prometheus][3] (用于指标)去打造一个 Kubernetes 集群的监视解决方案。当然了,这不仅是将三个东西连接起来那么简单,实现上,最终结果看起来应该如下图所示: + +![][4] + +正如你所了解的,Kubernetes 不是一件东西 —— 它由主控节点、工作节点、网络连接、配置管理等等组成。同样,Graylog 是一个配角(apache2、mongodb、等等),Prometheus 也一样(telegraf、grafana 等等)。在部署中连接这些点看起来似乎有些让人恐惧,但是使用合适的工具将不会那么困难。 + +我将使用 [conjure-up][5] 和 [Canonical 版本的 Kubernetes][6] (CDK) 去探索 Kubernetes。我发现 `conjure-up` 接口对部署大型软件很有帮助,但是我知道一些人可能不喜欢 GUI、TUI 以及其它用户界面。对于这些人,我将用命令行再去部署一遍。 + +在开始之前需要注意的一点是,Graylog 和 Prometheus 是部署在 Kubernetes 外侧而不是集群上。像 Kubernetes 仪表盘和 Heapster 是运行的集群的非常好的信息来源,但是我的目标是为日志/指标提供一个分析机制,而不管集群运行与否。 + +### 开始探索 + +如果你的系统上没有 `conjure-up`,首先要做的第一件事情是,请先安装它,在 Linux 上,这很简单: + +``` +sudo snap install conjure-up --classic +``` + +对于 macOS 用户也提供了 brew 包: + +``` +brew install conjure-up +``` + +你需要最新的 2.5.2 版,它的好处是添加了 CDK spell,因此,如果你的系统上已经安装了旧的版本,请使用 `sudo snap refresh conjure-up` 或者 `brew update && brew upgrade conjure-up` 去更新它。 + +安装完成后,运行它: + +``` +conjure-up +``` + +![][7] + +你将发现有一个 spell 列表。选择 CDK 然后按下回车。 + +![][8] + +这个时候,你将看到 CDK spell 可用的附加组件。我们感兴趣的是 Graylog 和 Prometheus,因此选择这两个,然后点击 “Continue”。 + +它将引导你选择各种云,以决定你的集群部署的地方。之后,你将看到一些部署的后续步骤,接下来是回顾屏幕,让你再次确认部署内容: + +![][9] + +除了典型的 K8s 相关的应用程序(etcd、flannel、load-balancer、master 以及 workers)之外,你将看到我们选择的日志和指标相关的额外应用程序。 + +Graylog 栈包含如下: + + * apache2:graylog web 界面的反向代理 + * elasticsearch:日志使用的文档数据库 + * filebeat:从 K8s master/workers 转发日志到 graylog + * graylog:为日志收集器提供一个 api,以及提供一个日志分析界面 + * mongodb:保存 graylog 元数据的数据库 + +Prometheus 栈包含如下: + + * grafana:指标相关的仪表板的 web 界面 + * prometheus:指标收集器以及时序数据库 + * telegraf:发送主机的指标到 prometheus 中 + + +你可以在回顾屏幕上微调部署,但是默认组件是必选 的。点击 “Deploy all Remaining Applications” 继续。 + +部署工作将花费一些时间,它将部署你的机器和配置你的云。完成后,`conjure-up` 将展示一个摘要屏幕,它包含一些链接,你可以用你的终端去浏览各种感兴趣的内容: + +![][10] + +#### 浏览日志 + +现在,Graylog 已经部署和配置完成,我们可以看一下采集到的一些数据。默认情况下,filebeat 应用程序将从 Kubernetes 的 master 和 worker 中转发系统日志( `/var/log/*.log` )和容器日志(`/var/log/containers/*.log`)到 graylog 中。 + +记住如下的 apache2 的地址和 graylog 的 admin 密码: + +``` +juju status --format yaml apache2/0 | grep public-address + public-address: +juju run-action --wait graylog/0 show-admin-password + admin-password: +``` + +在浏览器中输入 `http://` ,然后以管理员用户名(admin)和密码(\)登入。 + +**注意:** 如果这个界面不可用,请等待大约 5 分钟时间,以便于配置的反向代理生效。 + +登入后,顶部的 “Sources” 选项卡可以看到从 K8s 的 master 和 workers 中收集日志的概述: + +![][11] + +通过点击 “System / Inputs” 选项卡深入这些日志,选择 “Show received messages” 查看 filebeat 的输入: + +![][12] + +在这里,你可以应用各种过滤或者设置 Graylog 仪表板去帮助识别大多数比较重要的事件。查看 [Graylog Dashboard][13] 文档,可以了解如何定制你的视图的详细资料。 + +#### 浏览指标 + +我们的部署通过 grafana 仪表板提供了两种类型的指标:系统指标,包括像 K8s master 和 worker 的 CPU /内存/磁盘使用情况,以及集群指标,包括像从 K8s cAdvisor 端点上收集的容器级指标。 + +记住如下的 grafana 的地址和 admin 密码: + +``` +juju status --format yaml grafana/0 | grep public-address + public-address: +juju run-action --wait grafana/0 get-admin-password + password: +``` + +在浏览器中输入 `http://:3000`,输入管理员用户(admin)和密码(\)登入。成功登入后,点击 “Home” 下拉框,选取 “Kubernetes Metrics (via Prometheus)” 去查看集群指标仪表板: + +![][14] + +我们也可以通过下拉框切换到 “Node Metrics (via Telegraf) ” 去查看 K8s 主机的系统指标。 + +![][15] + +### 另一种方法 + +正如在文章开始的介绍中提到的,我喜欢用 `conjure-up` 的向导去完成像 Kubernetes 这种复杂软件的部署。现在,我们来看一下 `conjure-up` 的另一种方法,你可能希望去看到实现相同结果的一些命令行的方法。还有其它的可能已经部署了前面的 CDK,并想去扩展使用上述的 Graylog/Prometheus 组件。不管什么原因你既然看到这了,既来之则安之,继续向下看吧。 + +支持 `conjure-up` 的工具是 [Juju][16]。CDK spell 所做的一切,都可以使用 `juju` 命令行来完成。我们来看一下,如何一步步完成这些工作。 + +#### 从 Scratch 中启动 + +如果你使用的是 Linux,安装 Juju 很简单,命令如下: + +``` +sudo snap install juju --classic +``` + +对于 macOS,Juju 也可以从 brew 中安装: + +``` +brew install juju +``` + +现在为你选择的云配置一个控制器。你或许会被提示请求一个凭据(用户名密码): + +``` +juju bootstrap +``` + +我们接下来需要基于 CDK 捆绑部署: + +``` +juju deploy canonical-kubernetes +``` + +#### 从 CDK 开始 + +使用我们部署的 Kubernetes 集群,我们需要去添加 Graylog 和 Prometheus 所需要的全部应用程序: + +``` +## deploy graylog-related applications +juju deploy xenial/apache2 +juju deploy xenial/elasticsearch +juju deploy xenial/filebeat +juju deploy xenial/graylog +juju deploy xenial/mongodb +``` +``` +## deploy prometheus-related applications +juju deploy xenial/grafana +juju deploy xenial/prometheus +juju deploy xenial/telegraf +``` + +现在软件已经部署完毕,将它们连接到一起,以便于它们之间可以相互通讯: + +``` +## relate graylog applications +juju relate apache2:reverseproxy graylog:website +juju relate graylog:elasticsearch elasticsearch:client +juju relate graylog:mongodb mongodb:database +juju relate filebeat:beats-host kubernetes-master:juju-info +juju relate filebeat:beats-host kubernetes-worker:jujuu-info +``` +``` +## relate prometheus applications +juju relate prometheus:grafana-source grafana:grafana-source +juju relate telegraf:prometheus-client prometheus:target +juju relate kubernetes-master:juju-info telegraf:juju-info +juju relate kubernetes-worker:juju-info telegraf:juju-info +``` + +这个时候,所有的应用程序已经可以相互之间进行通讯了,但是我们还需要多做一点配置(比如,配置 apache2 反向代理、告诉 prometheus 如何从 K8s 中取数、导入到 grafana 仪表板等等): + +``` +## configure graylog applications +juju config apache2 enable_modules="headers proxy_html proxy_http" +juju config apache2 vhost_http_template="$(base64 )" +juju config elasticsearch firewall_enabled="false" +juju config filebeat \ + logpath="/var/log/*.log /var/log/containers/*.log" +juju config filebeat logstash_hosts=":5044" +juju config graylog elasticsearch_cluster_name="" +``` +``` +## configure prometheus applications +juju config prometheus scrape-jobs="" +juju run-action --wait grafana/0 import-dashboard \ + dashboard="$(base64 )" +``` + +以上的步骤需要根据你的部署来指定一些值。你可以用与 `conjure-up` 相同的方法得到这些: + + * ``: 从 github 获取我们的示例 [模板][17] + * ``: `juju run --unit graylog/0 'unit-get private-address'` + * ``: `juju config elasticsearch cluster-name` + * ``: 从 github 获取我们的示例 [scraper][18] ;`[K8S_PASSWORD][20]` 和 `[K8S_API_ENDPOINT][21]` [substitute][19] 的正确值 + * ``: 从 github 获取我们的 [主机][22] 和 [k8s][23] 仪表板 + + +最后,发布 apache2 和 grafana 应用程序,以便于可以通过它们的 web 界面访问: + +``` +## expose relevant endpoints +juju expose apache2 +juju expose grafana +``` + +现在我们已经完成了所有的部署、配置、和发布工作,你可以使用与上面的**浏览日志**和**浏览指标**部分相同的方法去查看它们。 + +### 总结 + +我的目标是向你展示如何去部署一个 Kubernetes 集群,很方便地去监视它的日志和指标。无论你是喜欢向导的方式还是命令行的方式,我希望你清楚地看到部署一个监视系统并不复杂。关键是要搞清楚所有部分是如何工作的,并将它们连接到一起工作,通过断开/修复/重复的方式,直到它们每一个都能正常工作。 + +这里有一些像 conjure-up 和 Juju 一样非常好的工具。充分发挥这个生态系统贡献者的专长让管理大型软件变得更容易。从一套可靠的应用程序开始,按需定制,然后投入到工作中! + +大胆去尝试吧,然后告诉我你用的如何。你可以在 Freenode IRC 的 **#conjure-up** 和 **#juju** 中找到像我这样的爱好者。感谢阅读! + +### 关于作者 + +Kevin 在 2014 年加入 Canonical 公司,他专注于复杂软件建模。他在 Juju 大型软件团队中找到了自己的位置,他的任务是将大数据和机器学习应用程序转化成可重复的(可靠的)解决方案。 + +-------------------------------------------------------------------------------- + +via: https://insights.ubuntu.com/2018/01/16/monitor-your-kubernetes-cluster/ + +作者:[Kevin Monroe][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://insights.ubuntu.com/author/kwmonroe/ +[1]:https://medium.com/@kwmonroe/monitor-your-kubernetes-cluster-a856d2603ec3 +[2]:https://www.graylog.org/ +[3]:https://prometheus.io/ +[4]:https://insights.ubuntu.com/wp-content/uploads/706b/1_TAA57DGVDpe9KHIzOirrBA.png +[5]:https://conjure-up.io/ +[6]:https://jujucharms.com/canonical-kubernetes +[7]:https://insights.ubuntu.com/wp-content/uploads/98fd/1_o0UmYzYkFiHIs2sBgj7G9A.png +[8]:https://insights.ubuntu.com/wp-content/uploads/0351/1_pgVaO_ZlalrjvYd5pOMJMA.png +[9]:https://insights.ubuntu.com/wp-content/uploads/9977/1_WXKxMlml2DWA5Kj6wW9oXQ.png +[10]:https://insights.ubuntu.com/wp-content/uploads/8588/1_NWq7u6g6UAzyFxtbM-ipqg.png +[11]:https://insights.ubuntu.com/wp-content/uploads/a1c3/1_hHK5mSrRJQi6A6u0yPSGOA.png +[12]:https://insights.ubuntu.com/wp-content/uploads/937f/1_cP36lpmSwlsPXJyDUpFluQ.png +[13]:http://docs.graylog.org/en/2.3/pages/dashboards.html +[14]:https://insights.ubuntu.com/wp-content/uploads/9256/1_kskust3AOImIh18QxQPgRw.png +[15]:https://insights.ubuntu.com/wp-content/uploads/2037/1_qJpjPOTGMQbjFY5-cZsYrQ.png +[16]:https://jujucharms.com/ +[17]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/graylog/steps/01_install-graylog/graylog-vhost.tmpl +[18]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/prometheus-scrape-k8s.yaml +[19]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L25 +[20]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L10 +[21]:https://github.com/conjure-up/spells/blob/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/after-deploy#L11 +[22]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/grafana-telegraf.json +[23]:https://raw.githubusercontent.com/conjure-up/spells/master/canonical-kubernetes/addons/prometheus/steps/01_install-prometheus/grafana-k8s.json diff --git a/translated/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md b/published/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md similarity index 77% rename from translated/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md rename to published/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md index fdd9c678c2..5fcbb6b05b 100644 --- a/translated/tech/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md +++ b/published/20180118 Configuring MSMTP On Ubuntu 16.04 (Again).md @@ -1,14 +1,20 @@ -(再次)在 Ubuntu 16.04 上配置 MSMTP +在 Ubuntu 16.04 上配置 msmtp ====== -这篇文章是在我之前的博客中发表过的在 Ubuntu 16.04 上配置 MSMTP 的一个副本。我再次发表是为了后续,我并不知道它是否能在更高版本上工作。由于我没有再托管自己的 Ubuntu/MSMTP 服务器了,所以我现在看不到有更新的,但是如果我需要重新设置,我会创建一个更新的帖子!无论如何,这是我现有的。 + +这篇文章是在我之前的博客中发表过的在 Ubuntu 16.04 上配置 MSMTP 的一个副本。我再次发表是为了后续,我并不知道它是否能在更高版本上工作。由于我没有再托管自己的 Ubuntu/MSMTP 服务器了,所以我现在看不到有需要更新的地方,但是如果我需要重新设置,我会创建一个更新的帖子!无论如何,这是我现有的。 我之前写了一篇在 Ubuntu 12.04 上配置 msmtp 的文章,但是正如我在之前的文章中暗示的那样,当我升级到 Ubuntu 16.04 后出现了一些问题。接下来的内容基本上是一样的,但 16.04 有一些小的更新。和以前一样,这里假定你使用 Apache 作为 Web 服务器,但是我相信如果你选择其他的 Web 服务器,也应该相差不多。 -我使用 [msmtp][1] 发送来自这个博客的邮件俩通知我评论和更新等。这里我会记录如何配置它通过 Google Apps 帐户发送电子邮件,虽然这应该与标准帐户一样。 +我使用 [msmtp][1] 发送来自这个博客的邮件俩通知我评论和更新等。这里我会记录如何配置它通过 Google Apps 帐户发送电子邮件,虽然这应该与标准的 Google 帐户一样。 首先,我们需要安装 3 个软件包: -`sudo apt-get install msmtp msmtp-mta ca-certificates` -安装完成后,就需要一个默认配置。默认情况下,msmtp 会在 `/etc/msmtprc` 中查找,所以我使用 vim 创建了这个文件,尽管任何文本编辑器都可以做到这一点。这个文件看起来像这样: + +``` +sudo apt-get install msmtp msmtp-mta ca-certificates +``` + +安装完成后,就需要一个默认配置。默认情况下,msmtp 会在 `/etc/msmtprc` 中查找,所以我使用 `vim` 创建了这个文件,尽管任何文本编辑器都可以做到这一点。这个文件看起来像这样: + ``` # Set defaults. defaults @@ -17,50 +23,57 @@ tls on tls_starttls on tls_trust_file /etc/ssl/certs/ca-certificates.crt # Setup WP account's settings. -account +account GMAIL host smtp.gmail.com port 587 auth login -user -password -from +user YOUR USERNAME +password YOUR PASSWORD +from FROM@ADDRESS logfile /var/log/msmtp/msmtp.log account default : - ``` -任何大写项(即``)都是需要替换为你特定的配置。日志文件是一个例外,当然你也可以将活动/警告/错误放在任何你想要的地方。 +任何大写选项都是需要替换为你特定的配置。日志文件是一个例外,当然你也可以将活动/警告/错误放在任何你想要的地方。 文件保存后,我们将更新上述配置文件的权限 ,如果该文件的权限过于开放,msmtp 将不会运行,并且创建日志文件的目录。 + ``` sudo mkdir /var/log/msmtp sudo chown -R www-data:adm /var/log/msmtp sudo chmod 0600 /etc/msmtprc - ``` 接下来,我选择为 msmtp 日志配置 logrotate,以确保日志文件不会太大并让日志目录更加整洁。为此,我们创建 `/etc/logrotate.d/msmtp` 并使用按以下内容配置。请注意,这是可选的,你可以选择不这样做,或者你可以选择以不同方式配置日志。 ``` /var/log/msmtp/*.log { -rotate 12 -monthly -compress -missingok -notifempty + rotate 12 + monthly + compress + missingok + notifempty } ``` 现在配置了日志,我们需要通过编辑 `/etc/php/7.0/apache2/php.ini` 告诉 PHP 使用 msmtp,并将 sendmail 路径从 -`sendmail_path =` + +``` +sendmail_path = +``` + 变成 -`sendmail_path = "/usr/bin/msmtp -C /etc/msmtprc -a -t"` + +``` +sendmail_path = "/usr/bin/msmtp -C /etc/msmtprc -a -t" +``` + 这里我遇到了一个问题,即使我指定了帐户名称,但是当我测试它时,它并没有正确发送电子邮件。这就是为什么 `account default : ` 这行被放在 msmtp 配置文件的末尾。要测试配置,请确保 PHP 文件已保存并运行 `sudo service apache2 restart`,然后运行 `php -a` 并执行以下命令 + ``` mail ('personal@email.com', 'Test Subject', 'Test body text'); exit(); - ``` 此时发生的任何错误都将显示在输出中,因此错误诊断会相对容易。如果一切顺利,你现在应该可以使用 PHP sendmail(至少 WordPress 可以)中用 Gmail(或 Google Apps)从 Ubuntu 服务器发送电子邮件。 @@ -74,7 +87,7 @@ via: https://codingproductivity.wordpress.com/2018/01/18/configuring-msmtp-on-ub 作者:[JOE][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180122 How to Create a Docker Image.md b/published/20180122 How to Create a Docker Image.md similarity index 76% rename from translated/tech/20180122 How to Create a Docker Image.md rename to published/20180122 How to Create a Docker Image.md index ec0810a10a..241af3faa7 100644 --- a/translated/tech/20180122 How to Create a Docker Image.md +++ b/published/20180122 How to Create a Docker Image.md @@ -3,181 +3,160 @@ ![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/container-image_0.jpg?itok=G_Gz80R9) -在 [前面的文章][1] 中,我们学习了在 Linux、macOS、以及 Windows 上如何使用 Docker 的基础知识。在这篇文章中,我们将去学习创建 Docker 镜像的基本知识。我们可以在 DockerHub 上得到你可以用于你自己的项目的预构建镜像,并且也可以将你自己的镜像发布到这里。 +在 [前面的文章][1] 中,我们学习了在 Linux、macOS、以及 Windows 上如何使用 Docker 的基础知识。在这篇文章中,我们将学习创建 Docker 镜像的基本知识。我们可以在 DockerHub 上得到可用于你自己的项目的预构建镜像,并且也可以将你自己的镜像发布到这里。 -我们使用预构建镜像得到一个基本的 Linux 子系统,因为,从头开始构建需要大量的工作。你可以得到 Alpine( Docker 版使用的官方版本)、Ubuntu、BusyBox、或者 scratch。在我们的示例中,我将使用 Ubuntu。 +我们使用预构建镜像得到一个基本的 Linux 子系统,因为,从头开始构建需要大量的工作。你可以使用 Alpine( Docker 版使用的官方版本)、Ubuntu、BusyBox、或者 scratch。在我们的示例中,我将使用 Ubuntu。 在我们开始构建镜像之前,让我们先“容器化”它们!我的意思是,为你的所有 Docker 镜像创建目录,这样你就可以维护不同的项目和阶段,并保持它们彼此隔离。 + ``` $ mkdir dockerprojects - cd dockerprojects - ``` 现在,在 `dockerprojects` 目录中,你可以使用自己喜欢的文本编辑器去创建一个 `Dockerfile` 文件;我喜欢使用 nano,它对新手来说很容易上手。 + ``` $ nano Dockerfile - ``` 然后添加这样的一行内容: + ``` FROM Ubuntu - ``` -![m7_f7No0pmZr2iQmEOH5_ID6MDG2oEnODpQZkUL7][2] +![][2] -使用 Ctrl+Exit 然后选择 Y 去保存它。 +使用 `Ctrl+Exit` 然后选择 `Y` 去保存它。 现在开始创建你的新镜像,然后给它起一个名字(在刚才的目录中运行如下的命令): + ``` $ docker build -t dockp . - ``` (注意命令后面的圆点)这样就创建成功了,因此,你将看到如下内容: + ``` -Sending build context to Docker daemon 2.048kB - +Sending build context to Docker daemon 2.048kB Step 1/1 : FROM ubuntu - ---> 2a4cca5ac898 - Successfully built 2a4cca5ac898 - Successfully tagged dockp:latest - ``` 现在去运行和测试一下你的镜像: + ``` $ docker run -it Ubuntu - ``` 你将看到 root 提示符: + ``` root@c06fcd6af0e8:/# - ``` 这意味着在 Linux、Windows、或者 macOS 中你可以运行一个最小的 Ubuntu 了。你可以运行所有的 Ubuntu 原生命令或者 CLI 实用程序。 -![vpZ8ts9oq3uk--z4n6KP3DD3uD_P4EpG7fX06MC3][3] +![][3] 我们来查看一下在你的目录下你拥有的所有 Docker 镜像: + ``` $docker images - REPOSITORY TAG IMAGE ID CREATED SIZE - dockp latest 2a4cca5ac898 1 hour ago 111MB - ubuntu latest 2a4cca5ac898 1 hour ago 111MB - hello-world latest f2a91732366c 8 weeks ago 1.85kB - ``` -你可以看到共有三个镜像:dockp、Ubuntu、和 hello-world, hello-world 是我在几周前创建的,这一系列的前面的文章就是在它下面工作的。构建一个完整的 LAMP 栈可能是一个挑战,因此,我们使用 Dockerfile 去创建一个简单的 Apache 服务器镜像。 +你可以看到共有三个镜像:`dockp`、`Ubuntu`、和 `hello-world`, `hello-world` 是我在几周前创建的,这一系列的前面的文章就是在它下面工作的。构建一个完整的 LAMP 栈可能是一个挑战,因此,我们使用 Dockerfile 去创建一个简单的 Apache 服务器镜像。 从本质上说,Dockerfile 是安装所有需要的包、配置、以及拷贝文件的一套指令。在这个案例中,它是安装配置 Apache 和 Nginx。 你也可以在 DockerHub 上去创建一个帐户,然后在构建镜像之前登入到你的帐户,在这个案例中,你需要从 DockerHub 上拉取一些东西。从命令行中登入 DockerHub,运行如下所求的命令: + ``` $ docker login - ``` 在登入时输入你的用户名和密码。 接下来,为这个 Docker 项目,在目录中创建一个 Apache 目录: + ``` $ mkdir apache - ``` 在 Apache 目录中创建 Dockerfile 文件: + ``` $ nano Dockerfile - ``` 然后,粘贴下列内容: + ``` FROM ubuntu - MAINTAINER Kimbro Staken version: 0.1 - RUN apt-get update && apt-get install -y apache2 && apt-get clean && rm -rf /var/lib/apt/lists/* - ENV APACHE_RUN_USER www-data - ENV APACHE_RUN_GROUP www-data - ENV APACHE_LOG_DIR /var/log/apache2 - EXPOSE 80 - CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"] - ``` 然后,构建镜像: + ``` docker build -t apache . - ``` (注意命令尾部的空格和圆点) 这将花费一些时间,然后你将看到如下的构建成功的消息: + ``` Successfully built e7083fd898c7 - Successfully tagged ng:latest - Swapnil:apache swapnil$ - ``` 现在,我们来运行一下这个服务器: + ``` $ docker run -d apache - a189a4db0f7c245dd6c934ef7164f3ddde09e1f3018b5b90350df8be85c8dc98 - ``` 发现了吗,你的容器镜像已经运行了。可以运行如下的命令来检查所有运行的容器: + ``` $ docker ps - CONTAINER ID IMAGE COMMAND CREATED - a189a4db0f7 apache "/usr/sbin/apache2ctl" 10 seconds ago - ``` -你可以使用 docker kill 命令来杀死容器: +你可以使用 `docker kill` 命令来杀死容器: + ``` $docker kill a189a4db0f7 - ``` -正如你所见,这个 "镜像" 它已经永久存在于你的目录中了,而不论运行与否。现在你可以根据你的需要创建很多的镜像,并且可以从这些镜像中繁衍出来更多的镜像。 +正如你所见,这个 “镜像” 它已经永久存在于你的目录中了,而不论运行与否。现在你可以根据你的需要创建很多的镜像,并且可以从这些镜像中繁衍出来更多的镜像。 这就是如何去创建镜像和运行容器。 -想学习更多内容,你可以打开你的浏览器,然后找到更多的关于如何构建像 LAMP 栈这样的完整的 Docker 镜像的文档。这里有一个帮你实现它的 [ Dockerfile][4] 文件。在下一篇文章中,我将演示如何推送一个镜像到 DockerHub。 +想学习更多内容,你可以打开你的浏览器,然后找到更多的关于如何构建像 LAMP 栈这样的完整的 Docker 镜像的文档。这里有一个帮你实现它的 [Dockerfile][4] 文件。在下一篇文章中,我将演示如何推送一个镜像到 DockerHub。 -你可以通过来自 Linux 基金会和 edX 的 ["介绍 Linux" ][5] 免费课程来学习更多的知识。 +你可以通过来自 Linux 基金会和 edX 的 [“介绍 Linux”][5] 免费课程来学习更多的知识。 -------------------------------------------------------------------------------- @@ -185,7 +164,7 @@ via: https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-create-docker-im 作者:[SWAPNIL BHARTIYA][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180123 Migrating to Linux- The Command Line.md b/published/20180123 Migrating to Linux- The Command Line.md new file mode 100644 index 0000000000..f99b49f980 --- /dev/null +++ b/published/20180123 Migrating to Linux- The Command Line.md @@ -0,0 +1,214 @@ +迁徙到 Linux:命令行环境 +====== + +> 刚接触 Linux?在这篇教程中将学习如何轻松地在命令行列出、移动和编辑文件。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/migrate.jpg?itok=2PBkvV7s) + +这是关于迁徙到 Linux 系列的第四篇文章了。如果您错过了之前的内容,可以回顾我们之前谈到的内容 [新手之 Linux][1]、[文件和文件系统][2]、和 [图形环境][3]。Linux 无处不在,它可以用于运行大部分的网络服务器,如 Web、email 和其他服务器;它同样可以在您的手机、汽车控制台和其他很多设备上使用。现在,您可能会开始好奇 Linux 系统,并对学习 Linux 的工作原理萌发兴趣。 + +在 Linux 下,命令行非常实用。Linux 的桌面系统中,尽管命令行只是可选操作,但是您依旧能看见很多朋友开着一个命令行窗口和其他应用窗口并肩作战。在互联网服务器上和在设备中运行 Linux 时(LCTT 译注:指 IoT),命令行通常是唯一能直接与操作系统交互的工具。因此,命令行是有必要了解的,至少应当涉猎一些基础命令。 + +在命令行(通常称之为 Linux shell)中,所有操作都是通过键入命令完成。您可以执行查看文件列表、移动文件位置、显示文件内容、编辑文件内容等一系列操作,通过命令行,您甚至可以查看网页中的内容。 + +如果您在 Windows(CMD 或者 PowerShell) 上已经熟悉关于命令行的使用,您是否想跳转到“Windows 命令行用户”的章节上去?先阅读这些内容吧。 + +### 导航 + +在命令行中,这里有一个当前工作目录(文件夹和目录是同义词,在 Linux 中它们通常都被称为目录)的概念。如果没有特别指定目录,许多命令的执行会在当前目录下生效。比如,键入 `ls` 列出文件目录,当前工作目录的文件将会被列举出来。看一个例子: + +``` +$ ls +Desktop Documents Downloads Music Pictures README.txt Videos +``` + +`ls Documents` 这条命令将会列出 `Documents` 目录下的文件: + +``` +$ ls Documents +report.txt todo.txt EmailHowTo.pdf +``` + +通过 `pwd` 命令可以显示当前您的工作目录。比如: + +``` +$ pwd +/home/student +``` + +您可以通过 `cd` 命令改变当前目录并切换到您想要抵达的目录。比如: + +``` +$ pwd +/home/student +$ cd Downloads +$ pwd +/home/student/Downloads +``` + +路径中的目录由 `/`(左斜杠)字符分隔。路径中有一个隐含的层次关系,比如 `/home/student` 目录中,home 是顶层目录,而 `student` 是 `home` 的子目录。 + +路径要么是绝对路径,要么是相对路径。绝对路径由一个 `/` 字符打头。 + +相对路径由 `.` 或者 `..` 开始。在一个路径中,一个 `.` 意味着当前目录,`..` 意味着当前目录的上级目录。比如,`ls ../Documents` 意味着在此寻找当前目录的上级名为 `Documents` 的目录: + +``` +$ pwd +/home/student +$ ls +Desktop Documents Downloads Music Pictures README.txt Videos +$ cd Downloads +$ pwd +/home/student/Downloads +$ ls ../Documents +report.txt todo.txt EmailHowTo.pdf +``` + +当您第一次打开命令行窗口时,您当前的工作目录被设置为您的家目录,通常为 `/home/<您的登录名>`。家目录专用于登录之后存储您的专属文件。 + +环境变量 `$HOME` 会展开为您的家目录,比如: + +``` +$ echo $HOME +/home/student +``` + +下表显示了用于目录导航和管理简单的文本文件的一些命令摘要。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table-1_0.png?itok=j4Sgv6Vy) + +### 搜索 + +有时我们会遗忘文件的位置,或者忘记了我要寻找的文件名。Linux 命令行有几个命令可以帮助您搜索到文件。 + +第一个命令是 `find`。您可以使用 `find` 命令通过文件名或其他属性搜索文件和目录。举个例子,当您遗忘了 `todo.txt` 文件的位置,我们可以执行下面的代码: + +``` +$ find $HOME -name todo.txt +/home/student/Documents/todo.txt +``` + +`find` 程序有很多功能和选项。一个简单的例子: + +``` +find <要寻找的目录> -name <文件名> +``` + +如果这里有 `todo.txt` 文件且不止一个,它将向我们列出拥有这个名字的所有文件的所有所在位置。`find` 命令有很多便于搜索的选项比如类型(文件或是目录等等)、时间、大小和其他一些选项。更多内容您可以同通过 `man find` 获取关于如何使用 `find` 命令的帮助。 + +您还可以使用 `grep` 命令搜索文件的特定内容,比如: + +``` +grep "01/02/2018" todo.txt +``` + +这将为您展示 `todo` 文件中 `01/02/2018` 所在行。 + +### 获取帮助 + +Linux 有很多命令,这里,我们没有办法一一列举。授人以鱼不如授人以渔,所以下一步我们将向您介绍帮助命令。 + +`apropos` 命令可以帮助您查找需要使用的命令。也许您想要查找能够操作目录或是获得文件列表的所有命令,但是您不知道该运行哪个命令。您可以这样尝试: + +``` +apropos directory +``` + +要在帮助文档中,得到一个于 `directiory` 关键字的相关命令列表,您可以这样操作: + +``` +apropos "list open files" +``` + +这将提供一个 `lsof` 命令给您,帮助您列出打开文件的列表。 + +当您明确知道您要使用的命令,但是不确定应该使用什么选项完成预期工作,您可以使用 `man` 命令,它是 manual 的缩写。您可以这样使用: + +``` +man ls +``` + +您可以在自己的设备上尝试这个命令。它会提供给您关于使用这个命令的完整信息。 + +通常,很多命令都能够接受 `help` 选项(比如说,`ls --help`),列出命令使用的提示。`man` 页面的内容通常太繁琐,`--help` 选项可能更适合快速浏览。 + +### 脚本 + +Linux 命令行中最贴心的功能之一是能够运行脚本文件,并且能重复运行。Linux 命令可以存储在文本文件中,您可以在文件的开头写入 `#!/bin/sh`,后面的行是命令。之后,一旦文件被存储为可执行文件,您就可以像执行命令一样运行脚本文件,比如, + +``` +--- contents of get_todays_todos.sh --- +#!/bin/sh +todays_date=`date +"%m/%d/%y"` +grep $todays_date $HOME/todos.txt +``` + +脚本可以以一套可重复的步骤自动化执行特定命令。如果需要的话,脚本也可以很复杂,能够使用循环、判断语句等。限于篇幅,这里不细述,但是您可以在网上查询到相关信息。 + +### Windows 命令行用户 + +如果您对 Windows CMD 或者 PowerShell 程序很熟悉,在命令行输入命令应该是轻车熟路的。然而,它们之间有很多差异,如果您没有理解它们之间的差异可能会为之困扰。 + +首先,在 Linux 下的 `PATH` 环境与 Windows 不同。在 Windows 中,当前目录被认为是该搜索路径(`PATH`)中的第一个文件夹,尽管该目录没有在环境变量中列出。而在 Linux 下,当前目录不会明确的放在搜索路径中。Linux 下设置环境变量会被认为是风险操作。在 Linux 的当前目录执行程序,您需要使用 `./`(代表当前目录的相对目录表示方式) 前缀。这可能会搞糊涂很多 CMD 用户。比如: + +``` +./my_program +``` + +而不是 + +``` +my_program +``` + +另外,在 Windows 环境变量的路径中是以 `;`(分号) 分割的。在 Linux 中,由 `:` 分割环境变量。同样,在 Linux 中路径由 `/` 字符分隔,而在 Windows 目录中路径由 `\` 字符分割。因此 Windows 中典型的环境变量会像这样: + +``` +PATH="C:\Program Files;C:\Program Files\Firefox;" +``` +而在 Linux 中看起来像这样: + +``` +PATH="/usr/bin:/opt/mozilla/firefox" +``` + +还要注意,在 Linux 中环境变量由 `$` 拓展,而在 Windows 中您需要使用百分号(就是这样: `%PATH%`)。 + +在 Linux 中,通过 `-` 使用命令选项,而在 Windows 中,使用选项要通过 `/` 字符。所以,在 Linux 中您应该: + +``` +a_prog -h +``` + +而不是 + +``` +a_prog /h +``` + +在 Linux 下,文件拓展名并没有意义。例如,将 `myscript` 重命名为 `myscript.bat` 并不会因此而变得可执行,需要设置文件的执行权限。文件执行权限会在下次的内容中覆盖到。 + +在 Linux 中,如果文件或者目录名以 `.` 字符开头,意味着它们是隐藏文件。比如,如果您申请编辑 `.bashrc` 文件,您不能在家目录中找到它,但是它可能真的存在,只不过它是隐藏文件。在命令行中,您可以通过 `ls` 命令的 `-a` 选项查看隐藏文件,比如: + +``` +ls -a +``` + +在 Linux 中,普通的命令与 Windows 的命令不尽相同。下面的表格显示了常用命令中 CMD 命令和 Linux 命令行的差异。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/table-2_0.png?itok=NNc8TZFZ) + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/1/migrating-linux-command-line + +作者:[John Bonesio][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/johnbonesio +[1]:https://linux.cn/article-9212-1.html +[2]:https://linux.cn/article-9213-1.html +[3]:https://linux.cn/article-9293-1.html diff --git a/sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md b/published/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md similarity index 50% rename from sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md rename to published/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md index bf7772ef1a..ba63c49894 100644 --- a/sources/tech/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md +++ b/published/20180128 How to add network bridge with nmcli (NetworkManager) on Linux.md @@ -1,63 +1,73 @@ -How to add network bridge with nmcli (NetworkManager) on Linux +如何在 Linux 里使用 nmcli 添加网桥 ====== -I am using Debian Linux 9 "stretch" on the desktop. I would like to create network bridge with NetworkManager. But, I am unable to find the option to add br0. How can I create or add network bridge with nmcli for NetworkManager on Linux? +Q:我正在电脑上使用 Debian Linux 9 “stretch”。 我想用 NetworkManager 来建网桥。但是根本就没有添加 br0的选项。我该如何在 Linux 里使用 nmcli 来为 NetworkManager 创建或者添加网桥呢? -A bridge is nothing but a device which joins two local networks into one network. It works at the data link layer, i.e., layer 2 of the OSI model. Network bridge often used with virtualization and other software. Disabling NetworkManager for a simple bridge especially on Linux Laptop/desktop doesn't make any sense. The nmcli tool can create Persistent bridge configuration without editing any files. **This page shows how to create a bridge interface using the Network Manager command line tool called nmcli**. +网桥没什么特别的,只是把两个网络连在一起。它工作在数据链路层,即 OSI 模型的第二层。网桥经常用在虚拟机或别的一些软件中。为了使用网桥而关闭桌面 Linux 上的 NetworkManager 显然是不明智的。`nmcli` 可以创建一个永久的网桥而不需要编辑任何文件。 +本文将展示如何使用 NetworkManager 的命令行工具 `nmcli` 来创建网桥。 +### 如何使用 nmcli 来创建/添加网桥 -### How to create/add network bridge with nmcli +使用 NetworkManager 在 Linux 上添加网桥接口的步骤如下: -The procedure to add a bridge interface on Linux is as follows when you want to use Network Manager: - -1. Open the Terminal app -2. Get info about the current connection: +1. 打开终端 +2. 获取当前连接状态: ``` nmcli con show ``` -3. Add a new bridge: +3. 添加新的网桥: ``` nmcli con add type bridge ifname br0 ``` -4. Create a slave interface: +4. 创建子网卡: ``` nmcli con add type bridge-slave ifname eno1 master br0 ``` -5. Turn on br0: +5. 打开 br0: ``` nmcli con up br0 ``` -Let us see how to create a bridge, named br0 in details. +让我们从细节层面看看如何创建一个名为 br0 的网桥。 -### Get current network config +### 获取当前网络配置 + +你可以通过 NetworkManager 的 GUI 来了解本机的网络连接: -You can view connection from the Network Manager GUI in settings: [![Getting Network Info on Linux][1]][1] -Another option is to type the following command: + +也可以使用如下命令行来查看: + ``` $ nmcli con show $ nmcli connection show --active ``` -[![View the connections with nmcli][2]][2] -I have a "Wired connection 1" which uses the eno1 Ethernet interface. My system has a VPN interface too. I am going to setup a bridge interface named br0 and add, (or enslave) an interface to eno1. -### How to create a bridge, named br0 +[![View the connections with nmcli][2]][2] + +我有一个使用网卡 `eno1` 的 “有线连接”。我的系统还有一个 VPN 接口。我将要创建一个名为 `br0` 的网桥,并连接到 `eno1`。 + +### 如何创建一个名为 br0 的网桥 ``` $ sudo nmcli con add ifname br0 type bridge con-name br0 $ sudo nmcli con add type bridge-slave ifname eno1 master br0 $ nmcli connection show ``` + [![Create bridge interface using nmcli on Linux][3]][3] -You can disable STP too: + +你也可以禁用 STP: + ``` $ sudo nmcli con modify br0 bridge.stp no $ nmcli con show $ nmcli -f bridge con show br0 ``` -The last command shows the bridge settings including disabled STP: + +最后一条命令展示了禁用 STP 后的网桥参数: + ``` bridge.mac-address: -- bridge.stp: no @@ -69,27 +79,35 @@ bridge.ageing-time: 300 bridge.multicast-snooping: yes ``` +### 如何打开网桥 -### How to turn on bridge interface +你必须先关闭 `Wired connection 1` ,然后打开 `br0`: -You must turn off "Wired connection 1" and turn on br0: ``` $ sudo nmcli con down "Wired connection 1" $ sudo nmcli con up br0 $ nmcli con show ``` -Use [ip command][4] to view the IP settings: + +使用 [ip 命令][4] 来查看 IP 信息: + ``` $ ip a s $ ip a s br0 ``` + [![Build a network bridge with nmcli on Linux][5]][5] -### Optional: How to use br0 with KVM +### 附录: 如何在 KVM 上使用 br0 + +现在你可以使用 KVM/VirtualBox/VMware workstation 创建的 VM(虚拟机)来直接连接网络而非通过 NAT。使用 `vi` 或者 [cat 命令][6]为虚拟机创建一个名为 `br0.xml` 的文件: + +``` +$ cat /tmp/br0.xml +``` + +添加以下代码: -Now you can connect VMs (virtual machine) created with KVM/VirtualBox/VMware workstation to a network directly without using NAT. Create a file named br0.xml for KVM using vi command or [cat command][6]: -`$ cat /tmp/br0.xml` -Append the following code: ``` br0 @@ -98,14 +116,17 @@ Append the following code: ``` -Run virsh command as follows: +如下所示运行 `virsh`命令: + ``` # virsh net-define /tmp/br0.xml # virsh net-start br0 # virsh net-autostart br0 # virsh net-list --all ``` -Sample outputs: + +输出: + ``` Name State Autostart Persistent ---------------------------------------------------------- @@ -113,24 +134,24 @@ Sample outputs: default inactive no yes ``` +阅读 man 页面获取更多信息: -For more info read the following man page: ``` $ man ip $ man nmcli ``` -### about the author +### 关于作者 -The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on [Twitter][7], [Facebook][8], [Google+][9]. +作者是 nixCraft 的创建者、老练的系统管理员和一个 Linux/Unix shell 脚本编程培训师。他为全球客户和各种公司工作,包括 IT,教育,国防,空间研究以及非营利组织。 他的联系方式 [Twitter][7]、 [Facebook][8]、 [Google+][9]。 -------------------------------------------------------------------------------- via: https://www.cyberciti.biz/faq/how-to-add-network-bridge-with-nmcli-networkmanager-on-linux/ 作者:[Vivek Gite][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) +译者:[kennethXia](https://github.com/kennethXia) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180129 A look inside Facebooks open source program.md b/published/20180129 A look inside Facebooks open source program.md new file mode 100644 index 0000000000..1684d005bb --- /dev/null +++ b/published/20180129 A look inside Facebooks open source program.md @@ -0,0 +1,64 @@ +Facebook 的开源计划一窥 +============================================================ + +> Facebook 开发人员 Christine Abernathy 讨论了开源如何帮助公司分享见解并推动创新。 + +![A look inside Facebook's open source program](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW-Internet_construction_9401467_520x292_0512_dc.png?itok=RPkPPtDe "A look inside Facebook's open source program") + +图像来源:opensource.com + +开源逐年变得无处不在,从[政府直辖市][11]到[大学][12]都有。各种规模的公司也越来越多地转向开源软件。事实上,一些公司正在通过财务支持项目或与开发人员合作进一步推进开源。 + +例如,Facebook 的开源计划鼓励其他人开源发布他们的代码,同时与社区合作支持开源项目。 [Christine Abernathy][13],是一名 Facebook 开发者、开源支持者,也是该公司开源团队成员,去年 11 月访问了罗切斯特理工学院,在 [11 月][14] 的 FOSS 系列演讲中发表了演讲。在她的演讲中,Abernathy 解释了 Facebook 如何开源以及为什么它是公司所做工作的重要组成部分。 + +### Facebook 和开源 + +Abernathy 说,开源在 Facebook 创建社区并使世界更加紧密的使命中扮演着重要的角色。这种意识形态的匹配是 Facebook 参与开源的一个激励因素。此外,Facebook 面临着独特的基础设施和开发挑战,而开源则为公司提供了一个平台,以共享可帮助他人的解决方案。开源还提供了一种加速创新和创建更好软件的方法,帮助工程团队生产更好的软件并更透明地工作。今天,Facebook 在 GitHub 的 443 个项目有 122,000 个分支、292,000 个提交和 732,000 个关注。 + +![open source projects by Facebook](https://opensource.com/sites/default/files/images/life-uploads/blog-article-facebook-open-source-projects.png "open source projects by Facebood") + +*一些以开源方式发布的 Facebook 项目包括 React、GraphQL、Caffe2 等等。(图片提供:Christine Abernathy 图片,经许可使用)* + +### 得到的教训 + +Abernathy 强调说 Facebook 已经从开源社区吸取了很多教训,并期待学到更多。她明确了三个最重要的: + +* 分享有用的东西 +* 突出你的英雄 +* 修复常见的痛点 + + _Christine Abernathy 作为 FOSS 演讲系列的嘉宾一员参观了 RIT。每个月,来自开源世界的演讲嘉宾都会与对自由和开源软件感兴趣的学生分享关于开源世界智慧、见解、建议。 [FOSS @MAGIC][3]社区感谢 Abernathy 作为演讲嘉宾出席。_ + +### 关于作者 + +Justin 是[罗切斯特理工学院][4]主修网络与系统管理的学生。他目前是 [Fedora Project][5] 的贡献者。在 Fedora 中,Justin 是 [Fedora Magazine][6] 的主编,[社区的领导][7]... [更多关于 Justin W. Flory]​​[8] + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/inside-facebooks-open-source-program + +作者:[Justin W. Flory][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/jflory +[1]:https://opensource.com/file/383786 +[2]:https://opensource.com/article/18/1/inside-facebooks-open-source-program?rate=H9_bfSwXiJfi2tvOLiDxC_tbC2xkEOYtCl-CiTq49SA +[3]:http://foss.rit.edu/ +[4]:https://www.rit.edu/ +[5]:https://fedoraproject.org/wiki/Overview +[6]:https://fedoramagazine.org/ +[7]:https://fedoraproject.org/wiki/CommOps +[8]:https://opensource.com/users/jflory +[9]:https://opensource.com/users/jflory +[10]:https://opensource.com/user/74361/feed +[11]:https://opensource.com/article/17/8/tirana-government-chooses-open-source +[12]:https://opensource.com/article/16/12/2016-election-night-hackathon +[13]:https://twitter.com/abernathyca +[14]:https://www.eventbrite.com/e/fossmagic-talks-open-source-facebook-with-christine-abernathy-tickets-38955037566# +[15]:https://opensource.com/users/jflory +[16]:https://opensource.com/users/jflory +[17]:https://opensource.com/users/jflory +[18]:https://opensource.com/article/18/1/inside-facebooks-open-source-program#comments \ No newline at end of file diff --git a/published/20180129 How to Use DockerHub.md b/published/20180129 How to Use DockerHub.md new file mode 100644 index 0000000000..0eaeaab289 --- /dev/null +++ b/published/20180129 How to Use DockerHub.md @@ -0,0 +1,143 @@ +如何使用 DockerHub +======== + +> 在这个 Docker 系列的最后一篇文章中,我们将讲述在 DockerHub 上使用和发布镜像。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/dockerhub-container.jpg?itok=tvraxGzh) + +在前面的文章中,我们了解到了基本的 [Docker 术语][1],在 Linux 桌面、MacOS 和 Windows上 [如何安装 Docker][2],[如何创建容器镜像][3] 并且在系统上运行它们。在本系列的最后一篇文章中,我们将讨论如何使用 DockerHub 中的镜像以及将自己的镜像发布到 DockerHub。 + +首先:什么是 DockerHub 以及为什么它很重要?DockerHub 是一个由 Docker 公司运行和管理的基于云的存储库。它是一个在线存储库,Docker 镜像可以由其他用户发布和使用。有两种库:公共存储库和私有存储库。如果你是一家公司,你可以在你自己的组织内拥有一个私有存储库,而公共镜像可以被任何人使用。 + +你也可以使用公开发布的官方 Docker 镜像。我使用了很多这样的镜像,包括我的试验 WordPress 环境、KDE plasma 应用程序等等。虽然我们上次学习了如何创建自己的 Docker 镜像,但你不必这样做。DockerHub 上发布了数千镜像供你使用。DockerHub 作为默认存储库硬编码到 Docker 中,所以当你对任何镜像运行 `docker pull` 命令时,它将从 DockerHub 下载。 + +### 从 Docker Hub 下载镜像并在本地运行 + +开始请查看本系列的前几篇文章,以便继续。然后,一旦 Docker 在你的系统上运行,你就可以打开终端并运行: + +``` +$ docker images +``` + +该命令将显示当前系统上所有的 docker 镜像。假设你想在本地机器上部署 Ubuntu,你可能会: + +``` +$ docker pull ubuntu +``` + +如果你的系统上已经存在 Ubuntu 镜像,那么该命令会自动将该系统更新到最新版本。因此,如果你想要更新现有的镜像,只需运行 `docker pull` 命令,易如反掌。这就像 `apt-get update` 一样,没有任何的混乱和麻烦。 + +你已经知道了如何运行镜像: + +``` +$ docker run -it +$ docker run -it ubuntu +``` + +命令提示符应该变为如下内容: + +``` +root@1b3ec4621737:/# +``` + +现在你可以运行任何属于 Ubuntu 的命令和实用程序,这些都被包含在内而且安全。你可以在 Ubuntu 上运行你想要的所有实验和测试。一旦你完成了测试,你就可以销毁镜像并下载一个新的。在虚拟机中不存在系统开销。 + +你可以通过运行 exit 命令退出该容器: + +``` +$ exit +``` + +现在假设你想在系统上安装 Nginx,运行 `search` 命令来找到需要的镜像: + +``` +$ docker search nginx +``` + +![](https://lh3.googleusercontent.com/aizMFFysICAEsgDDYrsrlqwoCgGbWVHtcOzgV9mAtV8IdBZgHPJTdHIZhWBNCRvOyJb108ZBajJ_Nz10yCxGSvk-AF-yvFxpojLdVu3Jjihcwaup6CQLc67A5nglBuGDaOZWcrbV) + +正如你所看到的,DockerHub 上有很多 Nginx 镜像。为什么?因为任何人都可以发布镜像,各种镜像针对不同的项目进行了优化,因此你可以选择合适的镜像。你只需要为你的需求安装合适的镜像。 + +假设你想要拉取 Bitnami 的 Nginx 镜像: + +``` +$ docker pull bitnami/nginx +``` + +现在运行: + +``` +$ docker run -it bitnami/nginx +``` + +### 如何发布镜像到 Docker Hub? + +在此之前,[我们学习了如何创建 Docker 镜像][3],我们可以轻松地将该镜像发布到 DockerHub 中。首先,你需要登录 DockerHub,如果没有账户,请 [创建账户][5]。然后,你可以打开终端应用,登录: + +``` +$ docker login --username= +``` + +将 “\” 替换为你自己的 Docker Hub 用户名。我这里是 arnieswap: + +``` +$ docker login --username=arnieswap +``` + +输入密码,你就登录了。现在运行 `docker images` 命令来获取你上次创建的镜像的 ID。 + +``` +$ docker images +``` + +![](https://lh6.googleusercontent.com/tW1jDOugkX7J2FfyFyToM6B8m5OYFwMba-Ag5aezVGf2A5gsKJ47QrCh_TOKWgIKfE824Uc2Cwwwj9jWps1yJlUZqDyIceVQs-nEbKavFDxuUxLyd4thBA4_rsXrQH4r7hrG8FnD) + +现在,假设你希望将镜像 `ng` 推送到 DockerHub,首先,我们需要标记该镜像([了解更多关于标记的信息][1]): + +``` +$ docker tag e7083fd898c7 arnieswap/my_repo:testing +``` + +现在推送镜像: + +``` +$ docker push arnieswap/my_repo +``` + +推送指向的是 [docker.io/arnieswap/my_repo] 仓库: + +``` +12628b20827e: Pushed +8600ee70176b: Mounted from library/ubuntu +2bbb3cec611d: Mounted from library/ubuntu +d2bb1fc88136: Mounted from library/ubuntu +a6a01ad8b53f: Mounted from library/ubuntu +833649a3e04c: Mounted from library/ubuntu +testing: digest: sha256:286cb866f34a2aa85c9fd810ac2cedd87699c02731db1b8ca1cfad16ef17c146 size: 1569 +``` + +哦耶!你的镜像正在上传。一旦完成,打开 DockerHub,登录到你的账户,你就能看到你的第一个 Docker 镜像。现在任何人都可以部署你的镜像。这是开发软件和发布软件最简单,最快速的方式。无论你何时更新镜像,用户都可以简单地运行: + +``` +$ docker run arnieswap/my_repo +``` + +现在你知道为什么人们喜欢 Docker 容器了。它解决了传统工作负载所面临的许多问题,并允许你在任何时候开发、测试和部署应用程序。通过遵循本系列中的步骤,你自己可以尝试以下。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/intro-to-linux/2018/1/how-use-dockerhub + +作者:[Swapnil Bhartiya][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[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/intro-to-linux/2017/12/container-basics-terms-you-need-know +[2]:https://www.linux.com/blog/learn/intro-to-linux/how-install-docker-ce-your-desktop +[3]:https://linux.cn/article-9541-1.html +[4]:https://lh3.googleusercontent.com/aizMFFysICAEsgDDYrsrlqwoCgGbWVHtcOzgV9mAtV8IdBZgHPJTdHIZhWBNCRvOyJb108ZBajJ_Nz10yCxGSvk-AF-yvFxpojLdVu3Jjihcwaup6CQLc67A5nglBuGDaOZWcrbV +[5]:https://hub.docker.com/ +[6]:https://lh6.googleusercontent.com/tW1jDOugkX7J2FfyFyToM6B8m5OYFwMba-Ag5aezVGf2A5gsKJ47QrCh_TOKWgIKfE824Uc2Cwwwj9jWps1yJlUZqDyIceVQs-nEbKavFDxuUxLyd4thBA4_rsXrQH4r7hrG8FnD \ No newline at end of file diff --git a/published/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md b/published/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md new file mode 100644 index 0000000000..6245810c69 --- /dev/null +++ b/published/20180130 Install AWFFull web server log analysis application on ubuntu 17.10.md @@ -0,0 +1,80 @@ +在 Ubuntu 17.10 上安装 AWFFull Web 服务器日志分析应用程序 +====== + +AWFFull 是基于 “Webalizer” 的 Web 服务器日志分析程序。AWFFull 以 HTML 格式生成使用统计信息以便用浏览器查看。结果以柱状和图形两种格式显示,这有利于解释数据。它提供每年、每月、每日和每小时的使用统计数据,并显示网站、URL、referrer、user agent(浏览器)、用户名、搜索字符串、进入/退出页面和国家(如果一些信息不存在于处理后日志中那么就没有)。AWFFull 支持 CLF(通用日志格式)日志文件,以及由 NCSA 等定义的组合日志格式,它还能只能地处理这些格式的变体。另外,AWFFull 还支持 wu-ftpd xferlog 格式的日志文件,它能够分析 ftp 服务器和 squid 代理日志。日志也可以通过 gzip 压缩。 + +如果检测到压缩日志文件,它将在读取时自动解压缩。压缩日志必须是 .gz 扩展名的标准 gzip 压缩。 + +### 对于 Webalizer 的修改 + +AWFFull 基于 Webalizer 的代码,并有许多或大或小的变化。包括: + +- 不止原始统计数据:利用已发布的公式,提供额外的网站使用情况。 +- GeoIP IP 地址能更准确地检测国家。 +- 可缩放的图形 +- 与 GNU gettext 集成,能够轻松翻译。目前支持 32 种语言。 +- 在首页显示超过 12 个月的网站历史记录。 +- 额外的页面计数跟踪和排序。 +- 一些小的可视化调整,包括 Geolizer 用量中使用 Kb、Mb。 +- 额外的用于 URL 计数、进入和退出页面、站点的饼图 +- 图形上的水平线更有意义,更易于阅读。 +- User Agent 和 Referral 跟踪现在通过 PAGES 而非 HITS 进行计算。 +- 现在支持 GNU 风格的长命令行选项(例如 --help)。 +- 可以通过排除“什么不是”以及原始的“什么是”来选择页面。 +- 对被分析站点的请求以匹配的引用 URL 显示。 +- 404 错误表,并且可以生成引用 URL。 +- 生成的 html 可以使用外部 CSS 文件。 +- POST 分析总结使得手动优化配置文件性能更简单。 +- 可以将指定的 IP 和地址分配给指定的国家。 +- 便于使用其他工具详细分析的转储选项。 +- 支持检测并处理 Lotus Domin- v6 日志。 + +### 在 Ubuntu 17.10 上安装 AWFFull + +``` +sud- apt-get install awffull +``` + +### 配置 AWFFull + +你必须在 `/etc/awffull/awffull.conf` 中编辑 AWFFull 配置文件。如果你在同一台计算机上运行多个虚拟站点,​​则可以制作多个默认配置文件的副本。 + +``` +sud- vi /etc/awffull/awffull.conf +``` + +确保有下面这几行: + +``` +LogFile /var/log/apache2/access.log.1 +OutputDir /var/www/html/awffull +``` + +保存并退出文件。 + +你可以使用以下命令运行 awffull。 + +``` +awffull -c [your config file name] +``` + +这将在 `/var/www/html/awffull` 目录下创建所有必需的文件,以便你可以使用 http://serverip/awffull/ 。 + +你应该看到类似于下面的页面: + +![](http://www.ubuntugeek.com/wp-content/uploads/2015/12/11.png) + + +如果你有更多站点,你可以使用 shell 和计划任务自动化这个过程。 + +-------------------------------------------------------------------------------- + +via: http://www.ubuntugeek.com/install-awffull-web-server-log-analysis-application-on-ubuntu-17-10.html + +作者:[ruchi][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.ubuntugeek.com/author/ubuntufix diff --git a/translated/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md b/published/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md similarity index 50% rename from translated/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md rename to published/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md index 8c6f0ba124..f96f8f1a6a 100644 --- a/translated/tech/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md +++ b/published/20180130 Linux ln Command Tutorial for Beginners (5 Examples).md @@ -1,29 +1,28 @@ -为初学者准备的 Linux ln 命令教程(5 个示例) +为初学者准备的 ln 命令教程(5 个示例) ====== -当我们在命令行上工作时,您可能需要在文件之间创建链接。这时,您可以可以借助一个专用命令,**ln**。本教程中,我们将通过一些简单易理解的例子来讨论此工具的基础知识。在此之前,值得一提的是,本教程所有例子都已在 Ubuntu 16.04 上测试通过。 +当我们在命令行上工作时,您可能需要在文件之间创建链接。这时,您可以可以借助一个专用命令,`ln`。本教程中,我们将通过一些简单易理解的例子来讨论此工具的基础知识。在此之前,值得一提的是,本教程所有例子都已在 Ubuntu 16.04 上测试通过。 ### Linux ln 命令 -正如你现在所了解的,ln 命令能够让您在文件之间创建链接。下面就是 ln 工具的语法(或者使用其他一些可行的语法)。 +正如你现在所了解的,`ln` 命令能够让您在文件之间创建链接。下面就是 `ln` 工具的语法(或者使用其他一些可行的语法)。 ``` -ln [OPTION]... [-T] TARGET LINK_NAME (1st form) -ln [OPTION]... TARGET (2nd form) -ln [OPTION]... TARGET... DIRECTORY (3rd form) -ln [OPTION]... -t DIRECTORY TARGET... (4th form) +ln [OPTION]... [-T] TARGET LINK_NAME (第一种形式) +ln [OPTION]... TARGET (第二种形式) +ln [OPTION]... TARGET... DIRECTORY (第三种形式) +ln [OPTION]... -t DIRECTORY TARGET... (第四种形式) ``` -下面是 ln 工具 man 文档描述的内容: -``` -在第一种形式下,为 TARGET 创建一个叫 LINK_NAME 的链接。在第二种形式下,为 TARGET 在当前目录下创建一个链接( LCTT 译注:创建的为同名链接)。在第三和第四中形式中,在 DIRECTORY 目录下为每一个 TARGET 创建链接。默认创建硬链接,符号链接需要 --symbolic 选项。默认创建的每一个目标(新链接的名字)都不能已经存在。当创建硬链接时,TARGET 文件必须存在。符号链接可以保存任意文本,如果之后解析,相对链接的解析与其父目录有关。 -``` +下面是 `ln` 工具 man 文档描述的内容: + +> 在第一种形式下,为目标位置(TARGET)创建一个叫 LINK_NAME 的链接。在第二种形式下,为目标位置(TARGET)在当前目录下创建一个链接(LCTT 译注:创建的为同名链接)。在第三和第四种形式中,在 DIRECTORY 目录下为每一个目标位置(TARGET)创建链接。默认创建硬链接,符号链接需要 `--symbolic` 选项。默认创建的每一个创建的链接(新链接的名字)都不能已经存在。当创建硬链接时,目标位置(TARGET)文件必须存在;符号链接可以保存任意文本,如果之后解析,相对链接的解析与其父目录有关。 通过下面问答风格的例子,可能会给你更好的理解。但是在此之前,建议您先了解 [硬链接和软链接的区别][1]. ### Q1. 如何使用 ln 命令创建硬链接? -这很简单,你只需要像下面使用 ln 命令: +这很简单,你只需要像下面使用 `ln` 命令: ``` ln [file] [hard-link-to-file] @@ -37,11 +36,11 @@ ln test.txt test_hard_link.txt [![如何使用 ln 命令创建硬链接][2]][3] -如此,您便可以看见一个已经创建好的,名为 test_hard_link.txt 的硬链接。 +如此,您便可以看见一个已经创建好的,名为 `test_hard_link.txt` 的硬链接。 ### Q2. 如何使用 ln 命令创建软/符号链接? -使用 -s 命令行选项 +使用 `-s` 命令行选项: ``` ln -s [file] [soft-link-to-file] @@ -55,39 +54,39 @@ ln -s test.txt test_soft_link.txt [![如何使用 ln 命令创建软/符号链接][4]][5] -test_soft_link.txt 文件就是一个软/符号链接,被天蓝色文本 [标识][6]。 +`test_soft_link.txt` 文件就是一个软/符号链接,以天蓝色文本 [标识][6]。 ### Q3. 如何使用 ln 命令删除既存的同名目标文件? -默认情况下,ln 不允许您在目标目录下创建已存在的链接。 +默认情况下,`ln` 不允许您在目标目录下创建已存在的链接。 [![ln 命令示例][7]][8] -然而,如果一定要这么做,您可以使用 **-f** 命令行选项覆盖此行为。 +然而,如果一定要这么做,您可以使用 `-f` 命令行选项覆盖此行为。 [![如何使用 ln 命令创建软/符号链接][9]][10] -**贴士** : 如果您想在此删除过程中有所交互,您可以使用 **-i** 选项。 +提示:如果您想在此删除过程中有所交互,您可以使用 `-i` 选项。 ### Q4. 如何使用 ln 命令创建现有文件的同名备份? -如果您不想 ln 删除同名的现有文件,您可以为这些文件创建备份。使用 **-b** 即可实现此效果,以这种方式创建的备份文件,会在其文件名结尾处包含一个波浪号(~)。 +如果您不想 `ln` 删除同名的现有文件,您可以为这些文件创建备份。使用 `-b` 即可实现此效果,以这种方式创建的备份文件,会在其文件名结尾处包含一个波浪号(`~`)。 [![如何使用 ln 命令创建现有文件的同名备份][11]][12] ### Q5. 如何在当前目录以外的其它目录创建链接? -使用 **-t** 选项指定一个文件目录(除了当前目录)。比如: +使用 `-t` 选项指定一个文件目录(除了当前目录)。比如: ``` ls test* | xargs ln -s -t /home/himanshu/Desktop/ ``` -上述命令会为所有 test* 文件(当前目录下的 test* 文件)创建链接,并放到桌面目录下。 +上述命令会为(当前目录下的)所有 `test*` 文件创建链接,并放到桌面目录下。 ### 总结 -当然,尤其对于新手来说,**ln** 并不是日常必备命令。但是,这是一个有用的命令,因为你永远不知道它什么时候能够节省你一天的时间。对于这个命令,我们已经讨论了一些实用的选项,如果你已经完成了这些,可以查询 [man 文档][13] 来了解更多详情。 +当然,尤其对于新手来说,`ln` 并不是日常必备命令。但是,这是一个有用的命令,因为你永远不知道它什么时候能够节省你一天的时间。对于这个命令,我们已经讨论了一些实用的选项,如果你已经完成了这些,可以查询 [man 文档][13] 来了解更多详情。 -------------------------------------------------------------------------------- diff --git a/published/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md b/published/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md new file mode 100644 index 0000000000..e891707cb0 --- /dev/null +++ b/published/20180130 Quick Look at the Arch Based Indie Linux Distribution- MagpieOS.md @@ -0,0 +1,79 @@ +一个基于 Arch 的独立 Linux 发行版 MagpieOS +====== + +目前使用的大多数 Linux 发行版都是由欧美创建和开发的。一位来自孟加拉国的年轻开发人员想要改变这一切。 + +### 谁是 Rizwan? + +[Rizwan][1] 是来自孟加拉国的计算机科学专业的学生。他目前正在学习成为一名专业的 Python 程序员。他在 2015 年开始使用 Linux。使用 Linux 启发他创建了自己的 Linux 发行版。他还希望让世界其他地方知道孟加拉国正在升级到 Linux。 + +他还致力于从头创建 [LFS 的 live 版本][2]。 + +![MagpieOS Linux][3] + +### 什么是 MagpieOS? + +Rizwan 的新发行版被命名为 MagpieOS。 [MagpieOS][4] 非常简单。它基本上是 GNOME3 桌面环境的 Arch。 MagpieOS 还包括一个自定义的仓库,其中包含图标和主题(据称)在其他基于 Arch 的发行版或 AUR 没有。 + +下面是 MagpieOS 包含的软件列表:Firefox、LibreOffice、Uget、Bleachbit、Notepadqq、SUSE Studio Image Writer、Pamac 软件包管理器、Gparted、Gimp、Rhythmbox、简单屏幕录像机等包括 Totem 视频播放器在内的所有默认 GNOME 软件,以及一套新的定制壁纸。 + +目前,MagpieOS 仅支持 GNOME 桌面环境。Rizwan 选择它是因为这是他的最爱。但是,他计划在未来添加更多的桌面环境。 + +不幸的是,MagpieOS 不支持孟加拉语或任何其他当地语言。它支持 GNOME 的默认语言,如英语、印地语等。 + +Rizwan 命名他的发行为 MagpieOS,因为[喜鹊][5]magpie 是孟加拉国的官方鸟。 + +![MagpieOS Linux][6] + +### 为什么选择 Arch? + +和大多数人一样,Rizwan 通过使用 [Ubuntu][7] 开始了他的 Linux 旅程。一开始,他对此感到满意。但是,有时他想安装的软件在仓库中没有,他不得不通过 Google 寻找正确的 PPA。他决定切换到 [Arch][8],因为 Arch 有许多在 Ubuntu 上没有的软件包。Rizwan 也喜欢 Arch 是一个滚动版本,并且始终是最新的。 + +Arch 的问题在于它的安装非常复杂和耗时。所以,Rizwan 尝试了几个基于 Arch 的发行版,并且对任何一个都不满意。他不喜欢 [Manjaro][9],因为它们没有权限使用 Arch 的仓库。此外,Arch 仓库镜像比 Manjaro 更快并且拥有更多软件。他喜欢 [Antergos][10],但要安装需要一个持续的互联网连接。如果在安装过程中连接失败,则必须重新开始。 + +由于这些问题,Rizwan 决定创建一个简单的发行版,让他和其他人无需麻烦地安装 Arch。他还希望通过使用他的发行版让他的祖国的开发人员从 Ubuntu 切换到 Arch。 + +### 如何通过 MagpieOS 帮助 Rizwan + +如果你有兴趣帮助 Rizwan 开发 MagpieOS,你可以通过 [MagpieOS 网站][4]与他联系。你也可以查看该项目的 [GitHub 页面][11]。Rizwan 表示,他目前不寻求财政支持。 + +![MagpieOS Linux][12] + +### 最后的想法 + +我快速地安装过一次 MagpieOS。它使用 [Calamares 安装程序][13],这意味着安装它相对快速轻松。重新启动后,我听到一封欢迎我来到 MagpieOS 的音频消息。 + +说实话,这是我第一次听到安装后的问候。(Windows 10 可能也有,但我不确定)屏幕底部还有一个 Mac OS 风格的应用程序停靠栏。除此之外,它感觉像我用过的其他任何 GNOME 3 桌面。 + +考虑到这是一个刚刚起步的独立项目,我不会推荐它作为你的主要操作系统。但是,如果你是一个发行版尝试者,你一定会试试看。 + +话虽如此,对于一个想把自己的国家放在技术地图上的学生来说,这是一个不错的尝试。做得很好,Rizwan。 + +你有没有听说过 MagpieOS?你最喜欢的地区或本地制作的 Linux 发行版是什么?请在下面的评论中告诉我们。 + +如果你发现这篇文章有趣,请花点时间在社交媒体上分享。 + +-------------------------------------------------------------------------------- + +via: https://itsfoss.com/magpieos/ + +作者:[John Paul][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://itsfoss.com/author/john/ +[1]:https://twitter.com/Linux_Saikat +[2]:https://itsfoss.com/linux-from-scratch-live-cd/ +[3]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos1.jpg +[4]:http://www.magpieos.net +[5]:https://en.wikipedia.org/wiki/Magpie +[6]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos2.jpg +[7]:https://www.ubuntu.com +[8]:https://www.archlinux.org +[9]:http://manjaro.org +[10]:https://antergos.com +[11]:https://github.com/Rizwan-Hasan/MagpieOS +[12]:https://itsfoss.com/wp-content/uploads/2018/01/magpieos3.png +[13]:https://calamares.io diff --git a/published/20060430 Linux Find Out Last System Reboot Time and Date Command.md b/published/201802/20060430 Linux Find Out Last System Reboot Time and Date Command.md similarity index 100% rename from published/20060430 Linux Find Out Last System Reboot Time and Date Command.md rename to published/201802/20060430 Linux Find Out Last System Reboot Time and Date Command.md diff --git a/published/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md b/published/201802/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md similarity index 100% rename from published/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md rename to published/201802/20061104 How To Turn On-Off Colors For ls Command In Bash On a Linux-Unix.md diff --git a/published/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md b/published/201802/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md similarity index 100% rename from published/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md rename to published/201802/20070129 How To Debug a Bash Shell Script Under Linux or UNIX.md diff --git a/published/201802/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md b/published/201802/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md new file mode 100644 index 0000000000..821f738d76 --- /dev/null +++ b/published/201802/20070810 How to use lftp to accelerate ftp-https download speed on Linux-UNIX.md @@ -0,0 +1,89 @@ +如何使用 lftp 来加速 Linux/UNIX 上的 ftp/https 下载速度 +====== + +`lftp` 是一个文件传输程序。它可以用于复杂的 FTP、 HTTP/HTTPS 和其他连接。如果指定了站点 URL,那么 `lftp` 将连接到该站点,否则会使用 `open` 命令建立连接。它是所有 Linux/Unix 命令行用户的必备工具。我目前写了一些关于 [Linux 下超快命令行下载加速器][1],比如 Axel 和 prozilla。`lftp` 是另一个能做相同的事,但有更多功能的工具。`lftp` 可以处理七种文件访问方式: + +1. ftp +2. ftps +3. http +4. https +5. hftp +6. fish +7. sftp +8. file + +### 那么 lftp 的独特之处是什么? + +* `lftp` 中的每个操作都是可靠的,即任何非致命错误都被忽略,并且重复进行操作。所以如果下载中断,它会自动重新启动。即使 FTP 服务器不支持 `REST` 命令,lftp 也会尝试从开头检索文件,直到文件传输完成。 +* `lftp` 具有类似 shell 的命令语法,允许你在后台并行启动多个命令。 +* `lftp` 有一个内置的镜像功能,可以下载或更新整个目录树。还有一个反向镜像功能(`mirror -R`),它可以上传或更新服务器上的目录树。镜像也可以在两个远程服务器之间同步目录,如果可用的话会使用 FXP。 + +### 如何使用 lftp 作为下载加速器 + +`lftp` 有 `pget` 命令。它能让你并行下载。语法是: + +``` +lftp -e 'pget -n NUM -c url; exit' +``` + +例如,使用 `pget` 分 5个部分下载 : + +``` +$ cd /tmp +$ lftp -e 'pget -n 5 -c http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.22.2.tar.bz2' +``` + +示例输出: + +``` +45108964 bytes transferred in 57 seconds (775.3K/s) +lftp :~>quit +``` + +这里: + +1. `pget` - 并行下载文件 +2. `-n 5` - 将最大连接数设置为 5 +3. `-c` - 如果当前目录存在 `lfile.lftp-pget-status`,则继续中断的传输 + +### 如何在 Linux/Unix 中使用 lftp 来加速 ftp/https下载 + +再尝试添加 `exit` 命令: + +``` +$ lftp -e 'pget -n 10 -c https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.15.tar.xz; exit' +``` + +[Linux-lftp-command-demo](https://www.cyberciti.biz/tips/wp-content/uploads/2007/08/Linux-lftp-command-demo.mp4) + +### 关于并行下载的说明 + +请注意,通过使用下载加速器,你将增加远程服务器负载。另请注意,`lftp` 可能无法在不支持多点下载的站点上工作,或者防火墙阻止了此类请求。 + +其它的命令提供了更多功能。有关更多信息,请参考 [lftp][2] 的 man 页面: + +``` +man lftp +``` + +### 关于作者 + +作者是 nixCraft 的创建者,经验丰富的系统管理员,也是 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][9]、[Facebook][10]、[Google +][11] 上关注他。通过 [RSS/XML 订阅][5]获取最新的系统管理、Linux/Unix 以及开源主题教程。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/tips/linux-unix-download-accelerator.html + +作者:[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/tips/download-accelerator-for-linux-command-line-tools.html +[2]:https://lftp.yar.ru/ +[3]:https://twitter.com/nixcraft +[4]:https://facebook.com/nixcraft +[5]:https://plus.google.com/+CybercitiBiz +[6]:https://www.cyberciti.biz/atom/atom.xml diff --git a/published/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md b/published/201802/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md similarity index 100% rename from published/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md rename to published/201802/20071007 Linux Check IDE - SATA SSD Hard Disk Transfer Speed.md diff --git a/translated/tech/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md b/published/201802/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md similarity index 70% rename from translated/tech/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md rename to published/201802/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md index bd57e8a1a3..53ba82bba6 100644 --- a/translated/tech/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md +++ b/published/201802/20090627 30 Linux System Monitoring Tools Every SysAdmin Should Know.md @@ -8,14 +8,13 @@ 3. CPU 和内存瓶颈 4. 网络瓶颈 - ### 1. top - 进程活动监控命令 -top 命令显示 Linux 的进程。它提供了一个系统的实时动态视图,即实际的进程活动。默认情况下,它显示在服务器上运行的 CPU 占用率最高的任务,并且每五秒更新一次。 +`top` 命令会显示 Linux 的进程。它提供了一个运行中系统的实时动态视图,即实际的进程活动。默认情况下,它显示在服务器上运行的 CPU 占用率最高的任务,并且每五秒更新一次。 ![](https://www.cyberciti.biz/tips/wp-content/uploads/2009/06/top-Linux-monitoring-command.jpg) -图 01:Linux top 命令 +*图 01:Linux top 命令* #### top 的常用快捷键 @@ -23,22 +22,24 @@ top 命令显示 Linux 的进程。它提供了一个系统的实时动态视图 | 快捷键 | 用法 | | ---- | -------------------------------------- | -| t | 是否显示总结信息 | -| m | 是否显示内存信息 | -| A | 根据各种系统资源的利用率对进程进行排序,有助于快速识别系统中性能不佳的任务。 | -| f | 进入 top 的交互式配置屏幕,用于根据特定的需求而设置 top 的显示。 | -| o | 交互式地调整 top 每一列的顺序。 | -| r | 调整优先级(renice) | -| k | 杀掉进程(kill) | -| z | 开启或关闭彩色或黑白模式 | +| `t` | 是否显示汇总信息 | +| `m` | 是否显示内存信息 | +| `A` | 根据各种系统资源的利用率对进程进行排序,有助于快速识别系统中性能不佳的任务。 | +| `f` | 进入 `top` 的交互式配置屏幕,用于根据特定的需求而设置 `top` 的显示。 | +| `o` | 交互式地调整 `top` 每一列的顺序。 | +| `r` | 调整优先级(`renice`) | +| `k` | 杀掉进程(`kill`) | +| `z` | 切换彩色或黑白模式 | 相关链接:[Linux 如何查看 CPU 利用率?][1] ### 2. vmstat - 虚拟内存统计 -vmstat 命令报告有关进程、内存、分页、块 IO、陷阱和 cpu 活动等信息。 +`vmstat` 命令报告有关进程、内存、分页、块 IO、中断和 CPU 活动等信息。 -`# vmstat 3` +``` +# vmstat 3 +``` 输出示例: @@ -56,11 +57,15 @@ procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- #### 显示 Slab 缓存的利用率 -`# vmstat -m` +``` +# vmstat -m +``` #### 获取有关活动和非活动内存页面的信息 -`# vmstat -a` +``` +# vmstat -a +``` 相关链接:[如何查看 Linux 的资源利用率从而找到系统瓶颈?][2] @@ -84,9 +89,11 @@ root pts/1 10.1.3.145 17:43 0.00s 0.03s 0.00s w ### 4. uptime - Linux 系统运行了多久 -uptime 命令可以用来查看服务器运行了多长时间:当前时间、已运行的时间、当前登录的用户连接数,以及过去 1 分钟、5 分钟和 15 分钟的系统负载平均值。 +`uptime` 命令可以用来查看服务器运行了多长时间:当前时间、已运行的时间、当前登录的用户连接数,以及过去 1 分钟、5 分钟和 15 分钟的系统负载平均值。 -`# uptime` +``` +# uptime +``` 输出示例: @@ -94,13 +101,15 @@ uptime 命令可以用来查看服务器运行了多长时间:当前时间、 18:02:41 up 41 days, 23:42, 1 user, load average: 0.00, 0.00, 0.00 ``` -1 可以被认为是最佳负载值。不同的系统会有不同的负载:对于单核 CPU 系统来说,1 到 3 的负载值是可以接受的;而对于 SMP(对称多处理)系统来说,负载可以是 6 到 10。 +`1` 可以被认为是最佳负载值。不同的系统会有不同的负载:对于单核 CPU 系统来说,`1` 到 `3` 的负载值是可以接受的;而对于 SMP(对称多处理)系统来说,负载可以是 `6` 到 `10`。 ### 5. ps - 显示系统进程 -ps 命令显示当前运行的进程。要显示所有的进程,请使用 -A 或 -e 选项: +`ps` 命令显示当前运行的进程。要显示所有的进程,请使用 `-A` 或 `-e` 选项: -`# ps -A` +``` +# ps -A +``` 输出示例: @@ -132,23 +141,31 @@ ps 命令显示当前运行的进程。要显示所有的进程,请使用 -A 55704 pts/1 00:00:00 ps ``` -ps 与 top 类似,但它提供了更多的信息。 +`ps` 与 `top` 类似,但它提供了更多的信息。 #### 显示长输出格式 -`# ps -Al` +``` +# ps -Al +``` 显示完整输出格式(它将显示传递给进程的命令行参数): -`# ps -AlF` +``` +# ps -AlF +``` #### 显示线程(轻量级进程(LWP)和线程的数量(NLWP)) -`# ps -AlFH` +``` +# ps -AlFH +``` #### 在进程后显示线程 -`# ps -AlLm` +``` +# ps -AlLm +``` #### 显示系统上所有的进程 @@ -162,7 +179,7 @@ ps 与 top 类似,但它提供了更多的信息。 ``` # ps -ejH # ps axjf -# [pstree][4] +# pstree ``` #### 显示进程的安全信息 @@ -192,11 +209,15 @@ ps 与 top 类似,但它提供了更多的信息。 ``` # ps -C lighttpd -o pid= ``` + 或 + ``` # pgrep lighttpd ``` + 或 + ``` # pgrep -u vivek php-cgi ``` @@ -215,15 +236,19 @@ ps 与 top 类似,但它提供了更多的信息。 #### 找出占用 CPU 资源最多的前 10 个进程 -`# ps -auxf | sort -nr -k 3 | head -10` +``` +# ps -auxf | sort -nr -k 3 | head -10 +``` 相关链接:[显示 Linux 上所有运行的进程][5] ### 6. free - 内存使用情况 -free 命令显示了系统的可用和已用的物理内存及交换内存的总量,以及内核用到的缓存空间。 +`free` 命令显示了系统的可用和已用的物理内存及交换内存的总量,以及内核用到的缓存空间。 -`# free ` +``` +# free +``` 输出示例: @@ -242,9 +267,11 @@ Swap: 1052248 0 1052248 ### 7. iostat - CPU 平均负载和磁盘活动 -iostat 命令用于汇报 CPU 的使用情况,以及设备、分区和网络文件系统(NFS)的 IO 统计信息。 +`iostat` 命令用于汇报 CPU 的使用情况,以及设备、分区和网络文件系统(NFS)的 IO 统计信息。 -`# iostat ` +``` +# iostat +``` 输出示例: @@ -265,17 +292,21 @@ sda3 0.00 0.00 0.00 1615 0 ### 8. sar - 监控、收集和汇报系统活动 -sar 命令用于收集、汇报和保存系统活动信息。要查看网络统计,请输入: +`sar` 命令用于收集、汇报和保存系统活动信息。要查看网络统计,请输入: -`# sar -n DEV | more` +``` +# sar -n DEV | more +``` 显示 24 日的网络统计: `# sar -n DEV -f /var/log/sa/sa24 | more` -您还可以使用 sar 显示实时使用情况: +您还可以使用 `sar` 显示实时使用情况: -`# sar 4 5` +``` +# sar 4 5 +``` 输出示例: @@ -295,12 +326,13 @@ Average: all 2.02 0.00 0.27 0.01 0.00 97.70 + [如何将 Linux 系统资源利用率的数据写入文件中][53] + [如何使用 kSar 创建 sar 性能图以找出系统瓶颈][54] - ### 9. mpstat - 监控多处理器的使用情况 -mpstat 命令显示每个可用处理器的使用情况,编号从 0 开始。命令 mpstat -P ALL 显示了每个处理器的平均使用率: +`mpstat` 命令显示每个可用处理器的使用情况,编号从 0 开始。命令 `mpstat -P ALL` 显示了每个处理器的平均使用率: -`# mpstat -P ALL` +``` +# mpstat -P ALL +``` 输出示例: @@ -323,13 +355,17 @@ Linux 2.6.18-128.1.14.el5 (www03.nixcraft.in) 06/26/2009 ### 10. pmap - 监控进程的内存使用情况 -pmap 命令用以显示进程的内存映射,使用此命令可以查找内存瓶颈。 +`pmap` 命令用以显示进程的内存映射,使用此命令可以查找内存瓶颈。 -`# pmap -d PID` +``` +# pmap -d PID +``` 显示 PID 为 47394 的进程的内存信息,请输入: -`# pmap -d 47394` +``` +# pmap -d 47394 +``` 输出示例: @@ -362,16 +398,15 @@ mapped: 933712K writeable/private: 4304K shared: 768000K 最后一行非常重要: - * **mapped: 933712K** 映射到文件的内存量 - * **writeable/private: 4304K** 私有地址空间 - * **shared: 768000K** 此进程与其他进程共享的地址空间 - + * `mapped: 933712K` 映射到文件的内存量 + * `writeable/private: 4304K` 私有地址空间 + * `shared: 768000K` 此进程与其他进程共享的地址空间 相关链接:[使用 pmap 命令查看 Linux 上单个程序或进程使用的内存][8] ### 11. netstat - Linux 网络统计监控工具 -netstat 命令显示网络连接、路由表、接口统计、伪装连接和多播连接等信息。 +`netstat` 命令显示网络连接、路由表、接口统计、伪装连接和多播连接等信息。 ``` # netstat -tulpn @@ -380,27 +415,32 @@ netstat 命令显示网络连接、路由表、接口统计、伪装连接和多 ### 12. ss - 网络统计 -ss 命令用于获取套接字统计信息。它可以显示类似于 netstat 的信息。不过 netstat 几乎要过时了,ss 命令更具优势。要显示所有 TCP 或 UDP 套接字: +`ss` 命令用于获取套接字统计信息。它可以显示类似于 `netstat` 的信息。不过 `netstat` 几乎要过时了,`ss` 命令更具优势。要显示所有 TCP 或 UDP 套接字: -`# ss -t -a` +``` +# ss -t -a +``` 或 -`# ss -u -a ` +``` +# ss -u -a +``` -显示所有带有 SELinux 安全上下文(Security Context)的 TCP 套接字: +显示所有带有 SELinux 安全上下文Security Context的 TCP 套接字: -`# ss -t -a -Z ` +``` +# ss -t -a -Z +``` -请参阅以下关于 ss 和 netstat 命令的资料: +请参阅以下关于 `ss` 和 `netstat` 命令的资料: + [ss:显示 Linux TCP / UDP 网络套接字信息][56] + [使用 netstat 命令获取有关特定 IP 地址连接的详细信息][57] - ### 13. iptraf - 获取实时网络统计信息 -iptraf 命令是一个基于 ncurses 的交互式 IP 网络监控工具。它可以生成多种网络统计信息,包括 TCP 信息、UDP 计数、ICMP 和 OSPF 信息、以太网负载信息、节点统计信息、IP 校验错误等。它以简单的格式提供了以下信息: +`iptraf` 命令是一个基于 ncurses 的交互式 IP 网络监控工具。它可以生成多种网络统计信息,包括 TCP 信息、UDP 计数、ICMP 和 OSPF 信息、以太网负载信息、节点统计信息、IP 校验错误等。它以简单的格式提供了以下信息: * 基于 TCP 连接的网络流量统计 * 基于网络接口的 IP 流量统计 @@ -410,41 +450,53 @@ iptraf 命令是一个基于 ncurses 的交互式 IP 网络监控工具。它可 ![Fig.02: General interface statistics: IP traffic statistics by network interface ][9] -图 02:常规接口统计:基于网络接口的 IP 流量统计 +*图 02:常规接口统计:基于网络接口的 IP 流量统计* ![Fig.03 Network traffic statistics by TCP connection][10] -图 03:基于 TCP 连接的网络流量统计 +*图 03:基于 TCP 连接的网络流量统计* 相关链接:[在 Centos / RHEL / Fedora Linux 上安装 IPTraf 以获取网络统计信息][11] ### 14. tcpdump - 详细的网络流量分析 -tcpdump 命令是简单的分析网络通信的命令。您需要充分了解 TCP/IP 协议才便于使用此工具。例如,要显示有关 DNS 的流量信息,请输入: +`tcpdump` 命令是简单的分析网络通信的命令。您需要充分了解 TCP/IP 协议才便于使用此工具。例如,要显示有关 DNS 的流量信息,请输入: -`# tcpdump -i eth1 'udp port 53'` +``` +# tcpdump -i eth1 'udp port 53' +``` 查看所有去往和来自端口 80 的 IPv4 HTTP 数据包,仅打印真正包含数据的包,而不是像 SYN、FIN 和仅含 ACK 这类的数据包,请输入: -`# tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'` +``` +# tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' +``` 显示所有目标地址为 202.54.1.5 的 FTP 会话,请输入: -`# tcpdump -i eth1 'dst 202.54.1.5 and (port 21 or 20'` +``` +# tcpdump -i eth1 'dst 202.54.1.5 and (port 21 or 20' +``` 打印所有目标地址为 192.168.1.5 的 HTTP 会话: -`# tcpdump -ni eth0 'dst 192.168.1.5 and tcp and port http'` +``` +# tcpdump -ni eth0 'dst 192.168.1.5 and tcp and port http' +``` 使用 [wireshark][12] 查看文件的详细内容,请输入: -`# tcpdump -n -i eth1 -s 0 -w output.txt src or dst port 80` +``` +# tcpdump -n -i eth1 -s 0 -w output.txt src or dst port 80 +``` ### 15. iotop - I/O 监控 -iotop 命令利用 Linux 内核监控 I/O 使用情况,它按进程或线程的顺序显示 I/O 使用情况。 +`iotop` 命令利用 Linux 内核监控 I/O 使用情况,它按进程或线程的顺序显示 I/O 使用情况。 -`$ sudo iotop` +``` +$ sudo iotop +``` 输出示例: @@ -454,9 +506,11 @@ iotop 命令利用 Linux 内核监控 I/O 使用情况,它按进程或线程 ### 16. htop - 交互式的进程查看器 -htop 是一款免费并开源的基于 ncurses 的 Linux 进程查看器。它比 top 命令更简单易用。您无需使用 PID、无需离开 htop 界面,便可以杀掉进程或调整其调度优先级。 +`htop` 是一款免费并开源的基于 ncurses 的 Linux 进程查看器。它比 `top` 命令更简单易用。您无需使用 PID、无需离开 `htop` 界面,便可以杀掉进程或调整其调度优先级。 -`$ htop` +``` +$ htop +``` 输出示例: @@ -464,40 +518,40 @@ htop 是一款免费并开源的基于 ncurses 的 Linux 进程查看器。它 相关链接:[CentOS / RHEL:安装 htop——交互式文本模式进程查看器][58] - ### 17. atop - 高级版系统与进程监控工具 -atop 是一个非常强大的交互式 Linux 系统负载监控器,它从性能的角度显示最关键的硬件资源信息。您可以快速查看 CPU、内存、磁盘和网络性能。它还可以从进程的级别显示哪些进程造成了相关 CPU 和内存的负载。 +`atop` 是一个非常强大的交互式 Linux 系统负载监控器,它从性能的角度显示最关键的硬件资源信息。您可以快速查看 CPU、内存、磁盘和网络性能。它还可以从进程的级别显示哪些进程造成了相关 CPU 和内存的负载。 -`$ atop` +``` +$ atop +``` ![atop Command Line Tools to Monitor Linux Performance][16] 相关链接:[CentOS / RHEL:安装 atop 工具——高级系统和进程监控器][59] - ### 18. ac 和 lastcomm -您一定需要监控 Linux 服务器上的进程和登录活动吧。psacct 或 acct 软件包中包含了多个用于监控进程活动的工具,包括: +您一定需要监控 Linux 服务器上的进程和登录活动吧。`psacct` 或 `acct` 软件包中包含了多个用于监控进程活动的工具,包括: - - 1. ac 命令:显示有关用户连接时间的统计信息 + 1. `ac` 命令:显示有关用户连接时间的统计信息 2. [lastcomm 命令][17]:显示已执行过的命令 - 3. accton 命令:打开或关闭进程账号记录功能 - 4. sa 命令:进程账号记录信息的摘要 + 3. `accton` 命令:打开或关闭进程账号记录功能 + 4. `sa` 命令:进程账号记录信息的摘要 相关链接:[如何对 Linux 系统的活动做详细的跟踪记录][18] ### 19. monit - 进程监控器 -Monit 是一个免费且开源的进程监控软件,它可以自动重启停掉的服务。您也可以使用 Systemd、daemontools 或其他类似工具来达到同样的目的。[本教程演示如何在 Debian 或 Ubuntu Linux 上安装和配置 monit 作为进程监控器][19]。 +`monit` 是一个免费且开源的进程监控软件,它可以自动重启停掉的服务。您也可以使用 Systemd、daemontools 或其他类似工具来达到同样的目的。[本教程演示如何在 Debian 或 Ubuntu Linux 上安装和配置 monit 作为进程监控器][19]。 - -### 20. nethogs - 找出占用带宽的进程 +### 20. NetHogs - 找出占用带宽的进程 NetHogs 是一个轻便的网络监控工具,它按照进程名称(如 Firefox、wget 等)对带宽进行分组。如果网络流量突然爆发,启动 NetHogs,您将看到哪个进程(PID)导致了带宽激增。 -`$ sudo nethogs` +``` +$ sudo nethogs +``` ![nethogs linux monitoring tools open source][20] @@ -505,31 +559,37 @@ NetHogs 是一个轻便的网络监控工具,它按照进程名称(如 Firef ### 21. iftop - 显示主机上网络接口的带宽使用情况 -iftop 命令监听指定接口(如 eth0)上的网络通信情况。[它显示了一对主机的带宽使用情况][22]。 +`iftop` 命令监听指定接口(如 eth0)上的网络通信情况。[它显示了一对主机的带宽使用情况][22]。 -`$ sudo iftop` +``` +$ sudo iftop +``` ![iftop in action][23] ### 22. vnstat - 基于控制台的网络流量监控工具 -vnstat 是一个简单易用的基于控制台的网络流量监视器,它为指定网络接口保留每小时、每天和每月网络流量日志。 +`vnstat` 是一个简单易用的基于控制台的网络流量监视器,它为指定网络接口保留每小时、每天和每月网络流量日志。 -`$ vnstat ` +``` +$ vnstat +``` ![vnstat linux network traffic monitor][25] 相关链接: + + [为 ADSL 或专用远程 Linux 服务器保留日常网络流量日志][60] + [CentOS / RHEL:安装 vnStat 网络流量监控器以保留日常网络流量日志][61] + [CentOS / RHEL:使用 PHP 网页前端接口查看 Vnstat 图表][62] - ### 23. nmon - Linux 系统管理员的调优和基准测量工具 -nmon 是 Linux 系统管理员用于性能调优的利器,它在命令行显示 CPU、内存、网络、磁盘、文件系统、NFS、消耗资源最多的进程和分区信息。 +`nmon` 是 Linux 系统管理员用于性能调优的利器,它在命令行显示 CPU、内存、网络、磁盘、文件系统、NFS、消耗资源最多的进程和分区信息。 -`$ nmon` +``` +$ nmon +``` ![nmon command][26] @@ -537,9 +597,11 @@ nmon 是 Linux 系统管理员用于性能调优的利器,它在命令行显 ### 24. glances - 密切关注 Linux 系统 -glances 是一款开源的跨平台监控工具。它在小小的屏幕上提供了大量的信息,还可以用作客户端-服务器架构。 +`glances` 是一款开源的跨平台监控工具。它在小小的屏幕上提供了大量的信息,还可以工作于客户端-服务器模式下。 -`$ glances` +``` +$ glances +``` ![Glances][28] @@ -547,11 +609,11 @@ glances 是一款开源的跨平台监控工具。它在小小的屏幕上提供 ### 25. strace - 查看系统调用 -想要跟踪 Linux 系统的调用和信号吗?试试 strace 命令吧。它对于调试网页服务器和其他服务器问题很有用。了解如何利用其 [追踪进程][30] 并查看它在做什么。 +想要跟踪 Linux 系统的调用和信号吗?试试 `strace` 命令吧。它对于调试网页服务器和其他服务器问题很有用。了解如何利用其 [追踪进程][30] 并查看它在做什么。 -### 26. /proc/ 文件系统 - 各种内核信息 +### 26. /proc 文件系统 - 各种内核信息 -/proc 文件系统提供了不同硬件设备和 Linux 内核的详细信息。更多详细信息,请参阅 [Linux 内核 /proc][31] 文档。常见的 /proc 例子: +`/proc` 文件系统提供了不同硬件设备和 Linux 内核的详细信息。更多详细信息,请参阅 [Linux 内核 /proc][31] 文档。常见的 `/proc` 例子: ``` # cat /proc/cpuinfo @@ -562,23 +624,23 @@ glances 是一款开源的跨平台监控工具。它在小小的屏幕上提供 ### 27. Nagios - Linux 服务器和网络监控 -[Nagios][32] 是一款普遍使用的开源系统和网络监控软件。您可以轻松地监控所有主机、网络设备和服务,当状态异常和恢复正常时它都会发出警报通知。[FAN][33] 是“全自动 Nagios”的缩写。FAN 的目标是提供包含由 Nagios 社区提供的大多数工具包的 Nagios 安装。FAN 提供了标准 ISO 格式的 CDRom 镜像,使安装变得更加容易。除此之外,为了改善 Nagios 的用户体验,发行版还包含了大量的工具。 +[Nagios][32] 是一款普遍使用的开源系统和网络监控软件。您可以轻松地监控所有主机、网络设备和服务,当状态异常和恢复正常时它都会发出警报通知。[FAN][33] 是“全自动 Nagios”的缩写。FAN 的目标是提供包含由 Nagios 社区提供的大多数工具包的 Nagios 安装。FAN 提供了标准 ISO 格式的 CD-Rom 镜像,使安装变得更加容易。除此之外,为了改善 Nagios 的用户体验,发行版还包含了大量的工具。 ### 28. Cacti - 基于 Web 的 Linux 监控工具 Cacti 是一个完整的网络图形化解决方案,旨在充分利用 RRDTool 的数据存储和图形功能。Cacti 提供了快速轮询器、高级图形模板、多种数据采集方法和用户管理功能。这些功能被包装在一个直观易用的界面中,确保可以实现从局域网到拥有数百台设备的复杂网络上的安装。它可以提供有关网络、CPU、内存、登录用户、Apache、DNS 服务器等的数据。了解如何在 CentOS / RHEL 下 [安装和配置 Cacti 网络图形化工具][34]。 -### 29. KDE System Guard - 实时系统报告和图形化显示 +### 29. KDE 系统监控器 - 实时系统报告和图形化显示 -KSysguard 是 KDE 桌面的网络化系统监控程序。这个工具可以通过 ssh 会话运行。它提供了许多功能,比如监控本地和远程主机的客户端-服务器架构。前端图形界面使用传感器来检索信息。传感器可以返回简单的值或更复杂的信息,如表格。每种类型的信息都有一个或多个显示界面,并被组织成工作表的形式,这些工作表可以分别保存和加载。所以,KSysguard 不仅是一个简单的任务管理器,还是一个控制大型服务器平台的强大工具。 +KSysguard 是 KDE 桌面的网络化系统监控程序。这个工具可以通过 ssh 会话运行。它提供了许多功能,比如可以监控本地和远程主机的客户端-服务器模式。前端图形界面使用传感器来检索信息。传感器可以返回简单的值或更复杂的信息,如表格。每种类型的信息都有一个或多个显示界面,并被组织成工作表的形式,这些工作表可以分别保存和加载。所以,KSysguard 不仅是一个简单的任务管理器,还是一个控制大型服务器平台的强大工具。 ![Fig.05 KDE System Guard][35] -图 05:KDE System Guard {图片来源:维基百科} +*图 05:KDE System Guard {图片来源:维基百科}* 详细用法,请参阅 [KSysguard 手册][36]。 -### 30. Gnome 系统监控器 +### 30. GNOME 系统监控器 系统监控程序能够显示系统基本信息,并监控系统进程、系统资源使用情况和文件系统。您还可以用其修改系统行为。虽然不如 KDE System Guard 强大,但它提供的基本信息对新用户还是有用的: @@ -598,7 +660,7 @@ KSysguard 是 KDE 桌面的网络化系统监控程序。这个工具可以通 ![Fig.06 The Gnome System Monitor application][37] -图 06:Gnome 系统监控程序 +*图 06:Gnome 系统监控程序* ### 福利:其他工具 @@ -606,16 +668,15 @@ KSysguard 是 KDE 桌面的网络化系统监控程序。这个工具可以通 * [nmap][38] - 扫描服务器的开放端口 * [lsof][39] - 列出打开的文件和网络连接等 - * [ntop][40] 网页工具 - ntop 是查看网络使用情况的最佳工具,与 top 命令之于进程的方式类似,即网络流量监控工具。您可以查看网络状态和 UDP、TCP、DNS、HTTP 等协议的流量分发。 - * [Conky][41] - X Window 系统的另一个很好的监控工具。它具有很高的可配置性,能够监视许多系统变量,包括 CPU 状态、内存、交换空间、磁盘存储、温度、进程、网络接口、电池、系统消息和电子邮件等。 + * [ntop][40] 基于网页的工具 - `ntop` 是查看网络使用情况的最佳工具,与 `top` 命令之于进程的方式类似,即网络流量监控工具。您可以查看网络状态和 UDP、TCP、DNS、HTTP 等协议的流量分发。 + * [Conky][41] - X Window 系统下的另一个很好的监控工具。它具有很高的可配置性,能够监视许多系统变量,包括 CPU 状态、内存、交换空间、磁盘存储、温度、进程、网络接口、电池、系统消息和电子邮件等。 * [GKrellM][42] - 它可以用来监控 CPU 状态、主内存、硬盘、网络接口、本地和远程邮箱及其他信息。 - * [mtr][43] - mtr 将 traceroute 和 ping 程序的功能结合在一个网络诊断工具中。 + * [mtr][43] - `mtr` 将 `traceroute` 和 `ping` 程序的功能结合在一个网络诊断工具中。 * [vtop][44] - 图形化活动监控终端 - 如果您有其他推荐的系统监控工具,欢迎在评论区分享。 -#### 关于作者 +### 关于作者 作者 Vivek Gite 是 nixCraft 的创建者,也是经验丰富的系统管理员,以及 Linux 操作系统和 Unix shell 脚本的培训师。他的客户遍布全球,行业涉及 IT、教育、国防航天研究以及非营利部门等。您可以在 [Twitter][45]、[Facebook][46] 和 [Google+][47] 上关注他。 @@ -625,7 +686,7 @@ via: https://www.cyberciti.biz/tips/top-linux-monitoring-tools.html 作者:[Vivek Gite][a] 译者:[jessie-pang](https://github.com/jessie-pang) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201802/20090724 Top 20 OpenSSH Server Best Security Practices.md b/published/201802/20090724 Top 20 OpenSSH Server Best Security Practices.md new file mode 100644 index 0000000000..53be8e2057 --- /dev/null +++ b/published/201802/20090724 Top 20 OpenSSH Server Best Security Practices.md @@ -0,0 +1,557 @@ +20 个 OpenSSH 最佳安全实践 +====== + +![OpenSSH 安全提示][1] + +OpenSSH 是 SSH 协议的一个实现。一般通过 `scp` 或 `sftp` 用于远程登录、备份、远程文件传输等功能。SSH能够完美保障两个网络或系统间数据传输的保密性和完整性。尽管如此,它最大的优势是使用公匙加密来进行服务器验证。时不时会出现关于 OpenSSH 零日漏洞的[传言][2]。本文将描述如何设置你的 Linux 或类 Unix 系统以提高 sshd 的安全性。 + + +### OpenSSH 默认设置 + +* TCP 端口 - 22 +* OpenSSH 服务配置文件 - `sshd_config` (位于 `/etc/ssh/`) + +### 1、 基于公匙的登录 + +OpenSSH 服务支持各种验证方式。推荐使用公匙加密验证。首先,使用以下 `ssh-keygen` 命令在本地电脑上创建密匙对: + +> 1024 位或低于它的 DSA 和 RSA 加密是很弱的,请不要使用。当考虑 ssh 客户端向后兼容性的时候,请使用 RSA密匙代替 ECDSA 密匙。所有的 ssh 密钥要么使用 ED25519 ,要么使用 RSA,不要使用其它类型。 + +``` +$ ssh-keygen -t key_type -b bits -C "comment" +``` + +示例: + +``` +$ ssh-keygen -t ed25519 -C "Login to production cluster at xyz corp" +或 +$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_aws_$(date +%Y-%m-%d) -C "AWS key for abc corp clients" +``` + +下一步,使用 `ssh-copy-id` 命令安装公匙: + +``` +$ ssh-copy-id -i /path/to/public-key-file user@host +或 +$ ssh-copy-id user@remote-server-ip-or-dns-name +``` + +示例: + +``` +$ ssh-copy-id vivek@rhel7-aws-server +``` + +提示输入用户名和密码的时候,确认基于 ssh 公匙的登录是否工作: + +``` +$ ssh vivek@rhel7-aws-server +``` + +[![OpenSSH 服务安全最佳实践][3]][3] + +更多有关 ssh 公匙的信息,参照以下文章: + +* [为备份脚本设置无密码安全登录][48] +* [sshpass:使用脚本密码登录 SSH 服务器][49] +* [如何为一个 Linux/类 Unix 系统设置 SSH 登录密匙][50] +* [如何使用 Ansible 工具上传 ssh 登录授权公匙][51] + + +### 2、 禁用 root 用户登录 + +禁用 root 用户登录前,确认普通用户可以以 root 身份登录。例如,允许用户 vivek 使用 `sudo` 命令以 root 身份登录。 + +#### 在 Debian/Ubuntu 系统中如何将用户 vivek 添加到 sudo 组中 + +允许 sudo 组中的用户执行任何命令。 [将用户 vivek 添加到 sudo 组中][4]: + +``` +$ sudo adduser vivek sudo +``` + +使用 [id 命令][5] 验证用户组。 + +``` +$ id vivek +``` + +#### 在 CentOS/RHEL 系统中如何将用户 vivek 添加到 sudo 组中 + +在 CentOS/RHEL 和 Fedora 系统中允许 wheel 组中的用户执行所有的命令。使用 `usermod` 命令将用户 vivek 添加到 wheel 组中: + +``` +$ sudo usermod -aG wheel vivek +$ id vivek +``` + +#### 测试 sudo 权限并禁用 ssh root 登录 + +测试并确保用户 vivek 可以以 root 身份登录执行以下命令: + +``` +$ sudo -i +$ sudo /etc/init.d/sshd status +$ sudo systemctl status httpd +``` + +添加以下内容到 `sshd_config` 文件中来禁用 root 登录: + +``` +PermitRootLogin no +ChallengeResponseAuthentication no +PasswordAuthentication no +UsePAM no +``` + +更多信息参见“[如何通过禁用 Linux 的 ssh 密码登录来增强系统安全][6]” 。 + +### 3、 禁用密码登录 + +所有的密码登录都应该禁用,仅留下公匙登录。添加以下内容到 `sshd_config` 文件中: + +``` +AuthenticationMethods publickey +PubkeyAuthentication yes +``` + +CentOS 6.x/RHEL 6.x 系统中老版本的 sshd 用户可以使用以下设置: + +``` +PubkeyAuthentication yes +``` + +### 4、 限制用户的 ssh 访问 + +默认状态下,所有的系统用户都可以使用密码或公匙登录。但是有些时候需要为 FTP 或者 email 服务创建 UNIX/Linux 用户。然而,这些用户也可以使用 ssh 登录系统。他们将获得访问系统工具的完整权限,包括编译器和诸如 Perl、Python(可以打开网络端口干很多疯狂的事情)等的脚本语言。通过添加以下内容到 `sshd_config` 文件中来仅允许用户 root、vivek 和 jerry 通过 SSH 登录系统: + +``` +AllowUsers vivek jerry +``` + +当然,你也可以添加以下内容到 `sshd_config` 文件中来达到仅拒绝一部分用户通过 SSH 登录系统的效果。 + +``` +DenyUsers root saroj anjali foo +``` + +你也可以通过[配置 Linux PAM][7] 来禁用或允许用户通过 sshd 登录。也可以允许或禁止一个[用户组列表][8]通过 ssh 登录系统。 + +### 5、 禁用空密码 + +你需要明确禁止空密码账户远程登录系统,更新 `sshd_config` 文件的以下内容: + +``` +PermitEmptyPasswords no +``` + +### 6、 为 ssh 用户或者密匙使用强密码 + +为密匙使用强密码和短语的重要性再怎么强调都不过分。暴力破解可以起作用就是因为用户使用了基于字典的密码。你可以强制用户避开[字典密码][9]并使用[约翰的开膛手工具][10]来检测弱密码。以下是一个随机密码生成器(放到你的 `~/.bashrc` 下): + +``` +genpasswd() { + local l=$1 + [ "$l" == "" ] && l=20 + tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs +} +``` + +运行: + +``` +genpasswd 16 +``` + +输出: + +``` +uw8CnDVMwC6vOKgW +``` + +* [使用 mkpasswd / makepasswd / pwgen 生成随机密码][52] +* [Linux / UNIX: 生成密码][53] +* [Linux 随机密码生成命令][54] + +### 7、 为 SSH 的 22端口配置防火墙 + +你需要更新 `iptables`/`ufw`/`firewall-cmd` 或 pf 防火墙配置来为 ssh 的 TCP 端口 22 配置防火墙。一般来说,OpenSSH 服务应该仅允许本地或者其他的远端地址访问。 + +#### Netfilter(Iptables) 配置 + +更新 [/etc/sysconfig/iptables (Redhat 和其派生系统特有文件) ][11] 实现仅接受来自于 192.168.1.0/24 和 202.54.1.5/29 的连接,输入: + +``` +-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT +-A RH-Firewall-1-INPUT -s 202.54.1.5/29 -m state --state NEW -p tcp --dport 22 -j ACCEPT +``` + +如果同时使用 IPv6 的话,可以编辑 `/etc/sysconfig/ip6tables` (Redhat 和其派生系统特有文件),输入: + +``` +-A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT +``` + +将 `ipv6network::/ipv6mask` 替换为实际的 IPv6 网段。 + +#### Debian/Ubuntu Linux 下的 UFW + +[UFW 是 Uncomplicated FireWall 的首字母缩写,主要用来管理 Linux 防火墙][12],目的是提供一种用户友好的界面。输入[以下命令使得系统仅允许网段 202.54.1.5/29 接入端口 22][13]: + +``` +$ sudo ufw allow from 202.54.1.5/29 to any port 22 +``` + +更多信息请参见 “[Linux:菜鸟管理员的 25 个 Iptables Netfilter 命令][14]”。 + +#### *BSD PF 防火墙配置 + +如果使用 PF 防火墙 [/etc/pf.conf][15] 配置如下: + +``` +pass in on $ext_if inet proto tcp from {192.168.1.0/24, 202.54.1.5/29} to $ssh_server_ip port ssh flags S/SA synproxy state +``` + +### 8、 修改 SSH 端口和绑定 IP + +ssh 默认监听系统中所有可用的网卡。修改并绑定 ssh 端口有助于避免暴力脚本的连接(许多暴力脚本只尝试端口 22)。更新文件 `sshd_config` 的以下内容来绑定端口 300 到 IP 192.168.1.5 和 202.54.1.5: + +``` +Port 300 +ListenAddress 192.168.1.5 +ListenAddress 202.54.1.5 +``` + +当需要接受动态广域网地址的连接时,使用主动脚本是个不错的选择,比如 fail2ban 或 denyhosts。 + +### 9、 使用 TCP wrappers (可选的) + +TCP wrapper 是一个基于主机的访问控制系统,用来过滤来自互联网的网络访问。OpenSSH 支持 TCP wrappers。只需要更新文件 `/etc/hosts.allow` 中的以下内容就可以使得 SSH 只接受来自于 192.168.1.2 和 172.16.23.12 的连接: + +``` +sshd : 192.168.1.2 172.16.23.12 +``` + +在 Linux/Mac OS X 和类 UNIX 系统中参见 [TCP wrappers 设置和使用的常见问题][16]。 + +### 10、 阻止 SSH 破解或暴力攻击 + +暴力破解是一种在单一或者分布式网络中使用大量(用户名和密码的)组合来尝试连接一个加密系统的方法。可以使用以下软件来应对暴力攻击: + +* [DenyHosts][17] 是一个基于 Python SSH 安全工具。该工具通过监控授权日志中的非法登录日志并封禁原始 IP 的方式来应对暴力攻击。 + * RHEL / Fedora 和 CentOS Linux 下如何设置 [DenyHosts][18]。 +* [Fail2ban][19] 是另一个类似的用来预防针对 SSH 攻击的工具。 +* [sshguard][20] 是一个使用 pf 来预防针对 SSH 和其他服务攻击的工具。 +* [security/sshblock][21] 阻止滥用 SSH 尝试登录。 +* [IPQ BDB filter][22] 可以看做是 fail2ban 的一个简化版。 + +### 11、 限制 TCP 端口 22 的传入速率(可选的) + +netfilter 和 pf 都提供速率限制选项可以对端口 22 的传入速率进行简单的限制。 + +#### Iptables 示例 + +以下脚本将会阻止 60 秒内尝试登录 5 次以上的客户端的连入。 + +``` +#!/bin/bash +inet_if=eth1 +ssh_port=22 +$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --set +$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --update --seconds 60 --hitcount 5 +``` + +在你的 iptables 脚本中调用以上脚本。其他配置选项: + +``` +$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT +$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT +$IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT +# another one line example +# $IPT -A INPUT -i ${inet_if} -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 5-j ACCEPT +``` + +其他细节参见 iptables 用户手册。 + +#### *BSD PF 示例 + +以下脚本将限制每个客户端的连入数量为 20,并且 5 秒内的连接不超过 15 个。如果客户端触发此规则,则将其加入 abusive_ips 表并限制该客户端连入。最后 flush 关键词杀死所有触发规则的客户端的连接。 + +``` +sshd_server_ip = "202.54.1.5" +table persist +block in quick from +pass in on $ext_if proto tcp to $sshd_server_ip port ssh flags S/SA keep state (max-src-conn 20, max-src-conn-rate 15/5, overload flush) +``` + +### 12、 使用端口敲门(可选的) + +[端口敲门][23]是通过在一组预先指定的封闭端口上生成连接尝试,以便从外部打开防火墙上的端口的方法。一旦指定的端口连接顺序被触发,防火墙规则就被动态修改以允许发送连接的主机连入指定的端口。以下是一个使用 iptables 实现的端口敲门的示例: + +``` +$IPT -N stage1 +$IPT -A stage1 -m recent --remove --name knock +$IPT -A stage1 -p tcp --dport 3456 -m recent --set --name knock2 + +$IPT -N stage2 +$IPT -A stage2 -m recent --remove --name knock2 +$IPT -A stage2 -p tcp --dport 2345 -m recent --set --name heaven + +$IPT -N door +$IPT -A door -m recent --rcheck --seconds 5 --name knock2 -j stage2 +$IPT -A door -m recent --rcheck --seconds 5 --name knock -j stage1 +$IPT -A door -p tcp --dport 1234 -m recent --set --name knock + +$IPT -A INPUT -m --state ESTABLISHED,RELATED -j ACCEPT +$IPT -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name heaven -j ACCEPT +$IPT -A INPUT -p tcp --syn -j door +``` + +更多信息请参见: + +[Debian / Ubuntu: 使用 Knockd and Iptables 设置端口敲门][55] + +### 13、 配置空闲超时注销时长 + +用户可以通过 ssh 连入服务器,可以配置一个超时时间间隔来避免无人值守的 ssh 会话。 打开 `sshd_config` 并确保配置以下值: + +``` +ClientAliveInterval 300 +ClientAliveCountMax 0 +``` + +以秒为单位设置一个空闲超时时间(300秒 = 5分钟)。一旦空闲时间超过这个值,空闲用户就会被踢出会话。更多细节参见[如何自动注销空闲超时的 BASH / TCSH / SSH 用户][24]。 + +### 14、 为 ssh 用户启用警示标语 + +更新 `sshd_config` 文件如下行来设置用户的警示标语: + +``` +Banner /etc/issue +``` + +`/etc/issue 示例文件: + +``` +---------------------------------------------------------------------------------------------- +You are accessing a XYZ Government (XYZG) Information System (IS) that is provided for authorized use only. +By using this IS (which includes any device attached to this IS), you consent to the following conditions: + ++ The XYZG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, +penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), +law enforcement (LE), and counterintelligence (CI) investigations. + ++ At any time, the XYZG may inspect and seize data stored on this IS. + ++ Communications using, or data stored on, this IS are not private, are subject to routine monitoring, +interception, and search, and may be disclosed or used for any XYZG authorized purpose. + ++ This IS includes security measures (e.g., authentication and access controls) to protect XYZG interests--not +for your personal benefit or privacy. + ++ Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching +or monitoring of the content of privileged communications, or work product, related to personal representation +or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work +product are private and confidential. See User Agreement for details. +---------------------------------------------------------------------------------------------- +``` + +以上是一个标准的示例,更多的用户协议和法律细节请咨询你的律师团队。 + +### 15、 禁用 .rhosts 文件(需核实) + +禁止读取用户的 `~/.rhosts` 和 `~/.shosts` 文件。更新 `sshd_config` 文件中的以下内容: + +``` +IgnoreRhosts yes +``` + +SSH 可以模拟过时的 rsh 命令,所以应该禁用不安全的 RSH 连接。 + +### 16、 禁用基于主机的授权(需核实) + +禁用基于主机的授权,更新 `sshd_config` 文件的以下选项: + +``` +HostbasedAuthentication no +``` + +### 17、 为 OpenSSH 和操作系统打补丁 + +推荐你使用类似 [yum][25]、[apt-get][26] 和 [freebsd-update][27] 等工具保持系统安装了最新的安全补丁。 + +### 18、 Chroot OpenSSH (将用户锁定在主目录) + +默认设置下用户可以浏览诸如 `/etc`、`/bin` 等目录。可以使用 chroot 或者其他专有工具如 [rssh][28] 来保护 ssh 连接。从版本 4.8p1 或 4.9p1 起,OpenSSH 不再需要依赖诸如 rssh 或复杂的 chroot(1) 等第三方工具来将用户锁定在主目录中。可以使用新的 `ChrootDirectory` 指令将用户锁定在其主目录,参见[这篇博文][29]。 + +### 19. 禁用客户端的 OpenSSH 服务 + +工作站和笔记本不需要 OpenSSH 服务。如果不需要提供 ssh 远程登录和文件传输功能的话,可以禁用 sshd 服务。CentOS / RHEL 用户可以使用 [yum 命令][30] 禁用或删除 openssh-server: + +``` +$ sudo yum erase openssh-server +``` + +Debian / Ubuntu 用户可以使用 [apt 命令][31]/[apt-get 命令][32] 删除 openssh-server: + +``` +$ sudo apt-get remove openssh-server +``` + +有可能需要更新 iptables 脚本来移除 ssh 的例外规则。CentOS / RHEL / Fedora 系统可以编辑文件 `/etc/sysconfig/iptables` 和 `/etc/sysconfig/ip6tables`。最后[重启 iptables][33] 服务: + +``` +# service iptables restart +# service ip6tables restart +``` + +### 20. 来自 Mozilla 的额外提示 + +如果使用 6.7+ 版本的 OpenSSH,可以尝试下[以下设置][34]: + +``` +#################[ WARNING ]######################## +# Do not use any setting blindly. Read sshd_config # +# man page. You must understand cryptography to # +# tweak following settings. Otherwise use defaults # +#################################################### + +# Supported HostKey algorithms by order of preference. +HostKey /etc/ssh/ssh_host_ed25519_key +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key + +# Specifies the available KEX (Key Exchange) algorithms. +KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 + +# Specifies the ciphers allowed +Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr + +#Specifies the available MAC (message authentication code) algorithms +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com + +# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in. +LogLevel VERBOSE + +# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise. +Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO +``` + +使用以下命令获取 OpenSSH 支持的加密方法: + +``` +$ ssh -Q cipher +$ ssh -Q cipher-auth +$ ssh -Q mac +$ ssh -Q kex +$ ssh -Q key +``` + +[![OpenSSH安全教程查询密码和算法选择][35]][35] + +### 如何测试 sshd_config 文件并重启/重新加载 SSH 服务? + +在重启 sshd 前检查配置文件的有效性和密匙的完整性,运行: + +``` +$ sudo sshd -t +``` + +扩展测试模式: + +``` +$ sudo sshd -T +``` + +最后,根据系统的的版本[重启 Linux 或类 Unix 系统中的 sshd 服务][37]: + +``` +$ [sudo systemctl start ssh][38] ## Debian/Ubunt Linux## +$ [sudo systemctl restart sshd.service][39] ## CentOS/RHEL/Fedora Linux## +$ doas /etc/rc.d/sshd restart ## OpenBSD## +$ sudo service sshd restart ## FreeBSD## +``` + +### 其他建议 + +1. [使用 2FA 加强 SSH 的安全性][40] - 可以使用 [OATH Toolkit][41] 或 [DuoSecurity][42] 启用多重身份验证。 +2. [基于密匙链的身份验证][43] - 密匙链是一个 bash 脚本,可以使得基于密匙的验证非常的灵活方便。相对于无密码密匙,它提供更好的安全性。 + +### 更多信息: + +* [OpenSSH 官方][44] 项目。 +* 用户手册: sshd(8)、ssh(1)、ssh-add(1)、ssh-agent(1)。 + +如果知道这里没用提及的方便的软件或者技术,请在下面的评论中分享,以帮助读者保持 OpenSSH 的安全。 + +### 关于作者 + +作者是 nixCraft 的创始人,一个经验丰富的系统管理员和 Linux/Unix 脚本培训师。他曾与全球客户合作,领域涉及 IT,教育,国防和空间研究以及非营利部门等多个行业。请在 [Twitter][45]、[Facebook][46]、[Google+][47] 上关注他。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/tips/linux-unix-bsd-openssh-server-best-practices.html + +作者:[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/media/new/tips/2009/07/openSSH_logo.png +[2]:https://isc.sans.edu/diary/OpenSSH+Rumors/6742 +[3]:https://www.cyberciti.biz/tips/wp-content/uploads/2009/07/OpenSSH-server-security-best-practices.png +[4]:https://www.cyberciti.biz/faq/how-to-create-a-sudo-user-on-ubuntu-linux-server/ +[5]:https://www.cyberciti.biz/faq/unix-linux-id-command-examples-usage-syntax/ (See Linux/Unix id command examples for more info) +[6]:https://www.cyberciti.biz/faq/how-to-disable-ssh-password-login-on-linux/ +[7]:https://www.cyberciti.biz/tips/linux-pam-configuration-that-allows-or-deny-login-via-the-sshd-server.html +[8]:https://www.cyberciti.biz/tips/openssh-deny-or-restrict-access-to-users-and-groups.html +[9]:https://www.cyberciti.biz/tips/linux-check-passwords-against-a-dictionary-attack.html +[10]:https://www.cyberciti.biz/faq/unix-linux-password-cracking-john-the-ripper/ +[11]:https://www.cyberciti.biz/faq/rhel-fedorta-linux-iptables-firewall-configuration-tutorial/ +[12]:https://www.cyberciti.biz/faq/howto-configure-setup-firewall-with-ufw-on-ubuntu-linux/ +[13]:https://www.cyberciti.biz/faq/ufw-allow-incoming-ssh-connections-from-a-specific-ip-address-subnet-on-ubuntu-debian/ +[14]:https://www.cyberciti.biz/tips/linux-iptables-examples.html +[15]:https://bash.cyberciti.biz/firewall/pf-firewall-script/ +[16]:https://www.cyberciti.biz/faq/tcp-wrappers-hosts-allow-deny-tutorial/ +[17]:https://www.cyberciti.biz/faq/block-ssh-attacks-with-denyhosts/ +[18]:https://www.cyberciti.biz/faq/rhel-linux-block-ssh-dictionary-brute-force-attacks/ +[19]:https://www.fail2ban.org +[20]:https://sshguard.sourceforge.net/ +[21]:http://www.bsdconsulting.no/tools/ +[22]:https://savannah.nongnu.org/projects/ipqbdb/ +[23]:https://en.wikipedia.org/wiki/Port_knocking +[24]:https://www.cyberciti.biz/faq/linux-unix-login-bash-shell-force-time-outs/ +[25]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ +[26]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html +[27]:https://www.cyberciti.biz/tips/howto-keep-freebsd-system-upto-date.html +[28]:https://www.cyberciti.biz/tips/rhel-centos-linux-install-configure-rssh-shell.html +[29]:https://www.debian-administration.org/articles/590 +[30]:https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ (See Linux/Unix yum command examples for more info) +[31]:https://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info) +[32]:https://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info) +[33]:https://www.cyberciti.biz/faq/howto-rhel-linux-open-port-using-iptables/ +[34]:https://wiki.mozilla.org/Security/Guidelines/OpenSSH +[35]:https://www.cyberciti.biz/tips/wp-content/uploads/2009/07/OpenSSH-Security-Tutorial-Query-Ciphers-and-algorithms-choice.jpg +[36]:https://www.cyberciti.biz/tips/checking-openssh-sshd-configuration-syntax-errors.html +[37]:https://www.cyberciti.biz/faq/howto-restart-ssh/ +[38]:https://www.cyberciti.biz/faq/howto-start-stop-ssh-server/ (Restart sshd on a Debian/Ubuntu Linux) +[39]:https://www.cyberciti.biz/faq/centos-stop-start-restart-sshd-command/ (Restart sshd on a CentOS/RHEL/Fedora Linux) +[40]:https://www.cyberciti.biz/open-source/howto-protect-linux-ssh-login-with-google-authenticator/ +[41]:http://www.nongnu.org/oath-toolkit/ +[42]:https://duo.com +[43]:https://www.cyberciti.biz/faq/ssh-passwordless-login-with-keychain-for-scripts/ +[44]:https://www.openssh.com/ +[45]:https://twitter.com/nixcraft +[46]:https://facebook.com/nixcraft +[47]:https://plus.google.com/+CybercitiBiz +[48]:https://www.cyberciti.biz/faq/ssh-passwordless-login-with-keychain-for-scripts/ +[49]:https://linux.cn/article-8086-1.html +[50]:https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/ +[51]:https://www.cyberciti.biz/faq/how-to-upload-ssh-public-key-to-as-authorized_key-using-ansible/ +[52]:https://www.cyberciti.biz/faq/generating-random-password/ +[53]:https://www.cyberciti.biz/faq/linux-unix-generating-passwords-command/ +[54]:https://www.cyberciti.biz/faq/linux-random-password-generator/ +[55]:https://www.cyberciti.biz/faq/debian-ubuntu-linux-iptables-knockd-port-knocking-tutorial/ diff --git a/published/20110917 Have I been hacked by root-notty- - Sysadmin World.md b/published/201802/20110917 Have I been hacked by root-notty- - Sysadmin World.md similarity index 100% rename from published/20110917 Have I been hacked by root-notty- - Sysadmin World.md rename to published/201802/20110917 Have I been hacked by root-notty- - Sysadmin World.md diff --git a/translated/tech/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md b/published/201802/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md similarity index 57% rename from translated/tech/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md rename to published/201802/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md index ec36c729f5..d53a5bb799 100644 --- a/translated/tech/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md +++ b/published/201802/20120624 6 Best Open Source Alternatives to Microsoft Office for Linux.md @@ -1,12 +1,13 @@ -# Liunx 平台 6 个最好的替代 Microsoft Office 的开源办公软件 +6 个 Liunx 平台下最好的替代 Microsoft Office 的开源办公软件 +=========== -**概要:还在 Linux 中寻找 Microsoft Office ? 这里有一些最好的在 Linux 平台替代 Microsoft Office 的开源软件。** +> 概要:还在 Linux 中寻找 Microsoft Office 吗? 这里有一些最好的在 Linux 平台下替代 Microsoft Office 的开源软件。 -办公套件是任何操作系统的必备品。很难想象没有Office 软件的桌面操作系统。虽然 Windows 有 MS Office 套件,Mac OS X 也有它自己的 iWork,但其他很多办公套件都是专门针对这些操作系统的,Linux 也有自己的办公套件。 +办公套件是任何操作系统的必备品。很难想象没有 Office 软件的桌面操作系统。虽然 Windows 有 MS Office 套件,Mac OS X 也有它自己的 iWork,但其他很多办公套件都是专门针对这些操作系统的,Linux 也有自己的办公套件。 在本文中,我会列举一些在 Linux 平台替代 Microsoft Office 的办公软件。 -## Linux 最好的 MS Office 开源替代软件 +### Linux 最好的 MS Office 开源替代软件 ![Best Microsoft office alternatives for Linux][1] @@ -16,62 +17,61 @@ * 电子表格 * 演示功能 - -我知道 Microsoft Office 提供了比上述三种工具更多的工具,但事实上, 您主要使用这三个工具。 开源办公套件并不限于只有这三种产品。 其中有一些套件提供了一些额外的工具,但我们的重点将放在上述工具上。 +我知道 Microsoft Office 提供了比上述三种工具更多的工具,但事实上,您主要使用这三个工具。开源办公套件并不限于只有这三种产品。其中有一些套件提供了一些额外的工具,但我们的重点将放在上述工具上。 让我们看看在 Linux 上有什么办公套件: -### 6. Apache OpenOffice +#### 6. Apache OpenOffice ![OpenOffice Logo][2] -[Apache OpenOffice][3] 或简单的称为 OpenOffice 有一段名称/所有者变更的历史。 它于1999年由 Sun Microsystems 公司开发,后来改名为 OpenOffice ,将它作为一个与 MS Office 对抗的免费的开源替代软件。 当Oracle 在 2010 年收购 Sun 公司后,一年之后便停止开发 OpenOffice。 最后是 Apache 支持它,现在被称为Apache OpenOffice。 +[Apache OpenOffice][3] 或简单的称为 OpenOffice 有一段名称/所有者变更的历史。 它于 1999 年由 Sun Microsystems 公司开发,后来改名为 OpenOffice,将它作为一个与 MS Office 对抗的自由开源的替代软件。 当 Oracle 在 2010 年收购 Sun 公司后,一年之后便停止开发 OpenOffice。 最后是 Apache 支持它,现在被称为 Apache OpenOffice。 -Apache OpenOffice 可用于多种平台,包括 Linux,Windows,Mac OS X,Unix,BSD。 除了 OpenDocument 格式外,它还支持 MS Office 文件。 办公套件包含以下应用程序:Writer,Calc,Impress,Base,Draw,Math。 +Apache OpenOffice 可用于多种平台,包括 Linux、Windows、Mac OS X、Unix、BSD。 除了 OpenDocument 格式外,它还支持 MS Office 文件。 办公套件包含以下应用程序:Writer、Calc、Impress、Base、Draw、Math。 -安装 OpenOffice 是一件痛苦的事,因为它没有提供一个友好的安装程序。 另外,有传言说 OpenOffice 开发可能已经停滞。 这两个是我不推荐的主要原因。 为了历史目的,我在这里列出它。 +安装 OpenOffice 是一件痛苦的事,因为它没有提供一个友好的安装程序。另外,有传言说 OpenOffice 开发可能已经停滞。 这是我不推荐的两个主要原因。 出于历史目的,我在这里列出它。 -### 5. Feng Office +#### 5. Feng Office ![Feng Office logo][6] -[Feng Office][7] 以前被称为 OpenGoo。 这不是一个常规的办公套件。 它完全专注于在线办公,如 Google 文档。 换句话说,这是一个开源[协作平台][8]。 +[Feng Office][7] 以前被称为 OpenGoo。 这不是一个常规的办公套件。 它完全专注于在线办公,如 Google 文档一样。 换句话说,这是一个开源[协作平台][8]。 -Feng Office 不支持桌面使用,因此如果您想在单个Linux 桌面上使用它,这个可能无法实现。 另一方面,如果你有一个小企业,一个机构或其他组织,你可以尝试将其部署在本地服务器上。 +Feng Office 不支持桌面使用,因此如果您想在单个 Linux 桌面上使用它,这个可能无法实现。 另一方面,如果你有一个小企业、一个机构或其他组织,你可以尝试将其部署在本地服务器上。 -### 4. Siag Office +#### 4. Siag Office ![SIAG Office logo][9] -[Siag][10] 是一个非常轻量级的办公套件,适用于类 Unix 系统,可以在 16 MB 系统上运行。 由于它非常轻便,因此缺少标准办公套件中的许多功能。 但小即是美丽的,不是吗? 它具有办公套件的所有必要功能,可以在[轻量级 Linux 发行版][11]上“正常工作”。它是 [Damn Small Linux][12] 默认安装软件。(译者注: 根据官网,现已不是默认安装软件) +[Siag][10] 是一个非常轻量级的办公套件,适用于类 Unix 系统,可以在 16MB 的系统上运行。 由于它非常轻便,因此缺少标准办公套件中的许多功能。 但小即是丽,不是吗? 它具有办公套件的所有必要功能,可以在[轻量级 Linux 发行版][11]上“正常工作”。它是 [Damn Small Linux][12] 默认安装软件。(LCTT 译注:根据官网,现已不是默认安装软件) -### 3. Calligra Suite +#### 3. Calligra Suite ![Calligra free and Open Source office logo][13] -[Calligra][14],以前被称为 KOffice,是 KDE 中默认的 Office 套件。 它支持 Mac OS X,Windows,Linux,FreeBSD系统。 它也曾经推出 Android 版本。 但不幸的是,后续没有继续支持 Android。 它拥有办公套件所需的必要应用程序以及一些额外的应用程序,如用于绘制流程图的 Flow 和用于项目管理的 Plane。 +[Calligra][14],以前被称为 KOffice,是 KDE 中默认的 Office 套件。 它支持 Mac OS X、Windows、Linux、FreeBSD 系统。 它也曾经推出 Android 版本。 但不幸的是,后续没有继续支持 Android。 它拥有办公套件所需的必要应用程序以及一些额外的应用程序,如用于绘制流程图的 Flow 和用于项目管理的 Plane。 Calligra 最近的发展产生了相当大的影响,很有可能成为 [LibreOffice 的替代品][16]。 -### 2. ONLYOFFICE +#### 2. ONLYOFFICE ![ONLYOFFICE is Linux alternative to Microsoft Office][17] [ONLYOFFICE][18] 是办公套件市场上的新玩家,它更专注于协作部分。 企业(甚至个人)可以将其部署到自己的服务器上,以获得类似 Google Docs 之类的协作办公套件。 -别担心。 您不必必须将其安装在服务器上。 有一个免费的开源[桌面版本][19] ONLYOFFICE。 您甚至可以获取 .deb 和 .rpm 二进制文件,以便将其安装在 Linux 桌面系统上。 +别担心,您不是必须将其安装在服务器上。有一个免费的开源[桌面版本][19] ONLYOFFICE。 您甚至可以获取 .deb 和 .rpm 二进制文件,以便将其安装在 Linux 桌面系统上。 -### 1. LibreOffice +#### 1. LibreOffice ![LibreOffice logo][20] -当 Oracle 决定停止 OpenOffice 的开发时,是[文档基金会][21]将其复制分发,这就是我们所熟知的 [Libre-Office][22] 。从那时起,许多 Linux 发行版都将 OpenOffice 替换为 LibreOffice 作为它们的默认办公应用程序。 +当 Oracle 决定停止 OpenOffice 的开发时,是[文档基金会][21]将其复制分发,这就是我们所熟知的 [Libre-Office][22]。从那时起,许多 Linux 发行版都将 OpenOffice 替换为 LibreOffice 作为它们的默认办公应用程序。 它适用于 Linux,Windows 和 Mac OS X,这使得在跨平台环境中易于使用。 和 Apache OpenOffice 一样,这也包括了除了 OpenDocument 格式以外的对 MS Office 文件的支持。 它还包含与 Apache OpenOffice 相同的应用程序。 -您还可以使用 LibreOffice 作为 [Collabora Online][23] 的协作平台。 基本上,LibreOffice 是一个完整的软件包,无疑是 Linux,Windows 和 MacOS 的**最佳 Microsoft Office 替代品**。 +您还可以使用 LibreOffice 作为 [Collabora Online][23] 的协作平台。 基本上,LibreOffice 是一个完整的软件包,无疑是 Linux、Windows 和 MacOS 的**最佳 Microsoft Office 替代品**。 -## 你认为呢? +### 你认为呢? 我希望 Microsoft Office 的这些开源替代软件可以节省您的资金。 您会使用哪种开源生产力办公套件? @@ -81,7 +81,7 @@ via: https://itsfoss.com/best-free-open-source-alternatives-microsoft-office/ 作者:[Abhishek Prakash][a] 译者:[amwps290](https://github.com/amwps290) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20130319 Linux - Unix Bash Shell List All Builtin Commands.md b/published/201802/20130319 Linux - Unix Bash Shell List All Builtin Commands.md similarity index 100% rename from published/20130319 Linux - Unix Bash Shell List All Builtin Commands.md rename to published/201802/20130319 Linux - Unix Bash Shell List All Builtin Commands.md diff --git a/published/20141029 What does an idle CPU do.md b/published/201802/20141029 What does an idle CPU do.md similarity index 100% rename from published/20141029 What does an idle CPU do.md rename to published/201802/20141029 What does an idle CPU do.md diff --git a/published/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md b/published/201802/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md similarity index 100% rename from published/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md rename to published/201802/20160605 Manjaro Gaming- Gaming on Linux Meets Manjaro-s Awesomeness.md diff --git a/translated/tech/20160606 Learn your tools Navigating your Git History.md b/published/201802/20160606 Learn your tools Navigating your Git History.md similarity index 71% rename from translated/tech/20160606 Learn your tools Navigating your Git History.md rename to published/201802/20160606 Learn your tools Navigating your Git History.md index 1a7d192837..cbf988f14e 100644 --- a/translated/tech/20160606 Learn your tools Navigating your Git History.md +++ b/published/201802/20160606 Learn your tools Navigating your Git History.md @@ -1,15 +1,15 @@ -学习你的工具:驾驭你的 Git 历史 +学习用工具来驾驭 Git 历史 ============================================================ -在你的日常工作中,不可能每天都从头开始去开发一个新的应用程序。而真实的情况是,在日常工作中,我们大多数时候所面对的都是遗留下来的一个代码库,我们能够去修改一些特性的内容或者现存的一些代码行,是我们在日常工作中很重要的一部分。而这也就是分布式版本控制系统 `git` 的价值所在。现在,我们来深入了解怎么去使用 `git` 的历史以及如何很轻松地去浏览它的历史。 +在你的日常工作中,不可能每天都从头开始去开发一个新的应用程序。而真实的情况是,在日常工作中,我们大多数时候所面对的都是遗留下来的一个代码库,去修改一些特性的内容或者现存的一些代码行,这是我们在日常工作中很重要的一部分。而这也就是分布式版本控制系统 `git` 的价值所在。现在,我们来深入了解怎么去使用 `git` 的历史以及如何很轻松地去浏览它的历史。 ### Git 历史 -首先和最重要的事是,什么是 `git` 历史?正如其名字一样,它是一个 `git` 仓库的提交历史。它包含一堆提交信息,其中有它们的作者的名字、提交的哈希值以及提交日期。查看一个 `git` 仓库历史的方法很简单,就是一个 `git log` 命令。 +首先和最重要的事是,什么是 `git` 历史?正如其名字一样,它是一个 `git` 仓库的提交历史。它包含一堆提交信息,其中有它们的作者的名字、该提交的哈希值以及提交日期。查看一个 `git` 仓库历史的方法很简单,就是一个 `git log` 命令。 -> _*旁注:**为便于本文的演示,我们使用 Ruby 在 Rails 仓库的 `master` 分支。之所以选择它的理由是因为,Rails 有很好的 `git` 历史,有很好的提交信息、引用以及每个变更的解释。如果考虑到代码库的大小、维护者的年龄和数据,Rails 肯定是我见过的最好的仓库。当然了,我并不是说其它 `git` 仓库做的不好,它只是我见过的比较好的一个仓库。_ +> _旁注:为便于本文的演示,我们使用 Ruby on Rails 的仓库的 `master` 分支。之所以选择它的理由是因为,Rails 有良好的 `git` 历史,漂亮的提交信息、引用以及对每个变更的解释。如果考虑到代码库的大小、维护者的年龄和数量,Rails 肯定是我见过的最好的仓库。当然了,我并不是说其它的 `git` 仓库做的不好,它只是我见过的比较好的一个仓库。_ -因此,回到 Rails 仓库。如果你在 Ralis 仓库上运行 `git log`。你将看到如下所示的输出: +那么,回到 Rails 仓库。如果你在 Ralis 仓库上运行 `git log`。你将看到如下所示的输出: ``` commit 66ebbc4952f6cfb37d719f63036441ef98149418 @@ -72,7 +72,7 @@ Date: Thu Jun 2 21:26:53 2016 -0500 [skip ci] Make header bullets consistent in engines.md ``` -正如你所见,`git log` 展示了提交哈希、作者和他的 email 以及提交日期。当然,`git` 输出的可定制性很强大,它允许你去定制 `git log` 命令的输出格式。比如说,我们希望看到提交的信息显示在一行上,我们可以运行 `git log --oneline`,它将输出一个更紧凑的日志: +正如你所见,`git log` 展示了提交的哈希、作者及其 email 以及该提交创建的日期。当然,`git` 输出的可定制性很强大,它允许你去定制 `git log` 命令的输出格式。比如说,我们只想看提交信息的第一行,我们可以运行 `git log --oneline`,它将输出一个更紧凑的日志: ``` 66ebbc4 Dont re-define class SQLite3Adapter on test @@ -89,15 +89,15 @@ e98caf8 [skip ci] Make header bullets consistent in engines.md 如果你想看 `git log` 的全部选项,我建议你去查阅 `git log` 的 man 页面,你可以在一个终端中输入 `man git-log` 或者 `git help log` 来获得。 -> _**小提示:**如果你觉得 `git log` 看起来太恐怖或者过于复杂,或者你觉得看它太无聊了,我建议你去寻找一些 `git` GUI 命令行工具。在以前的文章中,我使用过 [GitX][1] ,我觉得它很不错,但是,由于我看命令行更“亲切”一些,在我尝试了 [tig][2] 之后,就再也没有去用过它。_ +> _小提示:如果你觉得 `git log` 看起来太恐怖或者过于复杂,或者你觉得看它太无聊了,我建议你去寻找一些 `git` 的 GUI 或命令行工具。在之前,我使用过 [GitX][1] ,我觉得它很不错,但是,由于我看命令行更“亲切”一些,在我尝试了 [tig][2] 之后,就再也没有去用过它。_ -### 查找尼莫 +### 寻找尼莫 -现在,我们已经知道了关于 `git log` 命令一些很基础的知识之后,我们来看一下,在我们的日常工作中如何使用它更加高效地浏览历史。 +现在,我们已经知道了关于 `git log` 命令的一些很基础的知识之后,我们来看一下,在我们的日常工作中如何使用它更加高效地浏览历史。 假如,我们怀疑在 `String#classify` 方法中有一个预期之外的行为,我们希望能够找出原因,并且定位出实现它的代码行。 -为达到上述目的,你可以使用的第一个命令是 `git grep`,通过它可以找到这个方法定义在什么地方。简单来说,这个命令输出了给定的某些“样品”的匹配行。现在,我们来找出定义它的方法,它非常简单 —— 我们对  `def classify` 运行 grep,然后看到的输出如下: +为达到上述目的,你可以使用的第一个命令是 `git grep`,通过它可以找到这个方法定义在什么地方。简单来说,这个命令输出了匹配特定模式的那些行。现在,我们来找出定义它的方法,它非常简单 —— 我们对  `def classify` 运行 grep,然后看到的输出如下: ``` ➜ git grep 'def classify' @@ -113,7 +113,7 @@ activesupport/lib/active_support/core_ext/string/inflections.rb: def classifyact activesupport/lib/active_support/core_ext/string/inflections.rb:205: def classifyactivesupport/lib/active_support/inflector/methods.rb:186: def classify(table_name)tools/profile:112: def classify ``` -更好看了,是吧?考虑到上下文,我们可以很轻松地找到,这个方法在`activesupport/lib/active_support/core_ext/string/inflections.rb` 的第 205 行的 `classify` 方法,它看起来像这样,是不是很容易? +更好看了,是吧?考虑到上下文,我们可以很轻松地找到,这个方法在 `activesupport/lib/active_support/core_ext/string/inflections.rb` 的第 205 行的 `classify` 方法,它看起来像这样,是不是很容易? ``` # Creates a class name from a plural table name like Rails does for table names to models. @@ -127,7 +127,7 @@ activesupport/lib/active_support/core_ext/string/inflections.rb:205: def classi end ``` -尽管这个方法我们找到的是在 `String` 上的一个常见的调用,它涉及到`ActiveSupport::Inflector` 上的另一个方法,使用了相同的名字。获得了 `git grep` 的结果,我们可以很轻松地导航到这里,因此,我们看到了结果的第二行, `activesupport/lib/active_support/inflector/methods.rb` 在 186 行上。我们正在寻找的方法是: +尽管我们找到的这个方法是在 `String` 上的一个常见的调用,它调用了 `ActiveSupport::Inflector` 上的另一个同名的方法。根据之前的 `git grep` 的结果,我们可以很轻松地发现结果的第二行, `activesupport/lib/active_support/inflector/methods.rb` 在 186 行上。我们正在寻找的方法是这样的: ``` # Creates a class name from a plural table name like Rails does for table @@ -146,17 +146,17 @@ def classify(table_name) end ``` -酷!考虑到 Rails 仓库的大小,我们借助 `git grep` 找到它,用时没有超越 30 秒。 +酷!考虑到 Rails 仓库的大小,我们借助 `git grep` 找到它,用时都没有超越 30 秒。 ### 那么,最后的变更是什么? -我们已经掌握了有用的方法,现在,我们需要搞清楚这个文件所经历的变更。由于我们已经知道了正确的文件名和行数,我们可以使用 `git blame`。这个命令展示了一个文件中每一行的最后修订者和修订的内容。我们来看一下这个文件最后的修订都做了什么: +现在,我们已经找到了所要找的方法,现在,我们需要搞清楚这个文件所经历的变更。由于我们已经知道了正确的文件名和行数,我们可以使用 `git blame`。这个命令展示了一个文件中每一行的最后修订者和修订的内容。我们来看一下这个文件最后的修订都做了什么: ``` git blame activesupport/lib/active_support/inflector/methods.rb ``` -虽然我们得到了这个文件每一行的最后的变更,但是,我们更感兴趣的是对指定的方法(176 到 189 行)的最后变更。让我们在 `git blame` 命令上增加一个选项,它将只显示那些行。此外,我们将在命令上增加一个 `-s` (阻止) 选项,去跳过那一行变更时的作者名字和修订(提交)的时间戳: +虽然我们得到了这个文件每一行的最后的变更,但是,我们更感兴趣的是对特定方法(176 到 189 行)的最后变更。让我们在 `git blame` 命令上增加一个选项,让它只显示那些行的变化。此外,我们将在命令上增加一个 `-s` (忽略)选项,去跳过那一行变更时的作者名字和修订(提交)的时间戳: ``` git blame -L 176,189 -s activesupport/lib/active_support/inflector/methods.rb @@ -183,13 +183,13 @@ git blame -L 176,189 -s activesupport/lib/active_support/inflector/methods.rb git show 5bb1d4d2 ``` -你亲自做实验了吗?如果没有做,我直接告诉你结果,这个令人惊叹的 [提交][3] 是由 [Schneems][4] 做的,他通过使用 frozen 字符串做了一个非常有趣的性能优化,这在我们当前的上下文中是非常有意义的。但是,由于我们在这个假设的调试会话中,这样做并不能告诉我们当前问题所在。因此,我们怎么样才能够通过研究来发现,我们选定的方法经过了哪些变更? +你亲自做实验了吗?如果没有做,我直接告诉你结果,这个令人惊叹的 [提交][3] 是由 [Schneems][4] 完成的,他通过使用 frozen 字符串做了一个非常有趣的性能优化,这在我们当前的场景中是非常有意义的。但是,由于我们在这个假设的调试会话中,这样做并不能告诉我们当前问题所在。因此,我们怎么样才能够通过研究来发现,我们选定的方法经过了哪些变更? ### 搜索日志 现在,我们回到 `git` 日志,现在的问题是,怎么能够看到 `classify` 方法经历了哪些修订? -`git log` 命令非常强大,因此它提供了非常多的列表选项。我们尝试去看一下保存了这个文件的 `git` 日志内容。使用 `-p` 选项,它的意思是在 `git` 日志中显示这个文件的完整补丁: +`git log` 命令非常强大,因此它提供了非常多的列表选项。我们尝试使用 `-p` 选项去看一下保存了这个文件的 `git` 日志内容,这个选项的意思是在 `git` 日志中显示这个文件的完整补丁: ``` git log -p activesupport/lib/active_support/inflector/methods.rb @@ -201,13 +201,13 @@ git log -p activesupport/lib/active_support/inflector/methods.rb git log -L 176,189:activesupport/lib/active_support/inflector/methods.rb ``` -`git log` 命令接受了 `-L` 选项,它有一个行的范围和文件名做为参数。它的格式可能有点奇怪,格式解释如下: +`git log` 命令接受 `-L` 选项,它用一个行的范围和文件名做为参数。它的格式可能有点奇怪,格式解释如下: ``` git log -L ,: ``` -当我们去运行这个命令之后,我们可以看到对这些行的一个修订列表,它将带我们找到创建这个方法的第一个修订: +当我们运行这个命令之后,我们可以看到对这些行的一个修订列表,它将带我们找到创建这个方法的第一个修订: ``` commit 51xd6bb829c418c5fbf75de1dfbb177233b1b154 @@ -238,11 +238,11 @@ diff--git a/activesupport/lib/active_support/inflector/methods.rb b/activesuppor 现在,我们再来看一下 —— 它是在 2011 年提交的。`git` 可以让我们重回到这个时间。这是一个很好的例子,它充分说明了足够的提交信息对于重新了解当时的上下文环境是多么的重要,因为从这个提交信息中,我们并不能获得足够的信息来重新理解当时的创建这个方法的上下文环境,但是,话说回来,你**不应该**对此感到恼怒,因为,你看到的这些项目,它们的作者都是无偿提供他们的工作时间和精力来做开源工作的。(向开源项目贡献者致敬!) -回到我们的正题,我们并不能确认 `classify` 方法最初实现是怎么回事,考虑到这个第一次的提交只是一个重构。现在,如果你认为,“或许、有可能、这个方法不在 176 行到 189 行的范围之内,那么就你应该在这个文件中扩大搜索范围”,这样想是对的。我们看到在它的修订提交的信息中提到了“重构”这个词,它意味着这个方法可能在那个文件中是真实存在的,只是在重构之后它才存在于那个行的范围内。 +回到我们的正题,我们并不能确认 `classify` 方法最初实现是怎么回事,考虑到这个第一次的提交只是一个重构。现在,如果你认为,“或许、有可能、这个方法不在 176 行到 189 行的范围之内,那么就你应该在这个文件中扩大搜索范围”,这样想是对的。我们看到在它的修订提交的信息中提到了“重构”这个词,它意味着这个方法可能在那个文件中是真实存在的,而且是在重构之后它才存在于那个行的范围内。 但是,我们如何去确认这一点呢?不管你信不信,`git` 可以再次帮助你。`git log` 命令有一个 `-S` 选项,它可以传递一个特定的字符串作为参数,然后去查找代码变更(添加或者删除)。也就是说,如果我们执行 `git log -S classify` 这样的命令,我们可以看到所有包含 `classify` 字符串的变更行的提交。 -如果你在 Ralis 仓库上运行上述命令,首先你会发现这个命令运行有点慢。但是,你应该会发现 `git` 真的解析了在那个仓库中的所有修订来匹配这个字符串,因为仓库非常大,实际上它的运行速度是非常快的。在你的指尖下 `git` 再次展示了它的强大之处。因此,如果去找关于 `classify` 方法的第一个修订,我们可以运行如下的命令: +如果你在 Ralis 仓库上运行上述命令,首先你会发现这个命令运行有点慢。但是,你应该会发现 `git` 实际上解析了在那个仓库中的所有修订来匹配这个字符串,其实它的运行速度是非常快的。在你的指尖下 `git` 再次展示了它的强大之处。因此,如果去找关于 `classify` 方法的第一个修订,我们可以运行如下的命令: ``` git log -S 'def classify' @@ -258,7 +258,7 @@ Date: Wed Nov 24 01:04:44 2004 +0000 git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de ``` -很酷!是吧?它初次被提交到 Rails,是由 DHHD 在一个 `svn` 仓库上做的!这意味着 `classify` 提交到 Rails 仓库的大概时间。现在,我们去看一下这个提交的所有变更信息,我们运行如下的命令: +很酷!是吧?它初次被提交到 Rails,是由 DHH 在一个 `svn` 仓库上做的!这意味着 `classify` 大概在一开始就被提交到了 Rails 仓库。现在,我们去看一下这个提交的所有变更信息,我们运行如下的命令: ``` git show db045dbbf60b53dbe013ef25554fd013baf88134 @@ -268,7 +268,7 @@ git show db045dbbf60b53dbe013ef25554fd013baf88134 ### 下次见 -当然,我们并不会真的去修改任何 bug,因为我们只是去尝试使用一些 `git` 命令,来演示如何查看 `classify` 方法的演变历史。但是不管怎样,`git` 是一个非常强大的工具,我们必须学好它、用好它。我希望这篇文章可以帮助你掌握更多的关于如何使用 `git` 的知识。 +当然,我们并没有真的去修改任何 bug,因为我们只是去尝试使用一些 `git` 命令,来演示如何查看 `classify` 方法的演变历史。但是不管怎样,`git` 是一个非常强大的工具,我们必须学好它、用好它。我希望这篇文章可以帮助你掌握更多的关于如何使用 `git` 的知识。 你喜欢这些内容吗? @@ -284,9 +284,9 @@ git show db045dbbf60b53dbe013ef25554fd013baf88134 via: https://ieftimov.com/learn-your-tools-navigating-git-history -作者:[Ilija Eftimov ][a] +作者:[Ilija Eftimov][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20170216 25 Free Books To Learn Linux For Free.md b/published/201802/20170216 25 Free Books To Learn Linux For Free.md similarity index 100% rename from published/20170216 25 Free Books To Learn Linux For Free.md rename to published/201802/20170216 25 Free Books To Learn Linux For Free.md diff --git a/published/20170429 Monitoring network bandwidth with iftop command.md b/published/201802/20170429 Monitoring network bandwidth with iftop command.md similarity index 100% rename from published/20170429 Monitoring network bandwidth with iftop command.md rename to published/201802/20170429 Monitoring network bandwidth with iftop command.md diff --git a/published/20170511 Working with VI editor - The Basics.md b/published/201802/20170511 Working with VI editor - The Basics.md similarity index 100% rename from published/20170511 Working with VI editor - The Basics.md rename to published/201802/20170511 Working with VI editor - The Basics.md diff --git a/published/20170707 Lessons from my first year of live coding on Twitch.md b/published/201802/20170707 Lessons from my first year of live coding on Twitch.md similarity index 100% rename from published/20170707 Lessons from my first year of live coding on Twitch.md rename to published/201802/20170707 Lessons from my first year of live coding on Twitch.md diff --git a/published/20170724 How to automate your system administration tasks with Ansible.md b/published/201802/20170724 How to automate your system administration tasks with Ansible.md similarity index 100% rename from published/20170724 How to automate your system administration tasks with Ansible.md rename to published/201802/20170724 How to automate your system administration tasks with Ansible.md diff --git a/published/20170915 How To Install And Setup Vagrant.md b/published/201802/20170915 How To Install And Setup Vagrant.md similarity index 100% rename from published/20170915 How To Install And Setup Vagrant.md rename to published/201802/20170915 How To Install And Setup Vagrant.md diff --git a/published/201802/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md b/published/201802/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md new file mode 100644 index 0000000000..243b622b3e --- /dev/null +++ b/published/201802/20170918 Two Easy Ways To Install Bing Desktop Wallpaper Changer On Linux.md @@ -0,0 +1,124 @@ +在 Linux 上安装必应桌面墙纸更换器 +====== + +你是否厌倦了 Linux 桌面背景,想要设置好看的壁纸,但是不知道在哪里可以找到?别担心,我们在这里会帮助你。 + +我们都知道必应搜索引擎,但是由于一些原因很少有人使用它,每个人都喜欢必应网站的背景壁纸,它是非常漂亮和惊人的高分辨率图像。 + +如果你想使用这些图片作为你的桌面壁纸,你可以手动下载它,但是很难去每天下载一个新的图片,然后把它设置为壁纸。这就是自动壁纸改变的地方。 + +[必应桌面墙纸更换器][1]会自动下载并将桌面壁纸更改为当天的必应照片。所有的壁纸都储存在 `/home/[user]/Pictures/BingWallpapers/`。 + +### 方法 1: 使用 Utkarsh Gupta Shell 脚本 + +这个小型 Python 脚本会自动下载并将桌面壁纸更改为当天的必应照片。该脚本在机器启动时自动运行,并工作于 GNU/Linux 上的 Gnome 或 Cinnamon 环境。它不需要手动工作,安装程序会为你做所有事情。 + +从 2.0+ 版本开始,该脚本的安装程序就可以像普通的 Linux 二进制命令一样工作,它会为某些任务请求 sudo 权限。 + +只需克隆仓库并切换到项目目录,然后运行 shell 脚本即可安装必应桌面墙纸更换器。 + +``` +$ https://github.com/UtkarshGpta/bing-desktop-wallpaper-changer/archive/master.zip +$ unzip master +$ cd bing-desktop-wallpaper-changer-master +``` + +运行 `installer.sh` 使用 `--install` 选项来安装必应桌面墙纸更换器。它会下载并设置必应照片为你的 Linux 桌面。 + +``` +$ ./installer.sh --install + +Bing-Desktop-Wallpaper-Changer +BDWC Installer v3_beta2 + +GitHub: +Contributors: +. +. +[sudo] password for daygeek: ****** +. +Where do you want to install Bing-Desktop-Wallpaper-Changer? + Entering 'opt' or leaving input blank will install in /opt/bing-desktop-wallpaper-changer + Entering 'home' will install in /home/daygeek/bing-desktop-wallpaper-changer + Install Bing-Desktop-Wallpaper-Changer in (opt/home)? :Press Enter + +Should we create bing-desktop-wallpaper-changer symlink to /usr/bin/bingwallpaper so you could easily execute it? + Create symlink for easy execution, e.g. in Terminal (y/n)? : y + +Should bing-desktop-wallpaper-changer needs to autostart when you log in? (Add in Startup Application) + Add in Startup Application (y/n)? : y +. +. +Executing bing-desktop-wallpaper-changer... + + +Finished!! +``` + +![][3] + +要卸载该脚本: + +``` +$ ./installer.sh --uninstall +``` + +使用帮助页面了解更多关于此脚本的选项。 + +``` +$ ./installer.sh --help +``` + +### 方法 2: 使用 GNOME Shell 扩展 + +这个轻量级 [GNOME shell 扩展][4],可将你的壁纸每天更改为微软必应的壁纸。它还会显示一个包含图像标题和解释的通知。 + +该扩展大部分基于 Elinvention 的 NASA APOD 扩展,受到了 Utkarsh Gupta 的 Bing Desktop WallpaperChanger 启发。 + +#### 特点 + +- 获取当天的必应壁纸并设置为锁屏和桌面墙纸(这两者都是用户可选的) +- 可强制选择某个特定区域(即地区) +- 为多个显示器自动选择最高分辨率(和最合适的墙纸) +- 可以选择在 1 到 7 天之后清理墙纸目录(删除最旧的) +- 只有当它们被更新时,才会尝试下载壁纸 +- 不会持续进行更新 - 每天只进行一次,启动时也要进行一次(更新是在必应更新时进行的) + +#### 如何安装 + +访问 [extenisons.gnome.org][5] 网站并将切换按钮拖到 “ON”,然后点击 “Install” 按钮安装必应壁纸 GNOME 扩展。(LCTT 译注:页面上并没有发现 ON 按钮,但是有 Download 按钮) + +![][6] + +安装必应壁纸 GNOME 扩展后,它会自动下载并为你的 Linux 桌面设置当天的必应照片,并显示关于壁纸的通知。 + +![][7] + +托盘指示器将帮助你执行少量操作,也可以打开设置。 + +![][8] + +根据你的要求自定义设置。 + +![][9] + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/bing-desktop-wallpaper-changer-linux-bing-photo-of-the-day/ + +作者:[2daygeek][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/2daygeek/ +[1]:https://github.com/UtkarshGpta/bing-desktop-wallpaper-changer +[2]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[3]:https://www.2daygeek.com/wp-content/uploads/2017/09/bing-wallpaper-changer-linux-5.png +[4]:https://github.com/neffo/bing-wallpaper-gnome-extension +[5]:https://extensions.gnome.org/extension/1262/bing-wallpaper-changer/ +[6]:https://www.2daygeek.com/wp-content/uploads/2017/09/bing-wallpaper-changer-for-linux-1.png +[7]:https://www.2daygeek.com/wp-content/uploads/2017/09/bing-wallpaper-changer-for-linux-2.png +[8]:https://www.2daygeek.com/wp-content/uploads/2017/09/bing-wallpaper-changer-for-linux-3.png +[9]:https://www.2daygeek.com/wp-content/uploads/2017/09/bing-wallpaper-changer-for-linux-4.png diff --git a/published/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md b/published/201802/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md similarity index 100% rename from published/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md rename to published/201802/20170928 How to Use the ZFS Filesystem on Ubuntu Linux.md diff --git a/published/20171005 Reasons Kubernetes is cool.md b/published/201802/20171005 Reasons Kubernetes is cool.md similarity index 100% rename from published/20171005 Reasons Kubernetes is cool.md rename to published/201802/20171005 Reasons Kubernetes is cool.md diff --git a/published/20171016 Using the Linux find command with caution.md b/published/201802/20171016 Using the Linux find command with caution.md similarity index 100% rename from published/20171016 Using the Linux find command with caution.md rename to published/201802/20171016 Using the Linux find command with caution.md diff --git a/published/20171019 More ways to examine network connections on Linux.md b/published/201802/20171019 More ways to examine network connections on Linux.md similarity index 100% rename from published/20171019 More ways to examine network connections on Linux.md rename to published/201802/20171019 More ways to examine network connections on Linux.md diff --git a/published/201802/20171023 Processors-Everything You Need to Know.md b/published/201802/20171023 Processors-Everything You Need to Know.md new file mode 100644 index 0000000000..a7bfa40156 --- /dev/null +++ b/published/201802/20171023 Processors-Everything You Need to Know.md @@ -0,0 +1,107 @@ +关于处理器你所需要知道的一切 +============ + +[![][b]][b] + +我们的手机、主机以及笔记本电脑这样的数字设备已经变得如此成熟,以至于它们进化成为我们的一部分,而不只是一种设备。 + +在应用和软件的帮助下,处理器执行许多任务。我们是否曾经想过是什么给了这些软件这样的能力?它们是如何执行它们的逻辑的?它们的大脑在哪? + +我们知道 CPU (或称处理器)是那些需要处理数据和执行逻辑任务的设备的大脑。 + +[![cpu image][1]][1] + +在处理器的深处有那些不一样的概念呢?它们是如何演化的?一些处理器是如何做到比其它处理器更快的?让我们来看看关于处理器的主要术语,以及它们是如何影响处速度的。 + +### 架构 + +处理器有不同的架构,你一定遇到过不同类型的程序说它们是 64 位或 32 位的,这其中的意思就是程序支持特定的处理器架构。 + +如果一颗处理器是 32 位的架构,这意味着这颗处理器能够在一个处理周期内处理一个 32 位的数据。 + +同理可得,64 位的处理器能够在一个周期内处理一个 64 位的数据。 + +同时,你可以使用的内存大小决定于处理器的架构,你可以使用的内存总量为 2 的处理器架构的幂次方(如:`2^64`)。 + +16 位架构的处理器,仅仅有 64 kb 的内存使用。32 位架构的处理器,最大可使用的 RAM 是 4 GB,64 位架构的处理器的可用内存是 16 EB。 + +### 核心 + +在电脑上,核心是基本的处理单元。核心接收指令并且执行它。越多的核心带来越快的速度。把核心比作工厂里的工人,越多的工人使工作能够越快的完成。另一方面,工人越多,你所付出的薪水也就越多,工厂也会越拥挤;相对于核心来说,越多的核心消耗更多的能量,比核心少的 CPU 更容易发热。 + +### 时钟速度 + +[![CPU CLOCK SPEED][2]][2] + +GHz 是 GigaHertz 的简写,Giga 意思是 10 亿次,Hertz (赫兹)意思是一秒有几个周期,2 GHz 的处理器意味着处理器一秒能够执行 20 亿个周期 。 + +它也以“频率”或者“时钟速度”而熟知。这项数值越高,CPU 的性能越好。 + +### CPU 缓存 + +CPU 缓存是处理器内部的一块小的存储单元,用来存储一些内存。不管如何,我们需要执行一些任务时,数据需要从内存传递到 CPU,CPU 的工作速度远快于内存,CPU 在大多数时间是在等待从内存传递过来的数据,而此时 CPU 是处于空闲状态的。为了解决这个问题,内存持续的向 CPU 缓存发送数据。 + +一般的处理器会有 2 ~ 3 Mb 的 CPU 缓存。高端的处理器会有 6 Mb 的 CPU 缓存,越大的缓存,意味着处理器更好。 + +### 印刷工艺 + +晶体管的大小就是处理器平板印刷的大小,尺寸通常是纳米,更小的尺寸意味者更紧凑。这可以让你有更多的核心,更小的面积,更小的能量消耗。 + +最新的 Intel 处理器有 14 nm 的印刷工艺。 + +### 热功耗设计(TDP) + +代表着平均功耗,单位是瓦特,是在全核心激活以基础频率来处理 Intel 定义的高复杂度的负载时,处理器所散失的功耗。 + +所以,越低的热功耗设计对你越好。一个低的热功耗设计不仅可以更好的利用能量,而且产生更少的热量。 + +[![battery][3]][3] + +桌面版的处理器通常消耗更多的能量,热功耗消耗的能量能在 40% 以上,相对应的移动版本只有不到桌面版本的 1/3。 + +### 内存支持 + +我们已经提到了处理器的架构是如何影响到我们能够使用的内存总量,但这只是理论上而已。在实际的应用中,我们所能够使用的内存的总量对于处理器的规格来说是足够的,它通常是由处理器规格详细规定的。 + +[![RAM][4]][4] + +它也指出了内存所支持的 DDR 的版本号。 + +### 超频 + +前面我们讲过时钟频率,超频是程序强迫 CPU 执行更多的周期。游戏玩家经常会使他们的处理器超频,以此来获得更好的性能。这样确实会增加速度,但也会增加消耗的能量,产生更多的热量。 + +一些高端的处理器允许超频,如果我们想让一个不支持超频的处理器超频,我们需要在主板上安装一个新的 BIOS 。 +这样通常会成功,但这种情况是不安全的,也是不建议的。 + +### 超线程(HT) + +如果不能添加核心以满足特定的处理需要,那么超线程是建立一个虚拟核心的方式。 + +如果一个双核处理器有超线程,那么这个双核处理器就有两个物理核心和两个虚拟核心,在技术上讲,一个双核处理器拥有四个核心。 + +### 结论 + +处理器有许多相关的数据,这些对数字设备来说是最重要的部分。我们在选择设备时,我们应该在脑海中仔细的检查处理器在上面提到的数据。 + +时钟速度、核心数、CPU 缓存,以及架构是最重要的数据。印刷尺寸以及热功耗设计重要性差一些 。 + +仍然有疑惑? 欢迎评论,我会尽快回复的。 + +-------------------------------------------------------------------------------- + +via: http://www.theitstuff.com/processors-everything-need-know + +作者:[Rishabh Kandari][a] +译者:[singledo](https://github.com/singledo) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.theitstuff.com/author/reevkandari +[b]:http://www.theitstuff.com/wp-content/uploads/2017/10/processors-all-you-need-to-know.jpg +[1]:http://www.theitstuff.com/wp-content/uploads/2017/10/download.jpg +[2]:http://www.theitstuff.com/wp-content/uploads/2017/10/download-1.jpg +[3]:http://www.theitstuff.com/wp-content/uploads/2017/10/download-2.jpg +[4]:http://www.theitstuff.com/wp-content/uploads/2017/10/images.jpg +[5]:http://www.theitstuff.com/wp-content/uploads/2017/10/processors-all-you-need-to-know.jpg diff --git a/published/20171027 Easy guide to secure VNC server with TLS encryption.md b/published/201802/20171027 Easy guide to secure VNC server with TLS encryption.md similarity index 100% rename from published/20171027 Easy guide to secure VNC server with TLS encryption.md rename to published/201802/20171027 Easy guide to secure VNC server with TLS encryption.md diff --git a/published/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md b/published/201802/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md similarity index 100% rename from published/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md rename to published/201802/20171030 How to bind ntpd to specific IP addresses on Linux-Unix.md diff --git a/published/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md b/published/201802/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md similarity index 100% rename from published/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md rename to published/201802/20171103 How To Fully Update And Upgrade Offline Debian-based Systems.md diff --git a/published/20171108 How To Setup Japanese Language Environment In Arch Linux.md b/published/201802/20171108 How To Setup Japanese Language Environment In Arch Linux.md similarity index 100% rename from published/20171108 How To Setup Japanese Language Environment In Arch Linux.md rename to published/201802/20171108 How To Setup Japanese Language Environment In Arch Linux.md diff --git a/published/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md b/published/201802/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md similarity index 100% rename from published/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md rename to published/201802/20171112 Step by Step guide for creating Master Slave replication in MariaDB.md diff --git a/published/20171117 How to Install and Use Docker on Linux.md b/published/201802/20171117 How to Install and Use Docker on Linux.md similarity index 100% rename from published/20171117 How to Install and Use Docker on Linux.md rename to published/201802/20171117 How to Install and Use Docker on Linux.md diff --git a/published/20171120 How to use special permissions- the setuid, setgid and sticky bits.md b/published/201802/20171120 How to use special permissions- the setuid, setgid and sticky bits.md similarity index 100% rename from published/20171120 How to use special permissions- the setuid, setgid and sticky bits.md rename to published/201802/20171120 How to use special permissions- the setuid, setgid and sticky bits.md diff --git a/published/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md b/published/201802/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md similarity index 100% rename from published/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md rename to published/201802/20171127 Protecting Your Website From Application Layer DOS Attacks With mod.md diff --git a/published/20171128 Why Python and Pygame are a great pair for beginning programmers.md b/published/201802/20171128 Why Python and Pygame are a great pair for beginning programmers.md similarity index 100% rename from published/20171128 Why Python and Pygame are a great pair for beginning programmers.md rename to published/201802/20171128 Why Python and Pygame are a great pair for beginning programmers.md diff --git a/published/20171202 MariaDB administration commands for beginners.md b/published/201802/20171202 MariaDB administration commands for beginners.md similarity index 100% rename from published/20171202 MariaDB administration commands for beginners.md rename to published/201802/20171202 MariaDB administration commands for beginners.md diff --git a/translated/tech/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md b/published/201802/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md similarity index 80% rename from translated/tech/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md rename to published/201802/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md index 127bb21066..cbb2dda3e1 100644 --- a/translated/tech/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md +++ b/published/201802/20171203 Increase Torrent Speed - Here Is Why It Will Never Work.md @@ -1,23 +1,22 @@ -Torrent 提速 - 为什么总是无济于事 +Torrent 提速为什么总是无济于事 ====== -![](http://www.theitstuff.com/wp-content/uploads/2017/11/increase-torrent-speed.jpg) +![](http://www.theitstuff.com/wp-content/uploads/2017/11/increase-torrent-speed.jpg) + 是不是总是想要 **更快的 torrent 速度**?不管现在的速度有多块,但总是无法对此满足。我们对 torrent 速度的痴迷使我们经常从包括 YouTube 视频在内的许多网站上寻找并应用各种所谓的技巧。但是相信我,从小到大我就没发现哪个技巧有用过。因此本文我们就就来看看,为什么尝试提高 torrent 速度是行不通的。 -## 影响速度的因素 +### 影响速度的因素 -### 本地因素 +#### 本地因素 -从下图中可以看到 3 台电脑分别对应的 A,B,C 三个用户。A 和 B 本地相连,而 C 的位置则比较远,它与本地之间有 1,2,3 三个连接点。 +从下图中可以看到 3 台电脑分别对应的 A、B、C 三个用户。A 和 B 本地相连,而 C 的位置则比较远,它与本地之间有 1、2、3 三个连接点。 [![][1]][2] 若用户 A 和用户 B 之间要分享文件,他们之间直接分享就能达到最大速度了而无需使用 torrent。这个速度跟互联网什么的都没有关系。 + 网线的性能 - + 网卡的性能 - + 路由器的性能 当谈到 torrent 的时候,人们都是在说一些很复杂的东西,但是却总是不得要点。 @@ -30,7 +29,7 @@ Torrent 提速 - 为什么总是无济于事 即使你把目标降到 30 Megabytes,然而你连接到路由器的电缆/网线的性能最多只有 100 megabits 也就是 10 MegaBytes。这是一个纯粹的瓶颈问题,由一个薄弱的环节影响到了其他强健部分,也就是说这个传输速率只能达到 10 Megabytes,即电缆的极限速度。现在想象有一个 torrent 即使能够用最大速度进行下载,那也会由于你的硬件不够强大而导致瓶颈。 -### 外部因素 +#### 外部因素 现在再来看一下这幅图。用户 C 在很遥远的某个地方。甚至可能在另一个国家。 @@ -40,24 +39,23 @@ Torrent 提速 - 为什么总是无济于事 第二,由于 C 与本地之间多个有连接点,其中一个点就有可能成为瓶颈所在,可能由于繁重的流量和相对薄弱的硬件导致了缓慢的速度。 -### Seeders( 译者注:做种者) 与 Leechers( 译者注:只下载不做种的人) +#### 做种者与吸血者 -关于此已经有了太多的讨论,总的想法就是搜索更多的种子,但要注意上面的那些因素,一个很好的种子提供者但是跟我之间的连接不好的话那也是无济于事的。通常,这不可能发生,因为我们也不是唯一下载这个资源的人,一般都会有一些在本地的人已经下载好了这个文件并已经在做种了。 +关于此已经有了太多的讨论,总的想法就是搜索更多的种子,但要注意上面的那些因素,有一个很好的种子提供者,但是跟我之间的连接不好的话那也是无济于事的。通常,这不可能发生,因为我们也不是唯一下载这个资源的人,一般都会有一些在本地的人已经下载好了这个文件并已经在做种了。 -## 结论 +### 结论 我们尝试搞清楚哪些因素影响了 torrent 速度的好坏。不管我们如何用软件进行优化,大多数时候是这是由于物理瓶颈导致的。我从来不关心那些软件,使用默认配置对我来说就够了。 希望你会喜欢这篇文章,有什么想法敬请留言。 - -------------------------------------------------------------------------------- via: http://www.theitstuff.com/increase-torrent-speed-will-never-work 作者:[Rishabh Kandari][a] 译者:[lujun9972](https://github.com/lujun9972) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171204 Tutorial on how to write basic udev rules in Linux.md b/published/201802/20171204 Tutorial on how to write basic udev rules in Linux.md similarity index 100% rename from published/20171204 Tutorial on how to write basic udev rules in Linux.md rename to published/201802/20171204 Tutorial on how to write basic udev rules in Linux.md diff --git a/published/201802/20171208 Sessions And Cookies - How Does User-Login Work.md b/published/201802/20171208 Sessions And Cookies - How Does User-Login Work.md new file mode 100644 index 0000000000..e034b55a67 --- /dev/null +++ b/published/201802/20171208 Sessions And Cookies - How Does User-Login Work.md @@ -0,0 +1,73 @@ +会话与 Cookie:用户登录的原理是什么? +====== + +Facebook、 Gmail、 Twitter 是我们每天都会用的网站(LCTT 译注:才不是呢)。它们的共同点在于都需要你登录进去后才能做进一步的操作。只有你通过认证并登录后才能在 twitter 发推,在 Facebook 上评论,以及在 Gmail上处理电子邮件。 + +[![gmail, facebook login page](http://www.theitstuff.com/wp-content/uploads/2017/10/Untitled-design-1.jpg)][1] + +那么登录的原理是什么?网站是如何认证的?它怎么知道是哪个用户从哪儿登录进来的?下面我们来对这些问题进行一一解答。 + +### 用户登录的原理是什么? + +每次你在网站的登录页面中输入用户名和密码时,这些信息都会发送到服务器。服务器随后会将你的密码与服务器中的密码进行验证。如果两者不匹配,则你会得到一个错误密码的提示。如果两者匹配,则成功登录。 + +### 登录时发生了什么? + +登录后,web 服务器会初始化一个会话session并在你的浏览器中设置一个 cookie 变量。该 cookie 变量用于作为新建会话的一个引用。搞晕了?让我们说的再简单一点。 + +### 会话的原理是什么? + +服务器在用户名和密码都正确的情况下会初始化一个会话。会话的定义很复杂,你可以把它理解为“关系的开始”。 + +[![session beginning of a relationship or partnership](http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-9.png)][2] + +认证通过后,服务器就开始跟你展开一段关系了。由于服务器不能象我们人类一样看东西,它会在我们的浏览器中设置一个 cookie 来将我们的关系从其他人与服务器的关系标识出来。 + +### 什么是 Cookie? + +cookie 是网站在你的浏览器中存储的一小段数据。你应该已经见过他们了。 + +[![theitstuff official facebook page cookies](http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-1-4.png)][3] + +当你登录后,服务器为你创建一段关系或者说一个会话,然后将唯一标识这个会话的会话 id 以 cookie 的形式存储在你的浏览器中。 + +### 什么意思? + +所有这些东西存在的原因在于识别出你来,这样当你写评论或者发推时,服务器能知道是谁在发评论,是谁在发推。 + +当你登录后,会产生一个包含会话 id 的 cookie。这样,这个会话 id 就被赋予了那个输入正确用户名和密码的人了。 + +[![facebook cookies in web browser](http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-2-3-e1508926255472.png)][4] + +也就是说,会话 id 被赋予给了拥有这个账户的人了。之后,所有在网站上产生的行为,服务器都能通过他们的会话 id 来判断是由谁发起的。 + +### 如何让我保持登录状态? + +会话有一定的时间限制。这一点与现实生活中不一样,现实生活中的关系可以在不见面的情况下持续很长一段时间,而会话具有时间限制。你必须要不断地通过一些动作来告诉服务器你还在线。否则的话,服务器会关掉这个会话,而你会被登出。 + +[![websites keep me logged in option](http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-3-3-e1508926314117.png)][5] + +不过在某些网站上可以启用“保持登录”功能,这样服务器会将另一个唯一变量以 cookie 的形式保存到我们的浏览器中。这个唯一变量会通过与服务器上的变量进行对比来实现自动登录。若有人盗取了这个唯一标识(我们称之为 cookie stealing),他们就能访问你的账户了。 + +### 结论 + +我们讨论了登录系统的工作原理以及网站是如何进行认证的。我们还学到了什么是会话和 cookies,以及它们在登录机制中的作用。 + +我们希望你们以及理解了用户登录的工作原理,如有疑问,欢迎提问。 + +-------------------------------------------------------------------------------- + +via: http://www.theitstuff.com/sessions-cookies-user-login-work + +作者:[Rishabh Kandari][a] +译者:[lujun9972](https://github.com/lujun9972) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.theitstuff.com/author/reevkandari +[1]:http://www.theitstuff.com/wp-content/uploads/2017/10/Untitled-design-1.jpg +[2]:http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-9.png +[3]:http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-1-4.png +[4]:http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-2-3-e1508926255472.png +[5]:http://www.theitstuff.com/wp-content/uploads/2017/10/pasted-image-0-3-3-e1508926314117.png diff --git a/published/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md b/published/201802/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md similarity index 100% rename from published/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md rename to published/201802/20171210 The Best Linux Laptop 2017-2018- A Buyers Guide with Picks from an RHCE.md diff --git a/published/201802/20171211 A tour of containerd 1.0.md b/published/201802/20171211 A tour of containerd 1.0.md new file mode 100644 index 0000000000..56741f9dc7 --- /dev/null +++ b/published/201802/20171211 A tour of containerd 1.0.md @@ -0,0 +1,50 @@ +containerd 1.0 探索之旅 +====== + +我们在过去的文章中讨论了一些 containerd 的不同特性,它是如何设计的,以及随着时间推移已经修复的一些问题。containerd 被用于 Docker、Kubernetes CRI、以及一些其它的项目,在这些平台中事实上都使用了 containerd,而许多人并不知道 containerd 存在于这些平台之中,这篇文章就是为这些人所写的。我将来会写更多的关于 containerd 的设计以及特性集方面的文章,但是现在,让我们从它的基础知识开始。 + +![containerd][1] + +我认为容器生态系统有时候可能很复杂。尤其是我们所使用的术语。它是什么?一个运行时,还是别的?一个运行时 … containerd(它的发音是 “container-dee”)正如它的名字,它是一个容器守护进程,而不是一些人忽悠我的“收集containnerd”。它最初是作为 OCI 运行时(就像 runc 一样)的集成点而构建的,在过去的六个月中它增加了许多特性,使其达到了像 Docker 这样的现代容器平台以及像 Kubernetes 这样的编排平台的需求。 + +那么,你使用 containerd 能去做些什么呢?你可以拥有推送或拉取功能以及镜像管理。可以拥有容器生命周期 API 去创建、运行、以及管理容器和它们的任务。一个完整的专门用于快照管理的 API,以及一个其所依赖的开放治理的项目。如果你需要去构建一个容器平台,基本上你不需要去处理任何底层操作系统细节方面的事情。我认为关于 containerd 中最重要的部分是,它有一个版本化的并且有 bug 修复和安全补丁的稳定 API。 + +![containerd][2] + +由于在内核中没有一个 Linux 容器这样的东西,因此容器是多种内核特性捆绑在一起而成的,当你构建一个大型平台或者分布式系统时,你需要在你的管理代码和系统调用之间构建一个抽象层,然后将这些特性捆绑粘接在一起去运行一个容器。而这个抽象层就是 containerd 的所在之处。它为稳定类型的平台层提供了一个客户端,这样平台可以构建在顶部而无需进入到内核级。因此,可以让使用容器、任务、和快照类型的工作相比通过管理调用去 clone() 或者 mount() 要友好的多。与灵活性相平衡,直接与运行时或者宿主机交互,这些对象避免了常规的高级抽象所带来的性能牺牲。结果是简单的任务很容易完成,而困难的任务也变得更有可能完成。 + +![containerd][3] + +containerd 被设计用于 Docker 和 Kubernetes、以及想去抽象出系统调用或者在 Linux、Windows、Solaris 以及其它的操作系统上特定的功能去运行容器的其它容器系统。考虑到这些用户的想法,我们希望确保 containerd 只拥有它们所需要的东西,而没有它们不希望的东西。事实上这是不太可能的,但是至少我们想去尝试一下。虽然网络不在 containerd 的范围之内,它并不能做成让高级系统可以完全控制的东西。原因是,当你构建一个分布式系统时,网络是非常中心的地方。现在,对于 SDN 和服务发现,相比于在 Linux 上抽象出 netlink 调用,网络是更特殊的平台。大多数新的网络都是基于路由的,并且每次一个新的容器被创建或者删除时,都会请求更新路由表。服务发现、DNS 等等都需要及时被通知到这些改变。如果在 containerd 中添加对网络的管理,为了能够支持不同的网络接口、钩子、以及集成点,将会在 containerd 中增加很大的一块代码。而我们的选择是,在 containerd 中做一个健壮的事件系统,以便于多个消费者可以去订阅它们所关心的事件。我们也公开发布了一个 [任务 API][4],它可以让用户去创建一个运行任务,也可以在一个容器的网络命名空间中添加一个接口,以及在一个容器的生命周期中的任何时候,无需复杂的钩子来启用容器的进程。 + +在过去的几个月中另一个添加到 containerd 中的领域是完整的存储,以及支持 OCI 和 Docker 镜像格式的分布式系统。有了一个跨 containerd API 的完整的目录地址存储系统,它不仅适用于镜像,也适用于元数据、检查点、以及附加到容器的任何数据。 + +我们也花时间去 [重新考虑如何使用 “图驱动” 工作][5]。这些是叠加的或者允许镜像分层的块级文件系统,可以使你执行的构建更加高效。当我们添加对 devicemapper 的支持时,图驱动graphdrivers最初是由 Solomon 和我写的。Docker 在那个时候仅支持 AUFS,因此我们在叠加文件系统之后,对图驱动进行了建模。但是,做一个像 devicemapper/lvm 这样的块级文件系统,就如同一个堆叠文件系统一样,从长远来看是非常困难的。这些接口必须基于时间的推移进行扩展,以支持我们最初认为并不需要的那些不同的特性。对于 containerd,我们使用了一个不同的方法,像快照一样做一个堆叠文件系统而不是相反。这样做起来更容易,因为堆叠文件系统比起像 BTRFS、ZFS 以及 devicemapper 这样的快照文件系统提供了更好的灵活性。因为这些文件系统没有严格的父/子关系。这有助于我们去构建出 [快照的一个小型接口][6],同时还能满足 [构建者][7] 的要求,还能减少了需要的代码数量,从长远来看这样更易于维护。 + +![][8] + +你可以在 [Stephen Day 2017/12/7 在 KubeCon SIG Node 上的演讲][9]找到更多关于 containerd 的架构方面的详细资料。 + +除了在 1.0 代码库中的技术和设计上的更改之外,我们也将 [containerd 管理模式从长期 BDFL 模式转换为技术委员会][10],为社区提供一个独立的可信任的第三方资源。 + +-------------------------------------------------------------------------------- + +via: https://blog.docker.com/2017/12/containerd-ga-features-2/ + +作者:[Michael Crosby][a] +译者:[qhwdw](https://github.com/qhwdw) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://blog.docker.com/author/michael/ +[1]:https://i0.wp.com/blog.docker.com/wp-content/uploads/950cf948-7c08-4df6-afd9-cc9bc417cabe-6.jpg?resize=400%2C120&amp;ssl=1 +[2]:https://i1.wp.com/blog.docker.com/wp-content/uploads/4a7666e4-ebdb-4a40-b61a-26ac7c3f663e-4.jpg?resize=906%2C470&amp;ssl=1 "containerd" +[3]:https://i1.wp.com/blog.docker.com/wp-content/uploads/2a73a4d8-cd40-4187-851f-6104ae3c12ba-1.jpg?resize=1140%2C680&amp;ssl=1 +[4]:https://github.com/containerd/containerd/blob/master/api/services/tasks/v1/tasks.proto +[5]:https://blog.mobyproject.org/where-are-containerds-graph-drivers-145fc9b7255 +[6]:https://github.com/containerd/containerd/blob/master/api/services/snapshots/v1/snapshots.proto +[7]:https://blog.mobyproject.org/introducing-buildkit-17e056cc5317 +[8]:https://i1.wp.com/blog.docker.com/wp-content/uploads/d0fb5eb9-c561-415d-8d57-e74442a879a2-1.jpg?resize=1140%2C556&amp;ssl=1 +[9]:https://speakerdeck.com/stevvooe/whats-happening-with-containerd-and-the-cri +[10]:https://github.com/containerd/containerd/pull/1748 diff --git a/published/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md b/published/201802/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md similarity index 100% rename from published/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md rename to published/201802/20171212 How To Count The Number Of Files And Folders-Directories In Linux.md diff --git a/published/201802/20171214 How to install and use encryptpad on ubuntu 16.04.md b/published/201802/20171214 How to install and use encryptpad on ubuntu 16.04.md new file mode 100644 index 0000000000..baf29e563b --- /dev/null +++ b/published/201802/20171214 How to install and use encryptpad on ubuntu 16.04.md @@ -0,0 +1,125 @@ +如何在 Ubuntu 16.04 上安装和使用 Encryptpad +============== + +EncryptPad 是一个自由开源软件,它通过简单方便的图形界面和命令行接口来查看和修改加密的文本,它使用 OpenPGP RFC 4880 文件格式。通过 EncryptPad,你可以很容易的加密或者解密文件。你能够像保存密码、信用卡信息等私人信息,并使用密码或者密钥文件来访问。 + +### 特性 + +- 支持 windows、Linux 和 Max OS。 +- 可定制的密码生成器,可生成健壮的密码。 +- 随机的密钥文件和密码生成器。 +- 支持 GPG 和 EPD 文件格式。 +- 能够通过 CURL 自动从远程远程仓库下载密钥。 +- 密钥文件的路径能够存储在加密的文件中。如果这样做的话,你不需要每次打开文件都指定密钥文件。 +- 提供只读模式来防止文件被修改。 +- 可加密二进制文件,例如图片、视频、归档等。 + + +在这份教程中,我们将学习如何在 Ubuntu 16.04 中安装和使用 EncryptPad。 + +### 环境要求 + +- 在系统上安装了 Ubuntu 16.04 桌面版本。 +- 在系统上有 `sudo` 的权限的普通用户。 + +### 安装 EncryptPad + +在默认情况下,EncryPad 在 Ubuntu 16.04 的默认仓库是不存在的。你需要安装一个额外的仓库。你能够通过下面的命令来添加它 : + +``` +sudo apt-add-repository ppa:nilaimogard/webupd8 +``` + +下一步,用下面的命令来更新仓库: + +``` +sudo apt-get update -y +``` + +最后一步,通过下面命令安装 EncryptPad: + +``` +sudo apt-get install encryptpad encryptcli -y +``` + +当 EncryptPad 安装完成后,你可以在 Ubuntu 的 Dash 上找到它。 + +### 使用 EncryptPad 生成密钥和密码 + +现在,在 Ubunntu Dash 上输入 `encryptpad`,你能够在你的屏幕上看到下面的图片 : + +[![Ubuntu DeskTop][1]][2] + +下一步,点击 EncryptPad 的图标。你能够看到 EncryptPad 的界面,它是一个简单的文本编辑器,带有顶部菜单栏。 + +[![EncryptPad screen][3]][4] + +首先,你需要生成一个密钥文件和密码用于加密/解密任务。点击顶部菜单栏中的 “Encryption->Generate Key”,你会看见下面的界面: + +[![Generate key][5]][6] + +选择文件保存的路径,点击 “OK” 按钮,你将看到下面的界面: + +[![select path][7]][8] + +输入密钥文件的密码,点击 “OK” 按钮 ,你将看到下面的界面: + +[![last step][9]][10] + +点击 “yes” 按钮来完成该过程。 + +### 加密和解密文件 + +现在,密钥文件和密码都已经生成了。可以执行加密和解密操作了。在这个文件编辑器中打开一个文件文件,点击 “encryption” 图标 ,你会看见下面的界面: + +[![Encry operation][11]][12] + +提供需要加密的文件和指定输出的文件,提供密码和前面产生的密钥文件。点击 “Start” 按钮来开始加密的进程。当文件被成功的加密,会出现下面的界面: + +[![Success Encrypt][13]][14] + +文件已经被该密码和密钥文件加密了。 + +如果你想解密被加密后的文件,打开 EncryptPad ,点击 “File Encryption” ,选择 “Decryption” 操作,提供加密文件的位置和你要保存输出的解密文件的位置,然后提供密钥文件地址,点击 “Start” 按钮,它将要求你输入密码,输入你先前加密使用的密码,点击 “OK” 按钮开始解密过程。当该过程成功完成,你会看到 “File has been decrypted successfully” 的消息 。 + + +[![decrypt ][16]][17] +[![][18]][18] +[![][13]] + + +**注意:** + +如果你遗忘了你的密码或者丢失了密钥文件,就没有其他的方法可以打开你的加密信息了。对于 EncrypePad 所支持的格式是没有后门的。 + +-------------------------------------------------------------------------------- +via: https://www.howtoforge.com/tutorial/how-to-install-and-use-encryptpad-on-ubuntu-1604/ + +作者:[Hitesh Jethva][a] +译者:[singledo](https://github.com/singledo) +校对:[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/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-dash.png +[2]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-dash.png +[3]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-dashboard.png +[4]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-dashboard.png +[5]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-generate-key.png +[6]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-generate-key.png +[7]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-generate-passphrase.png +[8]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-generate-passphrase.png +[9]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-use-key-file.png +[10]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-use-key-file.png +[11]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-start-encryption.png +[12]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-start-encryption.png +[13]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-file-encrypted-successfully.png +[14]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-file-encrypted-successfully.png +[15]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-decryption-page.png +[16]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-decryption-page.png +[17]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-decryption-passphrase.png +[18]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-decryption-passphrase.png +[19]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/Screenshot-of-encryptpad-decryption-successfully.png +[20]:https://www.howtoforge.com/images/how_to_install_and_use_encryptpad_on_ubuntu_1604/big/Screenshot-of-encryptpad-decryption-successfully.png \ No newline at end of file diff --git a/published/20171215 Linux Vs Unix.md b/published/201802/20171215 Linux Vs Unix.md similarity index 100% rename from published/20171215 Linux Vs Unix.md rename to published/201802/20171215 Linux Vs Unix.md diff --git a/published/20171218 Internet Chemotherapy.md b/published/201802/20171218 Internet Chemotherapy.md similarity index 100% rename from published/20171218 Internet Chemotherapy.md rename to published/201802/20171218 Internet Chemotherapy.md diff --git a/published/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md b/published/201802/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md similarity index 100% rename from published/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md rename to published/201802/20171219 4 Easiest Ways To Find Out Process ID (PID) In Linux.md diff --git a/translated/tech/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md b/published/201802/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md similarity index 77% rename from translated/tech/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md rename to published/201802/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md index bc5ed80216..47aa34ecf4 100644 --- a/translated/tech/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md +++ b/published/201802/20171226 Dockerizing Compiled Software - Tianon-s Ramblings .md @@ -1,11 +1,11 @@ -Docker 化编译的软件 ┈ Tianon's Ramblings ✿ +如何 Docker 化编译的软件 ====== -我最近在 [docker-library/php][1] 仓库中关闭了大量问题,最老的(并且是最长的)讨论之一是关于安装编译扩展的依赖关系,我写了一个[中篇评论][2]解释了我如何用通常的方式为我想要的软件 Docker 化的。 -I'm going to copy most of that comment here and perhaps expand a little bit more in order to have a better/cleaner place to link to! -我要在这复制大部分的评论,或许扩展一点点,以便有一个更好的/更干净的链接! +我最近在 [docker-library/php][1] 仓库中关闭了大量问题,最老的(并且是最长的)讨论之一是关于安装编译扩展的依赖关系,我写了一个[中等篇幅的评论][2]解释了我如何用常规的方式为我想要的软件进行 Docker 化的。 -我第一步是编写 `Dockerfile` 的原始版本:下载源码,运行 `./configure && make` 等,清理。然后我尝试构建我的原始版本,并希望在这过程中看到错误消息。(对真的!) +我要在这里复制大部分的评论内容,或许扩展一点点,以便有一个更好的/更干净的链接! + +我第一步是编写 `Dockerfile` 的原始版本:下载源码,运行 `./configure && make` 等,清理。然后我尝试构建我的原始版本,并希望在这过程中看到错误消息。(对,真的!) 错误信息通常以 `error: could not find "xyz.h"` 或 `error: libxyz development headers not found` 的形式出现。 @@ -13,9 +13,9 @@ I'm going to copy most of that comment here and perhaps expand a little bit more 如果我在 Alpine 中构建,我将使用 进行类似的搜索。 -“libxyz development headers” 在某种程度上也是一样的,但是根据我的经验,对于这些 Google 对开发者来说效果更好,因为不同的发行版和项目会以不同的名字来调用这些开发包,所以有时候更难确切的知道哪一个是“正确”的。 +“libxyz development headers” 在某种程度上也是一样的,但是根据我的经验,对于这些用 Google 对开发者来说效果更好,因为不同的发行版和项目会以不同的名字来调用这些开发包,所以有时候更难确切的知道哪一个是“正确”的。 -当我得到包名后,我将这个包名称添加到我的 `Dockerfile` 中,清理之后,然后重复操作。最终通常会构建成功。偶尔我发现某些库不在 Debian 或 Alpine 中,或者是不够新的,由此我必须从源码构建它,但这些情况在我的经验中很少见 - 因人而异。 +当我得到包名后,我将这个包名称添加到我的 `Dockerfile` 中,清理之后,然后重复操作。最终通常会构建成功。偶尔我发现某些库不在 Debian 或 Alpine 中,或者是不够新的,由此我必须从源码构建它,但这些情况在我的经验中很少见 —— 因人而异。 我还会经常查看 Debian(通过 )或 Alpine(通过 )我要编译的软件包源码,特别关注 `Build-Depends`(如 [`php7.0=7.0.26-1` 的 `debian/control` 文件][3])以及/或者 `makedepends` (如 [`php7` 的 `APKBUILD` 文件][4])用于包名线索。 @@ -31,7 +31,7 @@ via: https://tianon.github.io/post/2017/12/26/dockerize-compiled-software.html 作者:[Tianon Gravi][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20171228 Dual Boot Ubuntu And Arch Linux.md b/published/201802/20171228 Dual Boot Ubuntu And Arch Linux.md similarity index 100% rename from published/20171228 Dual Boot Ubuntu And Arch Linux.md rename to published/201802/20171228 Dual Boot Ubuntu And Arch Linux.md diff --git a/published/20171228 Linux wc Command Explained for Beginners (6 Examples).md b/published/201802/20171228 Linux wc Command Explained for Beginners (6 Examples).md similarity index 100% rename from published/20171228 Linux wc Command Explained for Beginners (6 Examples).md rename to published/201802/20171228 Linux wc Command Explained for Beginners (6 Examples).md diff --git a/published/20171230 What Is A Web Crawler- How Web Crawlers work.md b/published/201802/20171230 What Is A Web Crawler- How Web Crawlers work.md similarity index 100% rename from published/20171230 What Is A Web Crawler- How Web Crawlers work.md rename to published/201802/20171230 What Is A Web Crawler- How Web Crawlers work.md diff --git a/published/201802/20171231 Making Vim Even More Awesome With These Cool Features.md b/published/201802/20171231 Making Vim Even More Awesome With These Cool Features.md new file mode 100644 index 0000000000..34a435d964 --- /dev/null +++ b/published/201802/20171231 Making Vim Even More Awesome With These Cool Features.md @@ -0,0 +1,108 @@ +用一些超酷的功能使 Vim 变得更强大 +====== + +![](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/making-vim-even-more-awesome-with-these-cool-features_orig.jpg) + +Vim 是每个 Linux 发行版]中不可或缺的一部分,也是 Linux 用户最常用的工具(当然是基于终端的)。至少,这个说法对我来说是成立的。人们可能会在利用什么工具进行程序设计更好方面产生争议,的确 Vim 可能不是一个好的选择,因为有很多不同的 IDE 或其它类似于 Sublime Text 3,Atom 等使程序设计变得更加容易的成熟的文本编辑器。 + +### 我的感想 + +但我认为,Vim 应该从一开始就以我们想要的方式运作,而其它编辑器让我们按照已经设计好的方式工作,实际上不是我们想要的工作方式。我不会过多地谈论其它编辑器,因为我没有过多地使用过它们(我对 Vim 情有独钟)。 + +不管怎样,让我们用 Vim 来做一些事情吧,它完全可以胜任。 + +### 利用 Vim 进行程序设计 + +#### 执行代码 + + +考虑一个场景,当我们使用 Vim 设计 C++ 代码并需要编译和运行它时,该怎么做呢。 + +(a). 我们通过 `Ctrl + Z` 返回到终端,或者利用 `:wq` 保存并退出。 + +(b). 但是任务还没有结束,接下来需要在终端上输入类似于 `g++ fileName.cxx` 的命令进行编译。 + +(c). 接下来需要键入 `./a.out` 执行它。 + +为了让我们的 C++ 代码在 shell 中运行,需要做很多事情。但这似乎并不是利用 Vim 操作的方法( Vim 总是倾向于把几乎所有操作方法利用一两个按键实现)。那么,做这些事情的 Vim 的方式究竟是什么? + +#### Vim 方式 + +Vim 不仅仅是一个文本编辑器,它是一种编辑文本的编程语言。这种帮助我们扩展 Vim 功能的编程语言是 “VimScript”(LCTT 译注: Vim 脚本)。 + +因此,在 VimScript 的帮助下,我们可以只需一个按键轻松地将编译和运行代码的任务自动化。 + + [![create functions in vim .vimrc](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_orig.png)][2] + +以上是在我的 `.vimrc` 配置文件里创建的一个名为 `CPP()` 函数的片段。 + +#### 利用 VimScript 创建函数 + +在 VimScript 中创建函数的语法非常简单。它以关键字 `func` 开头,然后是函数名(在 VimScript 中函数名必须以大写字母开头,否则 Vim 将提示错误)。在函数的结尾用关键词 `endfunc`。 + +在函数的主体中,可以看到 `exec` 语句,无论您在 `exec` 关键字之后写什么,都会在 Vim 的命令模式上执行(记住,就是在 Vim 窗口的底部以 `:` 开始的命令)。现在,传递给 `exec` 的字符串是(LCTT 译注:`:!clear && g++ % && ./a.out`) - + +[![vim functions commands & symbols](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_1_orig.png)][3] + + +当这个函数被调用时,它首先清除终端屏幕,因此只能看到输出,接着利用 `g++` 执行正在处理的文件,然后运行由前一步编译而形成的 `a.out` 文件。 + +#### 将 `Ctrl+r` 映射为运行 C++ 代码。 + +我将语句 `call CPP()` 映射到键组合 `Ctrl+r`,以便我现在可以按 `Ctrl+r` 来执行我的 C++ 代码,无需手动输入`:call CPP()` ,然后按回车键。 + +#### 最终结果 + +我们终于找到了 Vim 方式的操作方法。现在,你只需按一个(组合)键,你编写的 C++ 代码就输出在你的屏幕上,你不需要键入所有冗长的命令了。这也节省了你的时间。 + +我们也可以为其他语言实现这类功能。 + + [![create function in vim for python](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_2_orig.png)][4] + +对于Python:您可以按下 `Ctrl+e` 解释执行您的代码。 + + [![create function in vim for java](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_3_orig.png)][5] + + +对于Java:您现在可以按下 `Ctrl+j`,它将首先编译您的 Java 代码,然后执行您的 Java 类文件并显示输出。 + +### 进一步提高 + +所以,这就是如何在 Vim 中操作的方法。现在,我们来看看如何在 Vim 中实现所有这些。我们可以直接在 Vim 中使用这些代码片段,而另一种方法是使用 Vim 中的自动命令 `autocmd`。`autocmd` 的优点是这些命令无需用户调用,它们在用户所提供的任何特定条件下自动执行。 + +我想用 `autocmd` 实现这个,而不是对每种语言使用不同的映射,执行不同程序设计语言编译出的代码。 + + [![autocmd in vimrc](http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_4_orig.png)][6] + +在这里做的是,为所有的定义了执行相应文件类型代码的函数编写了自动命令。 + +会发生什么?当我打开任何上述提到的文件类型的缓冲区, Vim 会自动将 `Ctrl + r` 映射到函数调用,而 `` 表示回车键,这样就不需要每完成一个独立的任务就按一次回车键了。 + +为了实现这个功能,您只需将函数片段添加到 `.vimrc` 文件中,然后将所有这些 `autocmd` 也一并添加进去。这样,当您下一次打开 Vim 时,Vim 将拥有所有相应的功能来执行所有具有相同绑定键的代码。 + +### 总结 + +就这些了。希望这些能让你更爱 Vim 。我目前正在探究 Vim 中的一些内容,正阅读文档,补充 `.vimrc` 文件,当我研究出一些成果后我会再次与你分享。 + +如果你想看一下我现在的 `.vimrc` 文件,这是我的 Github 账户的链接: [MyVimrc][7]。 + +期待你的好评。 + +-------------------------------------------------------------------------------- + +via: http://www.linuxandubuntu.com/home/making-vim-even-more-awesome-with-these-cool-features + +作者:[LINUXANDUBUNTU][a] +译者:[stevenzdg988](https://github.com/stevenzdg988) +校对:[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/home/category/distros +[2]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_orig.png +[3]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_1_orig.png +[4]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_2_orig.png +[5]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_3_orig.png +[6]:http://www.linuxandubuntu.com/uploads/2/1/1/5/21152474/vim_4_orig.png +[7]:https://github.com/phenomenal-ab/VIm-Configurations/blob/master/.vimrc diff --git a/translated/tech/20171231 Why You Should Still Love Telnet.md b/published/201802/20171231 Why You Should Still Love Telnet.md similarity index 72% rename from translated/tech/20171231 Why You Should Still Love Telnet.md rename to published/201802/20171231 Why You Should Still Love Telnet.md index c08fe6a7eb..0a5b3d604b 100644 --- a/translated/tech/20171231 Why You Should Still Love Telnet.md +++ b/published/201802/20171231 Why You Should Still Love Telnet.md @@ -1,40 +1,41 @@ Telnet,爱一直在 ====== -Telnet, 是系统管理员登录远程服务器的协议和工具。然而,由于所有的通信都没有加密,包括密码,都是明文发送的。Telnet 在 SSH 被开发出来之后就基本弃用了。 + +Telnet,是系统管理员登录远程服务器的一种协议和工具。然而,由于所有的通信都没有加密,包括密码,都是明文发送的。Telnet 在 SSH 被开发出来之后就基本弃用了。 登录远程服务器,你可能不会也从未考虑过它。但这并不意味着 `telnet` 命令在调试远程连接问题时不是一个实用的工具。 -本教程中,我们将探索使用 `telnet` 解决所有常见问题,“我怎么又连不上啦?” +本教程中,我们将探索使用 `telnet` 解决所有常见问题:“我怎么又连不上啦?” -这种讨厌的问题通常会在安装了像web服务器、邮件服务器、ssh服务器、Samba服务器等诸如此类的事之后遇到,用户无法连接服务器。 +这种讨厌的问题通常会在安装了像 Web服务器、邮件服务器、ssh 服务器、Samba 服务器等诸如此类的事之后遇到,用户无法连接服务器。 `telnet` 不会解决问题但可以很快缩小问题的范围。 `telnet` 用来调试网络问题的简单命令和语法: + ``` telnet - ``` -因为 `telnet` 最初通过端口建立连接不会发送任何数据,适用于任何协议包括加密协议。 +因为 `telnet` 最初通过端口建立连接不会发送任何数据,适用于任何协议,包括加密协议。 -连接问题服务器有四个可能会遇到的主要问题。我们会研究这四个问题,研究他们意味着什么以及如何解决。 +连接问题服务器有四个可能会遇到的主要问题。我们会研究这四个问题,研究它们意味着什么以及如何解决。 本教程默认已经在 `samba.example.com` 安装了 [Samba][1] 服务器而且本地客户无法连上服务器。 ### Error 1 - 连接挂起 首先,我们需要试着用 `telnet` 连接 Samba 服务器。使用下列命令 (Samba 监听端口445): + ``` telnet samba.example.com 445 - ``` 有时连接会莫名停止: + ``` telnet samba.example.com 445 Trying 172.31.25.31... - ``` 这意味着 `telnet` 没有收到任何回应来建立连接。有两个可能的原因: @@ -43,10 +44,10 @@ Trying 172.31.25.31... 2. 防火墙拦截了你的请求。 +为了排除第 1 点,对服务器上进行一个快速 [`mtr samba.example.com`][2] 。如果服务器是可达的,那么便是防火墙(注意:防火墙总是存在的)。 -为了排除 **1.** 在服务器上运行一个快速 [`mtr samba.example.com`][2] 。如果服务器是可达的那么便是防火墙(注意:防火墙总是存在的)。 +首先用 `iptables -L -v -n` 命令检查服务器本身有没有防火墙,没有的话你能看到以下内容: -首先用 `iptables -L -v -n` 命令检查服务器本身有没有防火墙, 没有的话你能看到以下内容: ``` iptables -L -v -n Chain INPUT (policy ACCEPT 0 packets, 0 bytes) @@ -57,41 +58,38 @@ Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination - ``` 如果你看到其他东西那可能就是问题所在了。为了检验,停止 `iptables` 一下并再次运行 `telnet samba.example.com 445` 看看你是否能连接。如果你还是不能连接看看你的提供商或企业有没有防火墙拦截你。 ### Error 2 - DNS 问题 -DNS问题通常发生在你正使用的主机名没有解析到 IP 地址。错误如下: +DNS 问题通常发生在你正使用的主机名没有解析到 IP 地址。错误如下: + ``` telnet samba.example.com 445 Server lookup failure: samba.example.com:445, Name or service not known - ``` -第一步是把主机名替换成服务器的IP地址。如果你可以连上那么就是主机名的问题。 +第一步是把主机名替换成服务器的 IP 地址。如果你可以连上那么就是主机名的问题。 有很多发生的原因(以下是我见过的): - 1. 域注册了吗?用 `whois` 来检验。 - 2. 域过期了吗?用 `whois` 来检验。 + 1. 域名注册了吗?用 `whois` 来检验。 + 2. 域名过期了吗?用 `whois` 来检验。 3. 是否使用正确的主机名?用 `dig` 或 `host` 来确保你使用的主机名解析到正确的 IP。 4. 你的 **A** 记录正确吗?确保你没有偶然创建类似 `smaba.example.com` 的 **A** 记录。 - - -一定要多检查几次拼写和主机名是否正确(是 `samba.example.com` 还是 `samba1.example.com`)这些经常会困扰你特别是长、难或外来主机名。 +一定要多检查几次拼写和主机名是否正确(是 `samba.example.com` 还是 `samba1.example.com`)?这些经常会困扰你,特别是比较长、难记或其它国家的主机名。 ### Error 3 - 服务器没有侦听端口 这种错误发生在 `telnet` 可达服务器但是指定端口没有监听。就像这样: + ``` telnet samba.example.com 445 Trying 172.31.25.31... telnet: Unable to connect to remote host: Connection refused - ``` 有这些原因: @@ -100,18 +98,16 @@ telnet: Unable to connect to remote host: Connection refused 2. 你的应用服务器没有侦听预期的端口。在服务器上运行 `netstat -plunt` 来查看它究竟在干什么并看哪个端口才是对的,实际正在监听中的。 3. 应用服务器没有运行。这可能突然而又悄悄地发生在你启动应用服务器之后。启动服务器运行 `ps auxf` 或 `systemctl status application.service` 查看运行。 - - ### Error 4 - 连接被服务器关闭 这种错误发生在连接成功建立但是应用服务器建立的安全措施一连上就将其结束。错误如下: + ``` telnet samba.example.com 445 Trying 172.31.25.31... Connected to samba.example.com. Escape character is '^]'. -��Connection closed by foreign host. - +Connection closed by foreign host. ``` 最后一行 `Connection closed by foreign host.` 意味着连接被服务器主动终止。为了修复这个问题,需要看看应用服务器的安全设置确保你的 IP 或用户允许连接。 @@ -119,17 +115,18 @@ Escape character is '^]'. ### 成功连接 成功的 `telnet` 连接如下: + ``` telnet samba.example.com 445 Trying 172.31.25.31... Connected to samba.example.com. Escape character is '^]'. - ``` 连接会保持一段时间只要你连接的应用服务器时限没到。 -输入 `CTRL+]` 中止连接然后当你看到 `telnet>` 提示,输入 "quit" 并点击 ENTER 例: +输入 `CTRL+]` 中止连接,然后当你看到 `telnet>` 提示,输入 `quit` 并按回车: + ``` telnet samba.example.com 445 Trying 172.31.25.31... @@ -138,12 +135,11 @@ Escape character is '^]'. ^] telnet> quit Connection closed. - ``` ### 总结 -客户程序连不上服务器的原因有很多。确切原理很难确定特别是当客户是图形用户界面提供很少或没有错误信息。用 `telnet` 并观察输出可以让你很快确定问题所在节约很多时间。 +客户程序连不上服务器的原因有很多。确切原因很难确定,特别是当客户是图形用户界面提供很少或没有错误信息。用 `telnet` 并观察输出可以让你很快确定问题所在节约很多时间。 -------------------------------------------------------------------------------- @@ -151,7 +147,7 @@ via: https://bash-prompt.net/guides/telnet/ 作者:[Elliot Cooper][a] 译者:[XYenChi](https://github.com/XYenChi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201802/20180102 Best open source tutorials in 2017.md b/published/201802/20180102 Best open source tutorials in 2017.md new file mode 100644 index 0000000000..9eca82653f --- /dev/null +++ b/published/201802/20180102 Best open source tutorials in 2017.md @@ -0,0 +1,87 @@ +Opensource.com 的 2017 年最佳开源教程 +====== + +2017 年,Opensource.com 发布了一系列用于帮助从初学者到专家的教程。让我们看看哪些最好。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc-lead-teacher-learner.png?itok=rMJqBN5G) + +精心编写的教程对于任何软件的官方文档来说都是一个很好的补充。如果官方文件写得不好,不完整或根本没有,那么这些教程也可以是个有效的替代品。 + +2017 年,Opensource.com 发布一些有关各种主题的优秀教程。这些教程不只是针对专家们的,它们是针对各种技能水平和经验的用户的。 + +让我们来看看其中最好的教程。 + +### 关于代码 + +对许多人来说,他们第一次涉足开源是为一个项目或另一个项目贡献代码。你在哪里学习编码或编程的?以下两篇文章是很好的起点。 + +严格来说,VM Brasseur 的[如何开始学习编程][1]是新手程序员的一个很好的起点,而不是一个教程。它不仅指出了一些有助于你开始学习的优秀资源,而且还提供了了解你的学习方式和如何选择语言的重要建议。 + +如果您已经在一个 [IDE][2] 或文本编辑器中敲击了几个小时,那么您可能需要学习更多关于编码的不同方法。Fraser Tweedale 的[函数式编程简介][3]很好地介绍了可以应用到许多广泛使用的编程语言的范式。 + +### 踏足 Linux + +Linux 是开源的典范。它运行了大量的 Web 站点,为世界顶级的超级计算机提供了动力。它让任何人都可以替代台式机上的专有操作系统。 + +如果你有兴趣深入 Linux,这里有三个教程供你参考。 + +Jason Baker 告诉你[设置 Linux $PATH 变量][4]。他引导你掌握这一“任何 Linux 初学者的重要技巧”,使您能够告知系统包含了程序和脚本的目录。 + +感谢 David Both 的[建立一个 DNS 域名服务器][5]指南。他详细地记录了如何设置和运行服务器,包括要编辑的配置文件以及如何编辑它们。 + +想在你的电脑上更复古一点吗?Jim Hall 告诉你如何使用 [FreeDOS][7]和 [qemu][8] [在 Linux 下运行 DOS 程序][6]。Hall 的文章着重于运行 DOS 生产力工具,但并不全是严肃的——他也谈到了运行他最喜欢的 DOS 游戏。 + +### 3 片(篇)树莓派 + +廉价的单板计算机使硬件再次变得有趣,这并不是秘密。不仅如此,它们使更多的人更容易接近,无论他们的年龄或技术水平如何。 + +其中,[树莓派][9]可能是最广泛使用的单板计算机。Ben Nuttall 带我们一起[在树莓派上安装和设置 Postgres 数据库][10]。这样,你可以在任何你想要的项目中使用它。 + +如果你的品味包括文学和技术,你可能会对 Don Watkins 的[如何将树莓派变成电子书服务器][11]感兴趣。稍微付出一点努力和一份 [Calibre 电子书管理软件][12]副本,你就可以得到你最喜欢的电子书,无论你在哪里。 + +树莓派并不是其中唯一有特点的。还有 [Orange Pi Pc Plus][13],这是一种开源的单板机。David Egts 告诉你[如何开始使用这个可编程的迷你电脑][14]。 + +### 日常的计算机使用 + +开源并不仅针对技术专家,更多的普通人用它来做日常工作,而且更加效率。这里有三篇文章,可以使我们这些笨手笨脚的人(你可能不是)做任何事情变得优雅。 + +当你想到微博客的时候,你可能会想到 Twitter。但是 Twitter 的问题很多。[Mastodon][15] 是 Twitter 的开放的替代方案,它在 2016 年首次亮相。从此, Mastodon 就获得相当大的用户基数。Seth Kenlon 说明[如何加入和使用 Mastodon][16],甚至告诉你如何在 Mastodon 和 Twitter 间交替使用。 + +你需要一点帮助来维持开支吗?你所需要的只是一个电子表格和正确的模板。我关于[要控制你的财政状况][17]的文章,向你展示了如何用 [LibreOffice Calc][18] (或任何其他电子表格编辑器)创建一个简单而有吸引力的财务跟踪。 + +ImageMagick 是强大的图形处理工具。但是,很多人不经常使用。这意味着他们在最需要它们时忘记了命令。如果你也是这样,Greg Pittman 的 [ImageMagick 入门教程][19]能在你需要一些帮助时候能派上用场。 + +你有最喜欢的 2017 Opensource.com 发布的教程吗?请随意留言与社区分享。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/best-tutorials + +作者:[Scott Nesbitt][a] +译者:[zjon](https://github.com/zjon) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/scottnesbitt +[1]:https://linux.cn/article-8694-1.html +[2]:https://en.wikipedia.org/wiki/Integrated_development_environment +[3]:https://linux.cn/article-8869-1.html +[4]:https://opensource.com/article/17/6/set-path-linux +[5]:https://opensource.com/article/17/4/build-your-own-name-server +[6]:https://linux.cn/article-9014-1.html +[7]:http://www.freedos.org/ +[8]:https://www.qemu.org +[9]:https://en.wikipedia.org/wiki/Raspberry_Pi +[10]:https://linux.cn/article-9056-1.html +[11]:https://linux.cn/article-8684-1.html +[12]:https://calibre-ebook.com/ +[13]:http://www.orangepi.org/ +[14]:https://linux.cn/article-8308-1.html +[15]:https://joinmastodon.org/ +[16]:https://opensource.com/article/17/4/guide-to-mastodon +[17]:https://linux.cn/article-8831-1.html +[18]:https://www.libreoffice.org/discover/calc/ +[19]:https://linux.cn/article-8851-1.html + + diff --git a/published/20180102 Linux uptime Command Explained for Beginners with Examples.md b/published/201802/20180102 Linux uptime Command Explained for Beginners with Examples.md similarity index 100% rename from published/20180102 Linux uptime Command Explained for Beginners with Examples.md rename to published/201802/20180102 Linux uptime Command Explained for Beginners with Examples.md diff --git a/published/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md b/published/201802/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md similarity index 100% rename from published/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md rename to published/201802/20180102 cURL vs. wget- Their Differences, Usage and Which One You Should Use.md diff --git a/published/20180102 xfs file system commands with examples.md b/published/201802/20180102 xfs file system commands with examples.md similarity index 100% rename from published/20180102 xfs file system commands with examples.md rename to published/201802/20180102 xfs file system commands with examples.md diff --git a/published/20180103 Creating an Offline YUM repository for LAN.md b/published/201802/20180103 Creating an Offline YUM repository for LAN.md similarity index 100% rename from published/20180103 Creating an Offline YUM repository for LAN.md rename to published/201802/20180103 Creating an Offline YUM repository for LAN.md diff --git a/translated/tech/20180103 How to preconfigure LXD containers with cloud-init.md b/published/201802/20180103 How to preconfigure LXD containers with cloud-init.md similarity index 59% rename from translated/tech/20180103 How to preconfigure LXD containers with cloud-init.md rename to published/201802/20180103 How to preconfigure LXD containers with cloud-init.md index 919efe4a26..4e70cd3bcb 100644 --- a/translated/tech/20180103 How to preconfigure LXD containers with cloud-init.md +++ b/published/201802/20180103 How to preconfigure LXD containers with cloud-init.md @@ -1,12 +1,15 @@ -如何使用cloud-init来预配置LXD容器 +如何使用 cloud-init 来预配置 LXD 容器 ====== -当你正在创建LXD容器的时候,你希望它们能被预先配置好。例如在容器一启动就自动执行 **apt update**来安装一些软件包,或者运行一些命令。 -这篇文章将讲述如何用[**cloud-init**][1]来对[LXD容器进行进行早期初始化][2]。 + +当你正在创建 LXD 容器的时候,你希望它们能被预先配置好。例如在容器一启动就自动执行 `apt update`来安装一些软件包,或者运行一些命令。 + +这篇文章将讲述如何用 [cloud-init][1] 来对 [LXD 容器进行进行早期初始化][2]。 + 接下来,我们将创建一个包含cloud-init指令的LXD profile,然后启动一个新的容器来使用这个profile。 -### 如何创建一个新的LXD profile +### 如何创建一个新的 LXD profile -查看已经存在的profile: +查看已经存在的 profile: ```shell $ lxc profile list @@ -17,7 +20,7 @@ $ lxc profile list +---------|---------+ ``` -我们把名叫default的profile复制一份,然后在其内添加新的指令: +我们把名叫 `default` 的 profile 复制一份,然后在其内添加新的指令: ```shell $ lxc profile copy default devprofile @@ -32,7 +35,7 @@ $ lxc profile list +------------|---------+ ``` -我们就得到了一个新的profile: **devprofile**。下面是它的详情: +我们就得到了一个新的 profile: `devprofile`。下面是它的详情: ```yaml $ lxc profile show devprofile @@ -52,11 +55,12 @@ name: devprofile used_by: [] ``` -注意这几个部分: **config:** , **description:** , **devices:** , **name:** 和 **used_by:**,当你修改这些内容的时候注意不要搞错缩进。(译者注:因为这些内容是YAML格式的,缩进是语法的一部分) +注意这几个部分: `config:` 、 `description:` 、 `devices:` 、 `name:` 和 `used_by:`,当你修改这些内容的时候注意不要搞错缩进。(LCTT 译注:因为这些内容是 YAML 格式的,缩进是语法的一部分) -### 如何把cloud-init添加到LXD profile里 +### 如何把 cloud-init 添加到 LXD profile 里 + +[cloud-init][1] 可以添加到 LXD profile 的 `config` 里。当这些指令将被传递给容器后,会在容器第一次启动的时候执行。 -[cloud-init][1]可以添加到LXD profile的 **config** 里。当这些指令将被传递给容器后,会在容器第一次启动的时候执行。 下面是用在示例中的指令: ```yaml @@ -69,11 +73,9 @@ used_by: [] - [touch, /tmp/simos_was_here] ``` -**package_upgrade: true** 是指当容器第一次被启动时,我们想要**cloud-init** 运行 **sudo apt upgrade**。 -**packages:** 列出了我们想要自动安装的软件。然后我们设置了**locale** and **timezone**。在Ubuntu容器的镜像里,root用户默认的 locale 是**C.UTF-8**,而**ubuntu** 用户则是 **en_US.UTF-8**。此外,我们把时区设置为**Etc/UTC**。 -最后,我们展示了[如何使用**runcmd**来运行一个Unix命令][3]。 +`package_upgrade: true` 是指当容器第一次被启动时,我们想要 `cloud-init` 运行 `sudo apt upgrade`。`packages:` 列出了我们想要自动安装的软件。然后我们设置了 `locale` 和 `timezone`。在 Ubuntu 容器的镜像里,root 用户默认的 `locale` 是 `C.UTF-8`,而 `ubuntu` 用户则是 `en_US.UTF-8`。此外,我们把时区设置为 `Etc/UTC`。最后,我们展示了[如何使用 runcmd 来运行一个 Unix 命令][3]。 -我们需要关注如何将**cloud-init**指令插入LXD profile。 +我们需要关注如何将 `cloud-init` 指令插入 LXD profile。 我首选的方法是: @@ -110,15 +112,15 @@ name: devprofile used_by: [] ``` -### 如何使用LXD profile启动一个容器 +### 如何使用 LXD profile 启动一个容器 -使用profile **devprofile**来启动一个新容器: +使用 profile `devprofile` 来启动一个新容器: ``` $ lxc launch --profile devprofile ubuntu:x mydev ``` -然后访问该容器来查看我们的的指令是否生效: +然后访问该容器来查看我们的指令是否生效: ```shell $ lxc exec mydev bash @@ -139,7 +141,7 @@ root@mydev:~# ps ax root@mydev:~# ``` -如果我们连接得够快,通过**ps ax**将能够看到系统正在更新软件。我们可以从/var/log/cloud-init-output.log看到完整的日志: +如果我们连接得够快,通过 `ps ax` 将能够看到系统正在更新软件。我们可以从 `/var/log/cloud-init-output.log` 看到完整的日志: ``` Generating locales (this might take a while)... @@ -147,7 +149,7 @@ Generating locales (this might take a while)... Generation complete. ``` -以上可以看出locale已经被更改了。root 用户还是保持默认的**C.UTF-8**,只有非root用户**ubuntu**使用了新的locale。 +以上可以看出 `locale` 已经被更改了。root 用户还是保持默认的 `C.UTF-8`,只有非 root 用户 `ubuntu` 使用了新的`locale` 设置。 ``` Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease @@ -155,7 +157,7 @@ Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB] Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB] ``` -以上是安装软件包之前执行的**apt update**。 +以上是安装软件包之前执行的 `apt update`。 ``` The following packages will be upgraded: @@ -163,16 +165,18 @@ The following packages will be upgraded: 4 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 211 kB of archives. ``` -以上是在执行**package_upgrade: true**和安装软件包。 + +以上是在执行 `package_upgrade: true` 和安装软件包。 ``` The following NEW packages will be installed: binutils build-essential cpp cpp-5 dpkg-dev fakeroot g++ g++-5 gcc gcc-5 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl ``` -以上是我们安装**build-essential**软件包的指令。 -**runcmd** 执行的结果如何? +以上是我们安装 `build-essential` 软件包的指令。 + +`runcmd` 执行的结果如何? ``` root@mydev:~# ls -l /tmp/ @@ -185,7 +189,7 @@ root@mydev:~# ### 结论 -当我们启动LXD容器的时候,我们常常需要默认启用一些配置,并且希望能够避免重复工作。通常解决这个问题的方法是创建LXD profile,然后把需要的配置添加进去。最后,当我们启动新的容器时,只需要应用该LXD profile即可。 +当我们启动 LXD 容器的时候,我们常常需要默认启用一些配置,并且希望能够避免重复工作。通常解决这个问题的方法是创建 LXD profile,然后把需要的配置添加进去。最后,当我们启动新的容器时,只需要应用该 LXD profile 即可。 -------------------------------------------------------------------------------- @@ -193,7 +197,7 @@ via: https://blog.simos.info/how-to-preconfigure-lxd-containers-with-cloud-init/ 作者:[Simos Xenitellis][a] 译者:[kaneg](https://github.com/kaneg) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180104 How to Change Your Linux Console Fonts.md b/published/201802/20180104 How to Change Your Linux Console Fonts.md similarity index 100% rename from published/20180104 How to Change Your Linux Console Fonts.md rename to published/201802/20180104 How to Change Your Linux Console Fonts.md diff --git a/translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md b/published/201802/20180104 Whats behind the Intel design flaw forcing numerous patches.md similarity index 58% rename from translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md rename to published/201802/20180104 Whats behind the Intel design flaw forcing numerous patches.md index d0c247d6b3..9c264be0ac 100644 --- a/translated/tech/20180104 Whats behind the Intel design flaw forcing numerous patches.md +++ b/published/201802/20180104 Whats behind the Intel design flaw forcing numerous patches.md @@ -1,73 +1,71 @@ Intel 设计缺陷背后的原因是什么? ============================================================ -### 我们知道有问题,但是并不知道问题的详细情况。 - +> 我们知道有问题,但是并不知道问题的详细情况。 ![](https://cdn.arstechnica.net/wp-content/uploads/2015/06/intel-48-core-larrabee-probably-640x427.jpg) +(本文发表于 1 月份)最近 Windows 和 Linux 都发送了重大安全更新,为防范这个尚未完全公开的问题,在最坏的情况下,它可能会导致性能下降多达一半。 -最近 Windows 和 Linux 都发送了重大安全更新,为防范这个尚未完全公开的问题,在最坏的情况下,它可能会导致性能下降多达一半。 +在过去的几周,Linux 内核陆续打了几个补丁。Microsoft [自 11 月份开始也内部测试了 Windows 更新][3],并且它预计在下周二的例行补丁中将这个改进推送到主流 Windows 构建版中。Microsoft 的 Azure 也在下周的维护窗口中做好了安排,而 Amazon 的 AWS 也安排在周五对相关的设施进行维护。 -在过去的几周,Linux 内核陆续打了几个补丁。Microsoft [自 11 月份开始也内部测试了 Windows 更新][3],并且它预计在下周二的例行补丁中将这个改进推送到主流 Windows 构建版中。Microsoft 的 Azure 也在下周的维护窗口中做好了安排,而 Amazon 的 AWS 也安排在周五对相关的设施进行维护。 - -自从 Linux 第一个补丁 [KPTI:内核页表隔离的当前的发展][4] ,明确描绘了出现的错误以后。虽然 Linux 和 Windows 基于不同的考虑,对此持有不同的看法,但是这两个操作系统 — 当然还有其它的 x86 操作系统,比如 FreeBSD 和 [macOS][5] — 对系统内存的处理采用了相同的方式,因为对于操作系统在这一部分特性是与底层的处理器高度耦合的。 +自从 Linux 第一个补丁 (参见 [KPTI:内核页表隔离的当前的发展][4]) 明确描绘了出现的错误以后。虽然 Linux 和 Windows 基于不同的考虑,对此持有不同的看法,但是这两个操作系统 —— 当然还有其它的 x86 操作系统,比如 FreeBSD 和 [macOS][5] — 对系统内存的处理采用了相同的方式,因为对于操作系统在这一部分特性是与底层的处理器高度耦合的。 ### 保持地址跟踪 -在一个系统中的每个内存字节都是隐性编码的,这些数字是每个字节的地址。早期的操作系统使用物理内存地址,但是,物理内存地址由于各种原因,它并不很合适。例如,在地址中经常会有空隙,并且(尤其是 32 位的系统上)物理地址很难操作,需要 36 位的数字,甚至更多。 +在一个系统中的每个内存字节都是隐性编码的,这些编码数字是每个字节的地址。早期的操作系统使用物理内存地址,但是,物理内存地址由于各种原因,它并不很合适。例如,在地址中经常会有空隙,并且(尤其是 32 位的系统上)物理地址很难操作,需要 36 位数字,甚至更多。 -因此,现在操作系统完全依赖一个叫虚拟内存的概念。虚拟内存系统允许程序和内核一起在一个简单、清晰、统一的环境中各自去操作。而不是使用空隙和其它奇怪的东西的物理内存,每个程序和内核自身都使用虚拟地址去访问内存。这些虚拟地址是连续的 — 不用担心有空隙 — 并且合适的大小也更便于操作。32 位的程序仅可以看到 32 位的地址,而不用管物理地址是 36 位还是更多位。 +因此,现在操作系统完全依赖一个叫虚拟内存的概念。虚拟内存系统允许程序和内核一起在一个简单、清晰、统一的环境中各自去操作。而不是使用空隙和其它奇怪的东西的物理内存,每个程序和内核自身都使用虚拟地址去访问内存。这些虚拟地址是连续的 —— 不用担心有空隙 —— 并且合适的大小也更便于操作。32 位的程序仅可以看到 32 位的地址,而不用管物理地址是 36 位还是更多位。 虽然虚拟地址对每个软件几乎是透明的,但是,处理器最终还是需要知道虚拟地址引用的物理地址是哪个。因此,有一个虚拟地址到物理地址的映射,它保存在一个被称为页面表的数据结构中。操作系统构建页面表,使用一个由处理器决定的布局,并且处理器和操作系统在虚拟地址和物理地址之间进行转换时就需要用到页面表。 -这个映射过程是非常重要的,它也是现代操作系统和处理器的重要基础,处理器有专用的缓存 — translation lookaside buffer(简称 TLB)— 它保存了一定数量的虚拟地址到物理地址的映射,这样就不需要每次都使用全部页面。 +这个映射过程是非常重要的,它也是现代操作系统和处理器的重要基础,处理器有专用的缓存 — Translation Lookaside Buffer(简称 TLB)—— 它保存了一定数量的虚拟地址到物理地址的映射,这样就不需要每次都使用全部页面。 虚拟内存的使用为我们提供了很多除了简单寻址之外的有用的特性。其中最主要的是,每个程序都有了自己独立的一组虚拟地址,有了它自己的一组虚拟地址到物理地址的映射。这就是用于提供“内存保护”的关键技术,一个程序不能破坏或者篡改其它程序使用的内存,因为其它程序的内存并不在它的地址映射范围之内。 -由于每个进程使用一个单独的映射,因此每个程序也就有了一个额外的页面表,这就使得 TLB 缓存很拥挤。TLB 并不大 — 一般情况下总共可以容纳几百个映射 — 而系统使用的页面表越多,TLB 能够包含的任何特定的虚拟地址到物理地址的映射就越少。 +由于每个进程使用一个单独的映射,因此每个程序也就有了一个额外的页面表,这就使得 TLB 缓存很拥挤。TLB 并不大 —— 一般情况下总共可以容纳几百个映射 —— 而系统使用的页面表越多,TLB 能够包含的任何特定的虚拟地址到物理地址的映射就越少。 ### 一半一半 -为了更好地使用 TLB,每个主流的操作系统都将虚拟地址范围一分为二。一半用于程序;另一半用于内核。当进程切换时,仅有一半的页面表条目发生变化 — 仅属于程序的那一半。内核的那一半是每个程序公用的(因为只有一个内核)并且因此它可以为每个进程使用相同的页面表映射。这对 TLB 的帮助非常大;虽然它仍然会丢弃属于进程的那一半内存地址映射;但是它还保持着另一半属于内核的映射。 +为了更好地使用 TLB,每个主流的操作系统都将虚拟地址范围一分为二。一半用于程序;另一半用于内核。当进程切换时,仅有一半的页面表条目发生变化 —— 仅属于程序的那一半。内核的那一半是每个程序公用的(因为只有一个内核)并且因此它可以为每个进程使用相同的页面表映射。这对 TLB 的帮助非常大;虽然它仍然会丢弃属于进程的那一半内存地址映射;但是它还保持着另一半属于内核的映射。 这种设计并不是一成不变的。在 Linux 上做了一项工作,使它可以为一个 32 位的进程提供整个地址范围,而不用在内核页面表和每个进程之间共享。虽然这样为程序提供了更多的地址空间,但这是以牺牲性能为代价的,因为每次内核代码需要运行时,TLB 重新加载内核的页面表条目。因此,这种方法并没有广泛应用到 x86 的系统上。 在内核和每个程序之间分割虚拟地址的这种做法的一个负面影响是,内存保护被削弱了。如果内核有它自己的一组页面表和虚拟地址,它将在不同的程序之间提供相同的保护;内核内存将是简单的不可见。但是使用地址分割之后,用户程序和内核使用了相同的地址范围,并且从原理上来说,一个用户程序有可能去读写内核内存。 -为避免这种明显不好的情况,处理器和虚拟地址系统有一个 “Ring" 或者 ”模式“的概念。x86 处理器有许多 rings,但是对于这个问题,仅有两个是相关的:"user" (ring 3)和 "supervisor"(ring 0)。当运行普通的用户程序时,处理器将置为用户模式 (ring 3)。当运行内核代码时,处理器将处于 ring 0 —— supervisor 模式,也称为内核模式。 +为避免这种明显不好的情况,处理器和虚拟地址系统有一个 “Ring” 或者 “模式”的概念。x86 处理器有许多 Ring,但是对于这个问题,仅有两个是相关的:“user” (Ring 3)和 “supervisor”(ring 0)。当运行普通的用户程序时,处理器将置为用户模式 (Ring 3)。当运行内核代码时,处理器将处于 Ring 0 —— supervisor 模式,也称为内核模式。 -这些 rings 也用于从用户程序中保护内核内存。页面表并不仅仅有虚拟地址到物理地址的映射;它也包含关于这些地址的元数据,包含哪个 rings 可能访问哪个地址的信息。内核页面表条目被标记为仅 ring 0 可以访问;程序的条目被标记为任何 ring 都可以访问。如果一个处于 ring 3 中的进程去尝试访问标记为 ring 0 的内存,处理器将阻止这个访问并生成一个意外错误信息。运行在 ring 3 中的用户程序不能得到内核以及运行在 ring 0 内存中的任何东西。 +这些 Ring 也用于从用户程序中保护内核内存。页面表并不仅仅有虚拟地址到物理地址的映射;它也包含关于这些地址的元数据,包含哪个 Ring 可能访问哪个地址的信息。内核页面表条目被标记为仅有 Ring 0 可以访问;程序的条目被标记为任何 Ring 都可以访问。如果一个处于 Ring 3 中的进程去尝试访问标记为 Ring 0 的内存,处理器将阻止这个访问并生成一个意外错误信息。运行在 Ring 3 中的用户程序不能得到内核以及运行在 Ring 0 内存中的任何东西。 至少理论上是这样的。大量的补丁和更新表明,这个地方已经被突破了。这就是最大的谜团所在。 ### Ring 间迁移 -这就是我们所知道的。每个现代处理器都执行一定数量的推测运行。例如,给一些指令,让两个数加起来,然后将结果保存在内存中,在查明内存中的目标是否可访问和可写入之前,一个处理器可能已经推测性地做了加法。在一些常见案例中,在位置是可写入的地方,处理器节省了一些时间,因为它以并行方式计算出内存中的目标是什么。如果它发现目标位置不可写入 — 例如,一个程序尝试去写入到一个没有映射的地址以及压根就不存在的物理位置— 然后它将产生一个意外错误,而推测运行就白做了。 +这就是我们所知道的。每个现代处理器都执行一定数量的推测运行。例如,给一些指令,让两个数加起来,然后将结果保存在内存中,在查明内存中的目标是否可访问和可写入之前,一个处理器可能已经推测性地做了加法。在一些常见案例中,在地址可写入的地方,处理器节省了一些时间,因为它以并行方式计算出内存中的目标是什么。如果它发现目标位置不可写入 —— 例如,一个程序尝试去写入到一个没有映射的地址或压根就不存在的物理位置 —— 然后它将产生一个意外错误,而推测运行就白做了。 -Intel 处理器,尤其是 — [虽然不是 AMD 的][6] — 但允许对 ring 3 代码进行推测运行并写入到 ring 0 内存中的处理器上。处理器并不完全阻止这种写入,但是推测运行轻微扰乱了处理器状态,因为,为了查明目标位置是否可写入,某些数据已经被加载到缓存和 TLB 中。这又意味着一些操作可能快几个周期,或者慢几个周期,这取决于它们所需要的数据是否仍然在缓存中。除此之外,Intel 的处理器还有一些特殊的功能,比如,在 Skylake 处理器上引入的软件保护扩展(SGX)指令,它改变了一点点访问内存的方式。同样的,处理器仍然是保护 ring 0 的内存不被来自 ring 3 的程序所访问,但是同样的,它的缓存和其它内部状态已经发生了变化,产生了可测量的差异。 +Intel 处理器,尤其是([虽然不是 AMD 的][6])允许对 Ring 3 代码进行推测运行并写入到 Ring 0 内存中的处理器上。处理器并不完全阻止这种写入,但是推测运行轻微扰乱了处理器状态,因为,为了查明目标位置是否可写入,某些数据已经被加载到缓存和 TLB 中。这又意味着一些操作可能快几个周期,或者慢几个周期,这取决于它们所需要的数据是否仍然在缓存中。除此之外,Intel 的处理器还有一些特殊的功能,比如,在 Skylake 处理器上引入的软件保护扩展(SGX)指令,它改变了一点点访问内存的方式。同样的,处理器仍然是保护 Ring 0 的内存不被来自 Ring 3 的程序所访问,但是同样的,它的缓存和其它内部状态已经发生了变化,产生了可测量的差异。 -我们至今仍然并不知道具体的情况,到底有多少内核的内存信息泄露给了用户程序,或者信息泄露的情况有多容易发生。以及有哪些 Intel 处理器会受到影响?也或者并不完全清楚,但是,有迹象表明每个 Intel 芯片都使用了推测运行(是自 1995 年 Pentium Pro 以来的,所有主流处理器吗?),它们都可能会因此而泄露信息。 +我们至今仍然并不知道具体的情况,到底有多少内核的内存信息泄露给了用户程序,或者信息泄露的情况有多容易发生。以及有哪些 Intel 处理器会受到影响?也或者并不完全清楚,但是,有迹象表明每个 Intel 芯片都使用了推测运行(是自 1995 年 Pentium Pro 以来的所有主流处理器吗?),它们都可能会因此而泄露信息。 这个问题第一次被披露是由来自 [奥地利的 Graz Technical University][7] 的研究者。他们披露的信息表明这个问题已经足够破坏内核模式地址空间布局随机化(内核 ASLR,或称 KASLR)。ASLR 是防范 [缓冲区溢出][8] 漏洞利用的最后一道防线。启用 ASLR 之后,程序和它们的数据被置于随机的内存地址中,它将使一些安全漏洞利用更加困难。KASLR 将这种随机化应用到内核中,这样就使内核的数据(包括页面表)和代码也随机化分布。 Graz 的研究者开发了 [KAISER][9],一组防范这个问题的 Linux 内核补丁。 -如果这个问题正好使 ASLR 的随机化被破坏了,这或许将成为一个巨大的灾难。ASLR 是一个非常强大的保护措施,但是它并不是完美的,这意味着对于黑客来说将是一个很大的障碍,一个无法逾越的障碍。整个行业对此的反应是 — Windows 和 Linux 都有一个非常重要的变化,秘密开发 — 这表明不仅是 ASLR 被破坏了,而且从内核泄露出信息的更普遍的技术被开发出来了。确实是这样的,研究者已经 [在 tweet 上发布信息][10],他们已经可以随意泄露和读取内核数据了。另一种可能是,漏洞可能被用于从虚拟机中”越狱“,并可能会危及 hypervisor。 +如果这个问题正好使 ASLR 的随机化被破坏了,这或许将成为一个巨大的灾难。ASLR 是一个非常强大的保护措施,但是它并不是完美的,这意味着对于黑客来说将是一个很大的障碍,一个无法逾越的障碍。整个行业对此的反应是 —— Windows 和 Linux 都有一个非常重要的变化,秘密开发 —— 这表明不仅是 ASLR 被破坏了,而且从内核泄露出信息的更普遍的技术被开发出来了。确实是这样的,研究者已经 [在 Twitter 上发布信息][10],他们已经可以随意泄露和读取内核数据了。另一种可能是,漏洞可能被用于从虚拟机中“越狱”,并可能会危及 hypervisor。 Windows 和 Linux 选择的解决方案是非常相似的,将 KAISER 分为两个区域:内核页面表的条目不再是由每个进程共享。在 Linux 中,这被称为内核页面表隔离(KPTI)。 -应用补丁后,内存地址仍然被一分为二:这样使内核的那一半几乎是空的。当然它并不是非常的空,因为一些内核片断需要永久映射,不论进程是运行在 ring 3 还是 ring 0 中,它都几乎是空的。这意味着如果恶意用户程序尝试去探测内核内存以及泄露信息,它将会失败 — 因为那里几乎没有信息。而真正的内核页面中只有当内核自身运行的时刻它才能被用到。 +应用补丁后,内存地址仍然被一分为二:这样使内核的那一半几乎是空的。当然它并不是非常的空,因为一些内核片断需要永久映射,不论进程是运行在 Ring 3 还是 Ring 0 中,它都几乎是空的。这意味着如果恶意用户程序尝试去探测内核内存以及泄露信息,它将会失败 —— 因为那里几乎没有信息。而真正的内核页面中只有当内核自身运行的时刻它才能被用到。 这样做就破坏了最初将地址空间分割的理由。现在,每次切换到用户程序时,TLB 需要实时去清除与内核页面表相关的所有条目,这样就失去了启用分割带来的性能提升。 -影响的具体大小取决于工作负载。每当一个程序被调入到内核 — 从磁盘读入、发送数据到网络、打开一个文件等等 — 这种调用的成本可能会增加一点点,因为它强制 TLB 清除了缓存并实时加载内核页面表。不使用内核的程序可能会观测到 2 - 3 个百分点的性能影响 — 这里仍然有一些开销,因为内核仍然是偶尔会运行去处理一些事情,比如多任务等等。 +影响的具体大小取决于工作负载。每当一个程序被调入到内核 —— 从磁盘读入、发送数据到网络、打开一个文件等等 —— 这种调用的成本可能会增加一点点,因为它强制 TLB 清除了缓存并实时加载内核页面表。不使用内核的程序可能会观测到 2 - 3 个百分点的性能影响 —— 这里仍然有一些开销,因为内核仍然是偶尔会运行去处理一些事情,比如多任务等等。 但是大量调用进入到内核的工作负载将观测到很大的性能损失。在一个基准测试中,一个除了调入到内核之外什么都不做的程序,观察到 [它的性能下降大约为 50%][11];换句话说就是,打补丁后每次对内核的调用的时间要比不打补丁调用内核的时间增加一倍。基准测试使用的 Linux 的网络回环(loopback)也观测到一个很大的影响,比如,在 Postgres 的基准测试中大约是 [17%][12]。真实的数据库负载使用了实时网络可能观测到的影响要低一些,因为使用实时网络时,内核调用的开销基本是使用真实网络的开销。 -虽然对 Intel 系统的影响是众所周知的,但是它们可能并不是唯一受影响的。其它的一些平台,比如 SPARC 和 IBM 的 S390,是不受这个问题影响的,因为它们的处理器的内存管理并不需要分割地址空间和共享内核页面表;在这些平台上的操作系统一直就是将它们的内核页面表从用户模式中隔离出来的。但是其它的,比如 ARM,可能就没有这么幸运了;[适用于 ARM Linux 的类似补丁][13] 正在开发中。 +虽然对 Intel 系统的影响是众所周知的,但是它们可能并不是唯一受影响的。其它的一些平台,比如 SPARC 和 IBM 的 S390,是不受这个问题影响的,因为它们的处理器的内存管理并不需要分割地址空间和共享内核页面表;在这些平台上的操作系统一直就是将它们的内核页面表从用户模式中隔离出来的。但是其它的,比如 ARM,可能就没有这么幸运了;[适用于 ARM Linux 的类似补丁][13] 正在开发中。 - +--- [][15][PETER BRIGHT][14] 是 Ars 的一位技术编辑。他涉及微软、编程及软件开发、Web 技术和浏览器、以及安全方面。它居住在纽约的布鲁克林。 @@ -75,9 +73,9 @@ Windows 和 Linux 选择的解决方案是非常相似的,将 KAISER 分为两 via: https://arstechnica.com/gadgets/2018/01/whats-behind-the-intel-design-flaw-forcing-numerous-patches/ -作者:[ PETER BRIGHT ][a] +作者:[PETER BRIGHT][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20180105 How To Display Asterisks When You Type Password In terminal.md b/published/201802/20180105 How To Display Asterisks When You Type Password In terminal.md similarity index 62% rename from translated/tech/20180105 How To Display Asterisks When You Type Password In terminal.md rename to published/201802/20180105 How To Display Asterisks When You Type Password In terminal.md index 0b764d093f..d189cd30e6 100644 --- a/translated/tech/20180105 How To Display Asterisks When You Type Password In terminal.md +++ b/published/201802/20180105 How To Display Asterisks When You Type Password In terminal.md @@ -3,68 +3,70 @@ ![](https://www.ostechnix.com/wp-content/uploads/2018/01/Display-Asterisks-When-You-Type-Password-In-terminal-1-720x340.png) -当你在 Web 浏览器或任何 GUI 登录中输入密码时,密码会被标记成星号 ******** 或圆形符号 ••••••••••••• 。这是内置的安全机制,以防止你附近的用户看到你的密码。但是当你在终端输入密码来执行任何 **sudo** 或 **su** 的管理任务时,你不会在输入密码的时候看见星号或者圆形符号。它不会有任何输入密码的视觉指示,也不会有任何光标移动,什么也没有。你不知道你是否输入了所有的字符。你只会看到一个空白的屏幕! +当你在 Web 浏览器或任何 GUI 登录中输入密码时,密码会被标记成星号 `********` 或圆点符号 `•••••••••••••` 。这是内置的安全机制,以防止你附近的用户看到你的密码。但是当你在终端输入密码来执行任何 `sudo` 或 `su` 的管理任务时,你不会在输入密码的时候看见星号或者圆点符号。它不会有任何输入密码的视觉指示,也不会有任何光标移动,什么也没有。你不知道你是否输入了所有的字符。你只会看到一个空白的屏幕! 看看下面的截图。 ![][2] -正如你在上面的图片中看到的,我已经输入了密码,但没有任何指示(星号或圆形符号)。现在,我不确定我是否输入了所有密码。这个安全机制也可以防止你附近的人猜测密码长度。当然,这种行为可以改变。这是本指南要说的。这并不困难。请继续阅读。 +正如你在上面的图片中看到的,我已经输入了密码,但没有任何指示(星号或圆点符号)。现在,我不确定我是否输入了所有密码。这个安全机制也可以防止你附近的人猜测密码长度。当然,这种行为可以改变。这是本指南要说的。这并不困难。请继续阅读。 #### 当你在终端输入密码时显示星号 -要在终端输入密码时显示星号,我们需要在 **“/etc/sudoers”** 中做一些小修改。在做任何更改之前,最好备份这个文件。为此,只需运行: +要在终端输入密码时显示星号,我们需要在 `/etc/sudoers` 中做一些小修改。在做任何更改之前,最好备份这个文件。为此,只需运行: + ``` sudo cp /etc/sudoers{,.bak} ``` -上述命令将 /etc/sudoers 备份成名为 /etc/sudoers.bak。你可以恢复它,以防万一在编辑文件后出错。 +上述命令将 `/etc/sudoers` 备份成名为 `/etc/sudoers.bak`。你可以恢复它,以防万一在编辑文件后出错。 + +接下来,使用下面的命令编辑 `/etc/sudoers`: -接下来,使用下面的命令编辑 **“/etc/sudoers”**: ``` sudo visudo ``` 找到下面这行: + ``` Defaults env_reset ``` ![][3] -在该行的末尾添加一个额外的单词 **“,pwfeedback”**,如下所示。 +在该行的末尾添加一个额外的单词 `,pwfeedback`,如下所示。 + ``` Defaults env_reset,pwfeedback ``` ![][4] -然后,按下 **“CTRL + x”** 和 **“y”** 保存并关闭文件。重新启动终端以使更改生效。 +然后,按下 `CTRL + x` 和 `y` 保存并关闭文件。重新启动终端以使更改生效。 现在,当你在终端输入密码时,你会看到星号。 ![][5] -如果你对在终端输入密码时看不到密码感到不舒服,那么这个小技巧会有帮助。请注意,当你输入输入密码时其他用户就可以预测你的密码长度。如果你不介意,请按照上述方法进行更改,以使你的密码可见(当然,标记为星号!)。 +如果你对在终端输入密码时看不到密码感到不舒服,那么这个小技巧会有帮助。请注意,当你输入输入密码时其他用户就可以预测你的密码长度。如果你不介意,请按照上述方法进行更改,以使你的密码可见(当然,显示为星号!)。 现在就是这样了。还有更好的东西。敬请关注! 干杯! - - -------------------------------------------------------------------------------- via: https://www.ostechnix.com/display-asterisks-type-password-terminal/ 作者:[SK][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://www.ostechnix.com/author/sk/ -[2]:http://www.ostechnix.com/wp-content/uploads/2018/01/password-1.png () -[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/visudo-1.png () -[4]:http://www.ostechnix.com/wp-content/uploads/2018/01/visudo-1-1.png () -[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/visudo-2.png () +[2]:http://www.ostechnix.com/wp-content/uploads/2018/01/password-1.png +[3]:http://www.ostechnix.com/wp-content/uploads/2018/01/visudo-1.png +[4]:http://www.ostechnix.com/wp-content/uploads/2018/01/visudo-1-1.png +[5]:http://www.ostechnix.com/wp-content/uploads/2018/01/visudo-2.png diff --git a/published/20180106 Meltdown and Spectre Linux Kernel Status.md b/published/201802/20180106 Meltdown and Spectre Linux Kernel Status.md similarity index 100% rename from published/20180106 Meltdown and Spectre Linux Kernel Status.md rename to published/201802/20180106 Meltdown and Spectre Linux Kernel Status.md diff --git a/published/20180111 Multimedia Apps for the Linux Console.md b/published/201802/20180111 Multimedia Apps for the Linux Console.md similarity index 100% rename from published/20180111 Multimedia Apps for the Linux Console.md rename to published/201802/20180111 Multimedia Apps for the Linux Console.md diff --git a/translated/tech/20180112 Top 5 Firefox extensions to install now.md b/published/201802/20180112 Top 5 Firefox extensions to install now.md similarity index 56% rename from translated/tech/20180112 Top 5 Firefox extensions to install now.md rename to published/201802/20180112 Top 5 Firefox extensions to install now.md index 9f4698aea7..bef4ff5eef 100644 --- a/translated/tech/20180112 Top 5 Firefox extensions to install now.md +++ b/published/201802/20180112 Top 5 Firefox extensions to install now.md @@ -1,17 +1,17 @@ 五个值得现在安装的火狐插件 ====== -合适的插件能大大增强你浏览器的功能,但仔细挑选插件很重要。本文有五个值得一看的插件。 +> 合适的插件能大大增强你浏览器的功能,但仔细挑选插件很重要。本文有五个值得一看的插件。 ![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/firefox_blue_lead.jpg) -对于很多用户来说,网页浏览器已经成为电脑使用体验的重要环节。现代浏览器已经发展成强大、可拓展的平台。作为平台的一部分,_插件_能添加或修改浏览器的功能。火狐插件的构建使用了 WebExtensions API ,一个跨浏览器的开发系统。 +对于很多用户来说,网页浏览器已经成为电脑使用体验的重要环节。现代浏览器已经发展成强大、可拓展的平台。作为平台的一部分,_插件_能添加或修改浏览器的功能。火狐插件的构建使用了 WebExtensions API ,这是一个跨浏览器的开发系统。 -你得安装哪一个插件?一般而言,这个问题的答案取决于你如何使用你的浏览器、你对于隐私的看法、你信任插件开发者多少以及其他个人喜好。 +你应该安装哪一个插件?一般而言,这个问题的答案取决于你如何使用你的浏览器、你对于隐私的看法、你信任插件开发者多少以及其他个人喜好。 首先,我想指出浏览器插件通常需要读取和(或者)修改你浏览的网页上的每项内容。你应该_非常_仔细地考虑这件事的后果。如果一个插件有修改所有你访问过的网页的权限,那么它可能记录你的按键、拦截信用卡信息、在线跟踪你、插入广告,以及其他各种各样邪恶的行为。 -并不是每个插件都偷偷摸摸地做这些事,但是在你安装任何插件之前,你要慎重考虑下插件安装来源、涉及的权限、你的风险数据和其他因素。记住,你可以从个人数据的角度来管理一个插件如何影响你的攻击面( LCTT 译者注:攻击面是指入侵者能尝试获取或提取数据的途径总和)——例如使用特定的配置、不使用插件来完成例如网上银行的操作。 +并不是每个插件都偷偷摸摸地做这些事,但是在你安装任何插件之前,你要慎重考虑下插件安装来源、涉及的权限、你的风险数据和其他因素。记住,你可以从个人数据的角度来管理一个插件如何影响你的攻击面( LCTT 译注:攻击面是指入侵者能尝试获取或提取数据的途径总和)——例如使用特定的配置、不使用插件来完成例如网上银行的操作。 考虑到这一点,这里有你或许想要考虑的五个火狐插件 @@ -19,29 +19,29 @@ ![ublock origin ad blocker screenshot][2] -ublock Origin 可以拦截广告和恶意网页,还允许用户定义自己的内容过滤器。 +*ublock Origin 可以拦截广告和恶意网页,还允许用户定义自己的内容过滤器。* -[uBlock Origin][3] 是一款快速、内存占用低、适用范围广的拦截器,它不仅能屏蔽广告,还能让你执行你自己的内容过滤。uBlock Origin 默认使用多份预定义好的过滤名单来拦截广告、跟踪器和恶意网页。它允许你任意地添加列表和规则,或者锁定在一个默认拒绝的模式。除了强大之外,这个插件已被证明是效率高、性能好。 +[uBlock Origin][3] 是一款快速、内存占用低、适用范围广的拦截器,它不仅能屏蔽广告,还能让你执行你自己定制的内容过滤。uBlock Origin 默认使用多份预定义好的过滤名单来拦截广告、跟踪器和恶意网页。它允许你任意地添加列表和规则,或者锁定在一个默认拒绝的模式。除了强大之外,这个插件已被证明是效率高、性能好。 ### Privacy Badger ![privacy badger ad blocker][5] -Privacy Badger 运用了算法来无缝地屏蔽侵犯用户准则的广告和跟踪器。 +*Privacy Badger 运用了算法来无缝地屏蔽侵犯用户准则的广告和跟踪器。* -正如它名字所表明,[Privacy Badger][6] 是一款专注于隐私的插件,它屏蔽广告和第三方跟踪器。EFF (LCTT 译者注:EFF全称是电子前哨基金会(Electronic Frontier Foundation),旨在宣传互联网版权和监督执法机构 )说:“我们想要推荐一款能自动分析并屏蔽任何侵犯用户准则的跟踪器和广告,而 Privacy Badger 诞生于此目的;它不用任何设置、知识或者用户的配置,就能运行得很好;它是由一个明显为用户服务而不是为广告主服务的组织出品;它使用算法来绝定什么正在跟踪,什么没有在跟踪” +正如它名字所表明,[Privacy Badger][6] 是一款专注于隐私的插件,它屏蔽广告和第三方跟踪器。EFF (LCTT 译注:EFF 全称是电子前哨基金会Electronic Frontier Foundation,旨在宣传互联网版权和监督执法机构)说:“我们想要推荐一款能自动分析并屏蔽任何侵犯用户准则的跟踪器和广告,而 Privacy Badger 诞生于此目的;它不用任何设置、知识或者用户的配置,就能运行得很好;它是由一个明显为用户服务而不是为广告主服务的组织出品;它使用算法来确定正在跟踪什么,而没有跟踪什么。” -为什么 Privacy Badger 出现在这列表上的原因跟 uBlock Origin 如此相似?其中一个原因是Privacy Badger 从根本上跟 uBlock Origin 的工作不同。另一个原因是纵深防御的做法是个可以跟随的合理策略。 +为什么 Privacy Badger 出现在这列表上的原因跟 uBlock Origin 如此相似?其中一个原因是 Privacy Badger 从根本上跟 uBlock Origin 的工作不同。另一个原因是纵深防御的做法是个可以遵循的合理策略。 ### LastPass ![lastpass password manager screenshot][8] -LastPass 是一款用户友好的密码管理插件,支持双重授权。 +*LastPass 是一款用户友好的密码管理插件,支持双因子认证。* 这个插件对于很多人来说是个有争议的补充。你是否应该使用密码管理器——如果你用了,你是否应该选择一个浏览器插件——这都是个热议的话题,而答案取决于你的风险资料。我想说大部分不关心的电脑用户应该用一个,因为这比起常见的选择:每一处使用相同的弱密码,都好太多了。 -[LastPass][9] 对于用户很友好,支持双重授权,相当安全。这家公司过去出过点安全事故,但是都处理得当,而且资金充足。记住使用密码管理器不是非此即彼的命题。很多用户选择使用密码管理器管理绝大部分密码,但是保持了一点复杂性,为例如银行这样重要的网页精心设计了密码和使用多重认证。 +[LastPass][9] 对于用户很友好,支持双因子认证,相当安全。这家公司过去出过点安全事故,但是都处理得当,而且资金充足。记住使用密码管理器不是非此即彼的命题。很多用户选择使用密码管理器管理绝大部分密码,但是保持了一点复杂性,为例如银行这样重要的网页采用了精心设计的密码和多因子认证。 ### Xmarks Sync @@ -51,11 +51,11 @@ LastPass 是一款用户友好的密码管理插件,支持双重授权。 [Awesome Screenshot Plus][11] 允许你很容易捕获任意网页的全部或部分区域,也能添加注释、评论、使敏感信息模糊等。你还能用一个可选的在线服务来分享图片。我发现这工具在网页调试时截图、讨论设计和分享信息上很棒。这是一款比你预期中发现自己使用得多的工具。 -我发现这五款插件有用,我把它们推荐给其他人。这就是说,还有很多浏览器插件。我好奇其他的哪一款是 Opensource.com 社区用户正在使用并推荐的。让评论中让我知道。(LCTT 译者注:本文引用自 Opensource.com ,这两句话意在引导用户留言,推荐自己使用的插件) - ![Awesome Screenshot Plus screenshot][13] -Awesome Screenshot Plus 允许你容易地截下任何网页的部分或全部内容。 +*Awesome Screenshot Plus 允许你容易地截下任何网页的部分或全部内容。* + +我发现这五款插件有用,我把它们推荐给其他人。这就是说,还有很多浏览器插件。我很感兴趣社区用户们正在使用哪些插件,请在评论中让我知道。 -------------------------------------------------------------------------------- @@ -63,17 +63,17 @@ via: https://opensource.com/article/18/1/top-5-firefox-extensions 作者:[Jeremy Garcia][a] 译者:[ypingcn](https://github.com/ypingcn) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]: https://opensource.com/users/jeremy-garcia -[2]: https://opensource.com/sites/default/files/ublock.png "ublock origin ad blocker screenshot" +[2]: https://opensource.com/sites/default/files/ublock.png [3]: https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/ -[5]: https://opensource.com/sites/default/files/images/life-uploads/privacy_badger_1.0.1.png "privacy badger ad blocker screenshot" +[5]: https://opensource.com/sites/default/files/images/life-uploads/privacy_badger_1.0.1.png [6]: https://www.eff.org/privacybadger -[8]: https://opensource.com/sites/default/files/images/life-uploads/lastpass4.jpg "lastpass password manager screenshot" +[8]: https://opensource.com/sites/default/files/images/life-uploads/lastpass4.jpg [9]: https://addons.mozilla.org/en-US/firefox/addon/lastpass-password-manager/ [10]: https://addons.mozilla.org/en-US/firefox/addon/xmarks-sync/ [11]: https://addons.mozilla.org/en-US/firefox/addon/screenshot-capture-annotate/ -[13]: https://opensource.com/sites/default/files/screenshot_from_2018-01-04_17-11-32.png "Awesome Screenshot Plus screenshot" +[13]: https://opensource.com/sites/default/files/screenshot_from_2018-01-04_17-11-32.png \ No newline at end of file diff --git a/published/20180115 How To Boot Into Linux Command Line.md b/published/201802/20180115 How To Boot Into Linux Command Line.md similarity index 100% rename from published/20180115 How To Boot Into Linux Command Line.md rename to published/201802/20180115 How To Boot Into Linux Command Line.md diff --git a/published/20180118 Getting Started with ncurses.md b/published/201802/20180118 Getting Started with ncurses.md similarity index 100% rename from published/20180118 Getting Started with ncurses.md rename to published/201802/20180118 Getting Started with ncurses.md diff --git a/published/20180120 The World Map In Your Terminal.md b/published/201802/20180120 The World Map In Your Terminal.md similarity index 100% rename from published/20180120 The World Map In Your Terminal.md rename to published/201802/20180120 The World Map In Your Terminal.md diff --git a/published/20180121 Shell Scripting a Bunco Game.md b/published/201802/20180121 Shell Scripting a Bunco Game.md similarity index 100% rename from published/20180121 Shell Scripting a Bunco Game.md rename to published/201802/20180121 Shell Scripting a Bunco Game.md diff --git a/published/20180122 How to price cryptocurrencies.md b/published/201802/20180122 How to price cryptocurrencies.md similarity index 100% rename from published/20180122 How to price cryptocurrencies.md rename to published/201802/20180122 How to price cryptocurrencies.md diff --git a/published/20180122 Linux rm Command Explained for Beginners (8 Examples).md b/published/201802/20180122 Linux rm Command Explained for Beginners (8 Examples).md similarity index 100% rename from published/20180122 Linux rm Command Explained for Beginners (8 Examples).md rename to published/201802/20180122 Linux rm Command Explained for Beginners (8 Examples).md diff --git a/published/20180123 Linux mkdir Command Explained for Beginners (with examples).md b/published/201802/20180123 Linux mkdir Command Explained for Beginners (with examples).md similarity index 100% rename from published/20180123 Linux mkdir Command Explained for Beginners (with examples).md rename to published/201802/20180123 Linux mkdir Command Explained for Beginners (with examples).md diff --git a/published/20180124 8 ways to generate random password in Linux.md b/published/201802/20180124 8 ways to generate random password in Linux.md similarity index 100% rename from published/20180124 8 ways to generate random password in Linux.md rename to published/201802/20180124 8 ways to generate random password in Linux.md diff --git a/published/20180125 A step-by-step guide to Git.md b/published/201802/20180125 A step-by-step guide to Git.md similarity index 100% rename from published/20180125 A step-by-step guide to Git.md rename to published/201802/20180125 A step-by-step guide to Git.md diff --git a/published/201802/20180125 Linux whereis Command Explained for Beginners (5 Examples).md b/published/201802/20180125 Linux whereis Command Explained for Beginners (5 Examples).md new file mode 100644 index 0000000000..5e1ea9f175 --- /dev/null +++ b/published/201802/20180125 Linux whereis Command Explained for Beginners (5 Examples).md @@ -0,0 +1,104 @@ +为初学者介绍 Linux whereis 命令(5个例子) +====== + +有时,在使用命令行的时候,我们需要快速找到某一个命令的二进制文件所在位置。这种情况下可以选择 [find][1] 命令,但使用它会耗费时间,可能也会出现意料之外的情况。有一个专门为这种情况设计的命令:`whereis`。 + +在这篇文章里,我们会通过一些便于理解的例子来解释这一命令的基础内容。但在这之前,值得说明的一点是,下面出现的所有例子都在 Ubuntu 16.04 LTS 下测试过。 + +### Linux whereis 命令 + +`whereis` 命令可以帮助用户寻找某一命令的二进制文件,源码以及帮助页面。下面是它的格式: + +``` +whereis [options] [-BMS directory... -f] name... +``` + +这是这一命令的 man 页面给出的解释: + +> `whereis` 可以查找指定命令的二进制文件、源文件和帮助文件。 被找到的文件在显示时,会去掉主路径名,然后再去掉文件的(单个)尾部扩展名 (如: `.c`),来源于源代码控制的 `s.` 前缀也会被去掉。接下来,`whereis` 会尝试在标准的 Linux 位置里寻找具体程序,也会在由 `$PATH` 和 `$MANPATH` 指定的路径中寻找。 + + +下面这些以 Q&A 形式出现的例子,可以给你一个关于如何使用 whereis 命令的直观感受。 + +### Q1. 如何用 whereis 命令寻找二进制文件所在位置? + +假设你想找,比如说,`whereis` 命令自己所在位置。下面是你具体的操作: + +``` +whereis whereis +``` + +[![How to find location of binary file using whereis][2]][3] + +需要注意的是,输出的第一个路径才是你想要的结果。使用 `whereis` 命令,同时也会显示帮助页面和源码所在路径。(如果能找到的情况下会显示,但是在这一例中没有找到)所以你在输出中看见的第二个路径就是帮助页面文件所在位置。 + +### Q2. 怎么在搜索时规定只搜索二进制文件、帮助页面,还是源代码呢? + +如果你想只搜索,假设说,二进制文件,你可以使用 `-b`  这一命令行选项。例如: + +``` +whereis -b cp +``` + +[![How to specifically search for binaries, manuals, or source code][4]][5] + +类似的,  `-m` 和 `-s` 这两个 选项分别对应 帮助页面和源码。 + + +### Q3.如何限制 whereis 命令搜索位置? + +默认情况下,`whereis` 是从由匹配符所定义的硬编码路径来寻找文件的。但如果你想的话,你可以用命令行选项来限制搜索。例如,如果你只想在 `/usr/bin` 寻找二进制文件,你可以用 `-B` 这一选项来实现。 + +``` +whereis -B /usr/bin/ -f cp +``` + +注意:使用这种方式时可以给出多个路径。使用 `-f` 这一选项来明确分隔目录列表和要搜索的文件名。 + +类似的,如果你想只搜索帮助文件或源码,你可以对应使用  `-M` 和 `-S`  这两个选项。 + +### Q4. 如何查看 whereis 的搜索路径? + +与此相对应的也有一个选项。只要在 `whereis` 后加上 `-l`。 + +``` +whereis -l +``` + +这是例子的部分输出结果: + +[![How to see paths that whereis uses for search][6]][7] + +### Q5. 如何找到一个有异常条目的命令? + +对于 `whereis` 命令来说,如果一个命令对每个显式的请求类型都不止一项,则该命令被视为异常。例如,没有可用文档的命令,或者对应文档分散在各处的命令都可以算作异常命令。 当使用 `-u` 这一选项,`whereis` 就会显示那些有异常条目的命令。 + +例如,下面这一例子就显示,在当前目录中,没有对应文档或有多个文档的命令。 + +``` +whereis -m -u * +``` + +### 总结 + +我觉得,`whereis` 不是那种你需要经常使用的命令行工具。但在遇到某些特殊情况时,它绝对会让你的生活变得轻松。我们已经涉及了这一工具提供的一些重要命令行选项,所以要注意练习。想了解更多信息,直接去看它的 [man][8] 页面吧。 + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/linux-whereis-command/ + +作者:[Himanshu Arora][a] +译者:[wenwensnow](https://github.com/wenwensnow) +校对:[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/tutorial/linux-find-command/ +[2]:https://www.howtoforge.com/images/command-tutorial/whereis-basic-usage.png +[3]:https://www.howtoforge.com/images/command-tutorial/big/whereis-basic-usage.png +[4]:https://www.howtoforge.com/images/command-tutorial/whereis-b-option.png +[5]:https://www.howtoforge.com/images/command-tutorial/big/whereis-b-option.png +[6]:https://www.howtoforge.com/images/command-tutorial/whereis-l.png +[7]:https://www.howtoforge.com/images/command-tutorial/big/whereis-l.png +[8]:https://linux.die.net/man/1/whereis diff --git a/published/201802/20180126 Creating an Adventure Game in the Terminal with ncurses.md b/published/201802/20180126 Creating an Adventure Game in the Terminal with ncurses.md new file mode 100644 index 0000000000..d42a56fbcd --- /dev/null +++ b/published/201802/20180126 Creating an Adventure Game in the Terminal with ncurses.md @@ -0,0 +1,310 @@ +通过 ncurses 在终端创建一个冒险游戏 +====== + +怎样使用 curses 函数读取键盘并操作屏幕。 + +我[之前的文章][1]介绍了 ncurses 库,并提供了一个简单的程序展示了一些将文本放到屏幕上的 curses 函数。在接下来的文章中,我将介绍如何使用其它的 curses 函数。 + +### 探险 + +当我逐渐长大,家里有了一台苹果 II 电脑。我和我兄弟正是在这台电脑上自学了如何用 AppleSoft BASIC 写程序。我在写了一些数学智力游戏之后,继续创造游戏。作为 80 年代的人,我已经是龙与地下城桌游的粉丝,在游戏中角色扮演一个追求打败怪物并在陌生土地上抢掠的战士或者男巫,所以我创建一个基本的冒险游戏也在情理之中。 + +AppleSoft BASIC 支持一种简洁的特性:在标准分辨率图形模式(GR 模式)下,你可以检测屏幕上特定点的颜色。这为创建一个冒险游戏提供了捷径。比起创建并更新周期性传送到屏幕的内存地图,我现在可以依赖 GR 模式为我维护地图,我的程序还可以在玩家的角色(LCTT 译注:此处 character 双关一个代表玩家的角色,同时也是一个字符)在屏幕四处移动的时候查询屏幕。通过这种方式,我让电脑完成了大部分艰难的工作。因此,我的自顶向下的冒险游戏使用了块状的 GR 模式图形来展示我的游戏地图。 + +我的冒险游戏使用了一张简单的地图,上面有一大片绿地伴着山脉从中间蔓延向下和一个在左上方的大湖。我要粗略地为桌游战役绘制这个地图,其中包含一个允许玩家穿过到远处的狭窄通道。 + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-map.jpg) + +*图 1. 一个有湖和山的简单桌游地图* + +你可以用 curses 绘制这个地图,并用字符代表草地、山脉和水。接下来,我描述怎样使用 curses 那样做,以及如何在 Linux 终端创建和进行类似的一个冒险游戏。 + +### 构建程序 + +在我的上一篇文章,我提到了大多数 curses 程序以相同的一组指令获取终端类型和设置 curses 环境: + +``` +initscr(); +cbreak(); +noecho(); +``` + +在这个程序,我添加了另外的语句: + +``` +keypad(stdscr, TRUE); +``` + +这里的 `TRUE` 标志允许 curses 从用户终端读取小键盘和功能键。如果你想要在你的程序中使用上下左右方向键,你需要使用这里的 `keypad(stdscr, TRUE)`。 + +这样做了之后,你现在可以开始在终端屏幕上绘图了。curses 函数包括了一系列在屏幕上绘制文本的方法。在我之前的文章中,我展示了 `addch()` 和 `addstr()` 函数以及在添加文本之前先移动到指定屏幕位置的对应函数 `mvaddch()` 和 `mvaddstr()`。为了在终端上创建这个冒险游戏的地图,你可以使用另外一组函数:`vline()` 和 `hline()`,以及它们对应的函数 `mvvline()` 和 `mvhline()`。这些 mv 函数接受屏幕坐标、一个要绘制的字符和要重复此字符的次数的参数。例如,`mvhline(1, 2, '-', 20)` 将会绘制一条开始于第一行第二列并由 20 个横线组成的线段。 + +为了以编程方式绘制地图到终端屏幕上,让我们先定义这个 `draw_map()` 函数: + +``` +#define GRASS ' ' +#define EMPTY '.' +#define WATER '~' +#define MOUNTAIN '^' +#define PLAYER '*' + +void draw_map(void) +{ + int y, x; + + /* 绘制探索地图 */ + + /* 背景 */ + + for (y = 0; y < LINES; y++) { + mvhline(y, 0, GRASS, COLS); + } + + /* 山和山道 */ + + for (x = COLS / 2; x < COLS * 3 / 4; x++) { + mvvline(0, x, MOUNTAIN, LINES); + } + + mvhline(LINES / 4, 0, GRASS, COLS); + + /* 湖 */ + + for (y = 1; y < LINES / 2; y++) { + mvhline(y, 1, WATER, COLS / 3); + } +} + +``` + +在绘制这副地图时,记住填充大块字符到屏幕所使用的 `mvvline()` 和 `mvhline()` 函数。我绘制从 0 列开始的字符水平线(`mvhline`)以创建草地区域,直到占满整个屏幕的高度和宽度。我绘制从 0 行开始的多条垂直线(`mvvline`)在此上添加了山脉,绘制单行水平线添加了一条山道(`mvhline`)。并且,我通过绘制一系列短水平线(`mvhline`)创建了湖。这种绘制重叠方块的方式看起来似乎并没有效率,但是记住在我们调用 `refresh()` 函数之前 curses 并不会真正更新屏幕。 + +绘制完地图,创建游戏就还剩下进入循环让程序等待用户按下上下左右方向键中的一个然后让玩家图标正确移动了。如果玩家想要移动的地方是空的,就应该允许玩家到那里。 + +你可以把 curses 当做捷径使用。比起在程序中实例化一个版本的地图并复制到屏幕这么复杂,你可以让屏幕为你跟踪所有东西。`inch()` 函数和相关联的 `mvinch()` 函数允许你探测屏幕的内容。这让你可以查询 curses 以了解玩家想要移动到的位置是否被水填满或者被山阻挡。这样做你需要一个之后会用到的一个帮助函数: + +``` +int is_move_okay(int y, int x) +{ + int testch; + + /* 如果要进入的位置可以进入,返回 true */ + + testch = mvinch(y, x); + return ((testch == GRASS) || (testch == EMPTY)); +} +``` + +如你所见,这个函数探测行 `x`、列 `y` 并在空间未被占据的时候返回 `true`,否则返回 `false`。 + +这样我们写移动循环就很容易了:从键盘获取一个键值然后根据是上下左右键移动用户字符。这里是一个这种循环的简单版本: + +``` + + do { + ch = getch(); + + /* 测试输入的值并获取方向 */ + + switch (ch) { + case KEY_UP: + if ((y > 0) && is_move_okay(y - 1, x)) { + y = y - 1; + } + break; + case KEY_DOWN: + if ((y < LINES - 1) && is_move_okay(y + 1, x)) { + y = y + 1; + } + break; + case KEY_LEFT: + if ((x > 0) && is_move_okay(y, x - 1)) { + x = x - 1; + } + break; + case KEY_RIGHT + if ((x < COLS - 1) && is_move_okay(y, x + 1)) { + x = x + 1; + } + break; + } + } + while (1); +``` + +为了在游戏中使用这个循环,你需要在循环里添加一些代码来启用其它的键(例如传统的移动键 WASD),以提供让用户退出游戏和在屏幕上四处移动的方法。这里是完整的程序: + +``` +/* quest.c */ + +#include +#include + +#define GRASS ' ' +#define EMPTY '.' +#define WATER '~' +#define MOUNTAIN '^' +#define PLAYER '*' + +int is_move_okay(int y, int x); +void draw_map(void); + +int main(void) +{ + int y, x; + int ch; + + /* 初始化curses */ + + initscr(); + keypad(stdscr, TRUE); + cbreak(); + noecho(); + + clear(); + + /* 初始化探索地图 */ + + draw_map(); + + /* 在左下角初始化玩家 */ + + y = LINES - 1; + x = 0; + + do { + /* 默认获得一个闪烁的光标--表示玩家字符 */ + + mvaddch(y, x, PLAYER); + move(y, x); + refresh(); + + ch = getch(); + + /* 测试输入的键并获取方向 */ + + switch (ch) { + case KEY_UP: + case 'w': + case 'W': + if ((y > 0) && is_move_okay(y - 1, x)) { + mvaddch(y, x, EMPTY); + y = y - 1; + } + break; + case KEY_DOWN: + case 's': + case 'S': + if ((y < LINES - 1) && is_move_okay(y + 1, x)) { + mvaddch(y, x, EMPTY); + y = y + 1; + } + break; + case KEY_LEFT: + case 'a': + case 'A': + if ((x > 0) && is_move_okay(y, x - 1)) { + mvaddch(y, x, EMPTY); + x = x - 1; + } + break; + case KEY_RIGHT: + case 'd': + case 'D': + if ((x < COLS - 1) && is_move_okay(y, x + 1)) { + mvaddch(y, x, EMPTY); + x = x + 1; + } + break; + } + } + while ((ch != 'q') && (ch != 'Q')); + + endwin(); + + exit(0); +} + +int is_move_okay(int y, int x) +{ + int testch; + + /* 当空间可以进入时返回true */ + + testch = mvinch(y, x); + return ((testch == GRASS) || (testch == EMPTY)); +} + +void draw_map(void) +{ + int y, x; + + /* 绘制探索地图 */ + + /* 背景 */ + + for (y = 0; y < LINES; y++) { + mvhline(y, 0, GRASS, COLS); + } + + /* 山脉和山道 */ + + for (x = COLS / 2; x < COLS * 3 / 4; x++) { + mvvline(0, x, MOUNTAIN, LINES); + } + + mvhline(LINES / 4, 0, GRASS, COLS); + + /* 湖 */ + + for (y = 1; y < LINES / 2; y++) { + mvhline(y, 1, WATER, COLS / 3); + } +} +``` + +在完整的程序清单中,你可以看见使用 curses 函数创建游戏的完整布置: + +1. 初始化 curses 环境。 +2. 绘制地图。 +3. 初始化玩家坐标(左下角) +4. 循环: + * 绘制玩家的角色。 + * 从键盘获取键值。 + * 对应地上下左右调整玩家坐标。 + * 重复。 +5. 完成时关闭curses环境并退出。 + +### 开始玩 + +当你运行游戏时,玩家的字符在左下角初始化。当玩家在游戏区域四处移动的时候,程序创建了“一串”点。这样可以展示玩家经过了的点,让玩家避免经过不必要的路径。 + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-start.png) + +*图 2. 初始化在左下角的玩家* + +![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-1.png) + +*图 3. 玩家可以在游戏区域四处移动,例如湖周围和山的通道* + +为了创建上面这样的完整冒险游戏,你可能需要在他/她的角色在游戏区域四处移动的时候随机创建不同的怪物。你也可以创建玩家可以发现在打败敌人后可以掠夺的特殊道具,这些道具应能提高玩家的能力。 + +但是作为起点,这是一个展示如何使用 curses 函数读取键盘和操纵屏幕的好程序。 + +### 下一步 + +这是一个如何使用 curses 函数更新和读取屏幕和键盘的简单例子。按照你的程序需要做什么,curses 可以做得更多。在下一篇文章中,我计划展示如何更新这个简单程序以使用颜色。同时,如果你想要学习更多 curses,我鼓励你去读位于 Linux 文档计划的 Pradeep Padala 写的[如何使用 NCURSES 编程][2]。 + +-------------------------------------------------------------------------------- + +via: http://www.linuxjournal.com/content/creating-adventure-game-terminal-ncurses + +作者:[Jim Hall][a] +译者:[Leemeans](https://github.com/leemeans) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://www.linuxjournal.com/users/jim-hall +[1]:https://linux.cn/article-9348-1.html +[2]:http://tldp.org/HOWTO/NCURSES-Programming-HOWTO diff --git a/published/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md b/published/201802/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md similarity index 100% rename from published/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md rename to published/201802/20180130 Linux Kernel 4.15 An Unusual Release Cycle.md diff --git a/published/201802/20180131 Fastest way to unzip a zip file in Python.md b/published/201802/20180131 Fastest way to unzip a zip file in Python.md new file mode 100644 index 0000000000..be7e06bf04 --- /dev/null +++ b/published/201802/20180131 Fastest way to unzip a zip file in Python.md @@ -0,0 +1,160 @@ +Python 中最快解压 zip 文件的方法 +====== + +假设现在的上下文(LCTT 译注:context,计算机术语,此处意为业务情景)是这样的:一个 zip 文件被上传到一个[Web 服务][1]中,然后 Python 需要解压这个 zip 文件然后分析和处理其中的每个文件。这个特殊的应用查看每个文件各自的名称和大小,并和已经上传到 AWS S3 上的文件进行比较,如果文件(和 AWS S3 上的相比)有所不同或者文件本身更新,那么就将它上传到 AWS S3。 + +[![Uploads today][2]][3] + +挑战在于这些 zip 文件太大了。它们的平均大小是 560MB 但是其中一些大于 1GB。这些文件中大多数是文本文件,但是其中同样也有一些巨大的二进制文件。不同寻常的是,每个 zip 文件包含 100 个文件但是其中 1-3 个文件却占据了多达 95% 的 zip 文件大小。 + +最开始我尝试在内存中解压文件,并且每次只处理一个文件。在各种内存爆炸和 EC2 耗尽内存的情况下,这个方法壮烈失败了。我觉得这个原因是这样的。最开始你有 1GB 文件在内存中,然后你现在解压每个文件,在内存中大约就要占用 2-3GB。所以,在很多次测试之后,解决方案是将这些 zip 文件复制到磁盘上(在临时目录 `/tmp` 中),然后遍历这些文件。这次情况好多了但是我仍然注意到了整个解压过程花费了巨量的时间。**是否可能有方法优化呢?** + +### 原始函数 + +首先是下面这些模拟对 zip 文件中文件实际操作的普通函数: + +``` +def _count_file(fn): + with open(fn, 'rb') as f: + return _count_file_object(f) + +def _count_file_object(f): + # Note that this iterates on 'f'. + # You *could* do 'return len(f.read())' + # which would be faster but potentially memory + # inefficient and unrealistic in terms of this + # benchmark experiment. + total = 0 + for line in f: + total += len(line) + return total +``` + +这里是可能最简单的另一个函数: + +``` +def f1(fn, dest): + with open(fn, 'rb') as f: + zf = zipfile.ZipFile(f) + zf.extractall(dest) + + total = 0 + for root, dirs, files in os.walk(dest): + for file_ in files: + fn = os.path.join(root, file_) + total += _count_file(fn) + return total +``` + +如果我更仔细地分析一下,我将会发现这个函数花费时间 40% 运行 `extractall`,60% 的时间在遍历各个文件并读取其长度。 + +### 第一步尝试 + +我的第一步尝试是使用线程。先创建一个 `zipfile.ZipFile` 的实例,展开其中的每个文件名,然后为每一个文件开始一个线程。每个线程都给它一个函数来做“实质工作”(在这个基准测试中,就是遍历每个文件然后获取它的名称)。实际业务中的函数进行的工作是复杂的 S3、Redis 和 PostgreSQL 操作,但是在我的基准测试中我只需要制作一个可以找出文件长度的函数就好了。线程池函数: + +``` +def f2(fn, dest): + + def unzip_member(zf, member, dest): + zf.extract(member, dest) + fn = os.path.join(dest, member.filename) + return _count_file(fn) + + with open(fn, 'rb') as f: + zf = zipfile.ZipFile(f) + futures = [] + with concurrent.futures.ThreadPoolExecutor() as executor: + for member in zf.infolist(): + futures.append( + executor.submit( + unzip_member, + zf, + member, + dest, + ) + ) + total = 0 + for future in concurrent.futures.as_completed(futures): + total += future.result() + return total +``` + +**结果:加速 ~10%** + +### 第二步尝试 + +所以可能是 GIL(LCTT 译注:Global Interpreter Lock,一种全局锁,CPython 中的一个概念)阻碍了我。最自然的想法是尝试使用多线程在多个 CPU 上分配工作。但是这样做有缺点,那就是你不能传递一个非可 pickle 序列化的对象(LCTT 译注:意为只有可 pickle 序列化的对象可以被传递),所以你只能发送文件名到之后的函数中: + +``` +def unzip_member_f3(zip_filepath, filename, dest): + with open(zip_filepath, 'rb') as f: + zf = zipfile.ZipFile(f) + zf.extract(filename, dest) + fn = os.path.join(dest, filename) + return _count_file(fn) + + + +def f3(fn, dest): + with open(fn, 'rb') as f: + zf = zipfile.ZipFile(f) + futures = [] + with concurrent.futures.ProcessPoolExecutor() as executor: + for member in zf.infolist(): + futures.append( + executor.submit( + unzip_member_f3, + fn, + member.filename, + dest, + ) + ) + total = 0 + for future in concurrent.futures.as_completed(futures): + total += future.result() + return total +``` + +**结果: 加速 ~300%** + +### 这是作弊 + +使用处理器池的问题是这样需要存储在磁盘上的原始 `.zip` 文件。所以为了在我的 web 服务器上使用这个解决方案,我首先得要将内存中的 zip 文件保存到磁盘,然后调用这个函数。这样做的代价我不是很清楚但是应该不低。 + +好吧,再翻翻看又没有损失。可能,解压过程加速到足以弥补这样做的损失了吧。 + +但是一定记住!这个优化取决于使用所有可用的 CPU。如果一些其它的 CPU 需要执行在 `gunicorn` 中的其它事务呢?这时,这些其它进程必须等待,直到有 CPU 可用。由于在这个服务器上有其他的事务正在进行,我不是很确定我想要在进程中接管所有其他 CPU。 + +### 结论 + +一步一步地做这个任务的这个过程感觉挺好的。你被限制在一个 CPU 上但是表现仍然特别好。同样地,一定要看看在`f1` 和 `f2` 两段代码之间的不同之处!利用 `concurrent.futures` 池类你可以获取到允许使用的 CPU 的个数,但是这样做同样给人感觉不是很好。如果你在虚拟环境中获取的个数是错的呢?或者可用的个数太低以致无法从负载分配获取好处并且现在你仅仅是为了移动负载而支付营运开支呢? + +我将会继续使用 `zipfile.ZipFile(file_buffer).extractall(temp_dir)`。这个工作这样做已经足够好了。 + +### 想试试手吗? + +我使用一个 `c5.4xlarge` EC2 服务器来进行我的基准测试。文件可以从此处下载: + +``` +wget https://www.peterbe.com/unzip-in-parallel/hack.unzip-in-parallel.py +wget https://www.peterbe.com/unzip-in-parallel/symbols-2017-11-27T14_15_30.zip +``` + +这里的 `.zip` 文件有 34MB。和在服务器上的相比已经小了很多。 + +`hack.unzip-in-parallel.py` 文件里是一团糟。它包含了大量可怕的修正和丑陋的代码,但是这只是一个开始。 + +-------------------------------------------------------------------------------- + +via: https://www.peterbe.com/plog/fastest-way-to-unzip-a-zip-file-in-python + +作者:[Peterbe][a] +译者:[Leemeans](https://github.com/leemeans) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.peterbe.com/ +[1]:https://symbols.mozilla.org +[2]:https://cdn-2916.kxcdn.com/cache/b7/bb/b7bbcf60347a5fa91420f71bbeed6d37.png +[3]:https://cdn-2916.kxcdn.com/cache/e6/dc/e6dc20acd37d94239edbbc0727721e4a.png diff --git a/published/20180131 Why you should use named pipes on Linux.md b/published/201802/20180131 Why you should use named pipes on Linux.md similarity index 100% rename from published/20180131 Why you should use named pipes on Linux.md rename to published/201802/20180131 Why you should use named pipes on Linux.md diff --git a/published/20180201 Custom Embedded Linux Distributions.md b/published/201802/20180201 Custom Embedded Linux Distributions.md similarity index 100% rename from published/20180201 Custom Embedded Linux Distributions.md rename to published/201802/20180201 Custom Embedded Linux Distributions.md diff --git a/published/201802/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md b/published/201802/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md new file mode 100644 index 0000000000..0572935c15 --- /dev/null +++ b/published/201802/20180201 How to reload .vimrc file without restarting vim on Linux-Unix.md @@ -0,0 +1,73 @@ +如何在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件 +====== + +我是一位新的 Vim 编辑器用户。我通常使用 `:vs ~/.vimrc` 来加载 `~/.vimrc` 配置。而当我编辑 `.vimrc` 时,我需要不重启 Vim 会话而重新加载它。在 Linux 或者类 Unix 系统中,如何在编辑 `.vimrc` 后,重新加载它而不用重启 Vim 呢? + +Vim 是自由开源并且向上兼容 Vi 的编辑器。它可以用来编辑各种文本。它在编辑用 C/Perl/Python 编写的程序时特别有用。可以用它来编辑 Linux/Unix 配置文件。`~/.vimrc` 是你个人的 Vim 初始化和自定义文件。 + +### 如何在不重启 Vim 会话的情况下重新加载 .vimrc + +在 Vim 中重新加载 `.vimrc` 而不重新启动的流程: + +1. 输入 `vim filename` 启动 vim +2. 按下 `Esc` 接着输入 `:vs ~/.vimrc` 来加载 vim 配置 +3. 像这样添加自定义配置: + + ``` +filetype indent plugin on +set number +syntax on +``` +4. 使用 `:wq` 保存文件,并从 `~/.vimrc` 窗口退出 +5. 输入下面任一命令重载 `~/.vimrc`:`:so $MYVIMRC` 或者 `:source ~/.vimrc`。 + +[![How to reload .vimrc file without restarting vim][1]][1] + +*图1:编辑 ~/.vimrc 并在需要时重载它而不用退出 vim,这样你就可以继续编辑程序了* + +`:so[urce]! {file}` 这个 vim 命令会从给定的文件比如 `~/.vimrc` 读取配置。就像你输入的一样,这些命令是在普通模式下执行的。当你在 `:global`、:`argdo`、 `:windo`、`:bufdo` 之后、循环中或者跟着另一个命令时,显示不会再在执行命令时更新。 + +### 如何设置按键来编辑并重载 ~/.vimrc + +在你的 `~/.vimrc` 后面跟上这些: + +``` +" Edit vimr configuration file +nnoremap confe :e $MYVIMRC +" Reload vims configuration file +nnoremap confr :source $MYVIMRC +``` + +现在只要按下 `Esc` 接着输入 `confe` 就可以编辑 `~/.vimrc`。按下 `Esc` ,接着输入 `confr` 以重新加载。一些人喜欢在 `.vimrc` 中使用 `` 键。因此上面的映射变成: + +``` +" Edit vimr configuration file +nnoremap ve :e $MYVIMRC +" Reload vimr configuration file +nnoremap vr :source $MYVIMRC +``` + +`` 键默认映射成 `\` 键。因此只要输入 `\` 接着 `ve` 就能编辑文件。按下 `\` 接着 `vr` 就能重载 `~/vimrc`。 + +这就完成了,你可以不用再重启 Vim 就能重新加载 `.vimrc` 了。 + +### 关于作者 + +作者是 nixCraft 的创建者,经验丰富的系统管理员,也是 Linux / Unix shell 脚本的培训师。他曾与全球客户以及IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 [Twitter][9]、[Facebook][10]、[Google +][11] 上关注他。通过[RSS/XML 订阅][5]获取最新的系统管理、Linux/Unix 以及开源主题教程。 + +-------------------------------------------------------------------------------- + +via: https://www.cyberciti.biz/faq/how-to-reload-vimrc-file-without-restarting-vim-on-linux-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/2018/02/How-to-reload-.vimrc-file-without-restarting-vim.jpg +[2]:https://twitter.com/nixcraft +[3]:https://facebook.com/nixcraft +[4]:https://plus.google.com/+CybercitiBiz +[5]:https://www.cyberciti.biz/atom/atom.xml diff --git a/published/20180202 Tuning MySQL 3 Simple Tweaks.md b/published/201802/20180202 Tuning MySQL 3 Simple Tweaks.md similarity index 100% rename from published/20180202 Tuning MySQL 3 Simple Tweaks.md rename to published/201802/20180202 Tuning MySQL 3 Simple Tweaks.md diff --git a/published/20180202 Which Linux Kernel Version Is Stable.md b/published/201802/20180202 Which Linux Kernel Version Is Stable.md similarity index 100% rename from published/20180202 Which Linux Kernel Version Is Stable.md rename to published/201802/20180202 Which Linux Kernel Version Is Stable.md diff --git a/published/20180203 Open source software 20 years and counting.md b/published/201802/20180203 Open source software 20 years and counting.md similarity index 100% rename from published/20180203 Open source software 20 years and counting.md rename to published/201802/20180203 Open source software 20 years and counting.md diff --git a/published/20180206 Save Some Battery On Our Linux Machines With TLP.md b/published/201802/20180206 Save Some Battery On Our Linux Machines With TLP.md similarity index 100% rename from published/20180206 Save Some Battery On Our Linux Machines With TLP.md rename to published/201802/20180206 Save Some Battery On Our Linux Machines With TLP.md diff --git a/published/20180206 Simple TensorFlow Examples.md b/published/201802/20180206 Simple TensorFlow Examples.md similarity index 100% rename from published/20180206 Simple TensorFlow Examples.md rename to published/201802/20180206 Simple TensorFlow Examples.md diff --git a/translated/tech/20180206 What Is Kali Linux, and Do You Need It.md b/published/201802/20180206 What Is Kali Linux, and Do You Need It.md similarity index 85% rename from translated/tech/20180206 What Is Kali Linux, and Do You Need It.md rename to published/201802/20180206 What Is Kali Linux, and Do You Need It.md index f603d3a3fd..5506807a6b 100644 --- a/translated/tech/20180206 What Is Kali Linux, and Do You Need It.md +++ b/published/201802/20180206 What Is Kali Linux, and Do You Need It.md @@ -3,19 +3,19 @@ Kali Linux 是什么,你需要它吗? ![](https://www.maketecheasier.com/assets/uploads/2018/01/kl-feat.jpg) -如果你听到一个 13 岁的黑客吹嘘它是多么的牛逼,是有可能的,因为有 Kali Linux 的存在。尽管有可能会被称为“脚本小子”,但是事实上,Kali 仍旧是安全专家手头的重要工具(或工具集)。 +如果你听到一个 13 岁的黑客吹嘘他是多么的牛逼,是有可能的,因为有 Kali Linux 的存在。尽管有可能会被称为“脚本小子”,但是事实上,Kali 仍旧是安全专家手头的重要工具(或工具集)。 -Kali 是一个基于 Debian 的 Linux 发行版。它的目标就是为了简单;在一个实用的工具包里尽可能多的包含渗透和审计工具。Kali 实现了这个目标。大多数做安全测试的开源工具都被囊括在内。 +Kali 是一个基于 Debian 的 Linux 发行版。它的目标就是为了简单:在一个实用的工具包里尽可能多的包含渗透和审计工具。Kali 实现了这个目标。大多数做安全测试的开源工具都被囊括在内。 -**相关** : [4 个极好的为隐私和案例设计的 Linux 发行版][1] +**相关** : [4 个极好的为隐私和安全设计的 Linux 发行版][1] ### 为什么是 Kali? ![Kali Linux Desktop][2] -[Kali][3] 是由 Offensive Security (https://www.offensive-security.com/)公司开发和维护的。它在安全领域是一家知名的、值得信赖的公司,它甚至还有一些受人尊敬的认证,来对安全从业人员做资格认证。 +[Kali][3] 是由 [Offensive Security](https://www.offensive-security.com/) 公司开发和维护的。它在安全领域是一家知名的、值得信赖的公司,它甚至还有一些受人尊敬的认证,来对安全从业人员做资格认证。 -Kali 也是一个简便的安全解决方案。Kali 并不要求你自己去维护一个 Linux,或者收集你自己的软件和依赖。它是一个“交钥匙工程”。所有这些繁杂的工作都不需要你去考虑,因此,你只需要专注于要审计的真实工作上,而不需要去考虑准备测试系统。 +Kali 也是一个简便的安全解决方案。Kali 并不要求你自己去维护一个 Linux 系统,或者你自己去收集软件和依赖项。它是一个“交钥匙工程”。所有这些繁杂的工作都不需要你去考虑,因此,你只需要专注于要审计的真实工作上,而不需要去考虑准备测试系统。 ### 如何使用它? @@ -61,7 +61,7 @@ via: https://www.maketecheasier.com/what-is-kali-linux-and-do-you-need-it/ 作者:[Nick Congleton][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201802/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md b/published/201802/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md new file mode 100644 index 0000000000..52c5c59dc7 --- /dev/null +++ b/published/201802/20180209 How to Install Gogs Go Git Service on Ubuntu 16.04.md @@ -0,0 +1,434 @@ +如何在 Ubuntu 安装 Go 语言编写的 Git 服务器 Gogs +====== + +Gogs 是由 Go 语言编写的,自由开源的 Git 服务。Gogs 是一款无痛式自托管的 Git 服务器,能在尽可能小的硬件资源开销上搭建并运行您的私有 Git 服务器。Gogs 的网页界面和 GitHub 十分相近,且提供 MySQL、PostgreSQL 和 SQLite 数据库支持。 + +在本教程中,我们将使用 Gogs 在 Ununtu 16.04 上按步骤指导您安装和配置您的私有 Git 服务器。这篇教程中涵盖了如何在 Ubuntu 上安装 Go 语言、PostgreSQL 和安装并且配置 Nginx 网页服务器作为 Go 应用的反向代理的细节内容。 + +### 搭建环境 + + * Ubuntu 16.04 + * Root 权限 + +### 我们将会接触到的事物 + + 1. 更新和升级系统 + 2. 安装和配置 PostgreSQL + 3. 安装 Go 和 Git + 4. 安装 Gogs + 5. 配置 Gogs + 6. 运行 Gogs 服务器 + 7. 安装和配置 Nginx 反向代理 + 8. 测试 + +### 步骤 1 - 更新和升级系统 + +继续之前,更新 Ubuntu 所有的库,升级所有包。 + +运行下面的 `apt` 命令: + +``` +sudo apt update +sudo apt upgrade +``` + +### 步骤 2 - 安装和配置 PostgreSQL + +Gogs 提供 MySQL、PostgreSQL、SQLite 和 TiDB 数据库系统支持。 + +此步骤中,我们将使用 PostgreSQL 作为 Gogs 程序的数据库。 + +使用下面的 `apt` 命令安装 PostgreSQL。 + +``` +sudo apt install -y postgresql postgresql-client libpq-dev +``` + +安装完成之后,启动 PostgreSQL 服务并设置为开机启动。 + +``` +systemctl start postgresql +systemctl enable postgresql +``` + +此时 PostgreSQL 数据库在 Ubuntu 系统上完成安装了。 + +之后,我们需要为 Gogs 创建数据库和用户。 + +使用 `postgres` 用户登录并运行 `psql` 命令以访问 PostgreSQL 操作界面。 + +``` +su - postgres +psql +``` + +创建一个名为 `git` 的新用户,给予此用户 `CREATEDB` 权限。 + +``` +CREATE USER git CREATEDB; +\password git +``` + +创建名为 `gogs_production` 的数据库,设置 `git` 用户作为其所有者。 + +``` +CREATE DATABASE gogs_production OWNER git; +``` + +[![创建 Gogs 数据库][1]][2] + +用于 Gogs 的 `gogs_production` PostgreSQL 数据库和 `git` 用户已经创建完毕。 + +### 步骤 3 - 安装 Go 和 Git + +使用下面的 `apt` 命令从库中安装 Git。 + +``` +sudo apt install git +``` + +此时,为系统创建名为 `git` 的新用户。 + +``` +sudo adduser --disabled-login --gecos 'Gogs' git +``` + +登录 `git` 账户并且创建名为 `local` 的目录。 + +``` +su - git +mkdir -p /home/git/local +``` + +切换到 `local` 目录,依照下方所展示的内容,使用 `wget` 命令下载 Go(最新版)。 + +``` +cd ~/local +wget https://dl.google.com/go/go1.9.2.linux-amd64.tar.gz +``` + +[![安装 Go 和 Git][3]][4] + +解压并且删除 go 的压缩文件。 + +``` +tar -xf go1.9.2.linux-amd64.tar.gz +rm -f go1.9.2.linux-amd64.tar.gz +``` + +Go 二进制文件已经被下载到 `~/local/go` 目录。此时我们需要设置环境变量 - 设置 `GOROOT` 和 `GOPATH` 目录到系统环境,这样,我们就可以在 `git` 用户下执行 `go` 命令。 + +执行下方的命令。 + +``` +cd ~/ +echo 'export GOROOT=$HOME/local/go' >> $HOME/.bashrc +echo 'export GOPATH=$HOME/go' >> $HOME/.bashrc +echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' >> $HOME/.bashrc +``` + +之后通过运行 `source ~/.bashrc` 重载 Bash,如下: + +``` +source ~/.bashrc +``` + +确定您使用的 Bash 是默认的 shell。 + +[![安装 Go 编程语言][5]][6] + +现在运行 `go` 的版本查看命令。 + +``` +go version +``` + +之后确保您得到下图所示的结果。 + +[![检查 go 版本][7]][8] + +现在,Go 已经安装在系统的 `git` 用户下了。 + +### 步骤 4 - 使用 Gogs 安装 Git 服务 + +使用 `git` 用户登录并且使用 `go` 命令从 GitHub 下载 Gogs。 + +``` +su - git +go get -u github.com/gogits/gogs +``` + +此命令将在 `GOPATH/src` 目录下载 Gogs 的所有源代码。 + +切换至 `$GOPATH/src/github.com/gogits/gogs` 目录,并且使用下列命令搭建 Gogs。 + +``` +cd $GOPATH/src/github.com/gogits/gogs +go build +``` + +确保您没有遇到错误。 + +现在使用下面的命令运行 Gogs Go Git 服务器。 + +``` +./gogs web +``` + +此命令将会默认运行 Gogs 在 3000 端口上。 + +[![安装 Gogs Go Git 服务][9]][10] + +打开网页浏览器,键入您的 IP 地址和端口号,我的是 http://192.168.33.10:3000/ 。 + +您应该会得到与下方一致的反馈。 + +[![Gogs 网页服务器][11]][12] + +Gogs 已经在您的 Ubuntu 系统上安装完毕。现在返回到您的终端,并且键入 `Ctrl + C` 中止服务。 + +### 步骤 5 - 配置 Gogs Go Git 服务器 + +本步骤中,我们将为 Gogs 创建惯例配置。 + +进入 Gogs 安装目录并新建 `custom/conf` 目录。 + +``` +cd $GOPATH/src/github.com/gogits/gogs +mkdir -p custom/conf/ +``` + +复制默认的配置文件到 `custom` 目录,并使用 [vim][13] 修改。 + +``` +cp conf/app.ini custom/conf/app.ini +vim custom/conf/app.ini +``` + +在 `[server]` 小节中,修改 `HOST_ADDR` 为 `127.0.0.1`。 + +``` +[server] + PROTOCOL = http + DOMAIN = localhost + ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ + HTTP_ADDR = 127.0.0.1 + HTTP_PORT = 3000 +``` + +在 `[database]` 选项中,按照您的数据库信息修改。 + +``` +[database] + DB_TYPE = postgres + HOST = 127.0.0.1:5432 + NAME = gogs_production + USER = git + PASSWD = aqwe123@# +``` + +保存并退出。 + +运行下面的命令验证配置项。 + +``` +./gogs web +``` + +并且确保您得到如下的结果。 + +[![配置服务器][14]][15] + +Gogs 现在已经按照自定义配置下运行在 `localhost` 的 3000 端口上了。 + +### 步骤 6 - 运行 Gogs 服务器 + +这一步,我们将在 Ubuntu 系统上配置 Gogs 服务器。我们会在 `/etc/systemd/system` 目录下创建一个新的服务器配置文件 `gogs.service`。 + +切换到 `/etc/systemd/system` 目录,使用 [vim][13] 创建服务器配置文件 `gogs.service`。 + +``` +cd /etc/systemd/system +vim gogs.service +``` + +粘贴下面的代码到 Gogs 服务器配置文件中。 + +``` +[Unit] +Description=Gogs +After=syslog.target +After=network.target +After=mariadb.service mysqld.service postgresql.service memcached.service redis.service + +[Service] +# Modify these two values and uncomment them if you have +# repos with lots of files and get an HTTP error 500 because +# of that +### +#LimitMEMLOCK=infinity +#LimitNOFILE=65535 +Type=simple +User=git +Group=git +WorkingDirectory=/home/git/go/src/github.com/gogits/gogs +ExecStart=/home/git/go/src/github.com/gogits/gogs/gogs web +Restart=always +Environment=USER=git HOME=/home/git + +[Install] +WantedBy=multi-user.target +``` + +之后保存并且退出。 + +现在可以重载系统服务器。 + +``` +systemctl daemon-reload +``` + +使用下面的命令开启 Gogs 服务器并设置为开机启动。 + +``` +systemctl start gogs +systemctl enable gogs +``` + +[![运行 Gogs 服务器][16]][17] + +Gogs 服务器现在已经运行在 Ubuntu 系统上了。 + +使用下面的命令检测: + +``` +netstat -plntu +systemctl status gogs +``` + +您应该会得到下图所示的结果。 + +[![Gogs is listening on the network interface][18]][19] + +### 步骤 7 - 为 Gogs 安装和配置 Nginx 反向代理 + +在本步中,我们将为 Gogs 安装和配置 Nginx 反向代理。我们会在自己的库中调用 Nginx 包。 + +使用下面的命令添加 Nginx 库。 + +``` +sudo add-apt-repository -y ppa:nginx/stable +``` + +此时更新所有的库并且使用下面的命令安装 Nginx。 + +``` +sudo apt update +sudo apt install nginx -y +``` + +之后,进入 `/etc/nginx/sites-available` 目录并且创建虚拟主机文件 `gogs`。 + +``` +cd /etc/nginx/sites-available +vim gogs +``` + +粘贴下面的代码到配置文件。 + +``` +server { +     listen 80; +     server_name git.hakase-labs.co; + +     location / { +         proxy_pass http://localhost:3000; +     } + } +``` + +保存退出。 + +**注意:** 请使用您的域名修改 `server_name` 项。 + +现在激活虚拟主机并且测试 nginx 配置。 + +``` +ln -s /etc/nginx/sites-available/gogs /etc/nginx/sites-enabled/ +nginx -t +``` + +确保没有遇到错误,重启 Nginx 服务器。 + +``` +systemctl restart nginx +``` + +[![安装和配置 Nginx 反向代理][20]][21] + +### 步骤 8 - 测试 + +打开您的网页浏览器并且输入您的 Gogs URL,我的是 http://git.hakase-labs.co + +现在您将进入安装界面。在页面的顶部,输入您所有的 PostgreSQL 数据库信息。 + +[![Gogs 安装][22]][23] + +之后,滚动到底部,点击 “Admin account settings” 下拉选项。 + +输入您的管理者用户名和邮箱。 + +[![键入 gogs 安装设置][24]][25] + +之后点击 “Install Gogs” 按钮。 + +然后您将会被重定向到下图显示的 Gogs 用户面板。 + +[![Gogs 面板][26]][27] + +下面是 Gogs 的 “Admin Dashboard(管理员面板)”。 + +[![浏览 Gogs 面板][28]][29] + +现在,Gogs 已经通过 PostgreSQL 数据库和 Nginx 网页服务器在您的 Ubuntu 16.04 上完成安装。 + +-------------------------------------------------------------------------------- + +via: https://www.howtoforge.com/tutorial/how-to-install-gogs-go-git-service-on-ubuntu-1604/ + +作者:[Muhammad Arul][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/tutorial/server-monitoring-with-shinken-on-ubuntu-16-04/ +[1]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/1.png +[2]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/1.png +[3]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/2.png +[4]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/2.png +[5]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/3.png +[6]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/3.png +[7]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/4.png +[8]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/4.png +[9]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/5.png +[10]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/5.png +[11]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/6.png +[12]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/6.png +[13]:https://www.howtoforge.com/vim-basics +[14]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/7.png +[15]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/7.png +[16]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/8.png +[17]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/8.png +[18]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/9.png +[19]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/9.png +[20]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/10.png +[21]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/10.png +[22]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/11.png +[23]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/11.png +[24]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/12.png +[25]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/12.png +[26]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/13.png +[27]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/13.png +[28]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/14.png +[29]:https://www.howtoforge.com/images/how_to_install_gogs_go_git_service_on_ubuntu_1604/big/14.png diff --git a/published/20180209 Linux rmdir Command for Beginners (with Examples).md b/published/201802/20180209 Linux rmdir Command for Beginners (with Examples).md similarity index 100% rename from published/20180209 Linux rmdir Command for Beginners (with Examples).md rename to published/201802/20180209 Linux rmdir Command for Beginners (with Examples).md diff --git a/translated/tech/20180210 How to create AWS ec2 key using Ansible.md b/published/201802/20180210 How to create AWS ec2 key using Ansible.md similarity index 59% rename from translated/tech/20180210 How to create AWS ec2 key using Ansible.md rename to published/201802/20180210 How to create AWS ec2 key using Ansible.md index f0850d4134..7924b642eb 100644 --- a/translated/tech/20180210 How to create AWS ec2 key using Ansible.md +++ b/published/201802/20180210 How to create AWS ec2 key using Ansible.md @@ -1,33 +1,43 @@ 如何使用 Ansible 创建 AWS ec2 密钥 ====== -我想使用 Ansible 工具创建 Amazon EC2 密钥对。不想使用 AWS CLI 来创建。可以使用 Ansible 来创建 AWS ec2 密钥吗? -你需要使用 Ansible 的 ec2_key 模块。这个模块依赖于 python-boto 2.5 版本或者更高版本。 boto 只不过是亚马逊 Web 服务的一个 Python API。你可以将 boto 用于 Amazon S3,Amazon EC2 等其他服务。简而言之,你需要安装 ansible 和 boto 模块。我们一起来看下如何安装 boto 并结合 Ansible 使用。 +**我想使用 Ansible 工具创建 Amazon EC2 密钥对。不想使用 AWS CLI 来创建。可以使用 Ansible 来创建 AWS ec2 密钥吗?** + +你需要使用 Ansible 的 ec2_key 模块。这个模块依赖于 python-boto 2.5 版本或者更高版本。 boto 是亚马逊 Web 服务的一个 Python API。你可以将 boto 用于 Amazon S3、Amazon EC2 等其他服务。简而言之,你需要安装 Ansible 和 boto 模块。我们一起来看下如何安装 boto 并结合 Ansible 使用。 + +### 第一步 - 在 Ubuntu 上安装最新版本的 Ansible + +你必须[给你的系统配置 PPA 来安装最新版的 Ansible][2]。为了管理你从各种 PPA(Personal Package Archives)安装软件的仓库,你可以上传 Ubuntu 源码包并编译,然后通过 Launchpad 以 apt 仓库的形式发布。键入如下命令 [apt-get 命令][3]或者 [apt 命令][4]: -### 第一步 - [在 Ubuntu 上安装最新版本的 Ansible][1] -你必须[给你的系统配置 PPA 来安装最新版的 ansible][2]。为了管理你从各种 PPA(Personal Package Archives) 安装软件的仓库,你可以上传 Ubuntu 源码包并编译,然后通过 Launchpad 以 apt 仓库的形式发布。键入如下命令 [apt-get 命令][3]或者 [apt 命令][4]: ``` $ sudo apt update $ sudo apt upgrade $ sudo apt install software-properties-common ``` -接下来给你的系统的软件源中添加 ppa:ansible/ansible + +接下来给你的系统的软件源中添加 `ppa:ansible/ansible`。 + ``` $ sudo apt-add-repository ppa:ansible/ansible ``` -更新你的仓库并安装ansible: + +更新你的仓库并安装 Ansible: + ``` $ sudo apt update $ sudo apt install ansible ``` + 安装 boto: + ``` $ pip3 install boto3 ``` -#### 关于在CentOS/RHEL 7.x上安装Ansible的注意事项 +#### 关于在CentOS/RHEL 7.x上安装 Ansible 的注意事项 你[需要在 CentOS 和 RHEL 7.x 上配置 EPEL 源][5]和 [yum命令][6] + ``` $ cd /tmp $ wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm @@ -35,14 +45,17 @@ $ ls *.rpm $ sudo yum install epel-release-latest-7.noarch.rpm $ sudo yum install ansible ``` + 安装 boto: + ``` $ pip install boto3 ``` ### 第二步 2 – 配置 boto -你需要配置 AWS credentials/API 密钥。参考 “[AWS Security Credentials][7]” 文档如何创建 API key。用 mkdir 命令创建一个名为 ~/.aws 的目录,然后配置 API key: +你需要配置 AWS credentials/API 密钥。参考 “[AWS Security Credentials][7]” 文档如何创建 API key。用 `mkdir` 命令创建一个名为 `~/.aws` 的目录,然后配置 API key: + ``` $ mkdir -pv ~/.aws/ $ vi ~/.aws/credentials @@ -54,14 +67,20 @@ aws_secret_access_key = YOUR-SECRET-ACCESS-KEY-HERE ``` 还需要配置默认 [AWS 区域][8]: -`$ vi ~/.aws/config` + +``` +$ vi ~/.aws/config +``` + 输出样例如下: + ``` [default] region = us-west-1 ``` -通过创建一个简单的名为 test-boto.py 的 python 程序来测试你的 boto 配置是否正确: +通过创建一个简单的名为 `test-boto.py` 的 Python 程序来测试你的 boto 配置是否正确: + ``` #!/usr/bin/python3 # A simple program to test boto and print s3 bucket names @@ -72,20 +91,25 @@ for b in t.buckets.all(): ``` 按下面方式来运行该程序: -`$ python3 test-boto.py` + +``` +$ python3 test-boto.py +``` + 输出样例: + ``` nixcraft-images nixcraft-backups-cbz nixcraft-backups-forum - ``` 上面输出可以确定 Python-boto 可以使用 AWS API 正常工作。 ### 步骤 3 - 使用 Ansible 创建 AWS ec2 密钥 -创建一个名为 ec2.key.yml 的 playbook,如下所示: +创建一个名为 `ec2.key.yml` 的剧本,如下所示: + ``` --- - hosts: local @@ -106,44 +130,54 @@ nixcraft-backups-forum 其中, - * ec2_key: – ec2 密钥对。 - * name: nixcraft_key – 密钥对的名称。 - * region: us-west-1 – 使用的 AWS 区域。 - * register: ec2_key_result : 保存生成的密钥到 ec2_key_result 变量。 - * copy: content="{{ ec2_key_result.key.private_key }}" dest="./aws.nixcraft.pem" mode=0600 : 将 ec2_key_result.key.private_key 的内容保存到当前目录的一个名为 aws.nixcraft.pem 的文件中。设置该文件的权限为 0600 (unix 文件权限). - * when: ec2_key_result.changed : 仅仅在 ec2_key_result 改变时才保存。我们不想覆盖你的密钥文件。 + * `ec2_key:` – ec2 密钥对。 + * `name: nixcraft_key` – 密钥对的名称。 + * `region: us-west-1` – 使用的 AWS 区域。 + * `register: ec2_key_result` – 保存生成的密钥到 ec2_key_result 变量。 + * `copy: content="{{ ec2_key_result.key.private_key }}" dest="./aws.nixcraft.pem" mode=0600` – 将 `ec2_key_result.key.private_key` 的内容保存到当前目录的一个名为 `aws.nixcraft.pem` 的文件中。设置该文件的权限为 `0600` (unix 文件权限)。 + * `when: ec2_key_result.changed` – 仅仅在 `ec2_key_result` 改变时才保存。我们不想覆盖你的密钥文件。 +你还必须创建如下 `hosts` 文件: -你还必须创建如下主机文件: ``` [local] localhost - ``` -如下运行你的 playbook: -`$ ansible-playbook -i hosts ec2.key.yml` +如下运行你的剧本: + +``` +$ ansible-playbook -i hosts ec2.key.yml +``` + ![](https://www.cyberciti.biz/media/new/faq/2018/02/How-to-create-AWS-ec2-key-using-Ansible.jpg) -最后你应该有一个名为 aws.nixcraft.pem 私钥,该私钥可以和 AWS EC2 一起使用。查看你的密钥 [cat 命令][9]: +最后你应该有一个名为 `aws.nixcraft.pem 私钥,该私钥可以和 AWS EC2 一起使用。使用 [cat 命令][9]查看你的密钥: + ``` $ cat aws.nixcraft.pem ``` + 如果你有 EC2 虚拟机,请按如下方式使用: + ``` $ ssh -i aws.nixcraft.pem user@ec2-vm-dns-name ``` -#### 查看有关 python 数据结构变量名的信息,比如 ec2_key_result.changed 和 ec2_key_result.key.private_key +**查看有关 python 数据结构变量名的信息,比如 ec2_key_result.changed 和 ec2_key_result.key.private_key** -你一定在想我是如何使用变量名的,比如 ec2_key_result.changed 和 ec2_key_result.key.private_key。它们在哪里定义过吗?变量的值是通过 API 调用返回的。简单地使用 -v 选项运行 ansible-playbook 命令来查看这样的信息: -`$ ansible-playbook -v -i hosts ec2.key.yml` +你一定在想我是如何使用变量名的,比如 `ec2_key_result.changed` 和 `ec2_key_result.key.private_key`。它们在哪里定义过吗?变量的值是通过 API 调用返回的。简单地使用 `-v` 选项运行 `ansible-playbook` 命令来查看这样的信息: + +``` +$ ansible-playbook -v -i hosts ec2.key.yml +``` ![](https://www.cyberciti.biz/media/new/faq/2018/02/ansible-verbose-output.jpg) ### 我该如何删除一个密钥? -使用如下 ec2-key-delete.yml: +使用如下 `ec2-key-delete.yml`: + ``` --- - hosts: local @@ -160,8 +194,10 @@ $ ssh -i aws.nixcraft.pem user@ec2-vm-dns-name ``` 按照如下方式运行: -`$ ansible-playbook -i hosts ec2-key-delete.yml` +``` +$ ansible-playbook -i hosts ec2-key-delete.yml +``` ### 关于作者 @@ -173,7 +209,7 @@ via: https://www.cyberciti.biz/faq/how-to-create-aws-ec2-key-using-ansible/ 作者:[Vivek Gite][a] 译者:[qianghaohao](https://github.com/qianghaohao) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md b/published/201802/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md similarity index 100% rename from published/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md rename to published/201802/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md diff --git a/published/20180206 How to start an open source program in your company.md b/published/20180206 How to start an open source program in your company.md new file mode 100644 index 0000000000..43a6e09736 --- /dev/null +++ b/published/20180206 How to start an open source program in your company.md @@ -0,0 +1,49 @@ +如何在企业中开展开源计划 +====== + +> 有 65% 的企业使用开源软件,并非只有互联网企业才能受惠于开源计划。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LAW_openisopen.png?itok=FjmDxIaL) + +很多互联网企业如 Google、 Facebook、 Twitter 等,都已经正式建立了开源计划(有的公司中建立了单独的开源计划部门open source program office(OSPO)),这是在公司内部消化和支持开源产品的地方。在这样一个实际的部门中,企业可以清晰透明地执行开源策略,这是企业成功开源化的一个必要过程。开源计划部门的职责包括:制定使用、分配、选择和审查代码的相关政策;培育开源社区;培训开发技术人员和确保法律合规。 + +互联网企业并不是唯一建立开源计划的企业,有调查发现各种行业中有 [65% 的企业][1]的在使用开源和向开源贡献。在过去几年中 [VMware][2]、 [Amazon][3]、 [Microsoft][4] 等企业,甚至连[英国政府][5]都开始聘用开源管理人员,开展开源计划。可见近年来商业领域乃至政府都十分重视开源策略,在这样的环境下,各界也需要跟上他们的步伐,建立开源计划。 + +### 怎样建立开源计划 + +虽然根据企业的需求不同,各开源计划部门会有特殊的调整,但下面几个基本步骤是建立每个公司都会经历的,它们是: + + * **选定一位领导者:** 选出一位合适的领导之是建立开源计划的第一步。 [TODO Group][6] 发布了一份[开源人员基础工作任务清单][7],你可以根据这个清单筛选人员。 + * **确定计划构架:** 开源计划部门可以根据其服务的企业类型的侧重点,来适应不同种类的企业需求,以在各类企业中成功运行。知识型企业可以把开源计划放在法律事务部运行,技术驱动型企业可以把开源计划放在着眼于提高企业效能的部门中,如工程部。其他类型的企业可以把开源计划放在市场部内运行,以此促进开源产品的销售。TODO Group 发布的[开源计划案例][8]或许可以给你些启发。 + * **制定规章制度:** 开源策略的实施需要有一套规章制度,其中应当具体列出企业成员进行开源工作的标准流程,来减少失误的发生。这个流程应当简洁明了且简单易行,最好可以用设备进行自动化。如果工作人员有质疑标准流程的热情和能力,并提出改进意见,那再好不过了。许多活跃在开源领域的企业中,Google 发布的规章制度十分值得借鉴。你可以参照 [Google 发布的制度][9]起草适用于自己企业的规章制度,用 [TODO 提供其它开源策略][10]也可以参考。 +  +### 建立开源计划是企业发展中的关键一步 + +建立开源计划部门对很多企业来说是关键一步,尤其是对于那些软件公司或是想要转型进入软件领域的公司。不论雇员的满意度或是开发效率上,在开源计划中企业可以获得巨大的利益,这些利益远远大于对开源计划所需要的长期投资。在开源之路上有很多资源可以帮助你成功,例如 TODO Group 的[《怎样创建开源计划》][11]、[《开源计划的价值评估》][12]和[《管理开源计划的几种工具》][13]都很适合初学者阅读。 + +随着越来越多的企业形成开源计划,开源社区自身的可持续性逐渐加强,这会对这些企业的开源计划产生积极影响,促进企业的发展,这是企业和开源间的良性循环。我希望以上这些信息能够帮到你,祝你在建立开源计划的路上一路顺风。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/how-start-open-source-program-your-company + +作者:[Chris Aniszczyk][a] +译者:[Valoniakim](https://github.com/Valoniakim) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/caniszczyk +[1]:https://www.blackducksoftware.com/2016-future-of-open-source +[2]:http://www.cio.com/article/3095843/open-source-tools/vmware-today-has-a-strong-investment-in-open-source-dirk-hohndel.html +[3]:http://fortune.com/2016/12/01/amazon-open-source-guru/ +[4]:https://opensource.microsoft.com/ +[5]:https://www.linkedin.com/jobs/view/169669924 +[6]:http://todogroup.org +[7]:https://github.com/todogroup/job-descriptions +[8]:https://github.com/todogroup/guides/tree/master/casestudies +[9]:https://opensource.google.com/docs/why/ +[10]:https://github.com/todogroup/policies +[11]:https://github.com/todogroup/guides/blob/master/creating-an-open-source-program.md +[12]:https://github.com/todogroup/guides/blob/master/measuring-your-open-source-program.md +[13]:https://github.com/todogroup/guides/blob/master/tools-for-managing-open-source-programs.md diff --git a/published/20180206 Manage printers and printing.md b/published/20180206 Manage printers and printing.md new file mode 100644 index 0000000000..b849e8ebef --- /dev/null +++ b/published/20180206 Manage printers and printing.md @@ -0,0 +1,536 @@ +完全指南:在 Linux 中如何打印和管理打印机 +====== + +### Linux 中的打印 + +虽然现在大量的沟通都是电子化和无纸化的,但是在我们的公司中还有大量的材料需要打印。银行结算单、公用事业帐单、财务和其它报告、以及收益结算单等一些东西还是需要打印的。本教程将介绍在 Linux 中如何使用 CUPS 去打印。 + +CUPS,是通用 Unix 打印系统Common UNIX Printing System的首字母缩写,它是 Linux 中的打印机和打印任务的管理者。早期计算机上的打印机一般是在特定的字符集和字体大小下打印文本文件行。现在的图形打印机可以打印各种字体和大小的文本和图形。尽管如此,现在你所使用的一些命令,在古老的行式打印守护进程(LPD)技术的历史中仍能找到它们。 + +本教程将帮你了解 Linux 服务器专业考试(LPIC-1)的第 108 号主题的 108.4 目标。这个目标的权重为 2。 + +#### 前提条件 + +为了更好地学习本系列教程,你需要具备基本的 Linux 知识,和使用 Linux 系统实践本教程中的命令的能力,你应该熟悉 GNU 和 UNIX® 命令的使用。有时不同版本的程序输出可能会不同,因此,你的结果可能与本教程中的示例有所不同。 + +本教程中的示例使用的是 Fedora 27 的系统。 + +### 有关打印的一些历史 + +这一小部分历史并不是 LPI 目标的,但它有助于你理解这个目标的相关环境。 + +早期的计算机大都使用行式打印机。这些都是击打式打印机,那时,它们使用固定间距的字符和单一的字体来打印文本行。为提升整个系统性能,早期的主机要与慢速的外围设备(如读卡器、卡片穿孔机、和运行其它工作的行式打印机)交叉进行工作。因此就产生了在线的或者假脱机的同步外围操作,这一术语目前在谈到计算机打印时仍然在使用。 + +在 UNIX 和 Linux 系统上,打印初始化使用的是 BSD(伯克利软件分发版Berkeley Software Distribution)打印子系统,它是由一个作为服务器运行的行式打印守护程序(LPD)组成,而客户端命令如 `lpr` 是用于提交打印作业。这个协议后来被 IETF 标准化为 RFC 1179 —— **行式打印机守护进程协议**。 + +System V 也有一个打印守护程序。它的功能与BSD 的 LPD 守护程序类似,但是它们的命令集不一样。你在后面会经常看到完成相同的任务使用不同选项的两个命令。例如,对于打印文件的命令,伯克利实现版本是 `lpr`,而 System V 实现版本是 `lp`。 + +随着打印机技术的进步,在一个页面上混合出现不同字体成为可能,并且可以将图片像文字一样打印。可变间距字体,以及更多先进的打印技术,比如间距和连字符,现在都已经标准化。出现了几种对基本的 lpd/lpr 方法等改进设计,比如 LPRng,下一代的 LPR,以及 CUPS。 + +许多可以打印图形的打印机,使用 Adobe PostScript 语言进行初始化。一个 PostScript 打印机有一个解释器引擎,它可以解释打印任务中的命令并从这些命令中生成最终的页面。PostScript 经常被用做原始文件(比如一个文本文件或者一个图像文件)和最终格式没有适合的 PostScript 功能的特定打印机之间的中间层。转换这些特定的打印任务,比如将一个 ASCII 文本文件或者一个 JPEG 图像转换为 PostScript,然后再使用过滤器转换 PostScript 到非 PostScript 打印机所需要的最终光栅格式。 + +现在的便携式文档格式Portable Document Format(PDF),它就是基于 PostScript 的,已经替换了传统的原始 PostScript。PDF 设计为与硬件和软件无关,它封装了要打印的页面的完整描述。你可以查看 以及打印 PDF 文件。 + +### 管理打印队列 + +用户直接打印作业到一个名为打印队列print queue的逻辑实体。在单用户系统中,打印队列和打印机通常是几乎相同的意思。但是,CUPS 允许系统不用连接到一个打印机上,而最终在一个远程系统上的排队打印作业,并且通过使用分类,允许将定向到一个分类的打印作业在该分类第一个可用的打印机上打印。 + +你可以检查和管理打印队列。对于 CUPS 来说,其中一些命令实现了一些新操作。另外的一些是源于 LPD 的兼容命令,不过现在的一些选项通常是最初的 LPD 打印系统选项的有限子集。 + +你可以使用 CUPS 的 `lpstat` 命令去检查队列,以了解打印系统。一些常见选项如下表 1。 + + +| 选项 | 作用 | +| --- | --- | +| `-a` | 显示打印机状态 | +| `-c` | 显示打印分类 | +| `-p` | 显示打印状态:`enabled` 或者 `disabled` | +| `-s` | 显示默认打印机、打印机和类。相当于 `-d -c -v`。**注意:要指定多个选项,这些选项必须像值一样分隔开。**| +| `-v` | 显示打印机和它们的设备。| + +*表 1. lpstat 命令的选项* + +你也可以使用 LPD 的 `lpc` 命令(它可以在 `/usr/sbin` 中找到)使用它的 `status` 选项。如果你不想指定打印机名字,将列出所有的队列。列表 1 展示了命令的一些示例。 + +``` +[ian@atticf27 ~]$ lpstat -d +system default destination: HL-2280DW +[ian@atticf27 ~]$ lpstat -v HL-2280DW +device for HL-2280DW: dnssd://Brother%20HL-2280DW._pdl-datastream._tcp.local/ +[ian@atticf27 ~]$ lpstat -s +system default destination: HL-2280DW +members of class anyprint: + HL-2280DW + XP-610 +device for anyprint: ///dev/null +device for HL-2280DW: dnssd://Brother%20HL-2280DW._pdl-datastream._tcp.local/ +device for XP-610: dnssd://EPSON%20XP-610%20Series._ipp._tcp.local/?uuid=cfe92100-67c4-11d4-a45f-ac18266c48aa +[ian@atticf27 ~]$ lpstat -a XP-610 +XP-610 accepting requests since Thu 27 Apr 2017 05:53:59 PM EDT +[ian@atticf27 ~]$ /usr/sbin/lpc status HL-2280DW +HL-2280DW: + printer is on device 'dnssd' speed -1 + queuing is disabled + printing is enabled + no entries + daemon present + +``` + +*列表 1. 显示可用打印队列* + +这个示例展示了两台打印机 —— HL-2280DW 和 XP-610,和一个分类 `anyprint`,它允许打印作业定向到这两台打印机中的第一个可用打印机。 + +在这个示例中,已经禁用了打印到 HL-2280DW 队列,但是打印功能是启用的,这样便于将打印机脱机维护之前可以完成打印队列中的任务。启用还是禁用队列,可以使用 `cupsaccept` 和 `cupsreject` 命令来管理。以前它们叫做 `accept` 和 `reject`,你或许可能在 `/usr/sbin` 中找到这些命令,但它们现在都是符号链接到新的命令上了。同样,启用还是禁用打印,你可以使用 `cupsenable` 和 `cupsdisable` 命令来管理。在早期版本的 CUPS 中,这些被称为 `enable` 和 `disable`,它也许会与 bash shell 内置的 `enable` 混淆。列表 2 展示了如何去启用打印机 HL-2280DW 上的队列,而禁止它的打印。CUPS 的几个命令支持使用 `-r` 选项去提供一个该操作的理由。这个理由会在你使用 `lpstat` 时显示,但是如果你使用的是 `lpc` 命令则不会显示它。 + +``` +[ian@atticf27 ~]$ lpstat -a -p HL-2280DW +anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST +HL-2280DW not accepting requests since Thu 27 Apr 2017 05:52:27 PM EDT - + Maintenance scheduled +XP-610 accepting requests since Thu 27 Apr 2017 05:53:59 PM EDT +printer HL-2280DW is idle. enabled since Thu 27 Apr 2017 05:52:27 PM EDT + Maintenance scheduled +[ian@atticf27 ~]$ accept HL-2280DW +[ian@atticf27 ~]$ cupsdisable -r "waiting for toner delivery" HL-2280DW +[ian@atticf27 ~]$ lpstat -p -a +printer anyprint is idle. enabled since Mon 29 Jan 2018 01:17:09 PM EST +printer HL-2280DW disabled since Mon 29 Jan 2018 04:03:50 PM EST - + waiting for toner delivery +printer XP-610 is idle. enabled since Thu 27 Apr 2017 05:53:59 PM EDT +anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST +HL-2280DW accepting requests since Mon 29 Jan 2018 04:03:50 PM EST +XP-610 accepting requests since Thu 27 Apr 2017 05:53:59 PM EDT +``` + +*列表 2. 启用队列和禁用打印* + +注意:用户执行这些任务必须经过授权。它可能要求是 root 用户或者其它的授权用户。在 `/etc/cups/cups-files.conf` 中可以看到 `SystemGroup` 的条目,`cups-files.conf` 的 man 页面有更多授权用户组的信息。 + +### 管理用户打印作业 + +现在,你已经知道了一些如何去检查打印队列和类的方法,我将给你展示如何管理打印队列上的作业。你要做的第一件事是,如何找到一个特定打印机或者全部打印机上排队的任意作业。完成上述工作要使用 `lpq` 命令。如果没有指定任何选项,`lpq` 将显示默认打印机上的队列。使用 `-P` 选项和一个打印机名字将指定打印机,或者使用 `-a` 选项去指定所有的打印机,如下面的列表 3 所示。 + +``` +[pat@atticf27 ~]$ # As user pat (non-administrator) +[pat@atticf27 ~]$ lpq +HL-2280DW is not ready +Rank Owner Job File(s) Total Size +1st unknown 4 unknown 6144 bytes +2nd pat 6 bitlib.h 6144 bytes +3rd pat 7 bitlib.C 6144 bytes +4th unknown 8 unknown 1024 bytes +5th unknown 9 unknown 1024 bytes + +[ian@atticf27 ~]$ # As user ian (administrator) +[ian@atticf27 ~]$ lpq -P xp-610 +xp-610 is ready +no entries +[ian@atticf27 ~]$ lpq -a +Rank Owner Job File(s) Total Size +1st ian 4 permutation.C 6144 bytes +2nd pat 6 bitlib.h 6144 bytes +3rd pat 7 bitlib.C 6144 bytes +4th ian 8 .bashrc 1024 bytes +5th ian 9 .bashrc 1024 bytes +``` + +*列表 3. 使用 lpq 检查打印队列* + +在这个示例中,共有五个作业,它们是 4、6、7、8、和 9,并且它是名为 HL-2280DW 的打印机的队列,而不是 XP-610 的。在这个示例中使用 `-P` 选项,可简单地显示哪个打印机已经准备好,但是没有队列任务。注意,CUPS 的打印机命名,是大小写不敏感的。还要注意的是,用户 ian 提交了同样的作业两次,当一个作业没有第一时间打印时,经常能看到用户的这种动作。 + +一般情况下,你可能会查看或者维护你自己的打印作业,但是,root 用户或者其它授权的用户通常会去管理其它打印作业。大多数 CUPS 命令都可以使用一个 `-E` 选项,对 CUPS 服务器与客户端之间的通讯进行加密。 + +使用 `lprm` 命令从队列中去删除一个 `.bashrc` 作业。如果不使用选项,将删除当前的作业。使用 `-` 选项,将删除全部的作业。要么就如列表 4 那样,指定一个要删除的作业列表。 + +``` +[[pat@atticf27 ~]$ # As user pat (non-administrator) +[pat@atticf27 ~]$ lprm +lprm: Forbidden + +[ian@atticf27 ~]$ # As user ian (administrator) +[ian@atticf27 ~]$ lprm 8 +[ian@atticf27 ~]$ lpq +HL-2280DW is not ready +Rank Owner Job File(s) Total Size +1st ian 4 permutation.C 6144 bytes +2nd pat 6 bitlib.h 6144 bytes +3rd pat 7 bitlib.C 6144 bytes +4th ian 9 .bashrc 1024 bytes +``` + +*列表 4. 使用 lprm 删除打印作业* + +注意,用户 pat 不能删除队列中的第一个作业,因为它是用户 ian 的。但是,ian 可以删除他自己的 8 号作业。 + +另外的可以帮你操作打印队列中的作业的命令是 `lp`。使用它可以去修改作业属性,比如打印数量或者优先级。我们假设用户 ian 希望他的作业 9 在用户 pat 的作业之前打印,并且希望打印两份。作业优先级的默认值是 50,它的优先级范围从最低的 1 到最高的 100 之间。用户 ian 可以使用 `-i`、`-n`、以及 `-q` 选项去指定一个要修改的作业,而新的打印数量和优先级可以如下面的列表 5 所示的那样去修改。注意,使用 `-l` 选项的 `lpq` 命令可以提供更详细的输出。 + +``` +[ian@atticf27 ~]$ lpq +HL-2280DW is not ready +Rank Owner Job File(s) Total Size +1st ian 4 permutation.C 6144 bytes +2nd pat 6 bitlib.h 6144 bytes +3rd pat 7 bitlib.C 6144 bytes +4th ian 9 .bashrc 1024 bytes +[ian@atticf27 ~]$ lp -i 9 -q 60 -n 2 +[ian@atticf27 ~]$ lpq +HL-2280DW is not ready +Rank Owner Job File(s) Total Size +1st ian 9 .bashrc 1024 bytes +2nd ian 4 permutation.C 6144 bytes +3rd pat 6 bitlib.h 6144 bytes +4th pat 7 bitlib.C 6144 bytes +``` + +*列表 5. 使用 lp 去改变打印数量和优先级* + +最后,`lpmove` 命令可以允许一个作业从一个队列移动到另一个队列。例如,我们可能因为打印机 HL-2280DW 现在不能使用,而想去移动一个作业到另外的队列上。你可以指定一个作业编号,比如 9,或者你可以用一个队列名加一个连字符去限定它,比如,HL-2280DW-0。`lpmove` 命令的操作要求是授权用户。列表 6 展示了如何去从一个队列移动作业到另外的队列,先是指定打印机和作业 ID 移动,然后是移动指定打印机的所有作业。稍后我们可以去再次检查队列,其中一个作业已经在打印中了。 + +``` +[ian@atticf27 ~]$ lpmove HL-2280DW-9 anyprint +[ian@atticf27 ~]$ lpmove HL-2280DW xp-610 +[ian@atticf27 ~]$ lpq -a +Rank Owner Job File(s) Total Size +active ian 9 .bashrc 1024 bytes +1st ian 4 permutation.C 6144 bytes +2nd pat 6 bitlib.h 6144 bytes +3rd pat 7 bitlib.C 6144 bytes +[ian@atticf27 ~]$ # A few minutes later +[ian@atticf27 ~]$ lpq -a +Rank Owner Job File(s) Total Size +active pat 6 bitlib.h 6144 bytes +1st pat 7 bitlib.C 6144 bytes +``` + +*列表 6. 使用 lpmove 移动作业到另外一个打印队列* + +如果你使用的是 CUPS 之外的打印服务器,比如 LPD 或者 LPRng,大多数的队列管理功能是由 `lpc` 命令的子命令来处理的。例如,你可以使用 `lpc topq` 去移动一个作业到队列的顶端。其它的 `lpc` 子命令包括 `disable`、`down`、`enable`、`hold`、`move`、`redirect`、`release`、和 `start`。这些子命令在 CUPS 的兼容命令中没有实现。 + +#### 打印文件 + +如何去打印创建的作业?大多数图形界面程序都提供了一个打印方法,通常是 **文件** 菜单下面的选项。这些程序为选择打印机、设置页边距、彩色或者黑白打印、打印数量、选择每张纸打印的页面数(每张纸打印两个页面,通常用于讲义)等等,都提供了图形化的工具。现在,我将为你展示如何使用命令行工具去管理这些功能,然后和图形化实现进行比较。 + +打印文件最简单的方法是使用 `lpr` 命令,然后提供一个文件名字。这将在默认打印机上打印这个文件。而 `lp` 命令不仅可以打印文件,也可以修改打印作业。列表 7 展示了使用这个命令的一个简单示例。注意,`lpr` 会静默处理这个作业,但是 `lp` 会显示处理后的作业的 ID。 + +``` +[ian@atticf27 ~]$ echo "Print this text" > printexample.txt +[ian@atticf27 ~]$ lpr printexample.txt +[ian@atticf27 ~]$ lp printexample.txt +request id is HL-2280DW-12 (1 file(s)) +``` + +*列表 7. 使用 lpr 和 lp 打印* + +表 2 展示了 `lpr` 上你可以使用的一些选项。注意, `lp` 的选项和 `lpr` 的很类似,但是名字可能不一样;例如,`-#` 在 `lpr` 上是相当于 `lp` 的 `-n` 选项。查看 man 页面了解更多的信息。 + + +| 选项 | 作用 | +|---|---| +| `-C`, `-J` 或 `-T` | 设置一个作业名字。 | +| `-P` | 选择一个指定的打印机。| +| `-#` | 指定打印数量。注意这不同于 `lp` 命令的 `-n` 选项。| +| `-m` | 在作业完成时发送电子邮件。| +| `-l` | 表示打印文件已经为打印做好格式准备。相当于 `-o raw`。 | +| `-o` | 设置一个作业选项。| +| `-p` | 格式化一个带有阴影标题的文本文件。相关于 `-o prettyprint`。| +| `-q` | 暂缓(或排队)后面的打印作业。| +| `-r` | 在文件进入打印池之后,删除文件。 | + +*表 2. lpr 的选项* + +列表 8 展示了一些选项。我要求打印之后给我发确认电子邮件,那个作业被暂缓执行,并且在打印之后删除文件。 + +``` +[ian@atticf27 ~]$ lpr -P HL-2280DW -J "Ian's text file" -#2 -m -p -q -r printexample.txt +[[ian@atticf27 ~]$ lpq -l +HL-2280DW is ready + + +ian: 1st [job 13 localhost] + 2 copies of Ian's text file 1024 bytes +[ian@atticf27 ~]$ ls printexample.txt +ls: cannot access 'printexample.txt': No such file or directory +``` + +*列表 8. 使用 lpr 打印* + +我现在有一个在 HL-2280DW 打印队列上暂缓执行的作业。然后怎么做?`lp` 命令可以通过使用 `-H` 的各种选项来暂缓或者投放作业。列表 9 展示了如何投放被暂缓的作业。查看 `lp` 命令的 man 页面了解其它选项的信息。 + +``` +[ian@atticf27 ~]$ lp -i 13 -H resume +``` + +*列表 9. 重启一个暂缓的打印作业* + +并不是所有的可用打印机都支持相同的选项集。使用 `lpoptions` 命令去查看一个打印机的常用选项。添加 `-l` 选项去显示打印机专用的选项。列表 10 展示了两个示例。许多常见的选项涉及到人像/风景打印、页面大小和输出在纸张上的布局。详细信息查看 man 页面。 + +``` +[ian@atticf27 ~]$ lpoptions -p HL-2280DW +copies=1 device-uri=dnssd://Brother%20HL-2280DW._pdl-datastream._tcp.local/ +finishings=3 job-cancel-after=10800 job-hold-until=no-hold job-priority=50 +job-sheets=none,none marker-change-time=1517325288 marker-colors=#000000,#000000 +marker-levels=-1,92 marker-names='Black\ Toner\ Cartridge,Drum\ Unit' +marker-types=toner,opc number-up=1 printer-commands=none +printer-info='Brother HL-2280DW' printer-is-accepting-jobs=true +printer-is-shared=true printer-is-temporary=false printer-location +printer-make-and-model='Brother HL-2250DN - CUPS+Gutenprint v5.2.13 Simplified' +printer-state=3 printer-state-change-time=1517325288 printer-state-reasons=none +printer-type=135188 printer-uri-supported=ipp://localhost/printers/HL-2280DW +sides=one-sided + +[ian@atticf27 ~]$ lpoptions -l -p xp-610 +PageSize/Media Size: *Letter Legal Executive Statement A4 +ColorModel/Color Model: *Gray Black +InputSlot/Media Source: *Standard ManualAdj Manual MultiPurposeAdj MultiPurpose +UpperAdj Upper LowerAdj Lower LargeCapacityAdj LargeCapacity +StpQuality/Print Quality: None Draft *Standard High +Resolution/Resolution: *301x300dpi 150dpi 300dpi 600dpi +Duplex/2-Sided Printing: *None DuplexNoTumble DuplexTumble +StpiShrinkOutput/Shrink Page If Necessary to Fit Borders: *Shrink Crop Expand +StpColorCorrection/Color Correction: *None Accurate Bright Hue Uncorrected +Desaturated Threshold Density Raw Predithered +StpBrightness/Brightness: 0 100 200 300 400 500 600 700 800 900 *None 1100 +1200 1300 1400 1500 1600 1700 1800 1900 2000 Custom.REAL +StpContrast/Contrast: 0 100 200 300 400 500 600 700 800 900 *None 1100 1200 +1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 +2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 Custom.REAL +StpImageType/Image Type: None Text Graphics *TextGraphics Photo LineArt + +``` + +*列表 10. 检查打印机选项* + +大多数的 GUI 应用程序有一个打印对话框,通常你可以使用 **文件 >打印** 菜单去选择它。图 1 展示了在 GIMP 中的一个示例,GIMP 是一个图像处理程序。 + +![Printing from the GIMP][3] + +*图 1. 在 GIMP 中打印* + +到目前为止,我们所有的命令都是隐式指向到本地的 CUPS 打印服务器上。你也可以通过指定 `-h` 选项和一个端口号(如果不是 CUPS 的默认端口号 631 的话)将打印转向到另外一个系统上的服务器。 + +### CUPS 和 CUPS 服务器 + +CUPS 打印系统的核心是 `cupsd` 打印服务器,它是一个运行的守护进程。CUPS 配置文件一般位于 `/etc/cups/cupsd.conf`。`/etc/cups` 目录也有与 CUPS 相关的其它的配置文件。CUPS 一般在系统初始化期间启动,根据你的发行版不同,它也可能通过位于 `/etc/rc.d/init.d` 或者 `/etc/init.d` 目录中的 CUPS 脚本来控制。对于 最新使用 systemd 来初始化的系统,CUPS 服务脚本可能在 `/usr/lib/systemd/system/cups.service` 中。和大多数使用脚本的服务一样,你可以停止、启动、或者重启守护程序。查看我们的教程:[学习 Linux,101:运行级别、引导目标、关闭、和重启动][4],了解使用初始化脚本的更多信息。 + +配置文件 `/etc/cups/cupsd.conf` 包含一些管理参数,比如访问打印系统、是否允许远程打印、本地打印池文件等等。在一些系统上,第二部分单独描述了打印队列,它一般是由配置工具自动生成的。列表 11 展示了一个默认的 `cupsd.conf` 文件中的一些条目。注意,注释是以 `#` 字符开头的。默认值通常以注释的方式显示,并且可以通过删除前面的 `#` 字符去改变默认值。 + +``` +# Only listen for connections from the local machine. +Listen localhost:631 +Listen /var/run/cups/cups.sock + +# Show shared printers on the local network. +Browsing On +BrowseLocalProtocols dnssd + +# Default authentication type, when authentication is required... +DefaultAuthType Basic + +# Web interface setting... +WebInterface Yes + +# Set the default printer/job policies... + + # Job/subscription privacy... + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateValues default + + # Job-related operations must be done by the owner or an administrator... + + Order deny,allow + +``` + +*列表 11. 默认的 /etc/cups/cupsd.conf 文件的部分内容* + +可以用在 `cupsd.conf` 中使用的文件、目录、和用户配置命令,现在都存储在作为替代的 `cups-files.conf` 中。这是为了防范某些类型的提权攻击。列表 12 展示了 `cups-files.conf` 文件中的一些条目。注意,正如在文件层次结构标准(FHS)中所期望的那样,打印池文件默认保存在文件系统的 `/var/spool` 目录中。查看 man 页面了解 `cupsd.conf` 和 `cups-files.conf` 配置文件的更多信息。 + +``` +# Location of the file listing all of the local printers... +#Printcap /etc/printcap + +# Format of the Printcap file... +#PrintcapFormat bsd +#PrintcapFormat plist +#PrintcapFormat solaris + +# Location of all spool files... +#RequestRoot /var/spool/cups + +# Location of helper programs... +#ServerBin /usr/lib/cups + +# SSL/TLS keychain for the scheduler... +#ServerKeychain ssl + +# Location of other configuration files... +#ServerRoot /etc/cups +``` + +*列表 12. 默认的 /etc/cups/cups-files.conf 配置文件的部分内容* + + +列表 12 提及了 `/etc/printcap` 文件。这是 LPD 打印服务器的配置文件的名字,并且一些应用程序仍然使用它去确定可用的打印机和它们的属性。它通常是在 CUPS 系统上自动生成的,因此,你可能没有必要去修改它。但是,如果你在诊断用户打印问题,你可能需要去检查它。列表 13 展示了一个示例。 + +``` +# This file was automatically generated by cupsd(8) from the +# /etc/cups/printers.conf file. All changes to this file +# will be lost. +HL-2280DW|Brother HL-2280DW:rm=atticf27:rp=HL-2280DW: +anyprint|Any available printer:rm=atticf27:rp=anyprint: +XP-610|EPSON XP-610 Series:rm=atticf27:rp=XP-610: +``` + +*列表 13. 自动生成的 /etc/printcap* + +这个文件中的每一行都有一个打印机名字、打印机描述,远程机器(`rm`)的名字、以及那个远程机器上的远程打印机(`rp`)。老的 `/etc/printcap` 文件也描述了打印机的能力。 + +#### 文件转换过滤器 + +你可以使用 CUPS 打印许多类型的文件,包括明文的文本文件、PDF、PostScript、和各种格式的图像文件,你只需要提供要打印的文件名,除此之外你再无需向 `lpr` 或 `lp` 命令提供更多的信息。这个神奇的壮举是通过使用过滤器来实现的。实际上,这些年来最流行的过滤器就就叫做 magicfilter(神奇的过滤器)。 + +当打印一个文件时,CUPS 使用多用途因特网邮件扩展(MIME)类型去决定合适的转换过滤器。其它的打印数据包可能使用由 `file` 命令使用的神奇数字机制。关于 `file` 或者神奇数的更多信息可以查看它们的 man 页面。 + +输入文件被过滤器转换成中间层的光栅格式或者 PostScript 格式。一些作业信息,比如打印数量也会被添加进去。数据最终通过一个后端发送到目标打印机。还有一些可以用手动过滤的输入文件的过滤器(如 a2ps 或 dvips)。你可以通过这些过滤器获得特殊格式的结果,或者去处理一些 CUPS 原生并不支持的文件格式。 + +#### 添加打印机 + +CUPS 支持多种打印机,包括: + + * 本地连接的并行口和 USB 口打印机 + * 因特网打印协议(IPP)打印机 + * 远程 LPD 打印机 + * 使用 SAMBA 的 Microsoft® Windows® 打印机 + * 使用 NCP 的 Novell 打印机 + * HP Jetdirect 打印机 + +当系统启动或者设备连接时,现在的大多数系统都会尝试自动检测和自动配置本地硬件。同样,许多网络打印机也可以被自动检测到。使用 CUPS 的 web 管理工具( 或者 )去搜索或添加打印机。许多发行版都包含它们自己的配置工具,比如,在 SUSE 系统上的 YaST。图 2 展示了使用 localhost:631 的 CUPS 界面,图 3 展示了 Fedora 27 上的 GNOME 打印机设置对话框。 + + +![Using the CUPS web interface][5] + +*图 2. 使用 CUPS 的 web 界面* + + +![Using printer settings on Fedora 27][6] + +*图 3. Fedora 27 上的打印机设置* + +你也可以从命令行配置打印机。在配置打印机之前,你需要一些关于打印机和它的连接方式的基本信息。如果是一个远程系统,你还需要一个用户 ID 和密码。 + +你需要去知道你的打印机使用什么样的驱动程序。不是所有的打印机都支持 Linux,有些打印机在 Linux 上压根就不能使用,或者功能受限。你可以去 OpenPrinting.org 去查看是否有你的特定的打印机的驱动程序。`lpinfo` 命令也可以帮你识别有效的设备类型和驱动程序。使用 `-v` 选项去列出支持的设备,使用 `-m` 选项去列出驱动程序,如列表 14 所示。 + +``` +[ian@atticf27 ~]$ lpinfo -m | grep -i xp-610 +lsb/usr/Epson/epson-inkjet-printer-escpr/Epson-XP-610_Series-epson-escpr-en.ppd.gz +EPSON XP-610 Series, Epson Inkjet Printer Driver (ESC/P-R) for Linux +[ian@atticf27 ~]$ locate "Epson-XP-610_Series-epson-escpr-en.ppd.gz" +/usr/share/ppd/Epson/epson-inkjet-printer-escpr/Epson-XP-610_Series-epson-escpr-en.ppd.gz +[ian@atticf27 ~]$ lpinfo -v +network socket +network ipps +network lpd +network beh +network ipp +network http +network https +direct hp +serial serial:/dev/ttyS0?baud=115200 +direct parallel:/dev/lp0 +network smb +direct hpfax +network dnssd://Brother%20HL-2280DW._pdl-datastream._tcp.local/ +network dnssd://EPSON%20XP-610%20Series._ipp._tcp.local/?uuid=cfe92100-67c4-11d4-a45f-ac18266c48aa +network lpd://BRN001BA98A1891/BINARY_P1 +network lpd://192.168.1.38:515/PASSTHRU +``` + +*列表 14. 可用的打印机驱动程序* + +这个 Epson-XP-610_Series-epson-escpr-en.ppd.gz 驱动程序在我的系统上位于 `/usr/share/ppd/Epson/epson-inkjet-printer-escpr/` 目录中。 + +如果你找不到驱动程序,你可以到打印机生产商的网站看看,说不定会有专用的驱动程序。例如,在写这篇文章的时候,Brother 就有一个我的 HL-2280DW 打印机的驱动程序,但是,这个驱动程序在 OpenPrinting.org 上还没有列出来。 + +如果你收集齐了基本信息,你可以如列表 15 所示的那样,使用 `lpadmin` 命令去配置打印机。为此,我将为我的 HL-2280DW 打印机创建另外一个实例,以便于双面打印。 + +``` +[ian@atticf27 ~]$ lpinfo -m | grep -i "hl.*2280" +HL2280DW.ppd Brother HL2280DW for CUPS +lsb/usr/HL2280DW.ppd Brother HL2280DW for CUPS +[ian@atticf27 ~]$ lpadmin -p HL-2280DW-duplex -E -m HL2280DW.ppd \ +> -v dnssd://Brother%20HL-2280DW._pdl-datastream._tcp.local/ \ +> -D "Brother 1" -o sides=two-sided-long-edge +[ian@atticf27 ~]$ lpstat -a +anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST +HL-2280DW accepting requests since Tue 30 Jan 2018 10:56:10 AM EST +HL-2280DW-duplex accepting requests since Wed 31 Jan 2018 11:41:16 AM EST +HXP-610 accepting requests since Mon 29 Jan 2018 10:34:49 PM EST +``` + +*列表 15. 配置一台打印机* + +你可以使用带 `-c` 选项的 `lpadmin` 命令去创建一个仅用于双面打印的新分类,而不用为了双面打印去创建一个打印机的副本。 + +如果你需要删除一台打印机,使用带 `-x` 选项的 `lpadmin` 命令。 + +列表 16 展示了如何去删除打印机和创建一个替代类。 + +``` +[ian@atticf27 ~]$ lpadmin -x HL-2280DW-duplex +[ian@atticf27 ~]$ lpadmin -p HL-2280DW -c duplex -E -D "Duplex printing" -o sides=two-sided-long-edge +[ian@atticf27 ~]$ cupsenable duplex +[ian@atticf27 ~]$ cupsaccept duplex +[ian@atticf27 ~]$ lpstat -a +anyprint accepting requests since Mon 29 Jan 2018 01:17:09 PM EST +duplex accepting requests since Wed 31 Jan 2018 12:12:05 PM EST +HL-2280DW accepting requests since Wed 31 Jan 2018 11:51:16 AM EST +XP-610 accepting requests since Mon 29 Jan 2018 10:34:49 PM EST +``` + +*列表 16. 删除一个打印机和创建一个类* + +你也可以使用 `lpadmin` 或者 `lpoptions` 命令去设置各种打印机选项。详细信息请查看 man 页面。 + +### 排错 + +如果你有打印问题,尝试下列的提示: + + * 确保 CUPS 服务器正在运行。你可以使用 `lpstat` 命令,如果它不能连接到 cupsd 守护程序,它将会报告一个错误。或者,你可以使用 `ps -ef` 命令在输出中去检查是否有 cupsd。 + * 如果你试着排队一个打印作业而得到一个错误信息,指示打印机不接受这个作业,你可以使用 `lpstat -a` 或者 `lpc status` 去检查那个打印机是否接受作业。 + * 如果一个队列中的作业没有打印,使用 `lpstat -p` 或 `lpc status` 去检查那个打印机是否接受作业。如前面所讨论的那样,你可能需要将这个作业移动到其它的打印机。 + * 如果这个打印机是远程的,检查它在远程系统上是否存在,并且是可操作的。 + * 检查配置文件,确保特定的用户或者远程系统允许在这个打印机上打印。 + * 确保防火墙允许远程打印请求,是否允许从其它系统到你的系统,或者从你的系统到其它系统的数据包通讯。 + * 验证是否有正确的驱动程序。 + +正如你所见,打印涉及到你的系统中的几个组件,甚至还有网络。在本教程中,基于篇幅的考虑,我们仅能给你的诊断提供了几个着手点。大多数的 CUPS 系统也有实现我们所讨论的命令行功能的图形界面。一般情况下,这个界面是从本地主机使用浏览器指向 631 端口()来访问的,如前面的图 2 所示。 + +你可以通过将 CUPS 运行在前台而不是做为一个守护进程来诊断它的问题。如果有需要,你也可以通过这种方式去测试替代的配置文件。运行 `cupsd -h` 获得更多信息,或者查看 man 页面。 + +CUPS 也带有一个访问日志和错误日志。你可以在 `cupsd.conf` 中使用 `LogLevel` 语句来改变日志级别。默认情况下,日志是保存在 `/var/log/cups` 目录。它们可以在浏览器界面()下,从 **Administration** 选项卡中查看。使用不带任何选项的 `cupsctl` 命令可以显示日志选项。也可以编辑 `cupsd.conf` 或者使用 `cupsctl` 去调整各种日志参数。查看 `cupsctl` 命令的 man 页面了解更多信息。 + +在 Ubuntu 的 Wiki 页面上的 [调试打印问题][7] 页面也是一个非常好的学习的地方。 + +这就是关于打印和 CUPS 的介绍。 + +-------------------------------------------------------------------------------- + +via: https://www.ibm.com/developerworks/library/l-lpic1-108-4/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/ +[3]:https://www.ibm.com/developerworks/library/l-lpic1-108-4/gimp-print.jpg +[4]:https://www.ibm.com/developerworks/library/l-lpic1-101-3/ +[5]:https://www.ibm.com/developerworks/library/l-lpic1-108-4/fig-cups-web.jpg +[6]:https://www.ibm.com/developerworks/library/l-lpic1-108-4/fig-settings.jpg +[7]:https://wiki.ubuntu.com/DebuggingPrintingProblems diff --git a/translated/tech/20180206 Programming in Color with ncurses.md b/published/20180206 Programming in Color with ncurses.md similarity index 62% rename from translated/tech/20180206 Programming in Color with ncurses.md rename to published/20180206 Programming in Color with ncurses.md index 18960de398..b2ab9d273f 100755 --- a/translated/tech/20180206 Programming in Color with ncurses.md +++ b/published/20180206 Programming in Color with ncurses.md @@ -1,103 +1,92 @@ -使用ncurses进行颜色编程 +使用 ncurses 进行颜色编程 ====== -在我的使用ncurses库进行编程的系列文章的[第一篇][1]和[第二篇][2]中,我已经介绍了一些curses的函数来在屏幕上作画、从屏幕上查询和从键盘读取字符。为了搞清楚这些函数,我使用curses来利用简单字符绘制游戏地图和玩家字符创建了一个简单的冒险游戏。在这篇紧接着的文章里,我展示了如何为你的curses程序添加颜色。 -在屏幕上绘图一切都挺好的,但是如果只有黑底白字的文本,你的程序可能看起来很无趣。颜色可以帮助传递更多的信息。举个例子,如果你的程序需要报告(执行)成功或者(执行)失败时。在这样的情况下你可以使用绿色或者红色来帮助强调输出。或者,你只是简单地想要“潮艺”一下给你的程序来让它看起来更美观。 +![](https://www.linuxjournal.com/sites/default/files/styles/850x500/public/nodeimage/story/quest-color-1.png?itok=lOK4ldl6) -在这篇文章中,我用一个简单的例子来展示通过curses函数进行颜色操作。在我先前的文章中,我写了一个允许你在一个粗糙绘制的地图上移动玩家字符的初级冒险类游戏。但是那里面的地图完全是白色和黑色的文本,通过形状来表明是水(~)或者山(^)。所以,让我们将游戏更新到使用颜色(的版本)吧。 +> Jim 给他的终端冒险游戏添加了颜色,演示了如何用 curses 操纵颜色。 + +在我的使用 ncurses 库进行编程的系列文章的[第一篇][1]和[第二篇][2]中,我已经介绍了一些 curses 函数来在屏幕上作画、从屏幕上查询和从键盘读取字符。为了搞清楚这些函数,我使用 curses 来利用简单字符绘制游戏地图和玩家角色,创建了一个简单的冒险游戏。在这篇紧接着的文章里,我展示了如何为你的 curses 程序添加颜色。 + +在屏幕上绘图一切都挺好的,但是如果只有黑底白字的文本,你的程序可能看起来很无趣。颜色可以帮助传递更多的信息。举个例子,如果你的程序需要报告执行成功或者执行失败时。在这样的情况下你可以使用绿色或者红色来帮助强调输出。或者,你只是简单地想要“潮艺”一下给你的程序来让它看起来更美观。 + +在这篇文章中,我用一个简单的例子来展示通过 curses 函数进行颜色操作。在我先前的文章中,我写了一个可以让你在一个粗糙绘制的地图上移动玩家角色的初级冒险类游戏。但是那里面的地图完全是白色和黑色的文本,通过形状来表明是水(`~`)或者山(`^`)。所以,让我们将游戏更新到使用颜色的版本吧。 ### 颜色要素 -在你可以使用颜色之前,你的程序得要知道它是否可以依靠终端正确地显示颜色。在现代操作系统上,此处应该永远为true。但是在经典的计算机上,一些终端是单色的,例如令人尊敬的VT52和VT100终端,一般(它们)提供黑底白色或者黑底绿色的文本。 +在你可以使用颜色之前,你的程序需要知道它是否可以依靠终端正确地显示颜色。在现代操作系统上,此处应该永远为true。但是在经典的计算机上,一些终端是单色的,例如古老的 VT52 和 VT100 终端,一般它们提供黑底白色或者黑底绿色的文本。 -可以使用has_colors()函数查询终端的颜色功能。这个函数将会在终端可以显示颜色的时候返回true,否则将会返回false。这个函数一般用于if块的开头,就像这样: +可以使用 `has_colors()` 函数查询终端的颜色功能。这个函数将会在终端可以显示颜色的时候返回 `true`,否则将会返回 `false`。这个函数一般用于 `if` 块的开头,就像这样: ``` - if (has_colors() == FALSE) { endwin(); printf("Your terminal does not support color\n"); exit(1); } - ``` -在知道终端可以显示颜色之后,你可以使用start_color()函数来设置curses使用颜色。现在是时候定义程序将要使用的颜色了。 +在知道终端可以显示颜色之后,你可以使用 `start_color()` 函数来设置 curses 使用颜色。现在是时候定义程序将要使用的颜色了。 -在curses中,你应该按对定义颜色:一个前景色放在一个背景色上。这样允许curses一次性设置两个颜色属性,这也是一般你想要使用的方式。通过init_pair()函数可以定义一个前景色和背景色并关联到索引数字来设置颜色对。大致语法如下: +在 curses 中,你应该按对定义颜色:一个前景色放在一个背景色上。这样允许 curses 一次性设置两个颜色属性,这也是一般你想要使用的方式。通过 `init_pair()` 函数可以定义一个前景色和背景色并关联到索引数字来设置颜色对。大致语法如下: ``` - init_pair(index, foreground, background); - ``` 控制台支持八种基础的颜色:黑色、红色、绿色、黄色、蓝色、品红色、青色和白色。这些颜色通过下面的名称为你定义好了: -* COLOR_BLACK - -* COLOR_RED - -* COLOR_GREEN - -* COLOR_YELLOW - -* COLOR_BLUE - -* COLOR_MAGENTA - -* COLOR_CYAN - -* COLOR_WHITE +* `COLOR_BLACK` +* `COLOR_RED` +* `COLOR_GREEN` +* `COLOR_YELLOW` +* `COLOR_BLUE` +* `COLOR_MAGENTA` +* `COLOR_CYAN` +* `COLOR_WHITE` ### 应用颜色 -在我的冒险游戏中,我想要让草地呈现绿色而玩家的足迹变成不易察觉的绿底黄色点迹。水应该是蓝色,那些(表示波浪的)腭化符号应该是近似青色的。我想让山是灰色的,但是我可以用白底黑色文本做一个可用的折中方案。(译注:意为终端预设的颜色没有灰色,使用白底黑色文本做一个折中方案)为了让玩家的字符更易见,我想要使用一个刺目的品红底红色设计。我可以像这样定义这些颜色对: +在我的冒险游戏中,我想要让草地呈现绿色而玩家的足迹变成不易察觉的绿底黄色点迹。水应该是蓝色,那些表示波浪的 `~` 符号应该是近似青色的。我想让山(`^`)是灰色的,但是我可以用白底黑色文本做一个可用的折中方案。(LCTT 译注:意为终端预设的颜色没有灰色,使用白底黑色文本做一个折中方案)为了让玩家的角色更易见,我想要使用一个刺目的品红底红色设计。我可以像这样定义这些颜色对: ``` - start_color(); init_pair(1, COLOR_YELLOW, COLOR_GREEN); init_pair(2, COLOR_CYAN, COLOR_BLUE); init_pair(3, COLOR_BLACK, COLOR_WHITE); init_pair(4, COLOR_RED, COLOR_MAGENTA); - ``` 为了让颜色对更容易记忆,我的程序中定义了一些符号常量: -``` +``` #define GRASS_PAIR 1 #define EMPTY_PAIR 1 #define WATER_PAIR 2 #define MOUNTAIN_PAIR 3 #define PLAYER_PAIR 4 - ``` 有了这些常量,我的颜色定义就变成了: -``` +``` start_color(); init_pair(GRASS_PAIR, COLOR_YELLOW, COLOR_GREEN); init_pair(WATER_PAIR, COLOR_CYAN, COLOR_BLUE); init_pair(MOUNTAIN_PAIR, COLOR_BLACK, COLOR_WHITE); init_pair(PLAYER_PAIR, COLOR_RED, COLOR_MAGENTA); - ``` -在任何时候你想要使用颜色显示文本,你只需要告诉curses设置那种颜色属性。为了更好的编程实践,你同样应该在你完成了颜色使用的时候告诉curses取消颜色组合。为了设置颜色,应该在调用像mvaddch()这样的函数之前使用attron(),然后通过attroff()关闭颜色属性。例如,在我绘制玩家的字符的时候,我应该这样做: -``` +在任何时候你想要使用颜色显示文本,你只需要告诉 curses 设置哪种颜色属性。为了更好的编程实践,你同样应该在你完成了颜色使用的时候告诉 curses 取消颜色组合。为了设置颜色,应该在调用像 `mvaddch()` 这样的函数之前使用`attron()`,然后通过 `attroff()` 关闭颜色属性。例如,在我绘制玩家角色的时候,我应该这样做: +``` attron(COLOR_PAIR(PLAYER_PAIR)); mvaddch(y, x, PLAYER); attroff(COLOR_PAIR(PLAYER_PAIR)); - ``` -记住将颜色应用到你的程序添加了不可见的改变到你如何查询屏幕。一般来讲,由mvinch()函数返回的值是**没有**带颜色属性的类型chtype,这个值基本上是一个整型值也可以就当作整型值来用。但是,由于(使用)颜色添加了额外的属性到屏幕上的字符上,所以chtype按照扩展的位模式携带了额外的颜色信息。一旦你使用mvinch(),返回值将会包含这些额外的颜色值。为了只提取**文本**值,例如在is_move_okay()函数中,你需要和A_CHARTEXT做&位运算: -``` +记住将颜色应用到你的程序对你如何查询屏幕有一些微妙的影响。一般来讲,由 `mvinch()` 函数返回的值是**没有**带颜色属性的类型 `chtype`,这个值基本上是一个整型值,也可以当作整型值来用。但是,由于使用颜色添加了额外的属性到屏幕上的字符上,所以 `chtype` 按照扩展的位模式携带了额外的颜色信息。一旦你使用 `mvinch()`,返回值将会包含这些额外的颜色值。为了只提取**文本**值,例如在 `is_move_okay()` 函数中,你需要和 `A_CHARTEXT` 做 `&` 位运算: +``` int is_move_okay(int y, int x) { int testch; @@ -108,16 +97,15 @@ int is_move_okay(int y, int x) return (((testch & A_CHARTEXT) == GRASS) || ((testch & A_CHARTEXT) == EMPTY)); } - ``` 通过这些修改,我可以用颜色更新这个冒险游戏: -``` +``` /* quest.c */ -#include -#include +#include +#include #define GRASS ' ' #define EMPTY '.' @@ -280,12 +268,11 @@ void draw_map(void) } attroff(COLOR_PAIR(WATER_PAIR)); } - ``` -你可能不能认出所有为了在冒险游戏里面支持颜色需要的修改,除非你目光敏锐。diff工具展示了所有为了支持颜色而添加的函数或者修改的代码: -``` +你可能不能认出所有为了在冒险游戏里面支持颜色需要的修改,除非你目光敏锐。`diff` 工具展示了所有为了支持颜色而添加的函数或者修改的代码: +``` $ diff quest-color/quest.c quest/quest.c 12,17d11 < #define GRASS_PAIR 1 @@ -350,28 +337,27 @@ $ diff quest-color/quest.c quest/quest.c < attron(COLOR_PAIR(WATER_PAIR)); 164d125 < attroff(COLOR_PAIR(WATER_PAIR)); - ``` ### 开始玩吧--现在有颜色了 -程序现在有了更舒服的颜色设计了,更匹配起初的桌游地图,有绿地、蓝色的湖和壮观的灰色山峰。英雄穿着红色的制服十分夺目。 +程序现在有了更舒服的颜色设计了,更匹配原来的桌游地图,有绿色的地、蓝色的湖和壮观的灰色山峰。英雄穿着红色的制服十分夺目。 ![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-map_0.jpg) -图 1\. 一个简单的带湖和山的桌游地图 +*图 1. 一个简单的带湖和山的桌游地图* ![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-color-start.png) -图 2\.玩家站在左下角 +*图 2. 玩家站在左下角* ![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/quest-color-1.png) -图 3\. 玩家可以在游戏区域移动,比如围绕湖,通过山的通道到达未知的区域。 +*图 3. 玩家可以在游戏区域移动,比如围绕湖,通过山的通道到达未知的区域。* -通过颜色,你可以更清楚地展示信息。这个例子使用颜色指出可游戏的区域(绿色)相对着不可通过的区域(蓝色或者灰色)。我希望你可以使用这个示例游戏作为你自己的程序的一个起点或者参照。取决于你需要你的程序做什么,你可以通过curses做得更多。 +通过颜色,你可以更清楚地展示信息。这个例子使用颜色指出可游戏的区域(绿色)相对着不可通过的区域(蓝色或者灰色)。我希望你可以使用这个示例游戏作为你自己的程序的一个起点或者参照。这取决于你需要你的程序做什么,你可以通过 curses 做得更多。 -在下一篇文章,我计划展示ncurses库的其它特性,比如怎样创建窗口和边框。同时,如果你对于学习 curses 有兴趣,我建议你去读位于 [Linux 文档计划](http://www.tldp.org)的 Pradeep Padala 写的 [NCURSES Programming HOWTO](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO)。 +在下一篇文章,我计划展示 ncurses 库的其它特性,比如怎样创建窗口和边框。同时,如果你对于学习 curses 有兴趣,我建议你去读位于 [Linux 文档计划](http://www.tldp.org) 的 Pradeep Padala 写的 [NCURSES Programming HOWTO](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO)。 -------------------------------------------------------------------------------- @@ -379,11 +365,11 @@ via: http://www.linuxjournal.com/content/programming-color-ncurses 作者:[Jim Hall][a] 译者:[leemeans](https://github.com/leemeans) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:http://www.linuxjournal.com/users/jim-hall -[1]:http://www.linuxjournal.com/content/getting-started-ncurses -[2]:http://www.linuxjournal.com/content/creating-adventure-game-terminal-ncurses +[1]:https://linux.cn/article-9348-1.html +[2]:https://linux.cn/article-9383-1.html [3]:http://tldp.org/HOWTO/NCURSES-Programming-HOWTO \ No newline at end of file diff --git a/published/20180207 Python Global Keyword (With Examples).md b/published/20180207 Python Global Keyword (With Examples).md new file mode 100644 index 0000000000..1a15db8e44 --- /dev/null +++ b/published/20180207 Python Global Keyword (With Examples).md @@ -0,0 +1,181 @@ +初识 Python: global 关键字 +====== + +在读这篇文章之前,确保你对 [Python 全局、本地和非本地变量][1] 有一定的基础。 + +### global 关键字简介 + +在 Python 中,`global` 关键字允许你修改当前范围之外的变量。它用于创建全局变量并在本地上下文中更改变量。 + +### global 关键字的规则 + +在 Python 中,有关 `global` 关键字基本规则如下: + +* 当我们在一个函数中创建一个变量时,默认情况下它是本地变量。 +* 当我们在一个函数之外定义一个变量时,默认情况下它是全局变量。你不必使用 `global` 关键字。 +* 我们使用 `global` 关键字在一个函数中来读写全局变量。 +* 在一个函数外使用 `global` 关键字没有效果。 + +### 使用 global 关键字(含示例) + +我们来举个例子。 + +#### 示例 1:从函数内部访问全局变量 + +``` +c = 1 # 全局变量 +def add(): + print(c) + +add() +``` + +运行程序,输出为: + +``` +1 +``` + +但是我们可能有一些场景需要从函数内部修改全局变量。 + +#### 示例 2:在函数内部修改全局变量 + +``` +c = 1 # 全局变量 +def add(): + c = c + 2 # 将 c 增加 2 + print(c) +add() +``` + +运行程序,输出显示错误: + +``` +UnboundLocalError: local variable 'c' referenced before assignment +``` + +这是因为在函数中,我们只能访问全局变量但是不能修改它。 + +解决的办法是使用 `global` 关键字。 + +#### 示例 3:使用 global 在函数中改变全局变量 + +``` +c = 0 # global variable + +def add(): + global c + c = c + 2 # 将 c 增加 2 + print("Inside add():", c) + +add() +print("In main:", c) +``` + +运行程序,输出为: + +``` +Inside add(): 2 +In main: 2 +``` + +在上面的程序中,我们在 `add()` 函数中定义了 `c` 将其作为全局关键字。 + +然后,我们给变量 `c` 增加 `2`,即 `c = c + 2`。之后,我们调用了 `add()` 函数。最后,打印全局变量 `c`。 + +正如我们所看到的,在函数外的全局变量也发生了变化,`c = 2`。 + +### Python 模块中的全局变量 + +在 Python 中,我们创建一个单独的模块 `config.py` 来保存全局变量并在同一个程序中的 Python 模块之间共享信息。 + +以下是如何通过 Python 模块共享全局变量。 + +#### 示例 4:在Python模块中共享全局变量 + +创建 `config.py` 文件来存储全局变量 + +``` +a = 0 +b = "empty" +``` + +创建 `update.py` 文件来改变全局变量 + +``` +import config + +config.a = 10 +config.b = "alphabet" +``` + +创建 `main.py` 文件来测试其值的变化 + +``` +import config +import update + +print(config.a) +print(config.b) +``` + +运行 `main.py`,输出为: + +``` +10 +alphabet +``` + +在上面,我们创建了三个文件: `config.py`, `update.py` 和 `main.py`。 + +在 `config.py` 模块中保存了全局变量 `a` 和 `b`。在 `update.py` 文件中,我们导入了 `config.py` 模块并改变了 `a` 和 `b` 的值。同样,在 `main.py` 文件,我们导入了 `config.py` 和 `update.py` 模块。最后,我们打印并测试全局变量的值,无论它们是否被改变。 + +### 在嵌套函数中的全局变量 + +以下是如何在嵌套函数中使用全局变量。 + +#### 示例 5:在嵌套函数中使用全局变量 + +``` +def foo(): + x = 20 + def bar(): + global x + x = 25 + + print("Before calling bar: ", x) + print("Calling bar now") + bar() + print("After calling bar: ", x) + +foo() +print("x in main : ", x) +``` + +输出为: + +``` +Before calling bar: 20 +Calling bar now +After calling bar: 20 +x in main : 25 +``` + +在上面的程序中,我们在一个嵌套函数 `bar()` 中声明了全局变量。在 `foo()` 函数中, 变量 `x` 没有全局关键字的作用。 + +调用 `bar()` 之前和之后, 变量 `x` 取本地变量的值,即 `x = 20`。在 `foo()` 函数之外,变量 `x` 会取在函数 `bar()` 中的值,即 `x = 25`。这是因为在 `bar()` 中,我们对 `x` 使用 `global` 关键字创建了一个全局变量(本地范围)。 + +如果我们在 `bar()` 函数内进行了任何修改,那么这些修改就会出现在本地范围之外,即 `foo()`。 + +-------------------------------------------------------------------------------- + +via: [https://www.programiz.com/python-programming/global-keyword](https://www.programiz.com/python-programming/global-keyword) + +作者:[programiz][a] +译者:[MjSeven](https://github.com/MjSeven) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.programiz.com +[1]:https://www.programiz.com/python-programming/global-local-nonlocal-variables diff --git a/published/20180213 How to clone, modify, add, and delete files in Git.md b/published/20180213 How to clone, modify, add, and delete files in Git.md new file mode 100644 index 0000000000..d552a0f54f --- /dev/null +++ b/published/20180213 How to clone, modify, add, and delete files in Git.md @@ -0,0 +1,193 @@ +在 Git 中怎样克隆、修改、添加和删除文件? +===== + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LIFE_cat.png?itok=ta54QTAf) + +在 [本系列的第一篇文章][1] 开始使用 Git 时,我们创建了一个简单的 Git 仓库,并用我们的计算机连接到它,向其中添加一个文件。在本文中,我们将学习一些关于 Git 的其他内容,即如何克隆(下载)、修改、添加和删除 Git 仓库中的文件。 + +### 让我们来克隆一下 + +假设你在 GitHub 上已经有一个 Git 仓库,并且想从它那里获取你的文件——也许你在你的计算机上丢失了本地副本,或者你正在另一台计算机上工作,但是想访问仓库中的文件,你该怎么办?从 GitHub 下载你的文件?没错!在 Git 术语中我们称之为“克隆clone”。(你也可以将仓库作为 ZIP 文件下载,但我们将在本文中探讨克隆方式。) + +让我们克隆在上一篇文章中创建的名为 Demo 的仓库。(如果你还没有创建 Demo 仓库,请跳回到[那篇文章][1]并在继续之前执行那些步骤)要克隆文件,只需打开浏览器并导航到 `https://github.com//Demo` (其中 `` 是你仓库的名称。例如,我的仓库是 `https://github.com/kedark3/Demo`)。一旦你导航到该 URL,点击“克隆或下载Clone or download”按钮,你的浏览器看起来应该是这样的: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide11.png?itok=wJYqZyBX) + +正如你在上面看到的,“使用 HTTPS 克隆Clone with HTTPS”选项已打开。从该下拉框中复制你的仓库地址(`https://github.com//Demo.git`),打开终端并输入以下命令将 GitHub 仓库克隆到你的计算机: + +``` +git clone https://github.com//Demo.git +``` + +然后,要查看 `Demo` 目录中的文件列表,请输入以下命令: + +``` +ls Demo/ +``` + +终端看起来应该是这样的: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide12.png?itok=E7ZG9t-8) + +### 修改文件 + +现在我们已经克隆了仓库,让我们修改文件并在 GitHub 上更新它们。首先,逐个输入下面的命令,将目录更改为 `Demo/`,检查 `README.md` 中的内容,添加新的(附加的)内容到 `README.md`,然后使用 `git status` 检查状态: + +``` +cd Demo/ +ls +cat README.md +echo "Added another line to REAMD.md" >> README.md +cat README.md +git status +``` + +如果你逐一运行这些命令,终端看起开将会是这样: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide12.5.png?itok=jhb-EPH1) + +让我们看一下 `git status` 的输出,并了解它的意思。不要担心这样的语句: + +``` +On branch master +Your branch is up-to-date with 'origin/master'.". +``` + +因为我们还没有学习这些。(LCTT 译注:学了你就知道了)下一行说:`Changes not staged for commit`(变化未筹划提交);这是告诉你,它下面列出的文件没有被标记准备(“筹划stage”)提交。如果你运行 `git add`,Git 会把这些文件标记为 `Ready for commit`(准备提交);换句话说就是 `Changes staged for commit`(变化筹划提交)。在我们这样做之前,让我们用 `git diff` 命令来检查我们添加了什么到 Git 中,然后运行 `git add`。 + +这里是终端输出: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide13.png?itok=983p_vNw) + +我们来分析一下: + +* `diff --git a/README.md b/README.md` 是 Git 比较的内容(在这个例子中是 `README.md`)。 +* `--- a/README.md` 会显示从文件中删除的任何东西。 +* `+++ b/README.md` 会显示从文件中添加的任何东西。 +* 任何添加到文件中的内容都以绿色文本打印,并在该行的开头加上 `+` 号。 +* 如果我们删除了任何内容,它将以红色文本打印,并在该行的开头加上 `-` 号。 +* 现在 `git status` 显示 `Changes to be committed:`(变化将被提交),并列出文件名(即 `README.md`)以及该文件发生了什么(即它已经被 `modified` 并准备提交)。 + +提示:如果你已经运行了 `git add`,现在你想看看文件有什么不同,通常 `git diff` 不会输出任何东西,因为你已经添加了文件。相反,你必须使用 `git diff --cached`。它会告诉你 Git 添加的当前版本和以前版本文件之间的差别。你的终端输出看起来会是这样: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide14.png?itok=bva9fHJj) + +### 上传文件到你的仓库 + +我们用一些新内容修改了 `README.md` 文件,现在是时候将它上传到 GitHub。 + +让我们提交更改并将其推送到 GitHub。运行: + +``` +git commit -m "Updated Readme file" +``` + +这告诉 Git 你正在“提交”已经“添加”的更改,你可能还记得,从本系列的第一部分中,添加一条消息来解释你在提交中所做的操作是非常重要的,以便你在稍后回顾 Git 日志时了解当时的目的。(我们将在下一篇文章中更多地关注这个话题。)`Updated Readme file` 是这个提交的消息——如果你认为这没有合理解释你所做的事情,那么请根据需要写下你的提交消息。 + +运行 `git push -u origin master`,这会提示你输入用户名和密码,然后将文件上传到你的 GitHub 仓库。刷新你的 GitHub 页面,你应该会看到刚刚对 `README.md` 所做的更改。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide15.png?itok=Qa3spy13) + +终端的右下角显示我提交了更改,检查了 Git 状态,并将更改推送到了 GitHub。`git status` 显示: + +``` +Your branch is ahead of 'origin/master' by 1 commit +  (use "git push" to publish your local commits) +``` + +第一行表示在本地仓库中有一个提交,但不在 `origin/master` 中(即在 GitHub 上)。下一行指示我们将这些更改推送到 `origin/master` 中,这就是我们所做的。(在本例中,请参阅本系列的第一篇文章,以唤醒你对 `origin` 含义的记忆。我将在下一篇文章中讨论分支的时候,解释 `master` 的含义。) + +### 添加新文件到 Git + +现在我们修改了一个文件并在 GitHub 上更新了它,让我们创建一个新文件,将它添加到 Git,然后将其上传到 GitHub。 +运行: + +``` +echo "This is a new file" >> file.txt +``` + +这将会创建一个名为 `file.txt` 的新文件。 + +如果使用 `cat` 查看它: + +``` +cat file.txt +``` + +你将看到文件的内容。现在继续运行: + +``` +git status +``` + +Git 报告说你的仓库中有一个未跟踪的文件(名为 `file.txt`)。这是 Git 告诉你说在你的计算机中的仓库目录下有一个新文件,然而你并没有告诉 Git,Git 也没有跟踪你所做的任何修改。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide16.png?itok=UZpSKL13) + +我们需要告诉 Git 跟踪这个文件,以便我们可以提交并上传文件到我们的仓库。以下是执行该操作的命令: + +``` +git add file.txt +git status +``` + +终端输出如下: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide17.png?itok=quV-75Na) + +`git status` 告诉你有 `file.txt` 被修改,对于 Git 来说它是一个 `new file`,Git 在此之前并不知道。现在我们已经为 Git 添加了 `file.txt`,我们可以提交更改并将其推送到 `origin/master`。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide18.png?itok=e0D7-eol) + +Git 现在已经将这个新文件上传到 GitHub;如果刷新 GitHub 页面,则应该在 GitHub 上的仓库中看到新文件 `file.txt`。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide19.png?itok=FcuSsHQ6) + +通过这些步骤,你可以创建尽可能多的文件,将它们添加到 Git 中,然后提交并将它们推送到 GitHub。 + +### 从 Git 中删除文件 + +如果我们发现我们犯了一个错误,并且需要从我们的仓库中删除 `file.txt`,该怎么办?一种方法是使用以下命令从本地副本中删除文件: + +``` +rm file.txt +``` + +如果你现在做 `git status`,Git 就会说有一个文件 `not staged for commit`(未筹划提交),并且它已经从仓库的本地拷贝中删除了。如果我们现在运行: + +``` +git add file.txt +git status +``` + +我知道我们正在删除这个文件,但是我们仍然运行 `git add`,因为我们需要告诉 Git 我们正在做的**更改**,`git add` 可以用于我们添加新文件、修改一个已存在文件的内容、或者从仓库中删除文件时。实际上,`git add` 将所有更改考虑在内,并将这些筹划提交这些更改。如果有疑问,请仔细查看下面终端屏幕截图中每个命令的输出。 + +Git 会告诉我们已删除的文件正在进行提交。只要你提交此更改并将其推送到 GitHub,该文件也将从 GitHub 的仓库中删除。运行以下命令: + +``` +git commit -m "Delete file.txt" +git push -u origin master +``` + +现在你的终端看起来像这样: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide20.png?itok=SrJMqNXC) + +你的 GitHub 看起来像这样: + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/git_guide21.png?itok=RhXM4Gua) + +现在你知道如何从你的仓库克隆、添加、修改和删除 Git 文件。本系列的下一篇文章将检查 Git 分支。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/how-clone-modify-add-delete-git-files + +作者:[Kedar Vijay Kulkarni][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/kkulkarn +[1]:https://linux.cn/article-9319-1.html diff --git a/published/20180214 11 awesome vi tips and tricks.md b/published/20180214 11 awesome vi tips and tricks.md new file mode 100644 index 0000000000..530e2e1347 --- /dev/null +++ b/published/20180214 11 awesome vi tips and tricks.md @@ -0,0 +1,95 @@ +11 个超棒的 Vi 技巧和窍门 +====== + +> 是否你刚刚接触 Vi 还是想进阶,这些技巧可以很快让你成为高级用户。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/keyboaord_enter_writing_documentation.jpg?itok=kKrnXc5h) + +[Vi][1] 编辑器是 Unix 和像 Linux 这样的类 Unix 系统中 Linux 最流行的编辑器之一。无论您是 vi 新手还是想进阶,这里有 11 个技巧可以增强你使用的方式。 + +### 编辑 + +编辑长文本时可能很难受,特别是编辑其中某一行时,需要移动许久才能到这行。这有个很快的方法: + +1、 `:set number` 这个命令可是在编辑器左边显示行号。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/setnum.png?itok=sFVA97mG) + +您可以在命令行中输入 `vi +26 samp.txt` 命令直接打开文件到达 26 行,在 vi 编辑器中也可以输入 `:26` 跳转到 26 行。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/number.png?itok=d7FE0LL3) + +### 快速导航 + +2、 `i` 将工作方式从“命令模式”更改为“输入模式”,并在当前光标位置开始插入内容。 + +3、 `a` 除了是光标之后开始插入内容,与上面的效果是一样的。 + +4、 `o` 在光标的下一行位置开始插入内容。 + +### 删除 + +如果您发现错误或错别字,能快速的修正是很重要的。好在 Vi 都事先想好了。 + +了解 Vi 的删除功能,保证你不会意外按下某个键并永久删除一行或多段内容,这点至关重要。 + +5、 `x` 删除当前光标的字符。 + +6、 `dd` 删除当前行 (是的,整行内容!) + +下面看可怕的部分:`30dd` 从当前行开始删除以下 30 行!使用此命令请慎重。 + +### 搜索 + +您可以在“命令模式”搜索关键字,而不用在大量文本内容中手动导航查找特定的单词或内容。 + +7、 `:/` 搜索 `< >` 中的单词并将光标移动到第一个匹配项。 + +8、 导航到该单词的下一个匹配项,请输入 `n` 并继续按下, 直到找到您要找的内容。 + +例如,在这个图像中我要搜索包含 `ssh` 的内容, Vi 光标就会突出第一个结果的开始位置。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/ssh-search.png?itok=tJ-7FujH) + +按下 `n` 之后, Vi 光标就会突出下一个匹配项。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/n-search.png?itok=wU-u3LiI) + +### 保存并退出 + +开发人员 (或其他人) 可能会发现这个命令很有用。 + +9、 `:x` 保存您的工作并退出 Vi 。 + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/x.png?itok=kfoHx84m) + +10、 如果你想节省哪怕是纳秒,那么这有个更快的回到终端的方法。不用在键盘上按 `Shift+:` ,而是按下 `Shift+q` (或者大写字母 Q ) 来进入 [Ex 模式][2] 。但是如果你只是想按下 `x` 来保存退出,那就没有什么区别(如上所示)。 + +### 替换 + +如果您想将文中的某个单词全部替换为一个单词,这有个很巧妙的招式。例如,如果您想在一个大文件中将 “desktop” 替换为 “laptop” ,那么单调的搜索每个出现的 “desktop” 将其删掉,然后再输入 “laotop” ,是很浪费时间的。 + +11、 `:%s/desktop/laptop/g` 这个命令将在整个文件中的 “desktop” 用 “laptop” 替换,他就像 Linux 的 `sed` 命令一样。 + + +这个例子中我用 “user” 替换了 “root” : + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/subs-command.png?itok=M8MN72sp) + +![](https://opensource.com/sites/default/files/styles/panopoly_image_original/public/u128651/subs-result.png?itok=34zzVdUt) + +这些技巧应该能帮组任何想开始学 Vi 的人。我有遗漏其他巧妙的提示吗?请在评论中分享他们。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/1/top-11-vi-tips-and-tricks + +作者:[Archit Modi][a] +译者:[MZqk](https://github.com/MZqk) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux 中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/architmodi +[1]:http://ex-vi.sourceforge.net/ +[2]:https://en.wikibooks.org/wiki/Learning_the_vi_Editor/Vim/Modes#Ex-mode diff --git a/published/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md b/published/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md new file mode 100644 index 0000000000..abf68aeb2b --- /dev/null +++ b/published/20180214 Protecting Code Integrity with PGP - Part 1- Basic Concepts and Tools.md @@ -0,0 +1,201 @@ +用 PGP 保护代码完整性(一): 基本概念和工具 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/pgp-security.jpg?itok=lulwyzYc) + +在本系列文章中,我们将深度探讨如何使用 PGP 确保软件完整性。这些文章将为工作于自由软件项目的开发者提供实用指南,并且将包含以下主题: + + 1. PGP 基础和最佳实践 + 2. 如何用 Git 使用 PGP + 3. 如何保护你的开发者账户 + +我们使用与“Freedom”含义相同的词项 “Free”,但这个系列中列出的指南也可以被任何其它类型的依赖于分布式团队开发者贡献的软件中。如果你编写进入公共源仓库的代码,你可以从了解和遵循这篇指南中受益。 + +### 结构 + +每节分为两个部分: + + * 适用于你项目需求的清单 + * 形式自由的考虑事项的列表,解释这些决定取决于什么,并伴随着配置指令 + +#### 清单优先级 + +每个清单中各项包含着优先级,用来帮助指导你的决定: + + * (必要)该项一定要排在考虑事项列表的前面。如果没有这样做,它们将给提交到开源项目中的代码带来高风险。 + * (推荐)包含该项将提升整体安全性,但会影响你与工作环境的交互方式,并且可能需要学习新的习惯或者放弃旧的习惯。 + +记住,这些只是指导。如果你感到这些优先级不能反映你项目提交的安全,你应该根据自己的需要调整它们。 + +### PGP 基本概念和工具 + +#### 清单 + + 1. 理解 PGP 在自由软件开发中的作用 (必要) + 2. 理解公钥密码学Public Key Cryptography的基础知识 (必要) + 3. 理解 PGP 加密和签名的不同 (必要) + 4. 理解 PGP 密钥身份key identities (必要) + 5. 理解 PGP 密钥有效性key validity (必要) + 6. 安装 GnuPG 工具(版本 2.x) (必要) + +#### 考虑事项 + +自由软件社区长期依赖于 PGP 确保它生产的软件产品的真实性和完整性。你可能没有注意到,但无论你是一个 Linux +、Mac 和 Windowas 用户,你都曾依赖 PGP 来确保你电脑环境的完整性: + + * Linux 发行版依赖 PGP 来确保当二进制或者原代码包从被生产出来到被终端用户安装之间没被更改过 + * 自由软件项目通常会伴随发行软件的存档提供分离的 PGP 签名,使得下游的项目可以在把下载的版本集成到自己的分布式下载之前,验证下载版本的完整性。 + * 自由软件项目通常依赖代码本身的 PGP 签名来跟踪起源,并验证项目开发者提交的代码的完整性 + +这与工作于专有平台的程序员使用的开发者证书或代码签名机制非常相似。实际上,这两种技术背后的核心概念非常相似 —— 尽管它们在实现的技术层面和它们委托信任方式的大多不同。PGP 不依赖于集中式认证机构,而是让每个用户为每个证书赋予自己的信任。 + +我们的目标是使你的项目通过使用 PGP 来进行代码起源和完整性追踪,遵循最佳实践并遵守基本的安全预防措施。 + +#### 极其基本的 PGP 操作概括 + +你不需要知道 PGP 如何工作的具体细节 —— 理解核心概念足以成功地达到我们的目的。PGP 依赖于公钥密码学来将明文转换为密文。这个过程需要两种不同的密钥: + + * 公钥,被所有人知道 + * 私钥,只被拥有者知道 + +##### 加密 + +对加密来说,PGP 使用拥有者的公钥创造一条只能通过拥有者私钥解密的消息: + + 1. 发送者生成一个随机的加密密钥(“会话密钥”) + 2. 发送者使用该会话密钥(使用对称算法)加密内容 + 3. 发送者使用接收者的 PGP 公钥加密会话密钥 + 4. 发送者向接收者发送加密后的内容和加密后的会话密钥 + +要解密: + + 1. 接收者使用他们的 PGP 私钥解密会话密钥 + 2. 接收者使用会话密钥解密消息的内容 + +##### 签名 + +为了创建签名,PGP 私钥或公钥会以相反的方式使用: + + 1. 签名者生成内容的校检和哈希 + 2. 签名者使用自己的 PGP 私钥来加密该校检和 + 3. 签名者伴随内容提供加密后的校检和 + +要验证签名: + + 1. 验证者生成自己的内容校检和哈希 + 2. 验证者使用签名者的 PGP 公钥来解密提供的校检和 + 3. 如果校检和匹配,就验证了内容的完整性 + +##### 结合使用 + +通常,加密消息也被发送者自己的 PGP 密钥签名。无论何时使用加密消息,这应当是默认的,因为没有认证的加密没有很大意义(除非你是一个告密者或秘密代理并且需要可行的可否认性) + +#### 理解密钥身份 + +每个 PGP 密钥必须有一个或多个与之关联的身份。通常,“身份Identity”指的是以下格式中的人物全名和邮件地址: + +``` +Alice Engineer +``` + +有时也会在括号中包含说明,来告诉终端用户关于该特定密钥的更多信息: + +``` +Bob Designer (obsolete 1024-bit key) +``` + +由于人们可以和多个职业和个人实体相关联,因此在同一密钥上可以有多个身份: + +``` +Alice Engineer +Alice Engineer +Alice Engineer +``` + +当使用多个身份时,其中之一将被标记为“primary identity主要身份”来让检索更简单。 + +#### 理解密钥有效性 + +为了能使用其他人的公钥来加密或验证,你需要确保它确实属于正确的人(Alice)而不属于冒牌的(Eve)。在 PGP 中,这被称为“密钥有效性”: + + * 有效性:完全full -- 意味着非常确认该密钥属于 Alice + * 有效性:临界marginal -- 意味着大致确认该密钥属于 Alice + * 有效性:未知unknown -- 意味着不确认该密钥是否属于 Alice + +#### Web of Trust (WOT) 与 Trust on First Use (TOFU) + +PGP 使用了一种信任委托机制叫“Web of Trust”。它的核心是尝试替代 HTTPS/TLS 世界中对集中式认证机构的需求。PGP 把这个责任交给了每个用户,而不是各种软件开发商来决定谁应该是你的可信认证实体。 + +不幸的是,很少有人理解 Web of Trust 的是如何工作的,能使用它的人更少。它仍然是 OpenPGP 规范的一个重要方面,但 GnuPG 的近期版本(2.2 及以上)已经实现了一种替代机制叫“Trust on First Use”(TOFU)。 + +你可以把 TOFU 当作类似 SSH 的信任方式。使用 SSH,当你第一次连接到远程系统,它的密钥指纹会被记录和保存。如果将来密钥改变,SSH 客户端将会提醒你并拒绝连接,迫使你决定是否信任已改变的的密钥。 + +同样,当你第一次导入某人的 PGP 密钥,它被假定可信。如果在将来的任何时候,GnuPG 碰巧发现另一同样身份的密钥,过去导入的密钥和新密钥都将被标记为无效,并且你需要手动指出保留哪个。 + +#### 安装 OpenPGP 软件 + +首先,理解 PGP、OpenPGP、GnuPG 和 gpg 之间的不同很重要: + + * PGP (“Pretty Good Privacy”) 是最初商业软件的名字 + * OpenPGP 是与最初 PGP 工具兼容的 IETF 标准 + * GnuPG (“Gnu Privacy Guard”)是实现了 OpenPGP 标准的自由软件 + * GnuPG 的命令行工具称为 “gpg” + +今天,“PGP”这个词几乎被普遍用来表示开放的 OpenPGP 标准,而不是最初的商业软件,因此“PGP”和“OpenPGP”是可以互换的。“GnuPG”和“pgp”这两个词应该仅在提及工具时使用,而不用于它们产生的输出或它们实现的 OpenPGP 功能。举例: + + * PGP(而非 GnuPG 或 GPG)密钥 + * PGP(而非 GnuPG 或 GPG)签名 + * PGP(而非 GnuPG 或 GPG)密钥服务器 + +理解这一点应该可以保护你免受来自你遇到的其他 PGP 用户“实际上”不可避免的迂腐。 + +##### 安装 GnuPG + +如果你正在使用 Linux,你应该已经安装过了 GnuPG。在 Mac 上,你应该安装 [GPG-Suite][1],或者使用 `brew` 安装 `gnupg2`。在 Windows 上,你应该安装 [GPG4Win][2],并且为了可以工作,你可能需要调整指南中的部分命令,除非你设置了类似 Unix 的环境。对其他平台来说,你需要自行查找正确的地址来下载和安装 GnuPG。 + +##### GnuPG 1 vs. 2 + +GnuPG v.1 和 GnuPG v.2 都实现了同样的标准,但它们提供不兼容的库和命令行工具,所以许多发行版都带有了旧的版本 1 和最新的版本 2。你需要确保你总是使用 GnuPG v.2。 + +首先,运行: + +``` +$ gpg --version | head -n1 +``` + +如果你看到 `gpg (GnuPG) 1.4.x`,说明你正使用 GnuPG v.1。尝试下 `gpg2` 命令: + +``` +$ gpg2 --version | head -n1 +``` + +如果你看到 `gpg (GnuPG) 2.x.x`,说明你可以继续了。这篇指南将假设你使用 GnuPG 2.2 版本(或更新)。如果你正使用 GnuPG 的 2.0 版本,本指南中某些命令可能无效,你应该考虑安装 GnuPG 最新的 2.2 版本 + +##### 确保你总是使用 GnuPG v.2 + +如果你 `gpg` 和 `gpg2` 命令都有,你应该确保总是使用 GnuPG v.2,而不是旧的版本。你可以通过设置别名来确保这一点: + +``` +$ alias gpg=gpg2 +``` + +你可以把它放在你的 `.bashrc` 中,以确保它在你使用 `gpg` 命令时总是被加载。 + +在本系列的第 2 部分中,我们将介绍生成和保护你的 PGP 主密钥的基本步骤。 + +通过 Linux 基金会和 edX 的免费[“Introduction to Linux” ][3]课程了解关于 Linux 的更多信息。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools + +作者:[Konstantin Ryabitsev][a] +译者:[kimii](https://github.com/kimii) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/mricon +[1]:https://gpgtools.org/ +[2]:https://www.gpg4win.org/ +[3]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/published/20180215 What is a Linux -oops.md b/published/20180215 What is a Linux -oops.md new file mode 100644 index 0000000000..a8e6f56f25 --- /dev/null +++ b/published/20180215 What is a Linux -oops.md @@ -0,0 +1,71 @@ +什么是 Linux “oops”? +====== +> Linux 内核正在盯着你,当它检测到系统上运行的某些东西违反了正常内核行为时,它会关闭系统并发出一个“oops”! + +![](https://images.idgesg.net/images/article/2018/02/broken-wine-glass-100749404-large.jpg) + +如果你检查你的 Linux 系统上运行的进程,你可能会对一个叫做 “kerneloops” 的进程感到好奇。提示一下,它是 “kernel oops”,而不是 “kerne loops”。 + +坦率地说,“oops” 是 Linux 内核的一部分出现了偏差行为。你有做错了什么吗?可能没有。但有一些不对劲。而那个做了错事的进程可能已经被 CPU 结束。最糟糕的是,内核可能会报错并突然关闭系统。 + +请注意,“oops” 不是首字母缩略词。它不代表像“面向对象的编程和系统object-oriented programming and systems” 或“超出程序规范out of procedural specs” 之类的东西。它实际上就是“哎呀” (oops),就像你刚掉下一杯酒或踩在你的猫身上。哎呀! “oops” 的复数是 “oopses”。 + +oops 意味着系统上运行的某些东西违反了内核有关正确行为的规则。也许代码尝试采取不允许的代码路径或使用无效指针。不管它是什么,内核 —— 总是在监测进程的错误行为 —— 很可能会阻止特定进程,并将它做了什么的消息写入控制台、 `/var/log/dmesg` 或 `/var/log/kern.log` 中。 + +oops 可能是由内核本身引起的,也可能是某些进程试图让内核违反在系统上能做的事以及它们被允许做的事。 + +oops 将生成一个崩溃签名crash signature,这可以帮助内核开发人员找出错误并提高代码质量。 + +系统上运行的 kerneloops 进程可能如下所示: + +``` +kernoops 881 1 0 Feb11 ? 00:00:01 /usr/sbin/kerneloops +``` + +你可能会注意到该进程不是由 root 运行的,而是由名为 “kernoops” 的用户运行的,并且它的运行时间极少。实际上,分配给这个特定用户的唯一任务是运行 kerneloops。 + +``` +$ sudo grep kernoops /etc/passwd +kernoops:x:113:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false +``` + +如果你的 Linux 系统不带有 kerneloops(比如 Debian),你可以考虑添加它。查看这个 [Debian 页面][1]了解更多信息。 + +### 什么时候应该关注 oops? + +一般 oops 没什么大不了的。它在一定程度上取决于特定进程所扮演的角色。它也取决于 oops 的类别。 + +有些 oops 很严重,会导致系统恐慌system panic。从技术上讲,系统恐慌是 oops 的一个子集(即更严重的 oops)。当内核检测到的问题足够严重以至于内核认为它(内核)必须立即停止运行以防止数据丢失或对系统造成其他损害时会出现。因此,系统需要暂停并重新启动,以防止任何不一致导致不可用或不可靠。所以系统恐慌实际上是为了保护自己免受不可挽回的损害。 + +总之,所有的内核恐慌都是 oops,但并不是所有的 oops 都是内核恐慌。 + +`/var/log/kern.log` 和相关的轮转日志(`/var/log/kern.log.1`、`/var/log/kern.log.2` 等)包含由内核生成并由 syslog 处理的日志。 + +kerneloops 程序收集并默认将错误信息提交到 ,在那里它会被分析并呈现给内核开发者。此进程的配置详细信息在 `/etc/kerneloops.conf` 文件中指定。你可以使用下面的命令轻松查看设置: + +``` +$ sudo cat /etc/kerneloops.conf | grep -v ^# | grep -v ^$ +[sudo] password for shs: +allow-submit = ask +allow-pass-on = yes +submit-url = http://oops.kernel.org/submitoops.php +log-file = /var/log/kern.log +submit-pipe = /usr/share/apport/kernel_oops +``` + +在上面的(默认)设置中,内核问题可以被提交,但要求用户获得许可。如果设置为 `allow-submit = always`,则不会询问用户。 + +调试内核问题是使用 Linux 系统的更高级技巧之一。幸运的是,大多数 Linux 用户很少或从没有经历过 oops 或内核恐慌。不过,知道 kerneloops 这样的进程在系统中执行什么操作,了解可能会报告什么以及系统何时遇到严重的内核冲突也是很好的。 + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3254778/linux/what-is-a-linux-oops.html + +作者:[Sandra Henry-Stocker][a] +译者:[geekpi](https://github.com/geekpi) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.networkworld.com/author/Sandra-Henry_Stocker/ +[1]:https://packages.debian.org/stretch/kerneloops diff --git a/published/20180220 How to Get Started Using WSL in Windows 10.md b/published/20180220 How to Get Started Using WSL in Windows 10.md new file mode 100644 index 0000000000..68f507399f --- /dev/null +++ b/published/20180220 How to Get Started Using WSL in Windows 10.md @@ -0,0 +1,118 @@ +如何在 Windows 10 上开启 WSL 之旅 +====== + +> WSL 可以让你访问 Windows 上的 Linux Bash shell。 + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-main.png?itok=wJ5WrU9U) + +在 [上一篇文章][1] 中,我们讨论过关于 Windows 的子系统 LinuxWindows Subsystem for Linux(WSL)的目标用户。本文,我们将在 Windows 10 的设备上,开启 WSL 的旅程。 + +### 为 WSL 做准备 + +您必须使用最新版本的 Windows 10 Fall Creator Update。之后,通过在开始菜单栏搜索 “About”,检查 Windows 10 的版本。为了使用 WSL,您的版本应当为 1709 或者最新版。 + +这里有一张关于我的操作系统的截图。 + +![][2] + +如果您安装了之前的版本,您需要在 [这里][3] 下载并且安装 Windows 10 Fall Creator Update (FCU)。安装完毕后,安装可用的更新(在开始菜单的搜索框中搜索 “updates”)。 + +前往 “启用或关闭 Windows 功能” ,然后滚动至底部,如截图所示,勾选 “适用于 Linux 的 Windows 子系统”,点击确定。它将会下载安装需要的包。 + +![][4] + +安装完成之后,系统将会询问是否重启。是的,重启设备吧。WSL 在系统重启之前不会启动,如下所示: + +![][5] + +一旦您的系统重启,返回 “启用或关闭 Windows 功能” 页面,确认 “适用于 Linux 的 Windows 子系统” 已经被勾选。 + +### 在 Windows 中安装 Linux + +在 Windows 中安装 Linux,有很多方式,这里我们选择一种最简单的方式。打开 Microsoft Store,搜索 Linux。您将看到下面的选项: + +![][6] + +点击 “获取”,之后 Windows 商店将会提供三个选项:Ubuntu、openSUSE Leap 42 和 SUSE Linux Enterprise Server。您可以一并安装上述三个发行版,并且它们可以同时运行。为了能使用 SLE,您需要一份订阅。 + +在此,我将安装 openSUSE Leap 42 和 Ubuntu。选中您想要的发行版,点击“获得”按钮并安装。一旦安装完毕,您就可以在 Windows 中启动 openSUSE。为了方便访问,可以将其固定到开始菜单中。 + +![][7] + +### 在 Windwods 中使用 Linux + +当您启动该发行版,它将会打开一个 Bash Shell 并且安装此发行版。安装完毕之后,您就可以开始使用了。您需要留意,openSUSE 中并没有(普通)用户,它直接运行在 `root` 用户下,但是 Ubuntu 会询问您是否创建用户。在 Ubuntu,您可以以 `sudo` 用户执行管理任务。 + +在 openSUSE 上,您可以很轻松的创建一个用户: + +``` +# useradd [username] +# passwd [username] +``` + +为此用户创建一个新的密码。例如: + +``` +# useradd swapnil +# passwd swapnil +``` + +您可以通过 `su` 命令从 root 用户切换过来。 + +``` +su swapnil +``` + +您需要非根用户来执行许多任务,比如使用 `rsync` 移动文件到本地设备。 + +而首要任务是更新发行版。对于 openSUSE 来说,您应该: + +``` +zypper up +``` + +而对于 Ubuntu: + +``` +sudo apt-get update +sudo apt-get dist-upgrade +``` + +![][8] + +现在,您就在 Windows 上拥有了原生的 Linux Bash shell。想在 Windows 10 上通过 `ssh` 连接您的服务器?不需要安装 puTTY 或是 Cygwin。打开 Bash 之后,就可以通过 `ssh` 进入您的服务器。简单之至。 + +想通过 `rsync` 同步文件到您的服务器?直接使用 `rsync`。它切实的将我们的 Windows 设备转变得更为实用,帮助那些需要使用原生 Linux 命令和 Linux 工具的用户避开虚拟机,大开方便之门。 + +### Fedora 在哪里? + +您可能奇怪为什么没有 Fedora。可惜,商城里并没有 Fedora。Fedora 项目发布负责人在 Twitter 上表示,“我们正在解决一些非技术性问题。现在可能提供不了更多了。” + +我们并不确定这些非技术性问题是什么。当一些用户询问 WSL 团队为何不发布 Fedora,毕竟它也是一个开源项目。项目负责人 Rich Turner 在 Microsoft [回应][9],“我们有一个不发布其他知识产权到应用商店的政策。我们相信,相较于被微软或是其他非权威人士,社区更希望看到发行版由发行版所有者发布。” + +因此,微软不方便在 Windows 商店中直接发布 Debian 或是 Arch 系统。这些任务应该落在他们的官方团队中,应该由他们将发行版带给 Windows 10 的用户。 + +### 欲知后事,下回分解 + +下一篇文章,我们会讨论关于将 Windows 10 作为 Linux 设备,并且向您展示,您可能会在 Linux 系统上使用的命令行工具。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/2/how-get-started-using-wsl-windows-10 + +作者:[SWAPNIL 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/windows-subsystem-linux-bridge-between-two-platforms +[2]:https://lh6.googleusercontent.com/kHFKOvrbG1gXdB9lsbTqXC4N4w0Lbsz1Bul5ey9mr_E255GiiBxf8cRlatrte6z23yvo8lHJG8nQ_WeHhUNYqPp7kHuQTTMueqMshCT71JsbMr2Wih9KFHuHgNg1BclWz-iuBt4O +[3]:https://www.microsoft.com/en-us/software-download/windows10 +[4]:https://lh4.googleusercontent.com/oV1mDqGe3zwQgL0N3rDasHH6ZwHtxaHlyrLzjw7xF9M9_AcHPNSxM18KDWK2ZpVcUOfxVVpNH9LwUJT5EtRE7zUrJC_gWV5f345SZRAgXcJzOE-8rM8-RCPTNtns6vVP37V5Eflp +[5]:https://lh5.googleusercontent.com/GsNOQLJlHeZbkaCsrDIhfVvEoycu3D0upoTdt6aNEozAcQA59Z3hDu_SxT6I4K4gwxLPX0YnmUsCKjaQaaG2PoAgUYMcN0Zv0tBFaoUL3sZryddM4mdRj1E2tE-IK_GLK4PDa4zf +[6]:https://lh3.googleusercontent.com/YAR4UgZiFAy2cdkG4U7jQ7_m81lrxR6aHSMOdED7MKEoYxEsX_yLwyMj9N2edt3GJ2JLx6mUsFEZFILCCSBU2sMOqveFVWZTHcCXhFi5P2Xk-9Ikc3NK9seup5CJObIcYJPORdPW +[7]:https://lh6.googleusercontent.com/4LU6eRrzDgBprDuEbSFizRuP1J_zS3rBnoJbU2OAOH3Mx7nfOROfyf81k1s4YQyLBcu0qSXOoaqbYkXL5Wpp9gNCdKH_WsEcqWzjG6uXzYvCYQ42psOz6Iz3NF7ElsPrdiFI0cYv +[8]:https://lh6.googleusercontent.com/7cRgj1O6J8yfO3L4ol5sP-ZCU7_uwOuEoTzsuVW9cU5xiBWz_cpZ1IBidNT0C1wg9zROIncViUzXD0vPoH5cggQtuwkanRfRdDVXOI48AcKFLt-Iq2CBF4mGRwqqWvSOhb0HFpjm +[9]:https://github.com/Microsoft/WSL/issues/2584 diff --git a/published/20180221 Getting started with SQL.md b/published/20180221 Getting started with SQL.md new file mode 100644 index 0000000000..167b2d6f89 --- /dev/null +++ b/published/20180221 Getting started with SQL.md @@ -0,0 +1,177 @@ +SQL 入门 +====== + +> 使用 SQL 构建一个关系数据库比你想的更容易。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/brain_data.png?itok=RH6NA32X) + +使用 SQL 构建数据库比大多数人想象得要简单。实际上,你甚至不需要成为一个有经验的程序员就可以使用 SQL 创建数据库。在本文中,我将解释如何使用 MySQL 5.6 来创建简单的关系型数据库管理系统(RDMS)。在开始之前,我想顺便感谢一下 [SQL Fiddle][1],这是我用来运行脚本的工具。它提供了一个用于测试简单脚本的有用的沙箱。 + +在本教程中,我将构建一个使用如下实体关系图(ERD)中显示的简单架构的数据库。数据库列出了学生和正在学习的课程。为了保持简单,我使用了两个实体(即表),只有一种关系和依赖。这两个实体称为 `dbo_students` 和 `dbo_courses`。 + +![](https://opensource.com/sites/default/files/u128651/erd.png) + +数据库的多样性是一对多的,因为每门课程可以包含很多学生,但每个学生只能学习一门课程。 + +关于术语的快速说明: + + 1. 一张表称为一个实体。 + 2. 一个字段称为一个属性。 + 3. 一条记录称为一个元组。 + 4. 用于构建数据库的脚本称为架构。 + +### 构建架构 + +要构建数据库,使用 `CREATE TABLE <表名>` 命令,然后定义每个字段的名称和数据类型。数据库使用 `VARCHAR(n)` (字符串)和 `INT(n)` (整数),其中 `n` 表示可以存储的值的长度。例如 `INT(2)` 可以是 `01`。 + +这是用于创建两个表的代码: + +``` +CREATE TABLE dbo_students +( + student_id INT(2) AUTO_INCREMENT NOT NULL, + student_name VARCHAR(50), + course_studied INT(2), + PRIMARY KEY (student_id) +); + +CREATE TABLE dbo_courses +( + course_id INT(2) AUTO_INCREMENT NOT NULL, + course_name VARCHAR(30), + PRIMARY KEY (course_id) +); +``` + +`NOT NULL` 意味着字段不能为空,`AUTO_INCREMENT` 意味着当一个新的元组被添加时,ID 号将自动生成,是对先前存储的 ID 号加 1,以强化各实体之间的完整参照性。 `PRIMARY KEY` 是每个表的惟一标识符属性。这意味着每个元组都有自己的不同的标识。 + +### 关系作为一种约束 + +就目前来看,这两张表格是独立存在的,没有任何联系或关系。要连接它们,必须标识一个外键。在 `dbo_students` 中,外键是 `course_studied`,其来源在 `dbo_courses` 中,意味着该字段被引用。SQL 中的特定命令为 `CONSTRAINT`,并且将使用另一个名为 `ALTER TABLE` 的命令添加这种关系,这样即使在架构构建完毕后,也可以编辑表。 + +以下代码将关系添加到数据库构造脚本中: + +``` +ALTER TABLE dbo_students +ADD CONSTRAINT FK_course_studied +FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); +``` + +使用 `CONSTRAINT` 命令实际上并不是必要的,但这是一个好习惯,因为它意味着约束可以被命名并且使维护更容易。现在数据库已经完成了,是时候添加一些数据了。 + +### 将数据添加到数据库 + +`INSERT INTO <表名>` 是用于直接选择要添加哪些属性(即字段)数据的命令。首先声明实体名称,然后声明属性,下边是添加到实体的数据,从而创建一个元组。如果指定了 `NOT NULL`,这表示该属性不能留空。以下代码将展示如何向表中添加记录: + +``` +INSERT INTO dbo_courses(course_id,course_name) +VALUES(001,'Software Engineering'); +INSERT INTO dbo_courses(course_id,course_name) +VALUES(002,'Computer Science'); +INSERT INTO dbo_courses(course_id,course_name) +VALUES(003,'Computing'); + +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(001,'student1',001); +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(002,'student2',002); +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(003,'student3',002); +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(004,'student4',003); +``` + +现在数据库架构已经完成并添加了数据,现在是时候在数据库上运行查询了。 + +### 查询 + +查询遵循使用以下命令的集合结构: + +``` +SELECT +FROM +WHERE +``` + +要显示 `dbo_courses` 实体内的所有记录并显示课程代码和课程名称,请使用 `*` 。 这是一个通配符,它消除了键入所有属性名称的需要。(在生产数据库中不建议使用它。)此处查询的代码是: + +``` +SELECT * +FROM dbo_courses +``` + +此处查询的输出显示表中的所有元组,因此可显示所有可用课程: + +``` +| course_id |          course_name | +|-----------|----------------------| +|         1 | Software Engineering | +|         2 |     Computer Science | +|         3 |            Computing | +``` + +在后面的文章中,我将使用三种类型的连接之一来解释更复杂的查询:内连接、外连接和交叉连接。 + +这是完整的脚本: + +``` +CREATE TABLE dbo_students +( + student_id INT(2) AUTO_INCREMENT NOT NULL, + student_name VARCHAR(50), + course_studied INT(2), + PRIMARY KEY (student_id) +); + +CREATE TABLE dbo_courses +( + course_id INT(2) AUTO_INCREMENT NOT NULL, + course_name VARCHAR(30), + PRIMARY KEY (course_id) +); + +ALTER TABLE dbo_students +ADD CONSTRAINT FK_course_studied +FOREIGN KEY (course_studied) REFERENCES dbo_courses(course_id); + +INSERT INTO dbo_courses(course_id,course_name) +VALUES(001,'Software Engineering'); +INSERT INTO dbo_courses(course_id,course_name) +VALUES(002,'Computer Science'); +INSERT INTO dbo_courses(course_id,course_name) +VALUES(003,'Computing'); + +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(001,'student1',001); +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(002,'student2',002); +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(003,'student3',002); +INSERT INTO dbo_students(student_id,student_name,course_studied) +VALUES(004,'student4',003); + +SELECT * +FROM dbo_courses +``` + +### 学习更多 + +SQL 并不困难;我认为它比编程简单,并且该语言对于不同的数据库系统是通用的。 请注意,实体关系图中 `dbo.<实体>` (LCTT 译注:文章中使用的是 `dbo_<实体>`)不是必需的实体命名约定;我之所以使用,仅仅是因为它是 Microsoft SQL Server 中的标准。 + +如果你想了解更多,在网络上这方面的最佳指南是 [W3Schools.com][2] 中对所有数据库平台的 SQL 综合指南。 + +请随意使用我的数据库。另外,如果你有任何建议或疑问,请在评论中回复。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/getting-started-sql + +作者:[Aaron Cocker][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/aaroncocker +[1]:http://sqlfiddle.com +[2]:https://www.w3schools.com/sql/default.asp diff --git a/published/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md b/published/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md new file mode 100644 index 0000000000..9eb5f84eca --- /dev/null +++ b/published/20180221 Protecting Code Integrity with PGP - Part 2- Generating Your Master Key.md @@ -0,0 +1,150 @@ +用 PGP 保护代码完整性(二):生成你的主密钥 +====== + +![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/binary-1538717_1920.png?itok=kv_sxSnf) + +在本系列文章中,我们将深度探讨如何使用 PGP 以及为工作于自由软件项目的开发者提供实用指南。在前一篇文章中,我们介绍了[基本工具和概念][1]。在本文中,我们将展示如何生成和保护你的 PGP 主密钥。 + +### 清单 + + 1. 生成一个 4096 位的 RSA 主密钥 (必要) + 2. 使用 paperkey 备份你的 RSA 主密钥 (必要) + 3. 添加所有相关的身份 (必要) + +### 考虑事项 + +### 理解“主”(认证)密钥 + +在本节和下一节中,我们将讨论“主密钥”和“子密钥”。理解以下内容很重要: + + 1. 在“主密钥”和“子密钥”之间没有技术上的区别。 + 2. 在创建时,我们赋予每个密钥特定的能力来分配功能限制。 + 3. 一个 PGP 密钥有四项能力 + * [S] 密钥可以用于签名 + * [E] 密钥可以用于加密 + * \[A] 密钥可以用于身份认证 + * [C] 密钥可以用于认证其他密钥 + 4. 一个密钥可能有多种能力 + +带有 [C] (认证)能力的密钥被认为是“主”密钥,因为它是唯一可以用来表明与其他密钥关系的密钥。只有 [C] 密钥可以被用于: + + * 添加或撤销其他密钥(子密钥)的 S/E/A 能力 + * 添加、更改或撤销密钥关联的身份(uid) + * 添加或更改本身或其他子密钥的到期时间 + * 为了网络信任目的为其它密钥签名 + +在自由软件的世界里,[C] 密钥就是你的数字身份。一旦你创建该密钥,你应该格外小心地保护它并且防止它落入坏人的手中。 + +### 在你创建主密钥前 + +在你创建的你的主密钥前,你需要选择你的主要身份和主密码。 + +#### 主要身份 + +身份使用邮件中发件人一栏相同格式的字符串: + +``` +Alice Engineer +``` + +你可以在任何时候创建新的身份,取消旧的,并且更改你的“主要”身份。由于主要身份在所有 GnuPG 操作中都展示,你应该选择正式的和最有可能用于 PGP 保护通信的名字和邮件地址,比如你的工作地址或者用于在项目提交commit时签名的地址。 + +#### 密码 + +密码passphrase专用于私钥存储在磁盘上时使用对称加密算法对其进行加密。如果你的 `.gnupg` 目录的内容被泄露,那么一个好的密码就是小偷能够在线假冒你的最后一道防线,这就是为什么设置一个好的密码很重要的原因。 + +一个强密码最好使用丰富或混合的词典的 3-4 个词,而不引用自流行来源(歌曲、书籍、口号)。由于你将相当频繁地使用该密码,所以它应当易于输入和记忆。 + +#### 算法和密钥强度 + +尽管现在 GnuPG 已经支持椭圆曲线加密一段时间了,但我们仍坚持使用 RSA 密钥,至少较长一段时间会这样。虽然现在就可以开始使用 ED25519 密钥,但你可能会碰到无法正确处理它们的工具和硬件设备。 + +在后续的指南中我们说 2048 位的密钥对 RSA 公钥加密的生命周期已经足够,你可能也会好奇主密钥为什么是 4096 位。 原因很大程度是由于社会因素而非技术上的:主密钥在密钥链上是最显眼的,如果你的主密钥位数比一些和你交互的开发者的少,他们肯定会鄙视你。 + +#### 生成主密钥 + +为了生成你的主密钥,请使用以下命令,并且将 “Alice Engineer” 替换为正确值。 + +``` +$ gpg --quick-generate-key 'Alice Engineer ' rsa4096 cert +``` + +这将弹出一个要求输入密码的对话框。然后,你可能需要移动鼠标或随便按一些键才能生成足够的熵,直到该命令完成。 + +查看命令输出,它就像这样: + +``` +pub rsa4096 2017-12-06 [C] [expires: 2019-12-06] + 111122223333444455556666AAAABBBBCCCCDDDD +uid Alice Engineer +``` + +注意第二行的长字符串 —— 它是你新生成的密钥的完整指纹。密钥 ID(Key ID)可以用以下三种不同形式表达: + + * 指纹Fingerprint,一个完整的 40 个字符的密钥标识符 + * 长密钥 IDLong,指纹的最后 16 个字符(AAAABBBBCCCCDDDD) + * 短密钥 IDShort,指纹的最后 8 个字符(CCCCDDDD) + +你应该避免使用 8 个字符的短密钥 ID,因为它们不足够唯一。 + +这里,我建议你打开一个文本编辑器,复制你新密钥的指纹并粘贴。你需要在接下来几步中用到它,所以将它放在旁边会很方便。 + +#### 备份你的主密钥 + +出于灾后恢复的目的 —— 同时特别的如果你试图使用 Web of Trust 并且收集来自其他项目开发者的密钥签名 —— 你应该创建你的私钥的硬拷贝备份。万一所有其它的备份机制都失败了,这应当是最后的补救措施。 + +创建一个你的私钥的可打印的硬拷贝的最好方法是使用为此而写的软件 `paperkey`。`paperkey` 在所有 Linux 发行版上可用,在 Mac 上也可以通过 brew 安装 `paperkey`。 + +运行以下命令,用你密钥的完整指纹替换 `[fpr]`: + +``` +$ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt +``` + +输出将采用易于 OCR 或手动输入的格式,以防如果你需要恢复它的话。打印出该文件,然后拿支笔,并在纸的边缘写下密钥的密码。这是必要的一步,因为密钥输出仍然使用密码加密,并且如果你更改了密钥的密码,你不会记得第一次创建的密钥是什么 —— 我保证。 + +将打印结果和手写密码放入信封中,并存放在一个安全且保护好的地方,最好远离你家,例如银行保险库。 + +**打印机注意事项** 打印机连接到计算机的并行端口的时代已经过去了。现在他们拥有完整的操作系统,硬盘驱动器和云集成。由于我们发送给打印机的关键内容将使用密码进行加密,因此这是一项相当安全的操作,但请使用您最好的偏执判断。 + +#### 添加相关身份 + +如果你有多个相关的邮件地址(个人、工作、开源项目等),你应该将其添加到主密钥中。你不需要为任何你不希望用于 PGP 的地址(例如,可能不是你的校友地址)这样做。 + +该命令是(用你完整的密钥指纹替换 `[fpr]`): + +``` +$ gpg --quick-add-uid [fpr] 'Alice Engineer ' +``` + +你可以查看你已经使用的 UID: + +``` +$ gpg --list-key [fpr] | grep ^uid +``` + +#### 选择主 UID + +GnuPG 将会把你最近添加的 UID 作为你的主 UID,如果这与你想的不同,你应该改回来: + +``` +$ gpg --quick-set-primary-uid [fpr] 'Alice Engineer ' +``` + +下次,我们将介绍如何生成 PGP 子密钥,它是你实际用于日常工作的密钥。 + +通过 Linux 基金会和 edX 的免费[“Introduction to Linux” ][2]课程了解关于 Linux 的更多信息。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/PGP/2018/2/protecting-code-integrity-pgp-part-2-generating-and-protecting-your-master-pgp-key + +作者:[KONSTANTIN RYABITSEV][a] +译者:[kimii](https://github.com/kimii) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.linux.com/users/mricon +[1]:https://linux.cn/article-9524-1.html +[2]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux diff --git a/published/20180221 cTop - A CLI Tool For Container Monitoring.md b/published/20180221 cTop - A CLI Tool For Container Monitoring.md new file mode 100644 index 0000000000..a32ecf7701 --- /dev/null +++ b/published/20180221 cTop - A CLI Tool For Container Monitoring.md @@ -0,0 +1,132 @@ +cTop:用于容器监控的命令行工具 +====== + +最近 Linux 容器很火,我们中的大多数人甚至已经在使用它,同时一些人也开始学习它。 + +我们已经介绍了有名的 GUI(用户图形界面) 工具如 Portainer 和 Rancher 。这将会有助于我们通过 GUI 管理容器。 + +这篇指南将会通过 cTop 命令帮助我们理解和监控 Linux 容器。它是一个类似 `top` 命令的命令行工具。 + +### 什么是 cTop + +[ctop][1] 为多个容器提供了一个简洁凝练的实时指标概览。它是一个类 `top` 的针对容器指标的界面。 + +它展示了容器指标比如 CPU 利用率、内存利用率、磁盘 I/O 读写、进程 ID(PID)和网络发送(TX - 从此服务器发送)以及接受(RX - 此服务器接受)。 + +`ctop` 带有对 Docker 和 runc 的内建支持;对其他容器和集群系统的连接计划在未来版本中推出。 + +它不需要任何参数并且默认使用 Docker 主机变量。 + +**建议阅读:** + +- [Portainer – 一个简单的 Docker 图形管理界面][2] +- [Rancher – 一个完整的生产环境容器管理平台][3] + +### 如何安装 cTop + +开发者提供了一个简单的 shell 脚本来帮助我们直接使用 `ctop`。我们要做的,只是在 `/bin` 目录下下载 `ctop` shell 文件来保证全局访问。最后给予 `ctop` 脚本文件执行权限。 + +在 `/usr/local/bin` 目录下下载 ctop shell 脚本。 + +``` +$ sudo wget https://github.com/bcicen/ctop/releases/download/v0.7/ctop-0.7-linux-amd64 -O /usr/local/bin/ctop +``` + +对 `ctop` shell 脚本设置执行权限。 + +``` +$ sudo chmod +x /usr/local/bin/ctop +``` + +另外你可以通过 docker 来安装和运行 `ctop`。在此之前先确保你已经安装过 docker。为了安装 docker,参考以下链接。 + +**建议阅读:** + +- [如何在 Linux 上安装 Docker][4] +- [如何在 Linux 上玩转 Docker 镜像][5] +- [如何在 Linux 上玩转 Docker 容器][6] +- [如何在 Docker 容器中安装,运行应用][7] + +``` +$ docker run --rm -ti \ + --name=ctop \ + -v /var/run/docker.sock:/var/run/docker.sock \ + quay.io/vektorlab/ctop:latest +``` + +### 如何使用 cTop + +直接启动 `ctop` 程序而不用任何参数。默认它绑定的 `a` 键用来展示所有容器(运行的和没运行的)。 + +`ctop` 头部显示你的系统时间和容器的总数。 + +``` +$ ctop +``` + +你可能得到以下类似输出。 + +![][9] + +### 如何管理容器 + +你可以使用 `ctop` 来管理容器。选择一个你想要管理的容器然后按下回车键,选择所需选项如 `start`、`stop`、`remove` 等。 + +![][10] + +### 如何给容器排序 + +默认 `ctop` 使用 `state` 字段来给容器排序。按下 `s` 键来按不同的方面给容器排序。 + +![][11] + +### 如何查看容器指标 + +如何你想要查看关于容器的更多细节和指标,只用选择你想要查看的相应容器然后按 `o` 键。 + +![][12] + +### 如何查看容器日志 + +选择你想要查看日志的相应容器然后按 `l` 键。 + +![][13] + +### 仅显示活动容器 + +使用 `-a` 选项运行 `ctop` 命令来仅显示活动容器 + +![][14] + +### 打开帮助对话框 + +运行 `ctop`,只需按 `h` 键来打开帮助部分。 + +![][15] + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux/ + +作者:[2DAYGEEK][a] +译者:[kimii](https://github.com/kimii) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://www.2daygeek.com/author/2daygeek/ +[1]:https://github.com/bcicen/ctop +[2]:https://www.2daygeek.com/portainer-a-simple-docker-management-gui/ +[3]:https://www.2daygeek.com/rancher-a-complete-container-management-platform-for-production-environment/ +[4]:https://www.2daygeek.com/install-docker-on-centos-rhel-fedora-ubuntu-debian-oracle-archi-scentific-linux-mint-opensuse/ +[5]:https://www.2daygeek.com/list-search-pull-download-remove-docker-images-on-linux/ +[6]:https://www.2daygeek.com/create-run-list-start-stop-attach-delete-interactive-daemonized-docker-containers-on-linux/ +[7]:https://www.2daygeek.com/install-run-applications-inside-docker-containers/ +[8]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 +[9]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-1.png +[10]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-2.png +[11]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-3.png +[12]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-4a.png +[13]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-7.png +[14]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-5.png +[15]:https://www.2daygeek.com/wp-content/uploads/2018/02/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux-6.png diff --git a/published/20180222 How to configure an Apache web server.md b/published/20180222 How to configure an Apache web server.md new file mode 100644 index 0000000000..dd8d68cf2b --- /dev/null +++ b/published/20180222 How to configure an Apache web server.md @@ -0,0 +1,187 @@ +如何配置 Apache Web 服务器 +========== + +> 学习如何在 Apache 上托管你自己的网站,这是一个可靠、流行且易于配置的 Web 服务器。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/openweb-osdc-lead.png?itok=yjU4KliG) + +我托管自己的网站已经有很多年了。自从 20 多年前从 OS/2 切换到 Linux 以来,我一直将 [Apache][1] 作为我的服务器软件。Apache 是可靠、流行的,且基本的安装配置也很容易。对于更复杂的设置(比如多个网站)也并不是那么困难。 + +Apache Web 服务器的安装和配置必须以 root 身份执行。 防火墙的配置也需要以 root 身份执行。 使用浏览器查看安装配置的结果应该以非 root 用户的身份完成。 (我在我的虚拟主机上使用 `student` 这个用户。) + +### 安装 + +注意:我使用的实验环境是安装有 Fedora 27 的虚拟机,Apache 版本为 2.4.29。 如果您使用的是不同的发行版或不同版本的 Fedora,您的命令以及配置文件的位置和内容可能会有所不同。 但是,您需要修改的配置行是相同的。 + +Apache Web 服务器非常容易安装。 在我的 CentOS 6.x 服务器上,它只需要一个简单的 `yum` 命令。 它会安装所有必要的依赖(如果需要的话)。 我在我的 Fedora 虚拟机上使用了下面的 `dnf` 命令。 除了命令本身的名称之外, `dnf` 和 `yum` 的语法是相同的。 + +``` +dnf -y install httpd +``` + +这个虚拟机是个非常基础的桌面环境,我正在使用它作为编写书籍的测试平台。 即使在这个系统上,也只安装了六个依赖项,用了一分钟。 + +Apache 的所有配置文件都位于 `/etc/httpd/conf` 和 `/etc/httpd/conf.d` 。网站的数据默认位于 `/var/www`,但如果你愿意,你可以改变它。 + +### 配置 + +Apache 主要的配置文件是 `/etc/httpd/conf/httpd.conf` 。 它包含许多在基本安装中不需要更改的配置。 实际上,只需对此文件进行一些更改即可启动并运行一个简单的网站。 该文件非常大,因此,我不会将这篇文章与大量不必要的东西混淆起来,而只会显示那些需要更改的指令。 + +首先,花点时间熟悉一下 `httpd.conf` 文件。我喜欢 Red Hat 的一个原因是它的配置文件注释非常的详细。 `httpd.conf` 文件也不例外,因为它有很好的注释。可以使用这些注释来了解文件的配置。 + +第一个要修改的是 `Listen` 配置项,它定义了 Apache 要监听页面请求的 IP 地址和端口。 现在,你只需要使这个网站可以从本地访问,所以使用 `localhost` 地址。 完成后,该行应该看起来像这样:( LCTT 译注:`localhost` 的 IP 地址是 `127.0.0.1`,`80` 是端口) + +``` +Listen 127.0.0.1:80 +``` + +通过将此配置项设置为 `localhost`的 IP 地址,Apache 将只侦听来自本地主机的连接。 如果您希望 Web 服务器侦听来自远程主机的连接,则可以使用主机的外部 IP 地址。 + +`DocumentRoot` 配置项指定组成网站页面的 HTML 文件的位置。 该配置项不需要更改,因为它已经指向标准位置。 该行应该看起来像这样: + +``` +DocumentRoot "/var/www/html" +``` + +Apache 安装包会创建 `/var/www` 目录。 如果您想更改存储网站文件的位置,则使用此配置项来完成此操作。 例如,您可能想要为 `www` 目录使用不同的名称,以更明确地识别网站。 这可以是这样的: + +``` +DocumentRoot "/var/mywebsite/html" +``` + +这些是创建一个简单网站需要唯一修改的 Apache 配置项。 对于这个小练习,只对 `httpd.conf` 文件(`Listen` 配置项)进行了一些修改。 其它的配置项对于一个简单的 Web 服务器暂时无需配置。 + +另一个需要改变的地方是:在我们的防火墙中打开端口 80。 我使用 [iptables][2] 作为我的防火墙,因此我更改 `/etc/sysconfig/iptables` 文件以添加允许使用 HTTP 协议。 整个文件看起来像这样: + +``` +# sample configuration for iptables service +# you can edit this manually or use system-config-firewall +# please do not ask us to add additional ports/services to this default configuration +*filter +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT +-A INPUT -j REJECT --reject-with icmp-host-prohibited +-A FORWARD -j REJECT --reject-with icmp-host-prohibited +COMMIT +``` + +我在文件的倒数第三行上添加了一个新行,它允许在端口 `80` 上输入流量。现在我重新加载 iptables 配置文件。 + +``` +[root@testvm1 ~]# cd /etc/sysconfig/ ; iptables-restore iptables +``` + +### 创建 index.html 文件 + +`index.html` 文件是你使用域名访问网站而不是访问特定网页时的默认文件。在 `/var/www/html`中,创建一个名字为 `index.html` 的文件,在其中添加字符串 `Hello World` 。你不需要添加任何的 HTML 标志去完成这项工作。web 服务器的唯一任务是提供文本数据流,服务器不知道数据是什么,也不知道如何呈现它。它只是将数据流传输给请求主机。 + +保存文件后,将所有权设置为 `apache.apache` 。 + +``` +[root@testvm1 html]# chown apache.apache index.html +``` + +### 启动 Apache + +Apache 很容易启动。 当前版本的 Fedora 使用 systemd 。 运行以下命令启动它,然后检查服务器的状态:(LCTT 译注:`systemctl` 是一个 systemd 工具) + +``` +[root@testvm1 ~]# systemctl start httpd +[root@testvm1 ~]# systemctl status httpd +● httpd.service - The Apache HTTP Server + Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) + Active: active (running) since Thu 2018-02-08 13:18:54 EST; 5s ago + Docs: man:httpd.service(8) + Main PID: 27107 (httpd) + Status: "Processing requests..." + Tasks: 213 (limit: 4915) + CGroup: /system.slice/httpd.service + ├─27107 /usr/sbin/httpd -DFOREGROUND + ├─27108 /usr/sbin/httpd -DFOREGROUND + ├─27109 /usr/sbin/httpd -DFOREGROUND + ├─27110 /usr/sbin/httpd -DFOREGROUND + └─27111 /usr/sbin/httpd -DFOREGROUND + +Feb 08 13:18:54 testvm1 systemd[1]: Starting The Apache HTTP Server... +Feb 08 13:18:54 testvm1 systemd[1]: Started The Apache HTTP Server. +``` + +您的服务器上的命令可能不同。在使用 SystemV 启动脚本的 Linux 系统上,命令如下: + +``` +[root@testvm1 ~]# service httpd start +Starting httpd: [Fri Feb 09 08:18:07 2018]          [  OK  ] +[root@testvm1 ~]# service httpd status +httpd (pid  14649) is running... +``` + +如果您的主机上有像 Firefox 或 Chrome 这样的浏览器,您可以在浏览器的 URL 行上使用 URL `localhost` 来显示您的 web 页面,尽管看起来很简单。您还可以使用像 [Lynx][3] 这样的文本模式 web 浏览器来查看 web 页面。首先,安装 Lynx (如果它还没有被安装)。 + +``` +[root@testvm1 ~]# dnf -y install lynx +``` + +然后使用下面的命令来显示网页。 + +``` +[root@testvm1 ~]# lynx localhost +``` + +结果在我的终端中是这样的。我已经删除了页面上的很多空白。 + +``` + Hello World + + + + +Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back. + Arrow keys: Up and Down to move. Right to follow a link; Left to go back. + H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list``` +``` + +接下来,编辑您的 `index.html` 文件并添加一些 HTML 标记,使其看起来像这样: + +``` +

Hello World

+``` + +现在刷新浏览器。对于 Lynx,使用组合键 `Ctrl + R` 。 结果看起来有点不同。如果你的终端支持彩色的话文本是彩色显示的,Lynx 会显示标题,现在它处于居中状态。 在 GUI 浏览器中,文本将以大字体显示。 + +``` + Hello World + + + + +Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back. + Arrow keys: Up and Down to move. Right to follow a link; Left to go back. + H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list +``` + +### 后记 + +从这个小练习中可以看到,建立一个 Apache Web 服务器很容易。 具体情况取决于您的发行版和该发行版提供的 Apache 版本。 在我的环境中,这是一个非常简单的练习。 + +但不仅仅如此,因为 Apache 非常灵活强大。下个月,我将讨论使用单个 Apache 托管多个网站。 + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/how-configure-apache-web-server + +作者:[David Both][a] +译者:[amwps290](https://github.com/amwps290) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/dboth +[1]:https://httpd.apache.org/ +[2]:https://en.wikipedia.org/wiki/Iptables +[3]:http://lynx.browser.org/ diff --git a/published/20180226 How to Use WSL Like a Linux Pro.md b/published/20180226 How to Use WSL Like a Linux Pro.md new file mode 100644 index 0000000000..18e0edd1a8 --- /dev/null +++ b/published/20180226 How to Use WSL Like a Linux Pro.md @@ -0,0 +1,105 @@ +如何像 Linux 专家那样使用 WSL +============================================================ + +> 在本 WSL 教程中了解如何执行像挂载 USB 驱动器和操作文件等任务。 + +![WSL](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/wsl-pro.png?itok=e65wEEAw "WSL") + +在[之前的教程][4]中,我们学习了如何在 Windows 10 上设置 WSL。你可以在 Windows 10 中使用 WSL 执行许多 Linux 命令。无论是基于 Linux 的系统还是 macOS,它们的许多系统管理任务都是在终端内部完成的。然而,Windows 10 缺乏这样的功能。你想运行一个 cron 任务么?不行。你想 SSH 进入你的服务器,然后 `rsync` 文件么?没门。如何用强大的命令行工具管理本地文件,而不是使用缓慢和不可靠的 GUI 工具呢? + +在本教程中,你将看到如何使用 WSL 执行除了管理之外的任务 —— 例如挂载 USB 驱动器和操作文件。你需要运行一个完全更新的 Windows 10 并选择一个 Linux 发行版。我在[上一篇文章][5]中介绍了这些步骤,所以如果你跟上进度,那就从那里开始。让我们开始吧。 + +### 保持你的 Linux 系统更新 + +事实上,当你通过 WSL 运行 Ubuntu 或 openSUSE 时,其底层并没有运行 Linux 内核。然而,你必须保持你的发行版完整更新,以保护你的系统免受任何新的已知漏洞的影响。由于在 Windows 应用商店中只有两个免费的社区发行版,所以教程将只覆盖以下两个:openSUSE 和 Ubuntu。 + +更新你的 Ubuntu 系统: + +``` +# sudo apt-get update +# sudo apt-get dist-upgrade +``` + +运行 openSUSE 的更新: + +``` +# zypper up +``` + +您还可以使用 `dup` 命令将 openSUSE 升级到最新版本。但在运行系统升级之前,请使用上一个命令运行更新。 + +``` +# zypper dup +``` + +**注意:** openSUSE 默认为 root 用户。如果你想执行任何非管理员任务,请切换到非特权用户。您可以这篇[文章][6]中了解如何在 openSUSE上 创建用户。 + +### 管理本地文件 + +如果你想使用优秀的 Linux 命令行工具来管理本地文件,你可以使用 WSL 轻松完成此操作。不幸的是,WSL 还不支持像 `lsblk` 或 `mount` 这样的东西来挂载本地驱动器。但是,你可以 `cd` 到 C 盘并管理文件: + +``` +/mnt/c/Users/swapnil/Music +``` + +我现在在 C 盘的 Music 目录下。 + +要安装其他驱动器、分区和外部 USB 驱动器,你需要创建一个挂载点,然后挂载该驱动器。 + +打开文件资源管理器并检查该驱动器的挂载点。假设它在 Windows 中被挂载为 S:\。 + +在 Ubuntu/openSUSE 终端中,为驱动器创建一个挂载点。 + +``` +sudo mkdir /mnt/s +``` + +现在挂载驱动器: + +``` +mount -f drvfs S: /mnt/s +``` + +挂载完毕后,你现在可以从发行版访问该驱动器。请记住,使用 WSL 方式运行的发行版将会看到 Windows 能看到的内容。因此,你无法挂载在 Windows 上无法原生挂载的 ext4 驱动器。 + +现在你可以在这里使用所有这些神奇的 Linux 命令。想要将文件从一个文件夹复制或移动到另一个文件夹?只需运行 `cp` 或 `mv` 命令。 + +``` +cp /source-folder/source-file.txt /destination-folder/ +cp /music/classical/Beethoven/symphony-2.mp3 /plex-media/music/classical/ +``` + +如果你想移动文件夹或大文件,我会推荐 `rsync` 而不是 `cp` 命令: + +``` +rsync -avzP /music/classical/Beethoven/symphonies/ /plex-media/music/classical/ +``` + +耶! + +想要在 Windows 驱动器中创建新目录,只需使用 `mkdir` 命令。 + +想要在某个时间设置一个 cron 作业来自动执行任务吗?继续使用 `crontab -e` 创建一个 cron 作业。十分简单。 + +你还可以在 Linux 中挂载网络/远程文件夹,以便你可以使用更好的工具管理它们。我的所有驱动器都插在树莓派或者服务器上,因此我只需 `ssh` 进入该机器并管理硬盘。在本地计算机和远程系统之间传输文件可以再次使用 `rsync` 命令完成。 + +WSL 现在已经不再是测试版了,它将继续获得更多新功能。我很兴奋的两个特性是 `lsblk` 命令和 `dd` 命令,它们允许我在 Windows 中本机管理我的驱动器并创建可引导的 Linux 驱动器。如果你是 Linux 命令行的新手,[前一篇教程][7]将帮助你开始使用一些最基本的命令。 + +-------------------------------------------------------------------------------- + +via: https://www.linux.com/blog/learn/2018/2/how-use-wsl-linux-pro + +作者:[SWAPNIL BHARTIYA][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/arnieswap +[1]:https://www.linux.com/licenses/category/used-permission +[2]:https://blogs.msdn.microsoft.com/commandline/learn-about-windows-console-and-windows-subsystem-for-linux-wsl/ +[3]:https://www.linux.com/files/images/wsl-propng +[4]:https://linux.cn/article-9545-1.html +[5]:https://linux.cn/article-9545-1.html +[6]:https://linux.cn/article-9545-1.html +[7]:https://www.linux.com/learn/how-use-linux-command-line-basics-cli diff --git a/published/201803/20090203 How the Kernel Manages Your Memory.md b/published/201803/20090203 How the Kernel Manages Your Memory.md new file mode 100644 index 0000000000..2e72498165 --- /dev/null +++ b/published/201803/20090203 How the Kernel Manages Your Memory.md @@ -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 常驻内存大小Resident Set Size )、虚拟地址空间使用的 [总数量][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;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 diff --git a/published/201803/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md b/published/201803/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md new file mode 100644 index 0000000000..e2d88ce4ec --- /dev/null +++ b/published/201803/20090518 How to use yum-cron to automatically update RHEL-CentOS Linux.md @@ -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 diff --git a/published/201803/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md b/published/201803/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md new file mode 100644 index 0000000000..fe53159cec --- /dev/null +++ b/published/201803/20091215 How To Create sar Graphs With kSar To Identifying Linux Bottlenecks.md @@ -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 +--> Running transaction check +---> Package sysstat.x86_64 0:7.0.2-3.el5 set to be updated +--> 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 diff --git a/published/201803/20120424 How To Set Readonly File Permissions On Linux - Unix Web Server DocumentRoot.md b/published/201803/20120424 How To Set Readonly File Permissions On Linux - Unix Web Server DocumentRoot.md new file mode 100644 index 0000000000..2aad1679ba --- /dev/null +++ b/published/201803/20120424 How To Set Readonly File Permissions On Linux - Unix Web Server DocumentRoot.md @@ -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客户端的 Samba(CIFS)只读共享 + + +要以只读共享 `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 +``` + +### Linux:chattr 命令 + + +你可以在 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 diff --git a/published/201803/20140225 How To Safely Generate A Random Number - Quarrelsome.md b/published/201803/20140225 How To Safely Generate A Random Number - Quarrelsome.md new file mode 100644 index 0000000000..000b50f159 --- /dev/null +++ b/published/201803/20140225 How To Safely Generate A Random Number - Quarrelsome.md @@ -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` 还是 urandom,FreeBSD 的内核加密 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 diff --git a/translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md b/published/201803/20150615 Let-s Build A Simple Interpreter. Part 1..md similarity index 55% rename from translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md rename to published/201803/20150615 Let-s Build A Simple Interpreter. Part 1..md index 3a62934f42..ed2e0f0a0e 100644 --- a/translated/tech/20150615 Let-s Build A Simple Interpreter. Part 1..md +++ b/published/201803/20150615 Let-s Build A Simple Interpreter. Part 1..md @@ -1,26 +1,27 @@ -让我们做个简单的解释器(1) +让我们做个简单的解释器(一) ====== +> “如果你不知道编译器是怎么工作的,那你就不知道电脑是怎么工作的。如果你不能百分百确定,那就是不知道它们是如何工作的。” --Steve Yegge -> **" If you don't know how compilers work, then you don't know how computers work. If you're not 100% sure whether you know how compilers work, then you don't know how they work."** -- Steve Yegge -> **“如果你不知道编译器是怎么工作的,那你就不知道电脑是怎么工作的。如果你不能百分百确定,那就是不知道他们是如何工作的。”** --Steve Yegge +就是这样。想一想。你是萌新还是一个资深的软件开发者实际上都无关紧要:如果你不知道编译器compiler解释器interpreter是怎么工作的,那么你就不知道电脑是怎么工作的。就这么简单。 -就是这样。想一想。你是萌新还是一个资深的软件开发者实际上都无关紧要:如果你不知道编译器和解释器是怎么工作的,那么你就不知道电脑是怎么工作的。就这么简单。 +所以,你知道编译器和解释器是怎么工作的吗?我是说,你百分百确定自己知道他们怎么工作吗?如果不知道。 -所以,你知道编译器和解释器是怎么工作的吗?我是说,你百分百确定自己知道他们怎么工作吗?如果不知道。![][1] +![][1] -或者如果你不知道但你非常想要了解它。 ![][2] +或者如果你不知道但你非常想要了解它。 -不用担心。如果你能坚持跟着这个系列做下去,和我一起构建一个解释器和编译器,最后你将会知道他们是怎么工作的。并且你会变成一个自信满满的快乐的人。至少我希望如此。![][3]。 +![][2] + +不用担心。如果你能坚持跟着这个系列做下去,和我一起构建一个解释器和编译器,最后你将会知道他们是怎么工作的。并且你会变成一个自信满满的快乐的人。至少我希望如此。 + +![][3] 为什么要学习编译器和解释器?有三点理由。 - 1. 要写出一个解释器或编译器,你需要有很多的专业知识,并能融会贯通。写一个解释器或编译器能帮你加强这些能力,成为一个更厉害的软件开发者。而且,你要学的技能对写软件非常有用,而不是仅仅局限于解释器或编译器。 - 2. 你确实想要了解电脑是怎么工作的。一般解释器和编译器看上去很魔幻。你或许不习惯这种魔力。你会想去揭开构建解释器和编译器那层神秘的面纱,了解他们的原理,把事情做好。 - 3. 你想要创建自己的编程语言或者特定领域的语言。如果你创建了一个,你还要为它创建一个解释器或者编译器。最近,兴起了对新的编程语言的兴趣。你能看到几乎每天都有一门新的编程语言横空出世:Elixir,Go,Rust,还有很多。 - - - +1. 要写出一个解释器或编译器,你需要有很多的专业知识,并能融会贯通。写一个解释器或编译器能帮你加强这些能力,成为一个更厉害的软件开发者。而且,你要学的技能对编写软件非常有用,而不是仅仅局限于解释器或编译器。 +2. 你确实想要了解电脑是怎么工作的。通常解释器和编译器看上去很魔幻。你或许不习惯这种魔力。你会想去揭开构建解释器和编译器那层神秘的面纱,了解它们的原理,把事情做好。 +3. 你想要创建自己的编程语言或者特定领域的语言。如果你创建了一个,你还要为它创建一个解释器或者编译器。最近,兴起了对新的编程语言的兴趣。你能看到几乎每天都有一门新的编程语言横空出世:Elixir,Go,Rust,还有很多。 好,但什么是解释器和编译器? @@ -32,11 +33,12 @@ 我希望你现在确信你很想学习构建一个编译器和解释器。你期望在这个教程里学习解释器的哪些知识呢? -你看这样如何。你和我一起做一个简单的解释器当作 [Pascal][5] 语言的子集。在这个系列结束的时候你能做出一个可以运行的 Pascal 解释器和一个像 Python 的 [pdb][6] 那样的源代码级别的调试器。 +你看这样如何。你和我一起为 [Pascal][5] 语言的一个大子集做一个简单的解释器。在这个系列结束的时候你能做出一个可以运行的 Pascal 解释器和一个像 Python 的 [pdb][6] 那样的源代码级别的调试器。 -你或许会问,为什么是 Pascal?有一点,它不是我为了这个系列而提出的一个虚构的语言:它是真实存在的一门编程语言,有很多重要的语言结构。有些陈旧但有用的计算机书籍使用 Pascal 编程语言作为示例(我知道对于选择一门语言来构建解释器,这个理由并不令人信服,但我认为学一门非主流的语言也不错:)。 +你或许会问,为什么是 Pascal?一方面,它不是我为了这个系列而提出的一个虚构的语言:它是真实存在的一门编程语言,有很多重要的语言结构。有些陈旧但有用的计算机书籍使用 Pascal 编程语言作为示例(我知道对于选择一门语言来构建解释器,这个理由并不令人信服,但我认为学一门非主流的语言也不错 :))。 + +这有个 Pascal 中的阶乘函数示例,你将能用自己的解释器解释代码,还能够用可交互的源码级调试器进行调试,你可以这样创造: -这有个 Pascal 中的阶乘函数示例,你能用自己的解释器解释代码,还能够用可交互的源码级调试器进行调试,你可以这样创造: ``` program factorial; @@ -57,15 +59,14 @@ begin end. ``` -这个 Pascal 解释器的实现语言会用 Python,但你也可以用其他任何语言,因为这里展示的思想不依赖任何特殊的实现语言。好,让我们开始干活。准备好了,出发! - -你会从编写一个简单的算术表达式解析器,也就是常说的计算器,开始学习解释器和编译器。今天的目标非常简单:让你的计算器能处理两个个位数相加,比如 **3+5**。这是你的计算器的源代码,不好意思,是解释器: +这个 Pascal 解释器的实现语言会使用 Python,但你也可以用其他任何语言,因为这里展示的思想不依赖任何特殊的实现语言。好,让我们开始干活。准备好了,出发! +你会从编写一个简单的算术表达式解析器,也就是常说的计算器,开始学习解释器和编译器。今天的目标非常简单:让你的计算器能处理两个个位数相加,比如 `3+5`。下面是你的计算器的源代码——不好意思,是解释器: ``` # 标记类型 # -# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成 INTEGER, PLUS, EOF = 'INTEGER', 'PLUS', 'EOF' @@ -73,7 +74,7 @@ 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 + # token 值: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, '+', 或 None self.value = value def __str__(self): @@ -187,7 +188,8 @@ if __name__ == '__main__': ``` -把上面的代码保存到 calc1.py 文件,或者直接从 [GitHub][7] 上下载。在你深入研究代码前,在命令行里面运行它看看效果。试一试!这是我笔记本上的示例会话(如果你想在 Python3 下运行,你要把 raw_input 换成 input): +把上面的代码保存到 `calc1.py` 文件,或者直接从 [GitHub][7] 上下载。在你深入研究代码前,在命令行里面运行它看看效果。试一试!这是我笔记本上的示例会话(如果你想在 Python3 下运行,你要把 `raw_input` 换成 `input`): + ``` $ python calc1.py calc> 3+4 @@ -205,31 +207,32 @@ calc> * 此时支持的唯一一个运算符是加法 * 输入中不允许有任何的空格符号 - - 要让计算器变得简单,这些限制非常必要。不用担心,你很快就会让它变得很复杂。 好,现在让我们深入它,看看解释器是怎么工作,它是怎么评估出算术表达式的。 -当你在命令行中输入一个表达式 3+5,解释器就获得了字符串 “3+5”。为了让解释器能够真正理解要用这个字符串做什么,它首先要把输入 “3+5” 分到叫做 **token(标记)** 的容器里。**标记** 是一个拥有类型和值的对象。比如说,对字符 “3” 而言,标记的类型是 INTEGER 整数,对应的值是 3。 +当你在命令行中输入一个表达式 `3+5`,解释器就获得了字符串 “3+5”。为了让解释器能够真正理解要用这个字符串做什么,它首先要把输入 “3+5” 分到叫做 `token`(标记)的容器里。标记token 是一个拥有类型和值的对象。比如说,对字符 “3” 而言,标记的类型是 INTEGER 整数,对应的值是 3。 -把输入字符串分成标记的过程叫 **词法分析**。因此解释器的需要做的第一步是读取输入字符,并将其转换成标记流。解释器中的这一部分叫做 **词法分析器**,或者简短点叫 **lexer**。你也可以给它起别的名字,诸如 **扫描器** 或者 **标记器**。他们指的都是同一个东西:解释器或编译器中将输入字符转换成标记流的那部分。 +把输入字符串分成标记的过程叫词法分析lexical analysis。因此解释器的需要做的第一步是读取输入字符,并将其转换成标记流。解释器中的这一部分叫做词法分析器lexical analyzer,或者简短点叫 **lexer**。你也可以给它起别的名字,诸如扫描器scanner或者标记器tokenizer。它们指的都是同一个东西:解释器或编译器中将输入字符转换成标记流的那部分。 -Interpreter 类中的 get_next_token 方法就是词法分析器。每次调用它的时候,你都能从传入解释器的输入字符中获得创建的下一个标记。仔细看看这个方法,看看它是如何完成把字符转换成标记的任务的。输入被存在可变文本中,它保存了输入的字符串和关于该字符串的索引(把字符串想象成字符数组)。pos 开始时设为 0,指向 ‘3’.这个方法一开始检查字符是不是数字,如果是,就将 pos 加 1,并返回一个 INTEGER 类型的标记实例,并把字符 ‘3’ 的值设为整数,也就是整数 3: +`Interpreter` 类中的 `get_next_token` 方法就是词法分析器。每次调用它的时候,你都能从传入解释器的输入字符中获得创建的下一个标记。仔细看看这个方法,看看它是如何完成把字符转换成标记的任务的。输入被存在可变文本中,它保存了输入的字符串和关于该字符串的索引(把字符串想象成字符数组)。`pos` 开始时设为 0,指向字符 ‘3’。这个方法一开始检查字符是不是数字,如果是,就将 `pos` 加 1,并返回一个 INTEGER 类型的标记实例,并把字符 ‘3’ 的值设为整数,也就是整数 3: ![][8] -现在 pos 指向文本中的 ‘+’ 号。下次调用这个方法的时候,它会测试 pos 位置的字符是不是个数字,然后检测下一个字符是不是个加号,就是这样。结果这个方法把 pos 加一,返回一个新创建的标记,类型是 PLUS,值为 ‘+’。 +现在 `pos` 指向文本中的 ‘+’ 号。下次调用这个方法的时候,它会测试 `pos` 位置的字符是不是个数字,然后检测下一个字符是不是个加号,就是这样。结果这个方法把 `pos` 加 1,返回一个新创建的标记,类型是 PLUS,值为 ‘+’。 ![][9] -pos 现在指向字符 ‘5’。当你再调用 get_next_token 方法时,该方法会检查这是不是个数字,就是这样,然后它把 pos 加一,返回一个新的 INTEGER 标记,该标记的值被设为 5: +`pos` 现在指向字符 ‘5’。当你再调用 `get_next_token` 方法时,该方法会检查这是不是个数字,就是这样,然后它把 `pos` 加 1,返回一个新的 INTEGER 标记,该标记的值被设为整数 5: + ![][10] -因为 pos 索引现在到了字符串 “3+5” 的末尾,你每次调用 get_next_token 方法时,它将会返回 EOF 标记: +因为 `pos` 索引现在到了字符串 “3+5” 的末尾,你每次调用 `get_next_token` 方法时,它将会返回 EOF 标记: + ![][11] 自己试一试,看看计算器里的词法分析器的运行: + ``` >>> from calc1 import Interpreter >>> @@ -248,17 +251,16 @@ Token(EOF, None) >>> ``` -既然你的解释器能够从输入字符中获取标记流,解释器需要做点什么:它需要在词法分析器 get_next_token 中获取的标记流中找出相应的结构。你的解释器应该能够找到流中的结构:INTEGER -> PLUS -> INTEGER。就是这样,它尝试找出标记的序列:整数后面要跟着加号,加号后面要跟着整数。 +既然你的解释器能够从输入字符中获取标记流,解释器需要对它做点什么:它需要在词法分析器 `get_next_token` 中获取的标记流中找出相应的结构。你的解释器应该能够找到流中的结构:INTEGER -> PLUS -> INTEGER。就是这样,它尝试找出标记的序列:整数后面要跟着加号,加号后面要跟着整数。 -负责找出并解释结构的方法就是 expr。该方法检验标记序列确实与期望的标记序列是对应的,比如 INTEGER -> PLUS -> INTEGER。成功确认了这个结构后,就会生成加号左右两边的标记的值相加的结果,这样就成功解释你输入到解释器中的算术表达式了。 +负责找出并解释结构的方法就是 `expr`。该方法检验标记序列确实与期望的标记序列是对应的,比如 INTEGER -> PLUS -> INTEGER。成功确认了这个结构后,就会生成加号左右两边的标记的值相加的结果,这样就成功解释你输入到解释器中的算术表达式了。 -expr 方法用了一个助手方法 eat 来检验传入的标记类型是否与当前的标记类型相匹配。在匹配到传入的标记类型后,eat 方法获取下一个标记,并将其赋给 current_token 变量,然后高效地 “吃掉” 当前匹配的标记,并将标记流的虚拟指针向后移动。如果标记流的结构与期望的 INTEGER PLUS INTEGER 标记序列不对应,eat 方法就抛出一个异常。 +`expr` 方法用了一个助手方法 `eat` 来检验传入的标记类型是否与当前的标记类型相匹配。在匹配到传入的标记类型后,`eat` 方法会获取下一个标记,并将其赋给 `current_token` 变量,然后高效地 “吃掉” 当前匹配的标记,并将标记流的虚拟指针向后移动。如果标记流的结构与期望的 INTEGER -> PLUS -> INTEGER 标记序列不对应,`eat` 方法就抛出一个异常。 让我们回顾下解释器做了什么来对算术表达式进行评估的: - * 解释器接受输入字符串,就把它当作 “3+5” - * 解释器调用 expr 方法,在词法分析器 get_next_token 返回的标记流中找出结构。这个结构就是 INTEGER PLUS INTEGER 这样的格式。在确认了格式后,它就通过把两个整型标记相加解释输入,因为此时对于解释器来说很清楚,他要做的就是把两个整数 3 和 5 进行相加。 - +* 解释器接受输入字符串,比如说 “3+5” +* 解释器调用 `expr` 方法,在词法分析器 `get_next_token` 返回的标记流中找出结构。这个结构就是 INTEGER -> PLUS -> INTEGER 这样的格式。在确认了格式后,它就通过把两个整型标记相加来解释输入,因为此时对于解释器来说很清楚,它要做的就是把两个整数 3 和 5 进行相加。 恭喜。你刚刚学习了怎么构建自己的第一个解释器! @@ -268,42 +270,38 @@ expr 方法用了一个助手方法 eat 来检验传入的标记类型是否与 看了这篇文章,你肯定觉得不够,是吗?好,准备好做这些练习: - 1. 修改代码,允许输入多位数,比如 “12+3” - 2. 添加一个方法忽略空格符,让你的计算器能够处理带有空白的输入,比如“12 + 3” - 3. 修改代码,用 ‘-’ 号而非 ‘+’ 号去执行减法比如 “7-5” - +1. 修改代码,允许输入多位数,比如 “12+3” +2. 添加一个方法忽略空格符,让你的计算器能够处理带有空白的输入,比如 “12 + 3” +3. 修改代码,用 ‘-’ 号而非 ‘+’ 号去执行减法比如 “7-5” **检验你的理解** - 1. 什么是解释器? - 2. 什么是编译器 - 3. 解释器和编译器有什么差别? - 4. 什么是标记? - 5. 将输入分隔成若干个标记的过程叫什么? - 6. 解释器中进行词法分析的部分叫什么? - 7. 解释器或编译器中进行词法分析的部分有哪些其他的常见名字? - - +1. 什么是解释器? +2. 什么是编译器 +3. 解释器和编译器有什么差别? +4. 什么是标记? +5. 将输入分隔成若干个标记的过程叫什么? +6. 解释器中进行词法分析的部分叫什么? +7. 解释器或编译器中进行词法分析的部分有哪些其他的常见名字? 在结束本文前,我衷心希望你能留下学习解释器和编译器的承诺。并且现在就开始做。不要把它留到以后。不要拖延。如果你已经看完了本文,就开始吧。如果已经仔细看完了但是还没做什么练习 —— 现在就开始做吧。如果已经开始做练习了,那就把剩下的做完。你懂得。而且你知道吗?签下承诺书,今天就开始学习解释器和编译器! +> 本人, ______,身体健全,思想正常,在此承诺从今天开始学习解释器和编译器,直到我百分百了解它们是怎么工作的! -_本人, ______,身体健全,思想正常,在此承诺从今天开始学习解释器和编译器,直到我百分百了解它们是怎么工作的!_ +> -签字人: +> 签字人: -日期: +> 日期: ![][13] 签字,写上日期,把它放在你每天都能看到的地方,确保你能坚守承诺。谨记你的承诺: -> "Commitment is doing the thing you said you were going to do long after the mood you said it in has left you." -- Darren Hardy > “承诺就是,你说自己会去做的事,在你说完就一直陪着你的东西。” —— Darren Hardy 好,今天的就结束了。这个系列的下一篇文章里,你将会扩展自己的计算器,让它能够处理更复杂的算术表达式。敬请期待。 - -------------------------------------------------------------------------------- via: https://ruslanspivak.com/lsbasi-part1/ @@ -311,7 +309,7 @@ via: https://ruslanspivak.com/lsbasi-part1/ 作者:[Ruslan Spivak][a] 译者:[BriFuture](https://github.com/BriFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201803/20150708 Choosing a Linux Tracer (2015).md b/published/201803/20150708 Choosing a Linux Tracer (2015).md new file mode 100644 index 0000000000..2d04d8594f --- /dev/null +++ b/published/201803/20150708 Choosing a Linux Tracer (2015).md @@ -0,0 +1,189 @@ +Linux 跟踪器之选 +====== + +[![][1]][2] + +> Linux 跟踪很神奇! + +跟踪器tracer是一个高级的性能分析和调试工具,如果你使用过 `strace(1)` 或者 `tcpdump(8)`,你不应该被它吓到 ... 你使用的就是跟踪器。系统跟踪器能让你看到很多的东西,而不仅是系统调用或者数据包,因为常见的跟踪器都可以跟踪内核或者应用程序的任何东西。 + +有大量的 Linux 跟踪器可供你选择。由于它们中的每个都有一个官方的(或者非官方的)的吉祥物,我们有足够多的选择给孩子们展示。 + +你喜欢使用哪一个呢? + +我从两类读者的角度来回答这个问题:大多数人和性能/内核工程师。当然,随着时间的推移,这也可能会发生变化,因此,我需要及时去更新本文内容,或许是每年一次,或者更频繁。(LCTT 译注:本文最后更新于 2015 年) + +### 对于大多数人 + +大多数人(开发者、系统管理员、运维人员、网络可靠性工程师(SRE)…)是不需要去学习系统跟踪器的底层细节的。以下是你需要去了解和做的事情: + +#### 1. 使用 perf_events 进行 CPU 剖析 + +可以使用 perf_events 进行 CPU 剖析profiling。它可以用一个 [火焰图][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 剖析。虽然从技术角度来说,这并不是事件“跟踪”,而是采样sampling。最难的部分是获得完整的栈和符号,这部分在我的 [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_events,eBPF 已经集成到内核中了,然后用其它的跟踪器,如 SystemTap/LTTng 作为对 eBPF 的补充。我目前在 Netflix 的工作中就是这么做的。 + +![](http://www.brendangregg.com/blog/images/2015/choosing_a_tracer.png) + +以下是我对各个跟踪器的评价: + +#### 1. ftrace + +我爱 [ftrace][12],它是内核黑客最好的朋友。它被构建进内核中,它能够利用跟踪点、kprobes、以及 uprobes,以提供一些功能:使用可选的过滤器和参数进行事件跟踪;事件计数和计时,内核概览;函数流步进function-flow walking。关于它的示例可以查看内核源代码树中的 [ftrace.txt][13]。它通过 `/sys` 来管理,是面向单一的 root 用户的(虽然你可以使用缓冲实例以让其支持多用户),它的界面有时很繁琐,但是它比较容易调校hackable,并且有个前端:ftrace 的主要创建者 Steven Rostedt 设计了一个 trace-cmd,而且我也创建了 perf-tools 集合。我最诟病的就是它不是可编程的programmable,因此,举个例子说,你不能保存和获取时间戳、计算延迟,以及将其保存为直方图。你需要转储事件到用户级以便于进行后期处理,这需要花费一些成本。它也许可以通过 eBPF 实现可编程。 + +#### 2. perf_events + +[perf_events][14] 是 Linux 用户的主要跟踪工具,它的源代码位于 Linux 内核中,一般是通过 linux-tools-common 包来添加的。它又称为 `perf`,后者指的是它的前端,它相当高效(动态缓存),一般用于跟踪并转储到一个文件中(perf.data),然后可以在之后进行后期处理。它可以做大部分 ftrace 能做的事情。它不能进行函数流步进,并且不太容易调校(而它的安全/错误检查做的更好一些)。但它可以做剖析(采样)、CPU 性能计数、用户级的栈转换、以及使用本地变量利用调试信息debuginfo进行行级跟踪line tracing。它也支持多个并发用户。与 ftrace 一样,它也不是内核可编程的,除非 eBPF 支持(补丁已经在计划中)。如果只学习一个跟踪器,我建议大家去学习 perf,它可以解决大量的问题,并且它也相当安全。 + +#### 3. eBPF + +扩展的伯克利包过滤器extended Berkeley Packet Filter(eBPF)是一个内核内in-kernel的虚拟机,可以在事件上运行程序,它非常高效(JIT)。它可能最终为 ftrace 和 perf_events 提供内核内编程in-kernel programming,并可以去增强其它跟踪器。它现在是由 Alexei Starovoitov 开发的,还没有实现完全的整合,但是对于一些令人印象深刻的工具,有些内核版本(比如,4.1)已经支持了:比如,块设备 I/O 的延迟热力图latency heat map。更多参考资料,请查阅 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 中的。它令人印象深刻,一些供应器provider可以工作,还不是很完美,它最多应该算是实验性的工具(不安全)。我认为对于许可证的担心,使人们对它保持谨慎:它可能永远也进入不了 Linux 内核,因为 Sun 是基于 CDDL 许可证发布的 DTrace;Paul 的方法是将它作为一个插件。我非常希望看到 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` 的语法来处理系统调用syscall事件,并用 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&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/ diff --git a/published/201803/20160810 How does gdb work.md b/published/201803/20160810 How does gdb work.md new file mode 100644 index 0000000000..58fb60873e --- /dev/null +++ b/published/201803/20160810 How does gdb work.md @@ -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 +``` + +变量能够位于的地方有heapstack或者程序的文本段text。全局变量是程序的一部分。某种程度上,你可以把它们想象成是在编译的时候分配的。因此,我们可以很容易的找出全局变量的地址。让我们来看看,`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 diff --git a/published/201803/20170210 Evolutional Steps of Computer Systems.md b/published/201803/20170210 Evolutional Steps of Computer Systems.md new file mode 100644 index 0000000000..0b28a3588e --- /dev/null +++ b/published/201803/20170210 Evolutional Steps of Computer Systems.md @@ -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 diff --git a/published/201803/20170310 9 Lightweight Linux Applications to Speed Up Your System.md b/published/201803/20170310 9 Lightweight Linux Applications to Speed Up Your System.md new file mode 100644 index 0000000000..bf2e2d972a --- /dev/null +++ b/published/201803/20170310 9 Lightweight Linux Applications to Speed Up Your System.md @@ -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] + +尽管来自 LXDE,PCManFM 也同样适用于其他桌面环境。 + +#### 在基于 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 在技术上不是一个完整的办公套件。它由不同的独立应用程序组成,在这之中 AbiWord&Gnumeric 脱颖而出。 + +**AbiWord** 是文字处理器。它比其他替代品轻巧并且快得多。但是这样做是有代价的 —— 你可能会失去宏、语法检查等一些功能。AdiWord 并不完美,但它可以满足你基本的需求。 + +![AbiWord][22] + +**Gnumeric** 是电子表格编辑器。就像 AbiWord 一样,Gnumeric 也非常快速,提供了精确的计算功能。如果你正在寻找一个简单轻便的电子表格编辑器,Gnumeric 已经能满足你的需求了。 + +![Gnumeric][23] + +在 [Gnome Office][24] 下面还有一些其它应用程序。你可以在官方页面找到它们。 + +#### 在基于 Ubuntu 的发行版上安装 AbiWord&Gnumeric + +要安装 AbiWord&Gnumeric,只需在终端中输入以下指令: + +``` +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/ diff --git a/translated/tech/20170921 How to answer questions in a helpful way.md b/published/201803/20170921 How to answer questions in a helpful way.md similarity index 57% rename from translated/tech/20170921 How to answer questions in a helpful way.md rename to published/201803/20170921 How to answer questions in a helpful way.md index acc67fd10c..41436b0a90 100644 --- a/translated/tech/20170921 How to answer questions in a helpful way.md +++ b/published/201803/20170921 How to answer questions in a helpful way.md @@ -1,28 +1,21 @@ - 如何提供有帮助的回答 ============================= -如果你的同事问你一个不太清晰的问题,你会怎么回答?我认为提问题是一种技巧(可以看 [如何提出有意义的问题][1]) 同时,合理地回答问题也是一种技巧。他们都是非常实用的。 +如果你的同事问你一个不太清晰的问题,你会怎么回答?我认为提问题是一种技巧(可以看 [如何提出有意义的问题][1]) 同时,合理地回答问题也是一种技巧,它们都是非常实用的。 -一开始 - 有时向你提问的人不尊重你的时间,这很糟糕。 - -理想情况下,我们假设问你问题的人是一个理性的人并且正在尽力解决问题而你想帮助他们。和我一起工作的人是这样,我所生活的世界也是这样。当然,现实生活并不是这样。 +一开始 —— 有时向你提问的人不尊重你的时间,这很糟糕。理想情况下,我们假设问你问题的人是一个理性的人并且正在尽力解决问题,而你想帮助他们。和我一起工作的人是这样,我所生活的世界也是这样。当然,现实生活并不是这样。 下面是有助于回答问题的一些方法! - -### 如果他们提问不清楚,帮他们澄清 +### 如果他们的提问不清楚,帮他们澄清 通常初学者不会提出很清晰的问题,或者问一些对回答问题没有必要信息的问题。你可以尝试以下方法 澄清问题: -* ** 重述为一个更明确的问题 ** 来回复他们(”你是想问 X 吗?“) - -* ** 向他们了解更具体的他们并没有提供的信息 ** (”你使用 IPv6 ?”) - -* ** 问是什么导致了他们的问题 ** 例如,有时有些人会进入我的团队频道,询问我们的服务发现(service discovery )如何工作的。这通常是因为他们试图设置/重新配置服务。在这种情况下,如果问“你正在使用哪种服务?可以给我看看你正在处理的 pull requests 吗?”是有帮助的。 - -这些方法很多来自 [如何提出有意义的问题][2]中的要点。(尽管我永远不会对某人说“噢,你得先看完 “如何提出有意义的问题”这篇文章后再来像我提问) +* **重述为一个更明确的问题**来回复他们(“你是想问 X 吗?”) +* **向他们了解更具体的他们并没有提供的信息** (“你使用 IPv6 ?”) +* **问是什么导致了他们的问题**。例如,有时有些人会进入我的团队频道,询问我们的服务发现service discovery如何工作的。这通常是因为他们试图设置/重新配置服务。在这种情况下,如果问“你正在使用哪种服务?可以给我看看你正在处理的‘拉取请求’吗?”是有帮助的。 +这些方法很多来自[如何提出有意义的问题][2]中的要点。(尽管我永远不会对某人说“噢,你得先看完《如何提出有意义的问题》这篇文章后再来向我提问) ### 弄清楚他们已经知道了什么 @@ -30,66 +23,54 @@ Harold Treen 给了我一个很好的例子: -> 前几天,有人请我解释“ Redux-Sagas ”。与其深入解释不如说“ 他们就像 worker threads 监听行为(actions),让你更新 Redux store 。 +> 前几天,有人请我解释 “Redux-Sagas”。与其深入解释,不如说 “它们就像监听 action 的工人线程,并可以让你更新 Redux store。 -> 我开始搞清楚他们对 Redux 、行为(actions)、store 以及其他基本概念了解多少。将这些概念都联系在一起再来解释会容易得多。 +> 我开始搞清楚他们对 Redux、action、store 以及其他基本概念了解多少。将这些概念都联系在一起再来解释会容易得多。 -弄清楚问你问题的人已经知道什么是非常重要的。因为有时他们可能会对基础概念感到疑惑(“ Redux 是什么?“),或者他们可能是专家但是恰巧遇到了微妙的极端情况(corner case)。如果答案建立在他们不知道的概念上会令他们困惑,但如果重述他们已经知道的的又会是乏味的。 +弄清楚问你问题的人已经知道什么是非常重要的。因为有时他们可能会对基础概念感到疑惑(“Redux 是什么?”),或者他们可能是专家,但是恰巧遇到了微妙的极端情况corner case。如果答案建立在他们不知道的概念上会令他们困惑,但如果重述他们已经知道的的又会是乏味的。 这里有一个很实用的技巧来了解他们已经知道什么 - 比如可以尝试用“你对 X 了解多少?”而不是问“你知道 X 吗?”。 - ### 给他们一个文档 -“RTFM” (“去读那些他妈的手册”(Read The Fucking Manual))是一个典型的无用的回答,但事实上如果向他们指明一个特定的文档会是非常有用的!当我提问题的时候,我当然很乐意翻看那些能实际解决我的问题的文档,因为它也可能解决其他我想问的问题。 +“RTFM” (“去读那些他妈的手册”Read The Fucking Manual)是一个典型的无用的回答,但事实上如果向他们指明一个特定的文档会是非常有用的!当我提问题的时候,我当然很乐意翻看那些能实际解决我的问题的文档,因为它也可能解决其他我想问的问题。 我认为明确你所给的文档的确能够解决问题是非常重要的,或者至少经过查阅后确认它对解决问题有帮助。否则,你可能将以下面这种情形结束对话(非常常见): * Ali:我应该如何处理 X ? +* Jada:\<文档链接> +* Ali: 这个没有实际解释如何处理 X ,它仅仅解释了如何处理 Y ! -* Jada:<文档链接> - -* Ali: 这个并有实际解释如何处理 X ,它仅仅解释了如何处理 Y ! - -如果我所给的文档特别长,我会指明文档中那个我将会谈及的特定部分。[bash 手册][3] 有44000个字(真的!),所以如果只说“它在 bash 手册中有说明”是没有帮助的:) - +如果我所给的文档特别长,我会指明文档中那个我将会谈及的特定部分。[bash 手册][3] 有 44000 个字(真的!),所以如果只说“它在 bash 手册中有说明”是没有帮助的 :) ### 告诉他们一个有用的搜索 -在工作中,我经常发现我可以利用我所知道的关键字进行搜索找到能够解决我的问题的答案。对于初学者来说,这些关键字往往不是那么明显。所以说“这是我用来寻找这个答案的搜索”可能有用些。再次说明,回答时请经检查后以确保搜索能够得到他们所需要的答案:) - +在工作中,我经常发现我可以利用我所知道的关键字进行搜索来找到能够解决我的问题的答案。对于初学者来说,这些关键字往往不是那么明显。所以说“这是我用来寻找这个答案的搜索”可能有用些。再次说明,回答时请经检查后以确保搜索能够得到他们所需要的答案 :) ### 写新文档 -人们经常一次又一次地问我的团队同样的问题。很显然这并不是他们的错(他们怎么能够知道在他们之前已经有10个人问了这个问题,且知道答案是什么呢?)因此,我们会尝试写新文档,而不是直接回答回答问题。 +人们经常一次又一次地问我的团队同样的问题。很显然这并不是他们的错(他们怎么能够知道在他们之前已经有 10 个人问了这个问题,且知道答案是什么呢?)因此,我们会尝试写新文档,而不是直接回答回答问题。 1. 马上写新文档 - 2. 给他们我们刚刚写好的新文档 - 3. 公示 写文档有时往往比回答问题需要花很多时间,但这是值得的。写文档尤其重要,如果: a. 这个问题被问了一遍又一遍 - b. 随着时间的推移,这个答案不会变化太大(如果这个答案每一个星期或者一个月就会变化,文档就会过时并且令人受挫) - ### 解释你做了什么 对于一个话题,作为初学者来说,这样的交流会真让人沮丧: * 新人:“嗨!你如何处理 X ?” - * 有经验的人:“我已经处理过了,而且它已经完美解决了” - * 新人:”...... 但是你做了什么?!“ 如果问你问题的人想知道事情是如何进行的,这样是有帮助的: * 让他们去完成任务而不是自己做 - * 告诉他们你是如何得到你给他们的答案的。 这可能比你自己做的时间还要长,但对于被问的人来说这是一个学习机会,因为那样做使得他们将来能够更好地解决问题。 @@ -97,88 +78,74 @@ b. 随着时间的推移,这个答案不会变化太大(如果这个答案 这样,你可以进行更好的交流,像这: * 新人:“这个网站出现了错误,发生了什么?” - -* 有经验的人:(2分钟后)”oh 这是因为发生了数据库故障转移“ - -* 新人: ”你是怎么知道的??!?!?“ - -* 有经验的人:“以下是我所做的!“: - +* 有经验的人:(2分钟后)“oh 这是因为发生了数据库故障转移” +* 新人: “你是怎么知道的??!?!?” +* 有经验的人:“以下是我所做的!”: 1. 通常这些错误是因为服务器 Y 被关闭了。我查看了一下 `$PLACE` 但它表明服务器 Y 开着。所以,并不是这个原因导致的。 - 2. 然后我查看 X 的仪表盘 ,仪表盘的这个部分显示这里发生了数据库故障转移。 - 3. 然后我在日志中找到了相应服务器,并且它显示连接数据库错误,看起来错误就是这里。 如果你正在解释你是如何调试一个问题,解释你是如何发现问题,以及如何找出问题的。尽管看起来你好像已经得到正确答案,但感觉更好的是能够帮助他们提高学习和诊断能力,并了解可用的资源。 - ### 解决根本问题 -这一点有点棘手。有时候人们认为他们依旧找到了解决问题的正确途径,且他们只再多一点信息就可以解决问题。但他们可能并不是走在正确的道路上!比如: +这一点有点棘手。有时候人们认为他们依旧找到了解决问题的正确途径,且他们只要再多一点信息就可以解决问题。但他们可能并不是走在正确的道路上!比如: -* George:”我在处理 X 的时候遇到了错误,我该如何修复它?“ - -* Jasminda:”你是正在尝试解决 Y 吗?如果是这样,你不应该处理 X ,反而你应该处理 Z 。“ - -* George:“噢,你是对的!!!谢谢你!我回反过来处理 Z 的。“ +* George:“我在处理 X 的时候遇到了错误,我该如何修复它?” +* Jasminda:“你是正在尝试解决 Y 吗?如果是这样,你不应该处理 X ,反而你应该处理 Z 。” +* George:“噢,你是对的!!!谢谢你!我回反过来处理 Z 的。” Jasminda 一点都没有回答 George 的问题!反而,她猜测 George 并不想处理 X ,并且她是猜对了。这是非常有用的! 如果你这样做可能会产生高高在上的感觉: -* George:”我在处理 X 的时候遇到了错误,我该如何修复它?“ +* George:“我在处理 X 的时候遇到了错误,我该如何修复它?” +* Jasminda:“不要这样做,如果你想处理 Y ,你应该反过来完成 Z 。” +* George:“好吧,我并不是想处理 Y 。实际上我想处理 X 因为某些原因(REASONS)。所以我该如何处理 X 。” -* Jasminda:不要这样做,如果你想处理 Y ,你应该反过来完成 Z 。 - -* George:“好吧,我并不是想处理 Y 。实际上我想处理 X 因为某些原因(REASONS)。所以我该如何处理 X 。 - -所以不要高高在上,且要记住有时有些提问者可能已经偏离根本问题很远了。同时回答提问者提出的问题以及他们本该提出的问题都是合理的:“嗯,如果你想处理 X ,那么你可能需要这么做,但如果你想用这个解决 Y 问题,可能通过处理其他事情你可以更好地解决这个问题,这就是为什么可以做得更好的原因。 +所以不要高高在上,且要记住有时有些提问者可能已经偏离根本问题很远了。同时回答提问者提出的问题以及他们本该提出的问题都是合理的:“嗯,如果你想处理 X ,那么你可能需要这么做,但如果你想用这个解决 Y 问题,可能通过处理其他事情你可以更好地解决这个问题,这就是为什么可以做得更好的原因。” -### 询问”那个回答可以解决您的问题吗?” +### 询问“那个回答可以解决您的问题吗?” -我总是喜欢在我回答了问题之后核实是否真的已经解决了问题:”这个回答解决了您的问题吗?您还有其他问题吗?“在问完这个之后最好等待一会,因为人们通常需要一两分钟来知道他们是否已经找到了答案。 +我总是喜欢在我回答了问题之后核实是否真的已经解决了问题:“这个回答解决了您的问题吗?您还有其他问题吗?”在问完这个之后最好等待一会,因为人们通常需要一两分钟来知道他们是否已经找到了答案。 我发现尤其是问“这个回答解决了您的问题吗”这个额外的步骤在写完文档后是非常有用的。通常,在写关于我熟悉的东西的文档时,我会忽略掉重要的东西而不会意识到它。 - ### 结对编程和面对面交谈 我是远程工作的,所以我的很多对话都是基于文本的。我认为这是沟通的默认方式。 今天,我们生活在一个方便进行小视频会议和屏幕共享的世界!在工作时候,在任何时间我都可以点击一个按钮并快速加入与他人的视频对话或者屏幕共享的对话中! -例如,最近有人问如何自动调节他们的服务容量规划。我告诉他们我们有几样东西需要清理,但我还不太确定他们要清理的是什么。然后我们进行了一个简短的视屏会话并在5分钟后,我们解决了他们问题。 +例如,最近有人问如何自动调节他们的服务容量规划。我告诉他们我们有几样东西需要清理,但我还不太确定他们要清理的是什么。然后我们进行了一个简短的视频会话并在 5 分钟后,我们解决了他们问题。 我认为,特别是如果有人真的被困在该如何开始一项任务时,开启视频进行结对编程几分钟真的比电子邮件或者一些即时通信更有效。 - ### 不要表现得过于惊讶 这是源自 Recurse Center 的一则法则:[不要故作惊讶][4]。这里有一个常见的情景: -* 某人1:“什么是 Linux 内核” +* 某甲:“什么是 Linux 内核” +* 某乙:“你竟然不知道什么是 Linux 内核?!!!!?!!!????” -* 某人2:“你竟然不知道什么是 Linux 内核(LINUX KERNEL)?!!!!?!!!????” +某乙的表现(无论他们是否真的如此惊讶)是没有帮助的。这大部分只会让某甲不好受,因为他们确实不知道什么是 Linux 内核。 -某人2表现(无论他们是否真的如此惊讶)是没有帮助的。这大部分只会让某人1不好受,因为他们确实不知道什么是 Linux 内核。 +我一直在假装不惊讶,即使我事实上确实有点惊讶那个人不知道这种东西。 -我一直在假装不惊讶即使我事实上确实有点惊讶那个人不知道这种东西但它是令人敬畏的。 - -### 回答问题是令人敬畏的 +### 回答问题真的很棒 显然并不是所有方法都是合适的,但希望你能够发现这里有些是有帮助的!我发现花时间去回答问题并教导人们是其实是很有收获的。 -特别感谢 Josh Triplett 的一些建议并做了很多有益的补充,以及感谢 Harold Treen、Vaibhav Sagar、Peter Bhat Hatkins、Wesley Aptekar Cassels 和 Paul Gowder的阅读或评论。 +特别感谢 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] +作者:[Julia Evans][a] 译者:[HardworkFish](https://github.com/HardworkFish) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md b/published/201803/20171002 Bash Bypass Alias Linux-Unix Command.md similarity index 59% rename from translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md rename to published/201803/20171002 Bash Bypass Alias Linux-Unix Command.md index e4dec43782..e055c1f519 100644 --- a/translated/tech/20171002 Bash Bypass Alias Linux-Unix Command.md +++ b/published/201803/20171002 Bash Bypass Alias Linux-Unix Command.md @@ -1,23 +1,34 @@ -绕过 Linux/Unix 命令别名 +4 种绕过 Linux/Unix 命令别名的方法 ====== + 我在我的 Linux 系统上定义了如下 mount 别名: + ``` alias mount='mount | column -t' ``` -但是我需要在挂载文件系统和其他用途时绕过 bash 别名。我如何在 Linux、\*BSD、macOS 或者类 Unix 系统上临时禁用或者绕过 bash shell 呢? +但是我需要在挂载文件系统和其他用途时绕过这个 bash 别名。我如何在 Linux、*BSD、macOS 或者类 Unix 系统上临时禁用或者绕过 bash shell 呢? + +你可以使用 `alias` 命令定义或显示 bash shell 别名。一旦创建了 bash shell 别名,它们将优先于外部或内部命令。本文将展示如何暂时绕过 bash 别名,以便你可以运行实际的内部或外部命令。 -你可以使用 alias 命令定义或显示 bash shell 别名。一旦创建了 bash shell 别名,它们将优先于外部或内部命令。本文将展示如何暂时绕过 bash 别名,以便你可以运行实际的内部或外部命令。 [![Bash Bypass Alias Linux BSD macOS Unix Command][1]][1] -## 4 种绕过 bash 别名的方法 - +### 4 种绕过 bash 别名的方法 尝试以下任意一种方法来运行被 bash shell 别名绕过的命令。让我们[如下定义一个别名][2]: -`alias mount='mount | column -t'` + +``` +alias mount='mount | column -t' +``` + 运行如下: -`mount ` + +``` +mount +``` + 示例输出: + ``` sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) @@ -30,45 +41,83 @@ binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_m lxcfs on /var/lib/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) ``` -### 方法1 - 使用 \command +#### 方法 1 - 使用 `\command` -输入以下命令暂时绕过名为 mount 的 bash 别名: -`\mount` +输入以下命令暂时绕过名为 `mount` 的 bash 别名: -### 方法2 - 使用 "command" 或 'command' +``` +\mount +``` + +#### 方法 2 - 使用 `"command"` 或 `'command'` + +如下引用 `mount` 命令调用实际的 `/bin/mount`: + +``` +"mount" +``` -如下引用 mount 命令调用实际的 /bin/mount: -`"mount"` 或者 -`'mount'` -### Method 3 - Use full command path +``` +'mount' +``` -Use full binary path such as /bin/mount: -`/bin/mount -/bin/mount /dev/sda1 /mnt/sda` +#### 方法 3 - 使用命令的完全路径 -### 方法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 命令的说明 +``` +command cmd +command cmd arg1 arg2 +``` + +要覆盖 `.bash_aliases` 中设置的别名,例如 `mount`: + +``` +command mount +command mount /dev/sdc /mnt/pendrive/ +``` + +[“command” 直接运行命令或显示][3]关于命令的信息。它带参数运行命令会抑制 shell 函数查询或者别名,或者显示有关给定命令的信息。 + +### 关于 unalias 命令的说明 + +要从当前会话的已定义别名列表中移除别名,请使用 `unalias` 命令: + +``` +unalias mount +``` -要从当前会话的已定义别名列表中移除别名,请使用 unalias 命令: -`unalias mount` 要从当前 bash 会话中删除所有别名定义: -`unalias -a` -确保你更新你的 ~/.bashrc 或 $HOME/.bash_aliases。如果要永久删除定义的别名,则必须删除定义的别名: -`vi ~/.bashrc` + +``` +unalias -a +``` + +确保你更新你的 `~/.bashrc` 或 `$HOME/.bash_aliases`。如果要永久删除定义的别名,则必须删除定义的别名: + +``` +vi ~/.bashrc +``` + 或者 -`joe $HOME/.bash_aliases` + +``` +joe $HOME/.bash_aliases +``` + 想了解更多信息,参考[这里][4]的在线手册,或者输入下面的命令查看: + ``` man bash help command @@ -76,14 +125,13 @@ 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) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/translated/tech/20171002 Reset Linux Desktop To Default Settings With A Single Command.md b/published/201803/20171002 Reset Linux Desktop To Default Settings With A Single Command.md similarity index 51% rename from translated/tech/20171002 Reset Linux Desktop To Default Settings With A Single Command.md rename to published/201803/20171002 Reset Linux Desktop To Default Settings With A Single Command.md index d486a777de..cfeade8a8b 100644 --- a/translated/tech/20171002 Reset Linux Desktop To Default Settings With A Single Command.md +++ b/published/201803/20171002 Reset Linux Desktop To Default Settings With A Single Command.md @@ -1,18 +1,20 @@ -使用一个命令重置 Linux 桌面到默认设置 +使用一个命令重置 Linux 桌面为默认设置 ====== + ![](https://www.ostechnix.com/wp-content/uploads/2017/10/Reset-Linux-Desktop-To-Default-Settings-720x340.jpg) -前段时间,我们分享了一篇关于 [**Resetter**][1] 的文章 - 这是一个有用的软件,可以在几分钟内将 Ubuntu 重置为出厂默认设置。使用 Resetter,任何人都可以轻松地将 Ubuntu 重置为第一次安装时的状态。今天,我偶然发现了一个类似的东西。不,它不是一个应用程序,而是一个单行的命令来重置你的 Linux 桌面设置、调整和定制到默认状态。 +前段时间,我们分享了一篇关于 [Resetter][1] 的文章 - 这是一个有用的软件,可以在几分钟内将 Ubuntu 重置为出厂默认设置。使用 Resetter,任何人都可以轻松地将 Ubuntu 重置为第一次安装时的状态。今天,我偶然发现了一个类似的东西。不,它不是一个应用程序,而是一个单行的命令来重置你的 Linux 桌面设置、调整和定制到默认状态。 ### 将 Linux 桌面重置为默认设置 -这个命令会将 Ubuntu Unity、Gnome 和 MATE 桌面重置为默认状态。我在我的 **Arch Linux MATE** 和 **Ubuntu 16.04 Unity** 上测试了这个命令。它可以在两个系统上工作。我希望它也能在其他桌面上运行。在写这篇文章的时候,我还没有安装 GNOME 的 Linux 桌面,因此我无法确认。但是,我相信它也可以在 Gnome 桌面环境中使用。 +这个命令会将 Ubuntu Unity、Gnome 和 MATE 桌面重置为默认状态。我在我的 Arch Linux MATE 和 Ubuntu 16.04 Unity 上测试了这个命令。它可以在两个系统上工作。我希望它也能在其他桌面上运行。在写这篇文章的时候,我还没有安装 GNOME 的 Linux 桌面,因此我无法确认。但是,我相信它也可以在 Gnome 桌面环境中使用。 -**一句忠告:**请注意,此命令将重置你在系统中所做的所有定制和调整,包括 Unity 启动器或 Dock 中的固定应用程序、桌面小程序、桌面指示器、系统字体、GTK主题、图标主题、显示器分辨率、键盘快捷键、窗口按钮位置、菜单和启动器行为等。 +**一句忠告:**请注意,此命令将重置你在系统中所做的所有定制和调整,包括 Unity 启动器或 Dock 中固定的应用程序、桌面小程序、桌面指示器、系统字体、GTK主题、图标主题、显示器分辨率、键盘快捷键、窗口按钮位置、菜单和启动器行为等。 -好的是它只会重置桌面设置。它不会影响其他不使用 dconf 的程序。此外,它不会删除你的个人资料。 +好的是它只会重置桌面设置。它不会影响其他不使用 `dconf` 的程序。此外,它不会删除你的个人资料。 现在,让我们开始。要将 Ubuntu Unity 或其他带有 GNOME/MATE 环境的 Linux 桌面重置,运行下面的命令: + ``` dconf reset -f / ``` @@ -29,12 +31,13 @@ dconf reset -f / 看见了么?现在,我的 Ubuntu 桌面已经回到了出厂设置。 -有关 “dconf” 命令的更多详细信息,请参阅手册页。 +有关 `dconf` 命令的更多详细信息,请参阅手册页。 + ``` man dconf ``` -在重置桌面上我个人更喜欢 “Resetter” 而不是 “dconf” 命令。因为,Resetter 给用户提供了更多的选择。用户可以决定删除哪些应用程序、保留哪些应用程序、是保留现有用户帐户还是创建新用户等等。如果你懒得安装 Resetter,你可以使用这个 “dconf” 命令在几分钟内将你的 Linux 系统重置为默认设置。 +在重置桌面上我个人更喜欢 “Resetter” 而不是 `dconf` 命令。因为,Resetter 给用户提供了更多的选择。用户可以决定删除哪些应用程序、保留哪些应用程序、是保留现有用户帐户还是创建新用户等等。如果你懒得安装 Resetter,你可以使用这个 `dconf` 命令在几分钟内将你的 Linux 系统重置为默认设置。 就是这样了。希望这个有帮助。我将很快发布另一篇有用的指导。敬请关注! @@ -48,12 +51,12 @@ via: https://www.ostechnix.com/reset-linux-desktop-default-settings-single-comma 作者:[Edwin Arteaga][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://www.ostechnix.com -[1]:https://www.ostechnix.com/reset-ubuntu-factory-defaults/ +[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 () +[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 diff --git a/published/201803/20171007 How to use GNU Stow to manage programs installed from source and dotfiles.md b/published/201803/20171007 How to use GNU Stow to manage programs installed from source and dotfiles.md new file mode 100644 index 0000000000..306684f885 --- /dev/null +++ b/published/201803/20171007 How to use GNU Stow to manage programs installed from source and dotfiles.md @@ -0,0 +1,137 @@ +如何使用 GNU Stow 来管理从源代码安装的程序和点文件 +===== + +### 目的 + +使用 GNU Stow 轻松管理从源代码安装的程序和点文件(LCTT 译注:点文件dotfile,即以 `.` 开头的文件,在 *nix 下默认为隐藏文件,常用于存储程序的配置信息。) + +### 要求 + +* root 权限 + +### 难度 + +简单 + +### 约定 + +* `#` - 给定的命令要求直接以 root 用户身份或使用 `sudo` 命令以 root 权限执行 +* `$` - 给定的命令将作为普通的非特权用户来执行 + +### 介绍 + +有时候我们必须从源代码安装程序,因为它们也许不能通过标准渠道获得,或者我们可能需要特定版本的软件。 GNU Stow 是一个非常不错的符号链接工厂symlinks factory程序,它可以帮助我们保持文件的整洁,易于维护。 + +### 获得 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 diff --git a/published/201803/20171009 10 Free Linux Productivity Apps You Haven-t Heard Of.md b/published/201803/20171009 10 Free Linux Productivity Apps You Haven-t Heard Of.md new file mode 100644 index 0000000000..ebf7592b07 --- /dev/null +++ b/published/201803/20171009 10 Free Linux Productivity Apps You Haven-t Heard Of.md @@ -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/ diff --git a/published/201803/20171009 10 layers of Linux container security - Opensource.com.md b/published/201803/20171009 10 layers of Linux container security - Opensource.com.md new file mode 100644 index 0000000000..26188dd1ec --- /dev/null +++ b/published/201803/20171009 10 layers of Linux container security - Opensource.com.md @@ -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] 、capabilities(LCTT 译注: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、 RADOS(Ceph)、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 Oh;Microservives;Agile;Devops;Java Ee;Container;Openshift;Jboss;Evangelism + + + +-------------------------------------------------------------------------------- + +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 diff --git a/published/201803/20171016 Make -rm- Command To Move The Files To -Trash Can- Instead Of Removing Them Completely.md b/published/201803/20171016 Make -rm- Command To Move The Files To -Trash Can- Instead Of Removing Them Completely.md new file mode 100644 index 0000000000..3d4478ece2 --- /dev/null +++ b/published/201803/20171016 Make -rm- Command To Move The Files To -Trash Can- Instead Of Removing Them Completely.md @@ -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 diff --git a/published/201803/20171017 What Are the Hidden Files in my Linux Home Directory For.md b/published/201803/20171017 What Are the Hidden Files in my Linux Home Directory For.md new file mode 100644 index 0000000000..c221094e63 --- /dev/null +++ b/published/201803/20171017 What Are the Hidden Files in my Linux Home Directory For.md @@ -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/ diff --git a/published/201803/20171102 What is huge pages in Linux.md b/published/201803/20171102 What is huge pages in Linux.md new file mode 100644 index 0000000000..1f1d0b50a0 --- /dev/null +++ b/published/201803/20171102 What is huge pages in Linux.md @@ -0,0 +1,140 @@ +Linux 中的“大内存页”(hugepage)是个什么? +====== + +> 学习 Linux 中的大内存页hugepage。理解什么是“大内存页”,如何进行配置,如何查看当前状态以及如何禁用它。 + +![Huge Pages in Linux][1] + +本文中我们会详细介绍大内存页huge page,让你能够回答: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/ diff --git a/published/201803/20171108 How to Use GNOME Shell Extensions [Complete Guide].md b/published/201803/20171108 How to Use GNOME Shell Extensions [Complete Guide].md new file mode 100644 index 0000000000..47cb18df76 --- /dev/null +++ b/published/201803/20171108 How to Use GNOME Shell Extensions [Complete Guide].md @@ -0,0 +1,210 @@ +如何使用 GNOME Shell 扩展 +===== + +> 简介:这是一份详细指南,我将会向你展示如何手动或通过浏览器轻松安装 GNOME Shell 扩展Extension。 + +在讨论 [如何在 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/ \ No newline at end of file diff --git a/translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md b/published/201803/20171109 Concurrent Servers- Part 4 - libuv.md similarity index 64% rename from translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md rename to published/201803/20171109 Concurrent Servers- Part 4 - libuv.md index e819027b7d..2e714c630f 100644 --- a/translated/tech/20171109 Concurrent Servers- Part 4 - libuv.md +++ b/published/201803/20171109 Concurrent Servers- Part 4 - libuv.md @@ -12,17 +12,17 @@ ### 使用 libuv 抽象出事件驱动循环 -在 [第三节][11] 中,我们看到了基于 `select` 和 `epoll` 的服务器的相似之处,并且,我说过,在它们之间抽象出细微的差别是件很有吸引力的事。许多库已经做到了这些,所以在这一部分中我将去选一个并使用它。我选的这个库是 [libuv][12],它最初设计用于 Node.js 底层的可移植平台层,并且,后来发现在其它的项目中已有使用。libuv 是用 C 写的,因此,它具有很高的可移植性,非常适用嵌入到像 JavaScript 和 Python 这样的高级语言中。 +在 [第三节][11] 中,我们看到了基于 `select` 和 `epoll` 的服务器的相似之处,并且,我说过,在它们之间抽象出细微的差别是件很有吸引力的事。许多库已经做到了这些,所以在这一部分中我将去选一个并使用它。我选的这个库是 [libuv][12],它最初设计用于 Node.js 底层的可移植平台层,并且,后来发现在其它的项目中也有使用。libuv 是用 C 写的,因此,它具有很高的可移植性,非常适用嵌入到像 JavaScript 和 Python 这样的高级语言中。 -虽然 libuv 为抽象出底层平台细节已经变成了一个相当大的框架,但它仍然是以 _事件循环_ 思想为中心的。在我们第三部分的事件驱动服务器中,事件循环在 `main` 函数中是很明确的;当使用 libuv 时,该循环通常隐藏在库自身中,而用户代码仅需要注册事件句柄(作为一个回调函数)和运行这个循环。此外,libuv 会在给定的平台上使用更快的事件循环实现,对于 Linux 它是 epoll,等等。 +虽然 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 支持多路事件循环,因此事件循环在库中是非常重要的;它有一个句柄 —— `uv_loop_t`,以及创建/杀死/启动/停止循环的函数。也就是说,在这篇文章中,我将仅需要使用 “默认的” 循环,libuv 可通过 `uv_default_loop()` 提供它;多路循环大多用于多线程事件驱动的服务器,这是一个更高级别的话题,我将留在这一系列文章的以后部分。 ### 使用 libuv 的并发服务器 -为了对 libuv 有一个更深的印象,让我们跳转到我们的可靠协议的服务器,它通过我们的这个系列已经有了一个强大的重新实现。这个服务器的结构与第三部分中的基于 select 和 epoll 的服务器有一些相似之处,因为,它也依赖回调。完整的 [示例代码在这里][13];我们开始设置这个服务器的套接字绑定到一个本地端口: +为了对 libuv 有一个更深的印象,让我们跳转到我们的可靠协议的服务器,它通过我们的这个系列已经有了一个强大的重新实现。这个服务器的结构与第三部分中的基于 `select` 和 `epoll` 的服务器有一些相似之处,因为,它也依赖回调。完整的 [示例代码在这里][13];我们开始设置这个服务器的套接字绑定到一个本地端口: ``` int portnum = 9090; @@ -47,9 +47,9 @@ if ((rc = uv_tcp_bind(&server_stream, (const struct sockaddr*)&server_address, 0 } ``` -除了它被封装进 libuv API 中之外,你看到的是一个相当标准的套接字。在它的返回中,我们取得一个可工作于任何 libuv 支持的平台上的可移植接口。 +除了它被封装进 libuv API 中之外,你看到的是一个相当标准的套接字。在它的返回中,我们取得了一个可工作于任何 libuv 支持的平台上的可移植接口。 -这些代码也展示了很认真负责的错误处理;多数的 libuv 函数返回一个整数状态,返回一个负数意味着出现了一个错误。在我们的服务器中,我们把这些错误看做致命问题进行处理,但也可以设想为一个更优雅的错误恢复。 +这些代码也展示了很认真负责的错误处理;多数的 libuv 函数返回一个整数状态,返回一个负数意味着出现了一个错误。在我们的服务器中,我们把这些错误看做致命问题进行处理,但也可以设想一个更优雅的错误恢复。 现在,那个套接字已经绑定,是时候去监听它了。这里我们运行首个回调注册: @@ -73,7 +73,7 @@ uv_run(uv_default_loop(), UV_RUN_DEFAULT); return uv_loop_close(uv_default_loop()); ``` -注意,在运行事件循环之前,只有一个回调是通过 main 注册的;我们稍后将看到怎么去添加更多的回调。在事件循环的整个运行过程中,添加和删除回调并不是一个问题 —— 事实上,大多数服务器就是这么写的。 +注意,在运行事件循环之前,只有一个回调是通过 `main` 注册的;我们稍后将看到怎么去添加更多的回调。在事件循环的整个运行过程中,添加和删除回调并不是一个问题 —— 事实上,大多数服务器就是这么写的。 这是一个 `on_peer_connected`,它处理到服务器的新的客户端连接: @@ -132,8 +132,8 @@ void on_peer_connected(uv_stream_t* server_stream, int status) { 这些代码都有很好的注释,但是,这里有一些重要的 libuv 语法我想去强调一下: -* 传入自定义数据到回调中:因为 C 还没有闭包,这可能是个挑战,libuv 在它的所有的处理类型中有一个 `void* data` 字段;这些字段可以被用于传递用户数据。例如,注意 `client->data` 是如何指向到一个 `peer_state_t` 结构上,以便于 `uv_write` 和 `uv_read_start` 注册的回调可以知道它们正在处理的是哪个客户端的数据。 -* 内存管理:在带有垃圾回收的语言中进行事件驱动编程是非常容易的,因为,回调通常运行在一个它们注册的完全不同的栈帧中,使得基于栈的内存管理很困难。它总是需要传递堆分配的数据到 libuv 回调中(当所有回调运行时,除了 main,其它的都运行在栈上),并且,为了避免泄漏,许多情况下都要求这些数据去安全释放。这些都是些需要实践的内容 [[1]][6]。 +* 传入自定义数据到回调中:因为 C 语言还没有闭包,这可能是个挑战,libuv 在它的所有的处理类型中有一个 `void* data` 字段;这些字段可以被用于传递用户数据。例如,注意 `client->data` 是如何指向到一个 `peer_state_t` 结构上,以便于 `uv_write` 和 `uv_read_start` 注册的回调可以知道它们正在处理的是哪个客户端的数据。 +* 内存管理:在带有垃圾回收的语言中进行事件驱动编程是非常容易的,因为,回调通常运行在一个与它们注册的地方完全不同的栈帧中,使得基于栈的内存管理很困难。它总是需要传递堆分配的数据到 libuv 回调中(当所有回调运行时,除了 `main`,其它的都运行在栈上),并且,为了避免泄漏,许多情况下都要求这些数据去安全释放(`free()`)。这些都是些需要实践的内容 ^注1 。 这个服务器上对端的状态如下: @@ -146,7 +146,7 @@ typedef struct { } peer_state_t; ``` -它与第三部分中的状态非常类似;我们不再需要 sendptr,因为,在调用 "done writing" 回调之前,`uv_write` 将确保去发送它提供的整个缓冲。我们也为其它的回调使用保持了一个到客户端的指针。这里是 `on_wrote_init_ack`: +它与第三部分中的状态非常类似;我们不再需要 `sendptr`,因为,在调用 “done writing” 回调之前,`uv_write` 将确保发送它提供的整个缓冲。我们也为其它的回调使用保持了一个到客户端的指针。这里是 `on_wrote_init_ack`: ``` void on_wrote_init_ack(uv_write_t* req, int status) { @@ -171,7 +171,7 @@ void on_wrote_init_ack(uv_write_t* req, int status) { } ``` -然后,我们确信知道了这个初始的 '*' 已经被发送到对端,我们通过调用 `uv_read_start` 去监听从这个对端来的入站数据,它注册一个回调(`on_peer_read`)去被调用,不论什么时候,事件循环都在套接字上接收来自客户端的调用: +然后,我们确信知道了这个初始的 `'*'` 已经被发送到对端,我们通过调用 `uv_read_start` 去监听从这个对端来的入站数据,它注册一个将被事件循环调用的回调(`on_peer_read`),不论什么时候,事件循环都在套接字上接收来自客户端的调用: ``` void on_peer_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) { @@ -236,11 +236,11 @@ void on_peer_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) { } ``` -这个服务器的运行时行为非常类似于第三部分的事件驱动服务器:所有的客户端都在一个单个的线程中并发处理。并且一些行为被维护在服务器代码中:服务器的逻辑实现为一个集成的回调,并且长周期运行是禁止的,因为它会阻塞事件循环。这一点也很类似。让我们进一步探索这个问题。 +这个服务器的运行时行为非常类似于第三部分的事件驱动服务器:所有的客户端都在一个单个的线程中并发处理。并且类似的,一些特定的行为必须在服务器代码中维护:服务器的逻辑实现为一个集成的回调,并且长周期运行是禁止的,因为它会阻塞事件循环。这一点也很类似。让我们进一步探索这个问题。 ### 在事件驱动循环中的长周期运行的操作 -单线程的事件驱动代码使它先天地对一些常见问题非常敏感:整个循环中的长周期运行的代码块。参见如下的程序: +单线程的事件驱动代码使它先天就容易受到一些常见问题的影响:长周期运行的代码会阻塞整个循环。参见如下的程序: ``` void on_timer(uv_timer_t* timer) { @@ -280,23 +280,21 @@ on_timer [18850 ms] ... ``` -`on_timer` 忠实地每秒执行一次,直到随机出现的睡眠为止。在那个时间点,`on_timer` 不再被调用,直到睡眠时间结束;事实上,_没有其它的回调_  在这个时间帧中被调用。这个睡眠调用阻塞当前线程,它正是被调用的线程,并且也是事件循环使用的线程。当这个线程被阻塞后,事件循环也被阻塞。 +`on_timer` 忠实地每秒执行一次,直到随机出现的睡眠为止。在那个时间点,`on_timer` 不再被调用,直到睡眠时间结束;事实上,_没有其它的回调_  会在这个时间帧中被调用。这个睡眠调用阻塞了当前线程,它正是被调用的线程,并且也是事件循环使用的线程。当这个线程被阻塞后,事件循环也被阻塞。 这个示例演示了在事件驱动的调用中为什么回调不能被阻塞是多少的重要。并且,同样适用于 Node.js 服务器、客户端侧的 Javascript、大多数的 GUI 编程框架、以及许多其它的异步编程模型。 -但是,有时候运行耗时的任务是不可避免的。并不是所有任务都有一个异步 APIs;例如,我们可能使用一些仅有同步 API 的库去处理,或者,正在执行一个可能的长周期计算。我们如何用事件驱动编程去结合这些代码?线程可以帮到你! +但是,有时候运行耗时的任务是不可避免的。并不是所有任务都有一个异步 API;例如,我们可能使用一些仅有同步 API 的库去处理,或者,正在执行一个可能的长周期计算。我们如何用事件驱动编程去结合这些代码?线程可以帮到你! -### “转换” 阻塞调用到异步调用的线程 +### “转换” 阻塞调用为异步调用的线程 -一个线程池可以被用于去转换阻塞调用到异步调用,通过与事件循环并行运行,并且当任务完成时去由它去公布事件。一个给定的阻塞函数 `do_work()`,这里介绍了它是怎么运行的: +一个线程池可以用于转换阻塞调用为异步调用,通过与事件循环并行运行,并且当任务完成时去由它去公布事件。以阻塞函数 `do_work()` 为例,这里介绍了它是怎么运行的: -1. 在一个回调中,用 `do_work()` 代表直接调用,我们将它打包进一个 “任务”,并且请求线程池去运行这个任务。当任务完成时,我们也为循环去调用它注册一个回调;我们称它为 `on_work_done()`。 +1. 不在一个回调中直接调用 `do_work()` ,而是将它打包进一个 “任务”,让线程池去运行这个任务。当任务完成时,我们也为循环去调用它注册一个回调;我们称它为 `on_work_done()`。 +2. 在这个时间点,我们的回调就可以返回了,而事件循环保持运行;在同一时间点,线程池中的有一个线程运行这个任务。 +3. 一旦任务运行完成,通知主线程(指正在运行事件循环的线程),并且事件循环调用 `on_work_done()`。 -2. 在这个时间点,我们的回调可以返回并且事件循环保持运行;在同一时间点,线程池中的一个线程运行这个任务。 - -3. 一旦任务运行完成,通知主线程(指正在运行事件循环的线程),并且,通过事件循环调用 `on_work_done()`。 - -让我们看一下,使用 libuv 的工作调度 API,是怎么去解决我们前面的 timer/sleep 示例中展示的问题的: +让我们看一下,使用 libuv 的工作调度 API,是怎么去解决我们前面的计时器/睡眠示例中展示的问题的: ``` void on_after_work(uv_work_t* req, int status) { @@ -327,7 +325,7 @@ int main(int argc, const char** argv) { } ``` -通过一个 work_req [[2]][14] 类型的句柄,我们进入一个任务队列,代替在 `on_timer` 上直接调用 sleep,这个函数在任务中(`on_work`)运行,并且,一旦任务完成(`on_after_work`),这个函数被调用一次。`on_work` 在这里是指发生的 “work”(阻塞中的/耗时的操作)。在这两个回调传递到 `uv_queue_work` 时,注意一个关键的区别:`on_work` 运行在线程池中,而 `on_after_work` 运行在事件循环中的主线程上 - 就好像是其它的回调一样。 +通过一个 `work_req` ^注2 类型的句柄,我们进入一个任务队列,代替在 `on_timer` 上直接调用 sleep,这个函数在任务中(`on_work`)运行,并且,一旦任务完成(`on_after_work`),这个函数被调用一次。`on_work` 是指 “work”(阻塞中的/耗时的操作)进行的地方。注意在这两个回调传递到 `uv_queue_work` 时的一个关键区别:`on_work` 运行在线程池中,而 `on_after_work` 运行在事件循环中的主线程上 —— 就好像是其它的回调一样。 让我们看一下这种方式的运行: @@ -347,25 +345,25 @@ on_timer [97578 ms] ... ``` -即便在 sleep 函数被调用时,定时器也每秒钟滴答一下,睡眠(sleeping)现在运行在一个单独的线程中,并且不会阻塞事件循环。 +即便在 sleep 函数被调用时,定时器也每秒钟滴答一下,睡眠现在运行在一个单独的线程中,并且不会阻塞事件循环。 ### 一个用于练习的素数测试服务器 -因为通过睡眼去模拟工作并不是件让人兴奋的事,我有一个事先准备好的更综合的一个示例 - 一个基于套接字接受来自客户端的数字的服务器,检查这个数字是否是素数,然后去返回一个 “prime" 或者 “composite”。完整的 [服务器代码在这里][15] - 我不在这里粘贴了,因为它太长了,更希望读者在一些自己的练习中去体会它。 +因为通过睡眠去模拟工作并不是件让人兴奋的事,我有一个事先准备好的更综合的一个示例 —— 一个基于套接字接受来自客户端的数字的服务器,检查这个数字是否是素数,然后去返回一个 “prime" 或者 “composite”。完整的 [服务器代码在这里][15] —— 我不在这里粘贴了,因为它太长了,更希望读者在一些自己的练习中去体会它。 这个服务器使用了一个原生的素数测试算法,因此,对于大的素数可能花很长时间才返回一个回答。在我的机器中,对于 2305843009213693951,它花了 ~5 秒钟去计算,但是,你的方法可能不同。 -练习 1:服务器有一个设置(通过一个名为 MODE 的环境变量)要么去在套接字回调(意味着在主线程上)中运行素数测试,要么在 libuv 工作队列中。当多个客户端同时连接时,使用这个设置来观察服务器的行为。当它计算一个大的任务时,在阻塞模式中,服务器将不回复其它客户端,而在非阻塞模式中,它会回复。 +练习 1:服务器有一个设置(通过一个名为 `MODE` 的环境变量)要么在套接字回调(意味着在主线程上)中运行素数测试,要么在 libuv 工作队列中。当多个客户端同时连接时,使用这个设置来观察服务器的行为。当它计算一个大的任务时,在阻塞模式中,服务器将不回复其它客户端,而在非阻塞模式中,它会回复。 -练习 2;libuv 有一个缺省大小的线程池,并且线程池的大小可以通过环境变量配置。你可以通过使用多个客户端去实验找出它的缺省值是多少?找到线程池缺省值后,使用不同的设置去看一下,在重负载下怎么去影响服务器的响应能力。 +练习 2:libuv 有一个缺省大小的线程池,并且线程池的大小可以通过环境变量配置。你可以通过使用多个客户端去实验找出它的缺省值是多少?找到线程池缺省值后,使用不同的设置去看一下,在重负载下怎么去影响服务器的响应能力。 ### 在非阻塞文件系统中使用工作队列 -对于仅傻傻的演示和 CPU 密集型的计算来说,将可能的阻塞操作委托给一个线程池并不是明智的;libuv 在它的文件系统 APIs 中本身就大量使用了这种性能。通过这种方式,libuv 使用一个异步 API,在一个轻便的方式中,显示出它强大的文件系统的处理能力。 +对于只是呆板的演示和 CPU 密集型的计算来说,将可能的阻塞操作委托给一个线程池并不是明智的;libuv 在它的文件系统 API 中本身就大量使用了这种能力。通过这种方式,libuv 使用一个异步 API,以一个轻便的方式显示出它强大的文件系统的处理能力。 -让我们使用 `uv_fs_read()`,例如,这个函数从一个文件中(以一个 `uv_fs_t` 句柄为代表)读取一个文件到一个缓冲中 [[3]][16],并且当读取完成后调用一个回调。换句话说,`uv_fs_read()` 总是立即返回,甚至如果文件在一个类似 NFS 的系统上,并且,数据到达缓冲区可能需要一些时间。换句话说,这个 API 与这种方式中其它的 libuv APIs 是异步的。这是怎么工作的呢? +让我们使用 `uv_fs_read()`,例如,这个函数从一个文件中(表示为一个 `uv_fs_t` 句柄)读取一个文件到一个缓冲中 ^注3,并且当读取完成后调用一个回调。换句话说,`uv_fs_read()` 总是立即返回,即使是文件在一个类似 NFS 的系统上,而数据到达缓冲区可能需要一些时间。换句话说,这个 API 与这种方式中其它的 libuv API 是异步的。这是怎么工作的呢? -在这一点上,我们看一下 libuv 的底层;内部实际上非常简单,并且它是一个很好的练习。作为一个便携的库,libuv 对于 Windows 和 Unix 系统在它的许多函数上有不同的实现。我们去看一下在 libuv 源树中的 src/unix/fs.c。 +在这一点上,我们看一下 libuv 的底层;内部实际上非常简单,并且它是一个很好的练习。作为一个可移植的库,libuv 对于 Windows 和 Unix 系统在它的许多函数上有不同的实现。我们去看一下在 libuv 源树中的 `src/unix/fs.c`。 这是 `uv_fs_read` 的代码: @@ -400,9 +398,9 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, } ``` -第一次看可能觉得很困难,因为它延缓真实的工作到 INIT 和 POST 宏中,在 POST 中与一些本地变量一起设置。这样做可以避免了文件中的许多重复代码。 +第一次看可能觉得很困难,因为它延缓真实的工作到 `INIT` 和 `POST` 宏中,以及为 `POST` 设置了一些本地变量。这样做可以避免了文件中的许多重复代码。 -这是 INIT 宏: +这是 `INIT` 宏: ``` #define INIT(subtype) \ @@ -421,9 +419,9 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, while (0) ``` -它设置了请求,并且更重要的是,设置 `req->fs_type` 域为真实的 FS 请求类型。因为 `uv_fs_read` 调用 invokes INIT(READ),它意味着 `req->fs_type` 被分配一个常数 `UV_FS_READ`。 +它设置了请求,并且更重要的是,设置 `req->fs_type` 域为真实的 FS 请求类型。因为 `uv_fs_read` 调用 `INIT(READ)`,它意味着 `req->fs_type` 被分配一个常数 `UV_FS_READ`。 -这是 POST 宏: +这是 `POST` 宏: ``` #define POST \ @@ -440,31 +438,25 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, while (0) ``` -它做什么取决于回调是否为 NULL。在 libuv 文件系统 APIs 中,一个 NULL 回调意味着我们真实地希望去执行一个 _同步_ 操作。在这种情况下,POST 直接调用 `uv__fs_work`(我们需要了解一下这个函数的功能),而对于一个 non-NULL 回调,它提交 `uv__fs_work` 作为一个工作事项到工作队列(指的是线程池),然后,注册 `uv__fs_done` 作为回调;该函数执行一些登记并调用用户提供的回调。 +它做什么取决于回调是否为 `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 APIs 去读取。这个函数可以在一个 _阻塞_ 方式中很安全地实现。因为,它通过异步 API 调用时被置于一个线程池中。 +如果我们去看 `uv__fs_work` 的代码,我们将看到它使用很多宏按照需求将工作分发到实际的文件系统调用。在我们的案例中,对于 `UV_FS_READ` 这个调用将被 `uv__fs_read` 生成,它(最终)使用普通的 POSIX API 去读取。这个函数可以在一个 _阻塞_ 方式中很安全地实现。因为,它通过异步 API 调用时被置于一个线程池中。 -在 Node.js 中,fs.readFile 函数是映射到 `uv_fs_read` 上。因此,可以在一个非阻塞模式中读取文件,甚至是当底层文件系统 API 是阻塞方式时。 +在 Node.js 中,`fs.readFile` 函数是映射到 `uv_fs_read` 上。因此,可以在一个非阻塞模式中读取文件,甚至是当底层文件系统 API 是阻塞方式时。 * * * - -[[1]][1] 为确保服务器不泄露内存,我在一个启用泄露检查的 Valgrind 中运行它。因为服务器经常是被设计为永久运行,这是一个挑战;为克服这个问题,我在服务器上添加了一个 “kill 开关” - 一个从客户端接收的特定序列,以使它可以停止事件循环并退出。这个代码在 `theon_wrote_buf` 句柄中。 - - -[[2]][2] 在这里我们不过多地使用 `work_req`;讨论的素数测试服务器接下来将展示怎么被用于去传递上下文信息到回调中。 - - -[[3]][3] `uv_fs_read()` 提供了一个类似于 preadv Linux 系统调用的通用 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] +作者:[Eli Bendersky][a] 译者:[qhwdw](https://github.com/qhwdw) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 diff --git a/published/201803/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md b/published/201803/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md new file mode 100644 index 0000000000..bd0959ea64 --- /dev/null +++ b/published/201803/20171110 How to configure login banners in Linux (RedHat, Ubuntu, CentOS, Fedora).md @@ -0,0 +1,94 @@ +如何在 Linux 中配置 ssh 登录导语 +====== + +> 了解如何在 Linux 中创建登录导语,来向要登录或登录后的用户显示不同的警告或消息。 + +![Login banners in Linux][1] + +无论何时登录公司的某些生产系统,你都会看到一些登录消息、警告或关于你将登录或已登录的服务器的信息,如下所示。这些是登录导语login banner。 + +![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] + +你可以在用户输入密码登录系统之前看到此消息。 + +### 如何在用户登录后显示消息 + +消息用户在成功登录系统后看到的当天消息Message Of The Day(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/ diff --git a/published/201803/20171115 How to create better documentation with a kanban board.md b/published/201803/20171115 How to create better documentation with a kanban board.md new file mode 100644 index 0000000000..fa92553ea2 --- /dev/null +++ b/published/201803/20171115 How to create better documentation with a kanban board.md @@ -0,0 +1,46 @@ +如何使用看板(kanban)创建更好的文档 +====== +> 通过卡片分类和看板来给用户提供他们想要的信息。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/open%20source_collaboration.png?itok=68kU6BHy) + +如果你正在处理文档、网站或其他面向用户的内容,那么了解用户希望找到的内容(包括他们想要的信息以及信息的组织和结构)很有帮助。毕竟,如果人们无法找到他们想要的东西,那么再出色的内容也没有用。 + +卡片分类是一种简单而有效的方式,可以从用户那里收集有关菜单界面和页面的内容。最简单的实现方式是在计划在网站或文档中的部分分类标注一些索引卡,并要求用户按照查找信息的方式对卡片进行分类。一个变体是让人们编写自己的菜单标题或内容元素。 + +我们的目标是了解用户的期望以及他们希望在哪里找到它,而不是自己弄清楚菜单和布局。当与用户处于相同的物理位置时,这是相对简单的,但当尝试从多个位置的人员获得反馈时,这会更具挑战性。 + +我发现[看板kanban][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/ diff --git a/published/201803/20171116 Record and Share Terminal Session with Showterm.md b/published/201803/20171116 Record and Share Terminal Session with Showterm.md new file mode 100644 index 0000000000..a82efb3744 --- /dev/null +++ b/published/201803/20171116 Record and Share Terminal Session with Showterm.md @@ -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 ` 删除任何已上传的视频。在上传视频之前,你可以通过在 `showterm` 命令中添加 `-e` 选项来改变计时。如果视频无法上传,你可以使用 `showterm --retry + + +``` + + +我也喜欢 Vue 提供的简短绑定语法,`:` 用于在模板中绑定数据变量,`@` 用于绑定事件。这是一个细节,但写起来很爽而且能够让你的组件代码简洁。 + +### 2、 单文件组件 + +大多数人使用 Vue,都使用“单文件组件”。本质上就是一个 .vue 文件对应一个组件,其中包含三部分(CSS、HTML和JavaScript)。 + +这种技术结合是对的。它让人很容易在一个单独的地方了解每个组件,同时也非常好的鼓励了大家保持每个组件代码的简短。如果你的组件中 JavaScript、CSS 和 HTML 代码占了很多行,那么就到了进一步模块化的时刻了。 + +在使用 Vue 组件中的 ` -``` - - -I also like the short-bindings provided by Vue, ‘:’ for binding data variables into your template and ‘@’ for binding to events. It’s a small thing, but it feels nice to type and keeps your components succinct. - -2\. Single File Components - -When most people write Vue, they do so using ‘single file components’. Essentially it is a file with the suffix .vue containing up to 3 parts (the css, html and javascript) for each component. - -This coupling of technologies feels right. It makes it easy to understand each component in a single place. It also has the nice side effect of encouraging you to keep your code short for each component. If the JavaScript, CSS and HTML for your component is taking up too many lines then it might be time to modularise further. - -When it comes to the