├── .gitignore ├── img ├── 0-1.png ├── 0-2.png ├── 0-3.png ├── 0-4.png ├── 0-5.png ├── 0-6.png ├── 0-7.png ├── 12-1.png ├── 8-1.png ├── intro-1.png └── qr_alipay.png ├── README.md ├── next.md ├── ex13.md ├── SUMMARY.md ├── ex10.md ├── ex0.md ├── ex2.md ├── ex11.md ├── intro.md ├── ex21.md ├── ex5.md ├── ex9.md ├── ex1.md ├── ex12.md ├── ex3.md ├── ex7.md ├── ex4.md ├── ex29.md ├── ex30.md ├── ex6.md ├── ex25.md ├── styles └── ebook.css ├── ex17.md ├── ex8.md ├── ex23.md ├── ex14.md ├── ex19.md ├── ex22.md ├── ex15.md ├── ex16.md ├── mdi.md ├── ex18.md ├── ex20.md └── ex28.md /.gitignore: -------------------------------------------------------------------------------- 1 | _book 2 | Thumbs.db 3 | -------------------------------------------------------------------------------- /img/0-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/0-1.png -------------------------------------------------------------------------------- /img/0-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/0-2.png -------------------------------------------------------------------------------- /img/0-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/0-3.png -------------------------------------------------------------------------------- /img/0-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/0-4.png -------------------------------------------------------------------------------- /img/0-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/0-5.png -------------------------------------------------------------------------------- /img/0-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/0-6.png -------------------------------------------------------------------------------- /img/0-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/0-7.png -------------------------------------------------------------------------------- /img/12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/12-1.png -------------------------------------------------------------------------------- /img/8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/8-1.png -------------------------------------------------------------------------------- /img/intro-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/intro-1.png -------------------------------------------------------------------------------- /img/qr_alipay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardforcel/llthw-zh/HEAD/img/qr_alipay.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 笨办法学 Linux 中文版 2 | 3 | 原书:[Learn Linux The Hard Way (β version)](https://archive.fo/xDb8o) 4 | 5 | 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | 自豪地采用[谷歌翻译](https://translate.google.cn/) 8 | 9 | + [在线阅读](https://www.gitbook.com/book/wizardforcel/llthw/details) 10 | + [PDF格式](https://www.gitbook.com/download/pdf/book/wizardforcel/llthw) 11 | + [EPUB格式](https://www.gitbook.com/download/epub/book/wizardforcel/llthw) 12 | + [MOBI格式](https://www.gitbook.com/download/mobi/book/wizardforcel/llthw) 13 | + [代码仓库](http://github.com/wizardforcel/llthw-zh) 14 | 15 | ## 赞助我 16 | 17 | ![](img/qr_alipay.png) 18 | 19 | ## 协议 20 | 21 | [CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 22 | -------------------------------------------------------------------------------- /next.md: -------------------------------------------------------------------------------- 1 | # 下一步做什么 2 | 3 | > 原文:[What to do next](https://archive.fo/qkILJ) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 恭喜你到达了这里,但你的旅程才刚刚开始。请参阅下面的资源,来了解之后要做什么。 12 | 13 | + 每天阅读一个手册页。使其成为习惯。每天阅读一个随机的手册页。我的笔记本上现在有大约 6000 个手册页,所以可以看很多年。 14 | + 从零开始构建你自己的 Linux 发行版:。你可能希望将我的 Debian 装置用于此任务和其他任务。 15 | + 自己学一些正则表达式: 16 | + 自己学一些 bash 脚本: 17 | + 看书。例如,这本不错:[《Unix 和 Linux管理手册》](http://www.admin.com/)。另请阅读[《Unix 厌恶者手册》](http://en.wikipedia.org/wiki/The_UNIX-HATERS_Handbook,并写出你认为仍然有效的那些观点。现在意识到,所有的操作系​​统都是糟糕的,只是有些比其它更糟糕。 18 | + 去找一个提供 VPS(虚拟专用服务器或虚拟机)的托管服务器。安装像 Apache 这样的东西和你自己的 wiki。在线记录你的发现。 19 | + 请访问 ,看看 Microsoft 技术可以做什么。 20 | + 在你的 VPS 上按照 设置一切。只需设置,检查它是否正常工作并将其删除。或不要删除。无论如何,它将为你提供服务器管理所需的经验。 21 | 22 | 我会在某一天把它做得更好,但是由于这个资源列表,你应该已经很忙了。祝你好运。 23 | -------------------------------------------------------------------------------- /ex13.md: -------------------------------------------------------------------------------- 1 | # 练习 13:文档:Google 2 | 3 | > 原文:[Exercise 13. Documentation: Google](https://archive.fo/8kvYG) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | ## 文档搜索简介 12 | 13 | 现在你知道了如何使用 Linux 在线文档,我会告诉你:“Linux 在线文档是好的,但它还不够。”这意味着如果你已经熟悉了某个特定程序的工作原理,那么手册页很有用,但是当你没有时它们就没有帮助。 14 | 15 | 为了让自己起步,你需要阅读一本书,或者找到一个允许你开始的小秘籍,这被称为“如何做”。例如,要开始使用 Apache Web 服务器,你可能需要使用“如何使用 Apache”。没关系,这就是谷歌的意义,但现在我会给你一个大警告: 16 | 17 | > 不要盲目遵循任何“如何做”,永远不要! 18 | 19 | 使用 Google 的正确方法是: 20 | 21 | + 找到一个“如何做”。 22 | + 遵循它,但阅读,或至少浏览所有手册页,来了解你不了解的程序。另外,请阅读“如何做”中所有未知选项。这是非常重要的。 23 | 24 | ## 实用资源的列表 25 | 26 | 有时最好是搜索特定网站,而不是盲目地将内容输入 Google。这是有用资源的列表: 27 | 28 | + 是非常有价值的,当你获取某些主题的初始信息的时候。其链接部分更是无价之宝。 29 | + 这是非常有用的网站,用于查找使用示例和用例的信息。StackExchange 网络包括几个资源,其中最有用的是 。 当你编写 bash 脚本时, 是一个非常有用的资源。 30 | + 包含许多有用的“如何做”和例子。 31 | + 许多程序的主页提供了良好的,有时是优秀的文档。例如 Apache 和 ngnix,分别为:。 32 | + 是 Linux 文档项目,包含许多不同主题的深入指南。 33 | 34 | ## 搜索小提示 35 | 36 | Google 有一种查询语言,可以让你执行强大的查询。这是这种语言的主要命令: 37 | 38 | + `(screen|tmux) how to` - 同时搜索`screen`和`tmux`的“如何做”。记得 shell 参数的扩展嘛?这是相似的。 39 | + `site:serverfault.com query` - 仅在这个网站上搜索。你可以使用`(site:serverfault.com | site:stackexchange.com)`,一次性搜索多个站点。 40 | + `"..."` - 仅显示包含此查询的那些页面。 41 | + `-query` - 从搜索结果中排除某些内容。 42 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | + [笨办法学 Linux 中文版](README.md) 2 | + [练习 0:起步](ex0.md) 3 | + [练习 1:文本编辑器,vim](ex1.md) 4 | + [练习 2:文本浏览器,少即是多](ex2.md) 5 | + [练习 3:Bash:Shell、`.profile`、`.bashrc`、`.bash_history`](ex3.md) 6 | + [练习 4:Bash:处理文件,`pwd`,`ls`,`cp`,`mv`,`rm`,`touch`](ex4.md) 7 | + [练习 5:Bash:环境变量,`env`,`set`,`export`](ex5.md) 8 | + [练习 6:Bash:语言设置,`LANG`,`locale`,`dpkg-reconfigure locales`](ex6.md) 9 | + [练习 7:Bash:重定向,`stdin`,`stdout`,`stderr`,`<`,`>`,`>>`,`|`,`tee`,`pv`](ex7.md) 10 | + [练习 8:更多的重定向和过滤:`head`,`tail`,`awk`,`grep`,`sed`](ex8.md) 11 | + [练习 9:Bash:任务控制,`jobs`,`fg`](ex9.md) 12 | + [练习 10:Bash:程序退出代码(返回状态)](ex10.md) 13 | + [练习 11:总结](ex11.md) 14 | + [练习 12:文档:`man`,`info`](ex12.md) 15 | + [练习 13:文档:Google](ex13.md) 16 | + [练习 14:包管理:Debian 包管理工具`aptitude`](ex14.md) 17 | + [练习 15:系统启动:运行级别,`/etc/init.d`,`rcconf`,`update-rc.d`](ex15.md) 18 | + [练习 16:处理进程,`ps`,`kill`](ex16.md) 19 | + [练习 17:任务调度:`cron`,`at`](ex17.md) 20 | + [练习 18:日志:`/var/log`,`rsyslog`,`logger`](ex18.md) 21 | + [练习 19:文件系统:挂载,`mount`,`/etc/fstab`](ex19.md) 22 | + [练习 20:文件系统:修改和创建文件系统,`tune2fs`,`mkfs`](ex20.md) 23 | + [练习 21:文件系统:修改根目录,`chroot`](ex21.md) 24 | + [练习 22:文件系统:移动数据,`tar`,`dd`](ex22.md) 25 | + [练习 23:文件系统:权限,`chown`,`chmod`,`umask`](ex23.md) 26 | + [练习 24:接口配置,`ifconfig`,`netstat`,`iproute2`,`ss`,`route`](ex24.md) 27 | + [练习 25:网络:配置文件,`/etc/network/interfaces`](ex25.md) 28 | + [练习 26:网络:封包过滤配置,`iptables`](ex26.md) 29 | + [练习 27:安全 Shell,`ssh`,`sshd`,`scp`](ex27.md) 30 | + [练习 28:性能:获取性能情况,`uptime`,`free`,`top` 31 | ](ex28.md) 32 | + [练习 29:内核:内核消息,`dmesg`](ex29.md) 33 | + [练习 30:打磨、洗练、重复:总复习](ex30.md) 34 | + [下一步做什么](next.md) 35 | + [Debian 手动安装](dmi.md) 36 | -------------------------------------------------------------------------------- /ex10.md: -------------------------------------------------------------------------------- 1 | # 练习 10:Bash:程序退出代码(返回状态) 2 | 3 | > 原文:[Exercise 10. Bash: program exit code (return status)](https://archive.fo/ygzso) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 让我们假设你要复制一个目录。你可以通过键入`cp -vR /old/dir/path /new/dir/path`来执行此操作。发出此命令后,你可能想知道如何进行。目录是否被复制?还是出现了一些错误,因为目标目录空间不足,或其他出现错误的东西? 12 | 13 | 为了理解它是如何工作的,你必须了解两个程序如何通信。我们先这样说,bash 只是另一个程序,所以一般来说,当你发出上述的`cp`命令时,一个程序(bash,它是父进程)调用了另一个程序(`cp`,它是子进程)。 14 | 15 | 在 Linux 中,有一个标准机制,用于获取从子进程到父进程的信息,这个机制称为[退出状态或返回代码](http://en.wikipedia.org/wiki/Exit_status)。通过使用这种机制,当子进程完成其工作时,一个小的数字从子进程(或被调用者,这里是`cp`)传递给父进程(或调用者,这里是 bash)。当程序在执行期间没遇到错误时,它返回`0`,如果发生某些错误,则此代码不为零。就是这么简单。Bash 中的这个退出代码保存到`?`环境变量,你现在知道了,可以使用`$?`来访问。 16 | 17 | 让我再次重复一下我现在所说的话: 18 | 19 | ``` 20 | Bash 等待你的输入 21 | Bash 解析你的输入 22 | Bash 为你启动程序,并等待这个程序退出 23 | 程序启动 24 | 程序做你让他做的事情 25 | 程序生成了退出代码 26 | 程序退出并且将退出代码返回给 Bash 27 | Bash 将这个退出代码赋给变量 ? 28 | ``` 29 | 30 | 现在你学到了如何打印出你的程序的退出状态。 31 | 32 | ## 这样做 33 | 34 | ``` 35 | 1: ls 36 | 2: echo $? 37 | 3: ls /no/such/dir 38 | 4: echo $? 39 | ``` 40 | 41 | ## 你会看到什么 42 | 43 | ``` 44 | user1@vm1:~$ ls 45 | hello.txt ls.out 46 | user1@vm1:~$ echo $? 47 | 0 48 | user1@vm1:~$ ls /no/such/dir 49 | ls: cannot access /no/such/dir: No such file or directory 50 | user1@vm1:~$ echo $? 51 | 2 52 | user1@vm1:~$ 53 | ``` 54 | 55 | ## 解释 56 | 57 | + 打印出一个目录,成功。 58 | + 打印出`ls`的退出代码,它是`0`,这意味着`ls`没有遇到任何错误。 59 | + 尝试打印出不存在的目录,当然失败。 60 | + 打印`ls /no/such/dir`的退出代码,它确实是非零。 61 | 62 | ## 附加题 63 | 64 | 阅读`man ls`的退出代码部分。 65 | -------------------------------------------------------------------------------- /ex0.md: -------------------------------------------------------------------------------- 1 | # 练习 0:起步 2 | 3 | > 原文:[Exercise 0. The Setup](https://archive.fo/ZfhWN) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | ## Windows,手动安装 12 | 13 | [非常长的指南](https://archive.fo/p1ZHn) 14 | 15 | ## Windows,VirtualBox 虚拟机(`.ova`格式的预配置映像) 16 | 17 | ### 你需要什么 18 | 19 | + VitualBox,虚拟机播放器。 20 | + putty,终端模拟器。 21 | + 预配置的 VirtualBox Debian 映像。 22 | 23 | ## 这样做 24 | 25 | + 下载并安装 [VirtualBox](http://download.virtualbox.org/virtualbox/4.1.18/VirtualBox-4.1.18-78361-Win.exe) 26 | 27 | + 下载并安装 [Putty](http://the.earth.li/~sgtatham/putty/latest/x86/putty-0.62-installer.exe)。 28 | 29 | + 下载此文件: 30 | 31 | 另一个链接: 32 | 33 | 或另一个链接: 34 | 35 | ``` 36 | md5: 7ac8a6059460f7f3e39aee7c4ee2c230 37 | sha256: 18d8f31d0894c89865d5306b0cb3284d8889e15d155c7435fc7888f3dbafa3ec 38 | ``` 39 | 40 | + 打开文件 41 | 42 | ![](img/0-1.png) 43 | 44 | + 点击`Import` 45 | 46 | ![](img/0-2.png) 47 | 48 | + 选择`vm1`并点击`Start` 49 | 50 | ![](img/0-3.png) 51 | 52 | + 等待`vm1`启动 53 | 54 | ![](img/0-4.png) 55 | 56 | + 启动`putty`,在`Host Name`或者`IP Address`中输入`localhost`。之后点击`Open` 57 | 58 | ![](img/0-5.png) 59 | 60 | + 输入`user1`, ``, `123qwe`, ``。 61 | 62 | ![](img/0-6.png) 63 | 64 | + 恭喜,你现在登入了`vm1`。 65 | 66 | ![](img/0-7.png) 67 | 68 | ## Linux 69 | 70 | 你已经使用 Linux 了,你还需要什么嘛?开个玩笑。你可以严格遵循我的指南,或者随意在你的系统上做实验。 71 | 72 | ## Mac OS 73 | 74 | 以后我会在这里把步骤补上。 75 | 76 | -------------------------------------------------------------------------------- /ex2.md: -------------------------------------------------------------------------------- 1 | # 练习 2:文本浏览器,少即是多 2 | 3 | > 原文:[Exercise 2. Text Viewer, The: less is More](https://archive.fo/nFH4J) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 现在你可以编辑文本文件,这很好。但是如果你只想查看一个文本文件呢?当然,你可以使用 vim,但很多时候它是过度的。还有两件事要考虑: 12 | 13 | + 如果你想查看非常大的文件,你将需要在尽可能快的程序中查看它。 14 | + 通常你不想意外地改变文件中的某些东西。 15 | 16 | 所以,我向你介绍强大的`less`,少即是多。“比什么多呢?”你可能会问。嗯...有一次,有一个被称为`more`的浏览器。它很简单,只是向你显示你要求它显示的文本文件。它是如此简单,只能以一个方向显示文本文件,也就是向前。 马克·恩德尔曼(Mark Nudelman)发现它并不那么令人满意 ,1983 年至 1985 年,他编写了`less`。从那以后,它拥有了许多先进的功能。因为它比`more`更先进,一句话就诞生了:“少即是多,多即是少”。 17 | 18 | 好吧,让我们试试吧。 19 | 20 | 输入: 21 | 22 | ``` 23 | less .bashrc 24 | ``` 25 | 26 | 你应该看到: 27 | 28 | ``` 29 | user1@vm1:~$ less .bashrc 30 | # ~/.bashrc: executed by bash(1) for non-login shells. 31 | # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) 32 | # for examples 33 | 34 | # If not running interactively, don't do anything 35 | [ -z "$PS1" ] && return 36 | 37 | # don't put duplicate lines in the history. See bash(1) for more options 38 | # don't overwrite GNU Midnight Commander's setting of `ignorespace'. 39 | HISTCONTROL=$HISTCONTROL${HISTCONTROL+:}ignoredups 40 | .bashrc 41 | ``` 42 | 43 | 如果你的终端不是足够宽,文本将看起来像一团糟,因为它放不下整行。要修复它,请键入`- -ch`。是的,`dash-dash-ch-ENTER-ENTER`。这将开启水平滚动。 44 | 45 | 为了向上向下文浏览文字,使用已经熟悉的`j`和`k`。退出按`q`。 46 | 47 | 现在我将向你展示`less`的高级功能,这样你只能看到所需的那些行。键入`&enable`。你应该看到这个: 48 | 49 | ``` 50 | # enable color support of ls and also add hand 51 | # enable programmable completion features (you 52 | # this, if it's already enabled in /etc/bash.b 53 | ~ 54 | ~ 55 | ~ 56 | ~ 57 | ~ 58 | ~ 59 | ~ 60 | ~ 61 | ~ 62 | ~ 63 | ~ 64 | ~ 65 | & (END) 66 | ``` 67 | 68 | 注意看!为了移除过滤器,只需键入`&`。同样,要记住的命令: 69 | 70 | + `j` - 向上移动 71 | + `k` - 向下移动 72 | + `q` - 退出`less`。 73 | + `- -chop-long-lines或`- -ch` - 开启水平滚动。 74 | + `/` - 搜索。 75 | + `&something` - 只显示文件中包含某些内容的行。 76 | 77 | ## 附加题 78 | 79 | + Linux 具有在线手册,通过键入`man`来调用。默认情况下,在我们的系统中,本手册将使用`less`来查看。 键入`man man`并阅读,然后退出。 80 | + 就是这样,没有更多的附加题了。 81 | -------------------------------------------------------------------------------- /ex11.md: -------------------------------------------------------------------------------- 1 | # 练习 11:总结 2 | 3 | > 原文:[Exercise 11. Bash: wrapping up](https://archive.fo/PfSHQ) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 现在你已经尝试过,如何在 Linux 中使用 CLI 的感觉,下一步是打开你喜欢的文本编辑器,并为自己制作下表。搜索那些你不知道的命令和符号的意思。警告!为了有效,你必须手动输入此表。搜索这些新的术语和命令。 12 | 13 | 现在你将学习如何研究某些东西。并记住,不要复制粘贴! 14 | 15 | ## 术语 16 | 17 | | 术语 | 含义 | 18 | | --- | --- | 19 | | vim 正常模式 | | 20 | | vim 命令模式 | | 21 | | CLI | | 22 | | SHell | | 23 | | 配置 | | 24 | | 文件 | | 25 | | 文件描述符 | | 26 | | 进程 | | 27 | | 程序 | | 28 | | 环境 | | 29 | | 环境变量 | | 30 | | 重定向 | | 31 | | 管道 | | 32 | | 文本流 | | 33 | | 标准输入 | | 34 | | 标准输出 | | 35 | | 标准错误 | | 36 | | EOF | | 37 | | 过滤 | | 38 | | 任务 | | 39 | | 前台任务 | | 40 | | 后台任务 | | 41 | | 退出代码 | | 42 | 43 | ## `vim` 44 | 45 | | 命令 | 含义 | 46 | | --- | --- | 47 | | `vim` | | 48 | | `h` | | 49 | | `j` | | 50 | | `k` | | 51 | | `l` | | 52 | | `i` | | 53 | | `o` | | 54 | | `` | | 55 | | `x` | | 56 | | `dd` | | 57 | | `:wq` | | 58 | | `:q!` | | 59 | | `/` | | 60 | 61 | ## `less` 62 | 63 | | 命令 | 含义 | 64 | | --- | --- | 65 | | `less` | | 66 | | `j` | | 67 | | `k` | | 68 | | `q` | | 69 | | `--ch` | | 70 | | `/` | | 71 | | `&` | | 72 | 73 | ## Bash 和 Bash 内建命令 74 | 75 | | 命令 | 含义 | 76 | | --- | --- | 77 | | `echo` | | 78 | | `history` | | 79 | | `exit` | | 80 | | `pwd` | | 81 | | `=` | | 82 | | `$` | | 83 | | `?` | | 84 | | `set` | | 85 | | `env` | | 86 | | `export` | | 87 | | `$LANG` | | 88 | | `read` | | 89 | | `+z` | | 90 | | `+c` | | 91 | | `jobs` | | 92 | | `fg` | | 93 | 94 | ## 重定向 95 | 96 | | 命令 | 含义 | 97 | | --- | --- | 98 | | `>` | | 99 | | `<` | | 100 | | `>>` | | 101 | | `|` | | 102 | | `/dev/stdin` | | 103 | | `/dev/stdout` | | 104 | | `/dev/stderr` | | 105 | 106 | ## 其它你学到的程序 107 | 108 | | 命令 | 含义 | 109 | | --- | --- | 110 | | `man` | | 111 | | `ls` | | 112 | | `cat` | | 113 | | `dpkg-reconfigure` | | 114 | | `head` | | 115 | | `tail` | | 116 | | `grep` | | 117 | | `awk` | | 118 | | `sed` | | 119 | | `tee` | | 120 | | `dd` | | 121 | | `pv` | | 122 | | `locale` | | 123 | | `sudo` | | 124 | | `cp` | | 125 | | `mv` | | 126 | | `rm` | | 127 | | `touch` | | 128 | | `wc` | | 129 | 130 | 填写表格后,在后面为每个命令编写注解,然后重复一次,然后再睡一个礼拜。是的,我的意思是,从那些笔和纸上抖掉灰尘,然后这样做。 131 | 132 | ## 附加题 133 | 134 | 没有附加题。只需学习这些命令,直到你熟记于心。 135 | -------------------------------------------------------------------------------- /intro.md: -------------------------------------------------------------------------------- 1 | # 引言 2 | 3 | > 原文:[Introduction](https://archive.fo/xDb8o) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 深入兔子洞吧,这就是 Linux: 12 | 13 | 14 | 15 | 向它说声“你好”,点击链接并且键入`hello`,之后按下``。 16 | 17 | ## 简介 18 | 19 | 这是一个简单的指南,以“笨办法学 X”的风格编写,但作者不是 [Zed A. Shaw](https://learncodethehardway.org/)。它的目的是给你一些使用类 Unix 系统的经验。有许多很好的类似 UNIX 系统,例如 FreeBSD,OpenBSD,OpenSolaris 甚至 MAC OS X,仅举几例。我在本指南中决定使用哪个系统时,我选择了 Linux,主要是因为它是最受欢迎的类 UNIX 服务器操作系统,这意味着与其他 UNIX 衍生产品相比,在外面遇到的机会更大。而且 Linux 相关的技能更容易迁移到其他类 UNIX 系统。 20 | 21 | 现在我想告诉你一些细节。你将遇到许多详细的表格,包含许多字段的列表。你可能认为你不需要大部分的信息,但是我想在这里做的就是,教你正确的方法,来处理所有这些可怕的数据。这种正确的方法是将这些数据解释为数学公式,其中每个符号都有其含义。 22 | 23 | 如果你已经有了 Linux 的经验,你可能会知道很多命令,但是你知道这些命令输出的每一个字段嘛?我们以`ls`为例,只列出当前目录中的所有文件。 24 | 25 | ``` 26 | user1@vm1:~$ ls -al 27 | total 32 28 | drwxr-xr-x 2 user1 user1 4096 Jul 20 08:33 . 29 | drwxr-xr-x 4 root root 4096 Jul 2 06:19 .. 30 | -rw------- 1 user1 user1 4092 Jul 20 11:02 .bash_history 31 | -rw-r--r-- 1 user1 user1 220 Jul 2 06:19 .bash_logout 32 | -rw-r--r-- 1 user1 user1 3184 Jul 2 06:19 .bashrc 33 | -rw------- 1 user1 user1 295 Jul 2 11:34 .lesshst 34 | -rw-r--r-- 1 user1 user1 675 Jul 2 06:19 .profile 35 | -rw------- 1 user1 user1 1222 Jul 20 08:33 .viminfo 36 | ``` 37 | 38 | 你知道这里每个东西的意思吗?最顶上的`total`,`drwxr-xr-x`中的`d`,第二列中的数字,第三列中的数字,日期的含义,这些点`.`和`..`的含义,以及它们储存在哪里? 39 | 40 | 或者你只是耸耸肩,认为一些事情是 OK 的,这是文件的列表,这就是我现在需要的所有东西,这些额外字段不重要嘛?我想我知道,这个日期只是修改日期,`.`和`..`只是当前目录和上级目录的同义词。但是我不需要其它数据,我的大脑已经塞满了。 如果你想做的只是上网冲浪,这个方法没问题,但是如果你想了解 你的系统,这个方法是不行的。最重要的是,UNIX 是非常合乎逻辑的,通过让你了解有什么数据,你还将了解系统如何工作,所有关于程序运行,存储和数据访问以及互联网链接的细节。 41 | 42 | 底线是,精通你的领域。注意细节。了解屏幕上的每一个数据都有其意义,并且出于某种原因,被称为字段 ,不要忽视某些东西,因为发现它所做的事情是很难的。但不要走向另一个极端,那么你就变得痴迷于所有这些细节,就无法看到大局。如果一些东西现在没有任何意义,并且你已经花了大量的时间来研究它,有时最好把它写下来,再回到这个地方,或者问一个知道它的人,但是首先自己试着去了解它的功能。也许,如果你现在还在学习一些东西,你会明白,困难的部分也会变得容易很多。 43 | 44 | 为了总结我的观点,关于细节的关注和精通你的领域,我将在这里插入一张图片: 45 | 46 | > 精通你的领域,不要 · 像 · 这样: 47 | 48 | ![](img/intro-1.png) 49 | 50 | © [Nedroid](http://nedroid.com/2012/05/honk-the-databus/) 51 | 52 | 和这个指南的目的有一些关系。这是成败完全靠自己的东西,其主要目的是熟悉 Linux 环境和大量的概念和命令。其实不仅仅是熟悉,而是要记住!是的,你需要记住这些东西。是的,这意味着你必须记住一些东西,以便之后能够从自己的记忆中回忆它。是的,这很难。是的,你需要为自己制作记忆卡片,一面是术语,另一面是解释,来完成它。是的,你需要自己制作这些卡片(只在它们上面写东西,不要试图制作纸张)。是的,在这里,它会为你带来回报,灯光会打在你的头上,就像呯!我现在明白了! 53 | 54 | 最后,如果你不明白什么东西,马上问问题。每个练习的底部都有一个注解部分。或者你可以给我写信,`sistemshik at yahoo.com`。 55 | 56 | ## 读者 57 | 58 | + 对类 UNIX 系统感兴趣的系统管理员。 59 | + 程序员,因为一个好的程序员应该认识到,现在要管理他正在为其编程的系统。 60 | + 想要尝试新东西并了解这种“[UNIX 方式](http://en.wikipedia.org/wiki/Unix_philosophy)”的人们。 61 | 62 | ## 预备条件 63 | 64 | + 建议熟悉命令行界面。你可以通过完成 Zed A. Shaw 的[命令行速成课](http://cli.learncodethehardway.org/book/)来熟悉它。 65 | + 操作系统的基本知识通常是一个附加项。 66 | + 网络的基本知识是一个附加项。 67 | 68 | ## 如何阅读这个指南 69 | 70 | + 阅读每个练习的介绍。你可以跳过困难的部分,稍后回来。 71 | + 正确输入所显示内容。不允许复制粘贴。 72 | + 将你的输出与“你应该看到的”部分进行比较。 73 | + 阅读解释。 74 | + 做附加题。在这里,你可以跳过困难的部分,稍后再回来。 75 | + 阅读你输入的命令的手册。阅读描述就足够了 76 | + 不要赶时间!如果你尝试一次性完成这个指南,那么你将不会有任何好处。一天的锻炼是一个非常合理的进度。 77 | 78 | ## 为了完成这个练习,你需要下面的配置 79 | 80 | + 带有互联网连接的计算机 81 | + 一点空闲时间 82 | + 耐心 83 | -------------------------------------------------------------------------------- /ex21.md: -------------------------------------------------------------------------------- 1 | # 练习 21:文件系统:修改根目录,`chroot` 2 | 3 | > 原文:[Exercise 21. Filesystems: changing root directory, chroot](https://archive.fo/h9FWU) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 让我从另一个[维基百科](http://en.wikipedia.org/wiki/Chroot)的引用开始: 12 | 13 | > Unix 操作系统上的`chroot`是一个操作,可以为当前正在运行的进程及其进程修改根目录。在这种修改后的环境中运行的程序,不能指定(也就是访问)这个特定目录树之外的文件。术语`chroot`可以指`chroot(2)`系统调用或`chroot(8)`包装程序。修改后的环境称为`chroot`监牢。 14 | 15 | 这意味着你可以创建一个目录(例如`/opt/root`),将必要的程序复制到那里并执行此程序。对于这样的程序,`/opt/root/`就是根目录`/`。要了解为什么你需要这样,请阅读维基百科[`chroot`](http://en.wikipedia.org/wiki/Chroot%23Uses)文章。 16 | 17 | 这是练习的时候了。你现在将使用 bash 创建一个最小的`chroot`环境。为此,你将创建一个目录结构,并将 bash 及其依赖项复制到其中。 18 | 19 | 现在,你将学习如何创建一个`chroot`环境并进入它。 20 | 21 | ## 这样做 22 | 23 | ``` 24 | 1: sudo -s 25 | 2: ldd /bin/bash 26 | 3: mkdir -vp /opt/root/bin 27 | 4: mkdir -v /opt/root/lib 28 | 5: mkdir -v /opt/root/lib64 29 | 6: cp -v /bin/bash /opt/root/bin/ 30 | 7: cp -v /lib/libncurses.so.5 /opt/root/lib/ 31 | 8: cp -v /lib/libdl.so.2 /opt/root/lib 32 | 9: cp -v /lib/libc.so.6 /opt/root/lib 33 | 10: cp -v /lib64/ld-linux-x86-64.so.2 /opt/root/lib64 34 | 11: chroot /opt/root/ 35 | ``` 36 | 37 | 哇哦,你为你自己创建了一个 Linux,某种程度上是这样。 38 | 39 | ## 你会看到什么 40 | 41 | ``` 42 | user1@vm1:/opt~ sudo -s 43 | root@vm1:/opt# ldd /bin/bash 44 | linux-vdso.so.1 => (0x00007fff17bff000) 45 | libncurses.so.5 => /lib/libncurses.so.5 (0x00007f4b1edc6000) 46 | libdl.so.2 => /lib/libdl.so.2 (0x00007f4b1ebc2000) 47 | libc.so.6 => /lib/libc.so.6 (0x00007f4b1e85f000) 48 | /lib64/ld-linux-x86-64.so.2 (0x00007f4b1f012000) 49 | root@vm1:/opt# mkdir -vp /opt/root/bin 50 | mkdir: created directory `/opt/root' 51 | mkdir: created directory `/opt/root/bin' 52 | root@vm1:/opt# mkdir -v /opt/root/lib 53 | mkdir: created directory `/opt/root/lib' 54 | root@vm1:/opt# mkdir -v /opt/root/lib64 55 | mkdir: created directory `/opt/root/lib64' 56 | root@vm1:/opt# cp -v /bin/bash /opt/root/bin/ 57 | `/bin/bash' -> `/opt/root/bin/bash' 58 | root@vm1:/opt# cp -v /lib/libncurses.so.5 /opt/root/lib/ 59 | `/lib/libncurses.so.5' -> `/opt/root/lib/libncurses.so.5' 60 | root@vm1:/opt# cp -v /lib/libdl.so.2 /opt/root/lib 61 | `/lib/libdl.so.2' -> `/opt/root/lib/libdl.so.2' 62 | root@vm1:/opt# cp -v /lib/libc.so.6 /opt/root/lib 63 | `/lib/libc.so.6' -> `/opt/root/lib/libc.so.6' 64 | root@vm1:/opt# cp -v /lib64/ld-linux-x86-64.so.2 /opt/root/lib64 65 | `/lib64/ld-linux-x86-64.so.2' -> `/opt/root/lib64/ld-linux-x86-64.so.2' 66 | root@vm1:/opt# chroot /opt/root/ 67 | ``` 68 | 69 | ## 解释 70 | 71 | 1. 作为超级用户(root)执行 bash。 72 | 1. 打印出 bash 需要的的库。 73 | 1. 在一个命令中创建`/opt/root/`和`/opt/root/bin/`目录。很帅吧? 74 | 1. 创建`/opt/root/lib`目录。 75 | 1. 创建`/opt/root/lib64`目录。 76 | 1. 将`/bin/bash`复制到`/opt/root/bin/`。 77 | 1. 将`/lib/libncurses.so.5`复制到`/opt/root/lib/`。 78 | 1. 将`/lib/libdl.so.2`复制到`/opt/root/lib/`。 79 | 1. 将`/lib/libc.so.6`复制到`/opt/root/lib/`。 80 | 1. 将`/lib64/ld-linux-x86-64.so.2`复制到`/opt/root/lib64/`。 81 | 1. 将根目录更改为`/opt/root/`。 82 | 83 | ## 附加题 84 | 85 | + 阅读`man chroot`,`man ldd`。 86 | + 将`ls`命令复制到你的`chroot`并使其正常工作。 87 | + 一个难题:将`vim`复制到你的`chroot`并使其正常工作。 88 | -------------------------------------------------------------------------------- /ex5.md: -------------------------------------------------------------------------------- 1 | # 练习 5:Bash:环境变量,`env`,`set`,`export` 2 | 3 | > 原文:[Exercise 5. Bash: environment variables, env, set, export](https://archive.fo/M8Ndm) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 请考虑以下内容:你希望程序打印出你的用户名。这个程序怎么知道的?在 Linux 中有一些环境变量。这意味着你的 shell 中有许多变量,其中许多变量自动设置,每次运行程序时,其中一些变量将传递给该程序。 12 | 13 | 详细说明: 14 | 15 | + 一些变量只为你当前的 shell 设置。它们被称为本地 shell 变量。你可以通过键入`set`,一个 bash 内置命令来列出它们 ,这意味着没有启动其它程序,之后你执行了它。此命令由 bash 本身处理。 16 | 17 | + 其他变量被传递到你从当前 shell 启动的每个程序。它们被称为环境变量,可以通过`env`程序列出,这意味着,通过键入`env`, 你将看到,你启动的每个程序获得了什么变量。 18 | 19 | 你可能想要深入挖掘。要做到这一点,掌握 [subshell](http://en.wikipedia.org/wiki/Child_process) 的概念,这是一个子进程,当你运行程序时创建,并且成为你的程序。 20 | 21 | 现在,你将学习如何创建变量以及如何使用变量。 22 | 23 | ## 这样做 24 | 25 | ``` 26 | 1: foo='Hello World!' 27 | 2: echo $foo 28 | 3: set | grep foo 29 | 4: env | grep foo 30 | 5: export foo 31 | 6: env | grep foo 32 | 7: foo='ls -al' 33 | 8: $foo 34 | ``` 35 | 36 | ## 你会看到什么 37 | 38 | ``` 39 | uset1@vm1:~$ foo='Hello World!' 40 | user1@vm1:~$ echo $foo 41 | Hello World! 42 | user1@vm1:~$ set | grep foo 43 | foo='Hello World!' 44 | user1@vm1:~$ env | grep foo 45 | user1@vm1:~$ export foo 46 | user1@vm1:~$ env | grep foo 47 | foo=Hello World! 48 | user1@vm1:~$ foo='ls -al' 49 | user1@vm1:~$ $foo 50 | total 36 51 | drwxr-xr-x 2 user1 user1 4096 Jun 14 12:23 . 52 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 53 | -rw------- 1 user1 user1 4042 Jun 15 18:52 .bash_history 54 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 55 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc 56 | -rw------- 1 user1 user1 50 Jun 15 18:41 .lesshst 57 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 58 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 59 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 60 | ``` 61 | 62 | ## 解释 63 | 64 | 1. 创建变量`foo` ,并将`Hello World!`这一行放在其中。 65 | 2. 打印出变量`foo`。 66 | 3. 打印所有环境变量的列表,它传递给`grep`,打印出只包含变量`foo`的行。注意变量`foo`存在。 67 | 4. 打印所有环境变量列表,它们传递给你执行的任何程序。注意变量`foo`不存在。 68 | 5. 使变量`foo`可用于从当前 shell 执行的所有程序。 69 | 6. 现在你可以看到,你的变量确实可用于你执行的所有程序。 70 | 7. 将`ls /`放入变量`foo`。 71 | 8. 执行包含在变量`foo`中的命令。 72 | 73 | ## 附加题 74 | 75 | + 输入并执行`env`和`set`。看看有多少个不同的变量?不用担心,通常你可以通过谷歌搜索,快速了解一个变量的作用。尝试这样做。 76 | 77 | + 尝试输入: 78 | 79 | ``` 80 | set | egrep '^[[:alpha:]].*$' 81 | ``` 82 | 83 | 现在,试试`set`。看见我在这里做了什么嘛?快速的解释是: 84 | 85 | ``` 86 | egrep '^[[:alpha:]].*$' 87 | ``` 88 | 89 | 仅仅打印出以字母开头的行,它是每个字母,并忽略其他行。现在不要纠结这个,也不要纠结`|`符号。以后我会解释它。 90 | 91 | + 在这里阅读`env`和`set`之间的区别:。记住,stackoverflow 是你的朋友!我会重复多次。 92 | 93 | + 尝试输入`set FOO=helloworld bash -c 'echo $FOO'`。这里是解释:。同样,不要太纠结,你会在大量练习之后再次碰到它,我保证。 94 | 95 | + 试试这个: 96 | 97 | ``` 98 | PS1_BAK=$PS1 99 | PS1='Hello, world! $(pwd) > ' 100 | PS1=$PS1_BAK 101 | ``` 102 | 103 | 注意我使用`$(pwd)`,将命令输出作为变量访问。现在,键入`man bash /PS1`(是的,只是斜杠),按下``。你现在可以按下`n`查看下一个结果。浏览 PROMPTING,并键入`q`来退出`man`。现在,访问 并搜索`bash PS1`。了解这两个文档来源的区别。 104 | -------------------------------------------------------------------------------- /ex9.md: -------------------------------------------------------------------------------- 1 | # 练习 9:Bash:任务控制,`jobs`,`fg` 2 | 3 | > 原文:[Exercise 9. Bash: job control, jobs, fg](https://archive.fo/z1oWk) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | Linux是一个[多任务](http://en.wikipedia.org/wiki/Computer_multitasking)操作系统。这意味着有许多程序同时运行。从用户的角度来看,这意味着你可以同时运行几个程序,而且 bash 肯定有工具,为你控制多个任务的执行。为了能够使用此功能,你需要学习以下命令: 12 | 13 | + ` + z` - 将当前运行的程序放在后台。 14 | + `jobs` - 列出所有后台程序。 15 | + `fg` - 把程序带到前台。`fg`接受一个数字作为参数,它可以从`jobs`中获取数,或者如果无参数调用,则将最后一个挂起的程序带到前台。 16 | + `ctrl + c` - 一次性停止执行当前运行的程序。虽然我不会在这个练习中使用它,但我必须说,这可能是非常有用的。 17 | 18 | 现在,你将学习如何使用 bash 内置的工具来控制程序的执行。 19 | 20 | ## 这样做 21 | 22 | ``` 23 | 1: less -S .profile 24 | 2: 25 | 3: less -S .bashrc 26 | 4: 27 | 5: less -S .bash_history 28 | 6: 29 | 7: jobs 30 | 8: fg 31 | 9: q 32 | 10: fg 33 | 11: q 34 | 12: fg 35 | 13: q 36 | 14: fg 37 | 15: jobs 38 | ``` 39 | 40 | ## 你会看到什么 41 | 42 | ``` 43 | user1@vm1:~$ less -S .profile 44 | # exists. 45 | # see /usr/share/doc/bash/examples/startup-files for 46 | # the files are located in the bash-doc package. 47 | 48 | # the default umask is set in /etc/profile; for setti 49 | # for ssh logins, install and configure the libpam-um 50 | #umask 022 51 | 52 | # if running bash 53 | if [ -n "$BASH_VERSION" ]; then 54 | # include .bashrc if it exists 55 | if [ -f "$HOME/.bashrc" ]; then 56 | . "$HOME/.bashrc" 57 | 58 | [1]+ Stopped less -S .profile 59 | user1@vm1:~$ less -S .bashrc 60 | # for examples 61 | 62 | # If not running interactively, don't do anything 63 | [ -z "$PS1" ] && return 64 | 65 | # don't put duplicate lines in the history. See bash( 66 | # don't overwrite GNU Midnight Commander's setting of 67 | HISTCONTROL=$HISTCONTROL${HISTCONTROL+:}ignoredups 68 | # ... or force ignoredups and ignorespace 69 | HISTCONTROL=ignoreboth 70 | 71 | # append to the history file, don't overwrite it 72 | shopt -s histappend 73 | 74 | [2]+ Stopped less -S .bashrc 75 | user1@vm1:~$ less -S .bash_history 76 | echo Hello, $LOGNAME! 77 | echo 'echo Hello, $LOGNAME!' >> .profile 78 | cp .profile .profile.bak 79 | tail .profile 80 | ls -altr 81 | history -w 82 | ls -al 83 | cat .profile 84 | echo Hello, $LOGNAME! 85 | echo 'echo Hello, $LOGNAME!' >> .profile 86 | cp .profile .profile.bak 87 | tail .profile 88 | ls -altr 89 | 90 | [3]+ Stopped less -S .bash_history 91 | user1@vm1:~$ jobs 92 | [1] Stopped less -S .profile 93 | [2]- Stopped less -S .bashrc 94 | [3]+ Stopped less -S .bash_history 95 | user1@vm1:~$ fg 96 | user1@vm1:~$ fg 97 | user1@vm1:~$ fg 98 | user1@vm1:~$ fg 99 | -bash: fg: current: no such job 100 | user1@vm1:~$ jobs 101 | user1@vm1:~$ 102 | ``` 103 | 104 | ## 解释 105 | 106 | 1. 打开`.profile`来查看。注意我如何使用`-S`参数,让`less`开启`-chop-long-lines`选项来启动。 107 | 1. 挂起`less`。 108 | 1. 打开`.bashrc`来查看。 109 | 1. 挂起`less`。 110 | 1. 打开`.bash_history`来查看。 111 | 1. 挂起`less`。 112 | 1. 打印挂起程序的列表。 113 | 1. 切换到`less`。 114 | 1. 退出它。 115 | 1. 切换到第二个`less`。 116 | 1. 退出它。 117 | 1. 切换到第一个`less`。 118 | 1. 退出它。 119 | 1. 尝试切换到最后一个程序。没有任何程序,但你这样做是为了确保确实没有。 120 | 1. 打印挂起程序的列表。这是为了确保没有后台任务,通过看到`jobs`打印出空的输出。 121 | 122 | ## 附加题 123 | 124 | 打开`man bash`,搜索 JOB CONTROL,输入`/, JOB CONTROL, `,并阅读它。 125 | -------------------------------------------------------------------------------- /ex1.md: -------------------------------------------------------------------------------- 1 | # 练习 1:文本编辑器,vim 2 | 3 | > 原文:[Exercise 1. Text Editor, The: vim](https://archive.fo/5vf0X) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 在 Linux 中,就像任何类 Unix 操作系统,一切都只是文件。而 Unix 哲学指出,配置文件必须是人类可读和可编辑的。在几乎所有的情况下,它们只是纯文本。所以,首先,你必须学习如何编辑文本文件。 12 | 13 | 为此,我强烈建议你学习 vim 的基础知识,这是在 Linux 中处理文本的最强大的工具之一。Vim 是由 Bill Joy 于 1976 年编写的,[vi](http://en.wikipedia.org/wiki/Vi) 的重新实现。vi 实现了一个非常成功的概念,甚至 Microsoft Visual Studio 2012 有一个[插件](http://visualstudiogallery.msdn.microsoft.com/59ca71b3-a4a3-46ca-8fe1-0e90e3f79329/),它提供了一个模式,与这个超过 35 岁的编辑器兼容。你可以在这里玩转它([这是在浏览器中运行的真正的 Linux](https://bellard.org/jslinux/vm.html?url=https://bellard.org/jslinux/buildroot-x86.cfg))。完成之后,最后获取我的虚拟机。 14 | 15 | 如果我还没成功说服你,你可以了解 [nano](http://www.howtogeek.com/howto/42980/the-beginners-guide-to-nano-the-linux-command-line-text-editor/)来代替。但至少要试试。 16 | 17 | 现在,登入`vm1`,之后键入: 18 | 19 | ``` 20 | vim hello.txt 21 | ``` 22 | 23 | 你应该看到: 24 | 25 | ``` 26 | Hello, brave adventurer! 27 | ~ 28 | ~ 29 | ~ 30 | ~ 31 | ~ 32 | ~ 33 | ~ 34 | ~ 35 | ~ 36 | ~ 37 | ~ 38 | ~ 39 | ~ 40 | "hello.txt" [New File] 0,0-1 All 41 | ``` 42 | 43 | 有一个笑话说,vim有两种模式 - “反复哔哔”和“破坏一切”。那么,如果你不知道如何使用 vim,这是非常真实的,因为 vim 是模态的文本编辑器。模式是: 44 | 45 | + 普通模式:移动光标并执行删除,复制和粘贴等文本操作。 46 | + 插入模式:输入文本。 47 | 48 | > 译者注:还有一个命令模式,用于生成真 · 随机字符串(笑)。 49 | 50 | 这十分使新手头疼,因为他们试图尽可能地避免普通模式。那么这是错误的,所以现在我将给你正确的大纲来使用 vim : 51 | 52 | 53 | ``` 54 | start vim 55 | while editing is not finished, repeat 56 | navigate to desired position in NORMAL mode 57 | enter INSERT mode by pressing i 58 | type text 59 | exit INSERT mode by pressing 60 | when editing is finished, type :wq 61 | ``` 62 | 63 | 最重要的是,几乎任何时候都呆在普通模式,短时间内进入插入模式,然后立即退出。以这种方式,vim 只有一种模式,而这种模式是普通模式。 64 | 65 | 现在让我们试试吧。记住,按`i`进入插入模式,以及`` 返回到普通模式。键入以下内容(在每行末尾按``): 66 | 67 | ``` 68 | iRoses are red 69 | Linux is scary 70 | 71 | ``` 72 | 73 | 这是你应该看到的: 74 | 75 | ``` 76 | Roses are red 77 | Linux is scary 78 | ~ 79 | ~ 80 | ~ 81 | ~ 82 | ~ 83 | ~ 84 | ~ 85 | ~ 86 | ~ 87 | ~ 88 | ~ 89 | ~ 90 | ~ 91 | 4,17 All 92 | ``` 93 | 94 | 现在我给你命令列表,在普通模式下移动光标: 95 | 96 | + `h` - 向左移动 97 | + `j` - 向下移动 98 | + `k` - 向上移动 99 | + `l` - 右移 100 | + `i` - 进入插入模式 101 | + `o` - 在光标下插入一行并进入插入模式 102 | + `` - 退出插入模式 103 | + `x` - 删除光标下的符号 104 | + `dd` - 删除一行 105 | + `:wq` - 将更改写入文件并退出。是的,没错,这是一个冒号,后面跟着`wq`和``。 106 | + `:q!` - 不要对文件进行更改并退出。 107 | 108 | 那就够了。现在,将光标放在第一行并输入: 109 | 110 | ``` 111 | oViolets are blue 112 | ``` 113 | 之后,将光标放在`Linux is scary`那一行,并输入: 114 | 115 | 116 | ``` 117 | oBut I'm scary too 118 | ``` 119 | 120 | 你应该看到: 121 | 122 | ``` 123 | Roses are red 124 | Violets are blue 125 | Linux is scary 126 | But I'm scary too 127 | ~ 128 | ~ 129 | ~ 130 | ~ 131 | ~ 132 | ~ 133 | ~ 134 | ~ 135 | ~ 136 | ~ 137 | ~ 138 | 4,17 All 139 | ``` 140 | 141 | 现在键入`:wq`保存文件,并退出。你应该看到: 142 | 143 | ``` 144 | Violets are blue 145 | Linux is scary 146 | But I'm scary too 147 | ~ 148 | ~ 149 | ~ 150 | ~ 151 | ~ 152 | ~ 153 | ~ 154 | ~ 155 | ~ 156 | ~ 157 | ~ 158 | "hello.txt" 4L, 64C written 159 | user1@vm1:~$ 160 | ``` 161 | 162 | 好的。你做到它了。你刚刚在 vim 中编辑了文本文件,很好很强大! 163 | 164 | ## 附加题 165 | 166 | + 通过键入键入`vim hello.txt`再次启动 vim,并尝试我给你的一些命令。 167 | + 玩这个游戏,它会让你更熟悉 vim: 168 | -------------------------------------------------------------------------------- /ex12.md: -------------------------------------------------------------------------------- 1 | # 练习 12:文档:`man`,`info` 2 | 3 | > 原文:[Exercise 12. Documentation: man, info](https://archive.fo/6fbXi) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 既然你已经尝试过了 Linux,现在是时候介绍 Linux 在线文档工具了。你已经知道`man`了,因为我让你在里面查找东西。也许你甚至阅读了`man`的文档页面。所以无论如何,你需要什么来了解`man`,以便有效地使用它? 12 | 13 | 首先,手册页只是包含特殊标记的压缩文本文件,所以`man`程序知道如何为你设置格式。在 Debian 中,它们位于`/usr/share/man/`中。你可以使用`zless`浏览它们 。它甚至不是一个程序,而是一个 shell 脚本,它解压缩文件并调用`less`。 14 | 15 | 接下来,我将引用`man`手册页,关于它的分类: 16 | 17 | 1. 可执行程序或 shell 命令 18 | 2. 系统调用(内核提供的函数) 19 | 3. 库调用(程序库中的函数) 20 | 4. 特殊文件(通常在`/dev`中找到) 21 | 5. 文件格式和约定,例如`/etc/passwd` 22 | 6. 游戏 23 | 7. 其他(包括宏及惯例),例如`man(7)`,`groff(7)` 24 | 8. 系统管理命令(通常仅适用于 root 用户) 25 | 9. 内核例程[非标准] 26 | 27 | 这正是字面的意思。为了调用`man`的适当分类,请键入其分类编号,如`man 1`。如果你不明白某些分类是什么意思,则不用担心,现在你只需要第 1 个和第 8 个 ,这些分类是系统上安装的程序和系统管理员工作。此外,你已经知道`man(7)`是什么。 28 | 29 | 这是手册页的标准小节: 30 | 31 | + NAME(名称) - 程序名称和简短描述。 32 | + SYNOPSIS(概要) - 可用程序选项的简短列表 33 | + DESCRIPTION(描述) - 程序的描述和可用参数的说明。 34 | + OPTIONS(选项) - 一些手册页在这里继续说明可用的参数。 35 | + EXIT STATUS(退出状态) - 每个程序返回一个代表其成功或失败的代码。这里解释这些代码值。 36 | + RETURN VALUE(返回值) - 通常与退出状态相同。 37 | + ERRORS(错误) - 程序中已知的错误。 38 | + ENVIRONMENT(环境) - 环境变量。在调用程序之前设置它们。 39 | + FILES(文件) - 通常是程序配置文件。 40 | + VERSIONS(版本) - 有关程序更改的信息。 41 | + CONFORMING TO(适用于) - 兼容性说明。 42 | + NOTES(注意) - 手册的作者不知道放在哪里的信息。 43 | + BUGS - 程序中已知的错误。 44 | + EXAMPLE(示例) - 包含程序调用的示例。很有用! 45 | + AUTHORS(作者) - 谁写的程序。 46 | + SEE ALSO(另见)- 相关手册页。 47 | 48 | 现在是惯例,再次引用: 49 | 50 | + **粗体文本** - 类型完全如图所示。 51 | + *斜体文本* - 用适当的参数替换。这个文字大部分显示不是斜体,而是像下划线一样 。 52 | + `[-abc]` - `[]`内的任何或所有参数是可选的。 53 | + `-a|-b` - 由`|`分隔的选项不能一起使用 54 | + `argument …` - 参数是可重复的。 55 | + `[expression] …` - `[]`中的整个表达式是可重复的。 56 | 57 | 我会通过示例来演示它。`man less`会展示: 58 | 59 | ![](img/12-1.png) 60 | 61 | 好吧,看起来有些恐怖。前四行很简单,只需要键入展示的东西,就是这样: 62 | 63 | 1\. `less -?` 64 | 2\. `less –help` 65 | 3\. `less -V` 66 | 4\. `less –version` 67 | 68 | 从第 5 行开始,我们可以看到,斜体 文本确实显示为下划线。而且,看起来完全不可理解。让我们一起看看。 69 | 70 | 5\. `less [-[+]aBcCdeEfFgGiIJKLmMnNqQrRsSuUVwWX~]` - 这看起来更可怕。 71 | 72 | 首先,它是可选的,因为所有参数都包含在`[]`中。 73 | 其次,当指定参数时,必须以`-`开头。这是非可选的。 74 | 第三,之后,你可以指定可选修饰符`+`,这在手册中进一步说明。 75 | 第四,你可以指定一个或几个命令,在这里显示为字母序列。例如,你可以输入`less -S .bashrc`,或`less -+S .bashrc`或`less -SG .bashrc .profile`或更少`less -+SG .bashrc .profile`。 76 | 77 | 6\. `[-b space] [-h lines] [-j line] [-k keyfile]` - 简单的说,你可以指定任何选项`-b`,`-h`,`-j`,`-k`,分别带有参数空格,多个行,单个行和密钥文件,它们在手册中进一步介绍。 78 | 79 | 7\. `[-{oO} logfile] [-p pattern] [-P prompt] [-t tag]` - 几乎和第六行相同。`-{oO}`的意思是,你可以指定`-o`或`-O`,但不能同时指定二者。 80 | 81 | 8\. `[-T tagsfile] [-x tab,…] [-y lines] [-[z] lines]` - 同样,几乎和第六行相同。`-x tab,…`的意思是,,你可以在`-x`之后指定几个值,例如`-x9`或`-x9,17`。`-[z] lines`表示,`-z`是可选的,你可以输入`less -10`来代替`less -z10`。 82 | 83 | 9\. `[-# shift] [+[+]cmd] [- -] [filename]…` - 这有点更加神秘。`+[+]cmd`表示你可以输入`less +cmd`或`less ++ cmd`。`- -`只是一个前缀。`[filename]…`读取一个或多个,意思是你可以在调用`less`时指定多个文件,例如`less .bashrc`,`less .bashrc .profile`,以及其他。 84 | 85 | 我们结束了!不是那么可怕,是吗?记住,由于你正在使用`less`查看手册,为了搜索某些选项的含义,键入`/key`或`&key`。例如,要搜索`-T`选项的意思,请键入`/-T`。 86 | 87 | 现在我将向你提供实用的`man`命令的列表: 88 | 89 | + `man -k` - 列出系统中的所有手册页。不是非常有用,但你可能希望看到此列表。或者你可以通过键入`man -k | wc`来计数它们。 90 | + `man -k [search string]` - 在搜索手册页描述中搜索内容。试试这个:`man -k tty`。 91 | + `man -wK [search string]` - 在手册页正文中搜索内容。试试这个:`man -wK tty`。 92 | 93 | 那么这是用于`man`的。现在,还有一个有用的文档工具,`info`。命令列表如下: 94 | 95 | + `info […]` - 调用`info`。如果你不使用参数调用它,它会将你带到索引页面。 96 | + ``, ``, ``, ``可让你滚动文字。 97 | + ``打开光标下的链接。链接以`*`开头。 98 | + `` - 跳转到文档中的下一个链接。 99 | + `u` - 转到上一级 100 | + `p` - 转到上一页,就像浏览器一样。 101 | + `n` - 转到下一页。 102 | + `q` - 关闭`info`。 103 | 104 | 为了使用`vi`选项来启动`info`,我希望你已经熟悉它了,键入`info -vi-keys`。现在你可以使用`j`和`k`来滚动。 105 | 106 | ## 附加题 107 | 108 | + 键入`man man`并尝试解码 SYNOPSIS(概要)部分,这将解释如何调用它。 109 | + 键入`info`和`h`,阅读`info`的帮助部分。 110 | -------------------------------------------------------------------------------- /ex3.md: -------------------------------------------------------------------------------- 1 | # 练习 3:Bash:Shell、`.profile`、`.bashrc`、`.bash_history`。 2 | 3 | > 原文:[Exercise 3. Bash: The shell, .profile, .bashrc, .bash_history](https://archive.fo/DKP67) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 当使用 CLI(命令行界面)来使用 Linux 时,你正在与一个名为 shell 的程序进行交互。所有你输入的都传递给 shell,它解释你输入的内容,执行参数扩展(这有点类似于代数中的花括号扩展),并为你执行程序。我们将使用的 Shell 称为 Bash,它代表 Bourne Again Shell,而 Bourne Again Shell 又是一个双关语。现在我将使用纯中文,向大家介绍一下 bash 的工作方式: 12 | 13 | + 你 14 | + 登入 Linux 虚拟机 15 | + 你的身份由用户名(`user1`)和密码(`123qwe`)确定。 16 | + Bash 执行了。 17 | + Bash 18 | + 从你的配置中读取并执行首个命令,它定义了: 19 | + 命令提示符是什么样子 20 | + 使用 Linux 时,你会看到什么颜色 21 | + 你的编辑器是什么 22 | + 你的浏览器是什么 23 | + ... 24 | + 读取首个命令后,Bash 进入循环 25 | + 没有通过输入`exit`或者按下``,来要求退出的时候: 26 | + 读取一行 27 | + 解析这一行,扩展花括号 28 | + 使用扩展参数执行命令 29 | 30 | 我重复一下,你输入的任何命令都不会直接执行,而是首先扩展,然后执行。例如,当你输入`ls *`时,星号`*`将扩展为当前目录中所有文件的列表。 31 | 32 | 现在你将学习如何修改你的配置,以及如何编写和查看你的历史记录。 33 | 34 | ## 这样做 35 | 36 | ``` 37 | 1: ls -al 38 | 2: cat .profile 39 | 3: echo Hello, $LOGNAME! 40 | 4: cp -v .profile .profile.bak 41 | 5: echo 'echo Hello, $LOGNAME!' >> .profile 42 | 6: tail -n 5 .profile 43 | 7: history -w 44 | 8: ls -altr 45 | 9: cat .bash_history 46 | 10: exit 47 | ``` 48 | 49 | ## 你会看到什么 50 | 51 | ``` 52 | user1@vm1's password: 53 | Linux vm1 2.6.32-5-amd64 #1 SMP Sun May 6 04:00:17 UTC 2012 x86_64 54 | 55 | The programs included with the Debian GNU/Linux system are free software; 56 | the exact distribution terms for each program are described in the 57 | individual files in /usr/share/doc/*/copyright. 58 | 59 | Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent 60 | permitted by applicable law. 61 | Last login: Thu Jun 7 12:03:29 2012 from sis.site 62 | Hello, user1! 63 | user1@vm1:~$ ls -al 64 | total 20 65 | drwxr-xr-x 2 user1 user1 4096 Jun 7 12:18 . 66 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 67 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 68 | -rw-r--r-- 1 user1 user1 3184 Jun 6 21:48 .bashrc 69 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:04 .profile 70 | user1@vm1:~$ cat .profile 71 | # ~/.profile: executed by the command interpreter for login shells. 72 | # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login 73 | # exists. 74 | # see /usr/share/doc/bash/examples/startup-files for examples. 75 | # the files are located in the bash-doc package. 76 | 77 | # the default umask is set in /etc/profile; for setting the umask 78 | # for ssh logins, install and configure the libpam-umask package. 79 | #umask 022 80 | 81 | # if running bash 82 | if [ -n "$BASH_VERSION" ]; then 83 | # include .bashrc if it exists 84 | if [ -f "$HOME/.bashrc" ]; then 85 | . "$HOME/.bashrc" 86 | fi 87 | fi 88 | 89 | # set PATH so it includes user's private bin if it exists 90 | if [ -d "$HOME/bin" ] ; then 91 | PATH="$HOME/bin:$PATH" 92 | fi 93 | echo Hello, $LOGNAME! 94 | user1@vm1:~$ echo Hello, $LOGNAME! 95 | Hello, user1! 96 | user1@vm1:~$ cp -v .profile .profile.bak 97 | `.profile' -> `.profile.bak' 98 | user1@vm1:~$ echo 'echo Hello, $LOGNAME!' >> .profile 99 | user1@vm1:~$ tail -n 5 .profile 100 | # set PATH so it includes user's private bin if it exists 101 | if [ -d "$HOME/bin" ] ; then 102 | PATH="$HOME/bin:$PATH" 103 | fi 104 | echo Hello, $LOGNAME! 105 | user1@vm1:~$ history -w 106 | user1@vm1:~$ ls -altr 107 | total 28 108 | -rw-r--r-- 1 user1 user1 3184 Jun 6 21:48 .bashrc 109 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 110 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 111 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 112 | -rw------- 1 user1 user1 308 Jun 7 12:21 .bash_history 113 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 114 | drwxr-xr-x 2 user1 user1 4096 Jun 7 12:25 . 115 | user1@vm1:~$ cat .bash_history 116 | ls -al 117 | cat .profile 118 | echo Hello, $LOGNAME! 119 | cp -v .profile .profile.bak 120 | echo 'echo Hello, $LOGNAME!' >> .profile 121 | tail -n 5 .profile 122 | history -w 123 | ls -altr 124 | user1@vm1:~$ exit 125 | logout 126 | ``` 127 | 128 | 不要害怕,所有命令都会解释。行号对应“现在输入它”的部分。 129 | 130 | ## 解释 131 | 132 | 1. 打印当前目录中的所有文件,包括隐藏的文件。选项`-al`告诉`ls` 以`long`格式打印文件列表,并包括所有文件,包括隐藏文件。`.profile`和`.bash_rc`是隐藏文件,因为它们以点`.`开头。以点开头的每个文件都是隐藏的,这很简单。这两个特殊文件是 shell 脚本,它们包含登录时执行的指令。 133 | 134 | 2. 打印出你的`.profile`文件。只是这样。 135 | 136 | 3. 告诉你的 shell,你这里是 bash,输出一个字符串`Hello, $LOGNAME!`,用环境变量``$LOGNAME`替换$LOGNAME`,它包含你的登录名。 137 | 138 | 4. 将`.profile`文件复制到`.profile.bak`。选项`-v`让`cp`详细输出,这意味着它会打印所有的操作。记住这个选项,它通常用于让命令给你提供比默认更多的信息。 139 | 140 | 5. 在`.bash_rc`配置文件中添加一行。从现在开始,每次登录到`vm1`时, 都将执行该命令。注意,`>>`代表向文件添加了一些东西,但`>`意味着使用一些东西来替换文件。如果你不小心替换了`.profile`而不是向它添加,则命令 141 | 142 | ``` 143 | cp -v .profile.bak .profile 144 | ``` 145 | 146 | 会向你返回旧的`.profile`文件。 147 | 148 | 6. 从`.profile`文件中精确打印出最后 5 行。 149 | 150 | 7. 将所有命令历史写入`.bash_history`文件。通常这是在会话结束时完成的,当你通过键入`exit`或按` + D`关闭它。 151 | 152 | 8. 打印当前目录中的文件。选项`-tr`表示文件列表按时间反向排序。这意味着最近创建和修改的文件最后打印。注意你现在有两个新的文件。 153 | 154 | 9. 打印出保存命令历史记录的文件。注意你所有的输入都在这里。 155 | 156 | 0. 关闭会话 157 | 158 | ## 附加题 159 | 160 | + 在线搜索为什么`ls -al`告诉你“总共 20”,但是只有 5 个文件存在。 这是什么意思? 请注意,`.`和`..`是特殊文件条目,分别对应于当前目录和父目录的。 161 | 162 | + 登录`vm1`并键入`man -K /etc/profile`,现在使用光标键滚动到`INVOCATION`部分并阅读它。 要退出`man`,请键入`q`。 键入`man man`来找出`man -K`选项的含义。 163 | 164 | + 在命令之前键入`uname`与空格。 现在,键入`history`。 看到了吗?如果你将空格放到命令前面,则不会将其保存在历史记录中!提示:当你需要在命令行上指定密码时,很实用。 165 | 166 | + 找到 bash 的 wiki 页面,并尝试阅读它。不用担心,如果它吓到你,只需要省略可怕的部分。 167 | 168 | -------------------------------------------------------------------------------- /ex7.md: -------------------------------------------------------------------------------- 1 | # 练习 7:Bash:重定向,`stdin`,`stdout`,`stderr`,`<`,`>`,`>>`,`|`,`tee`,`pv` 2 | 3 | > 原文:[Exercise 7. Bash: redirection, stdin, stdout, stderr, <, >, >>, |, tee, pv](https://archive.fo/hZqGb) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 在 Linux 中,一切都只是文件。这意味着,对于控制台程序: 12 | 13 | + 键盘表示为一个文件,Bash 从中读取你的输入。 14 | + 显示器表示为一个文件,Bash向输出写入它。 15 | 16 | 让我们假设,你有一个程序可以计算文件中的行。你可以通过键入`wc -l`来调用它。现在尝试一下 没有发生什么事吧?它只是卡在那里。错了,它正在等待你的输入。这是它的工作原理: 17 | 18 | ``` 19 | line_counter = 0 20 | while end of file is not reached 21 | read a line 22 | add 1 to line_counter 23 | print line_counter 24 | ``` 25 | 26 | 所以`wc`目前从`/dev/tty`读取行,这在当前上下文中是你的键盘。每次你按下回车,`wc`都会获取一行。任意键入几行,然后按`CTRL + D`,这将为`wc`产生`EOF`字符,使其明白达到[文件末尾](http://en.wikipedia.org/wiki/End-of-file)。现在它会告诉你你输入了多少行。 27 | 28 | 但是如果你想计算现有文件中的行呢?那么,这就需要重定向 了!为了在其输入上提供现有文件,请键入以下内容:`wc -l < .bash_history`。你看,它有作用!真的是那么简单![重定向](http://en.wikipedia.org/wiki/Redirection_%28computing%29) 是一种机制,允许你告诉程序,将其来自键入输入和/或到显示器的输出,重定向到另一个文件。为此,你可以使用这些特殊命令,然后启动程序: 29 | 30 | + `<` - 用文件替换标准输入(例如键盘)。 31 | + `>` - 用文件替换标准输出(例如显示器)。警告!此命令将覆盖 你的指定文件的内容,因此请小心。 32 | + `>>` - 与上面相同,但不是覆盖 文件,而是写入到它的末尾,保存在该文件中已存在的信息。小心不要混淆两者。 33 | + `|` - 从一个程序获取输出,并将其连接到另一个程序。这将在下一个练习中详细阐述。 34 | 35 | 现在,你将学习如何将程序的输入和输出重定向到文件或其他程序。 36 | 37 | ## 这样做 38 | 39 | ``` 40 | 1: sudo aptitude install pv 41 | 2: read foo < /dev/tty 42 | 3: Hello World! 43 | 4: echo $foo > foo.out 44 | 5: cat foo.out 45 | 6: echo $foo >> foo.out 46 | 7: cat foo.out 47 | 8: echo > foo.out 48 | 9: cat foo.out 49 | 10: ls -al | grep foo 50 | 11: ls -al | tee ls.out 51 | 12: dd if=/dev/zero of=~/test.img bs=1M count=10 52 | 13: pv ~/test.img | dd if=/dev/stdin of=/dev/null bs=1 53 | 14: rm -v foo.out 54 | 15: rm -v test.img 55 | ``` 56 | 57 | ## 你应该看到什么 58 | 59 | ``` 60 | user1@vm1:~$ sudo aptitude install pv 61 | The following NEW packages will be installed: 62 | pv 63 | 0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded. 64 | Need to get 0 B/28.9 kB of archives. After unpacking 143 kB will be used. 65 | Selecting previously deselected package pv. 66 | (Reading database ... 39657 files and directories currently installed.) 67 | Unpacking pv (from .../archives/pv_1.1.4-1_amd64.deb) ... 68 | Processing triggers for man-db ... 69 | Setting up pv (1.1.4-1) ... 70 | 71 | user1@vm1:~$ read foo < /dev/tty 72 | Hello World! 73 | user1@vm1:~$ echo $foo > foo.out 74 | user1@vm1:~$ cat foo.out 75 | Hello World! 76 | user1@vm1:~$ echo $foo >> foo.out 77 | user1@vm1:~$ cat foo.out 78 | Hello World! 79 | Hello World! 80 | user1@vm1:~$ echo > foo.out 81 | user1@vm1:~$ cat foo.out 82 | 83 | user1@vm1:~$ ls -al | grep foo 84 | -rw-r--r-- 1 user1 user1 1 Jun 15 20:03 foo.out 85 | user1@vm1:~$ ls -al | tee ls.out 86 | total 44 87 | drwxr-xr-x 2 user1 user1 4096 Jun 15 20:01 . 88 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 89 | -rw------- 1 user1 user1 4865 Jun 15 19:34 .bash_history 90 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 91 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc 92 | -rw-r--r-- 1 user1 user1 1 Jun 15 20:03 foo.out 93 | -rw------- 1 user1 user1 50 Jun 15 18:41 .lesshst 94 | -rw-r--r-- 1 user1 user1 0 Jun 15 20:03 ls.out 95 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 96 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 97 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 98 | -rw-r--r-- 1 user1 user1 0 Jun 15 20:02 test.img 99 | user1@vm1:~$ dd if=/dev/zero of=~/test.img bs=1M count=10 100 | 10+0 records in 101 | 10+0 records out 102 | 10485760 bytes (10 MB) copied, 0.0130061 s, 806 MB/s 103 | user1@vm1:~$ pv ~/test.img | dd if=/dev/stdin of=/dev/null bs=1 104 | 10MB 0:00:03 [3.24MB/s] [=================================================================================>] 100% 105 | 10485760+0 records in 106 | 10485760+0 records out 107 | 10485760 bytes (10 MB) copied, 3.10446 s, 3.4 MB/s 108 | user1@vm1:~$ rm -v foo.out 109 | removed `foo.out' 110 | user1@vm1:~$ rm -v test.img 111 | removed `test.img' 112 | user1@vm1:~$ 113 | ``` 114 | 115 | ## 解释 116 | 117 | 1. 在你的系统上安装`pv`(管道查看器)程序,稍后你需要它。 118 | 2. 将你的输入读取到变量`foo`。这是可能的,因为显示器和键盘实际上是系统的电传打字机。是的,[那个](http://www.google.ru/search?rlz=1C1CHKZ_enRU438RU438&sugexp=chrome,mod%3D11&q=unix+filter&um=1&ie=UTF-8&hl=en&tbm=isch&source=og&sa=N&tab=wi&ei=QWDbT7LILsTi4QTJxNXWCg&biw=1116&bih=875&sei=Q2DbT93XOLLS4QTmst2ACg%23um=1&hl=en&newwindow=1&rlz=1C1CHKZ_enRU438RU438&tbm=isch&sa=1&q=teletype&oq=teletype&aq=f&aqi=g10&aql=&gs_l=img.3..0l10.455489.456448.4.456736.8.6.0.2.2.0.144.567.4j2.6.0...0.0.Qa6W2PHvUWw&pbx=1&bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&fp=e87c07212bd9e2a6&biw=1116&bih=875)电传打字机!在线阅读更多关于`tty`的东西。 119 | 3. 这是你输入的东西。 120 | 4. 将`foo`变量的内容重定向到`foo.out`文件,在进程中创建文件或覆盖现有文件,而不会警告删除所有内容! 121 | 5. 打印出`foo.out`的内容。 122 | 6. 将`foo`变量的内容重定向到`foo.out`文件,在进程中创建文件或附加 到现有文件。这是安全的,但不要混淆这两者,否则你会有巨大的悲剧。 123 | 7. 再次打印出`foo.out`内容。 124 | 8. 将空内容重定向到`foo.out`,在进程中清空文件。 125 | 9. 显示文件确实是空的。 126 | 0. 列出你的目录并将其通过管道输出到`grep`。它的原理是,获取所有`ls -al`的输出,并将其扔给`grep`。这又称为管道。 127 | 1. 将你的目录列出到屏幕上,并写入`ls.out`。很有用! 128 | 2. 创建大小为 10 兆字节的清零文件。现在不要纠结它如何工作。 129 | 3. 将这个文件读取到`/dev/null`,这是你系统中终极的垃圾桶,什么都没有。写入它的一切都会消失。请注意,`pv`会向你展示读取文件的进程,如果你尝试使用其他命令读取它,你就不会知道它需要多长时间来完成。 130 | 4. 删除`foo.out`。记得自己清理一下。 131 | 5. 删除`test.img`。 132 | 133 | ## 附加题 134 | 135 | + 阅读 [stackoverflow](http://stackoverflow.com/questions/5802879/difference-between-pipelining-and-redirection-in-linux) 上的管道和重定向,再次阅读 [stackoverflow](http://stackoverflow.com/questions/19122/bash-pipe-handling?rq=1) 和 [Greg 的 Wiki](http://mywiki.wooledge.org/BashFAQ/024),这是非常有用的资源,记住它。 136 | + 打开 bash 的`man`页面,向下滚动到 REDIRECTION 部分并阅读它。 137 | + 阅读`man pv`和`man tee`的描述。 138 | -------------------------------------------------------------------------------- /ex4.md: -------------------------------------------------------------------------------- 1 | # 练习 4:Bash:处理文件,`pwd`,`ls`,`cp`,`mv`,`rm`,`touch` 2 | 3 | > 原文:[Exercise 4. Bash: working with files, pwd, ls, cp, mv, rm, touch](https://archive.fo/xb8YB) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 在 Linux 中,一切都是文件。但是什么是文件?现在完全可以说,它是一个包含一些信息的对象。它通常[定义](http://en.wikipedia.org/wiki/Computer_file)如下: 12 | 13 | > 计算机文件是用于存储信息的,任意的信息块或资源。它可用于计算机程序,并且通常基于某种持久的存储器。文件是持久的,因为它在当前程序完成后,仍然可用于其它程序。计算机文件可以认为是纸质文档的现代对应物,它们通常保存于办公室和图书馆的文件中,这是该术语的来源。 14 | 15 | 但这个定义太笼统了,所以让我们更具体一些。`man stat`告诉我们,文件是一个对象,它包含以下属性: 16 | 17 | ```c 18 | struct stat { 19 | dev_t st_dev; /* ID of device containing file */ 20 | ino_t st_ino; /* inode number */ 21 | mode_t st_mode; /* protection */ 22 | nlink_t st_nlink; /* number of hard links */ 23 | uid_t st_uid; /* user ID of owner */ 24 | gid_t st_gid; /* group ID of owner */ 25 | dev_t st_rdev; /* device ID (if special file) */ 26 | off_t st_size; /* total size, in bytes */ 27 | blksize_t st_blksize; /* blocksize for file system I/O */ 28 | blkcnt_t st_blocks; /* number of 512B blocks allocated */ 29 | time_t st_atime; /* time of last access */ 30 | time_t st_mtime; /* time of last modification */ 31 | time_t st_ctime; /* time of last status change */ 32 | }; 33 | ``` 34 | 35 | 不要害怕,只要记住以下属性: 36 | 37 | + 大小,这正好是它所说的。 38 | + 上次访问的时间,当你查看文件时更新。 39 | + 上次修改的时间,当你更改文件时更新。 40 | 41 | 现在你将学习如何打印当前目录,目录中的文件,复制和移动文件。 42 | 43 | ## 这样做 44 | 45 | ``` 46 | 1: pwd 47 | 2: ls 48 | 3: ls -a 49 | 4: ls -al 50 | 5: ls -altr 51 | 6: cp -v .bash_history{,1} 52 | 7: cp -v .bash_history1 .bash_history2 53 | 8: mv -v .bash_history1 .bash_history2 54 | 9: rm -v .bash_history2 55 | 10: touch .bashrc 56 | 11: ls -al 57 | 12: ls .* 58 | ``` 59 | 60 | ## 你应该看到什么 61 | 62 | ``` 63 | Hello, user1! 64 | user1@vm1:~$ pwd 65 | /home/user1 66 | user1@vm1:~$ ls 67 | user1@vm1:~$ ls -a 68 | . .. .bash_history .bash_history1 .bash_logout .bashrc .lesshst .profile .profile.bak .profile.bak1 69 | user1@vm1:~$ ls -al 70 | total 40 71 | drwxr-xr-x 2 user1 user1 4096 Jun 7 13:30 . 72 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 73 | -rw------- 1 user1 user1 853 Jun 7 15:03 .bash_history 74 | -rw------- 1 user1 user1 308 Jun 7 13:14 .bash_history1 75 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 76 | -rw-r--r-- 1 user1 user1 3184 Jun 6 21:48 .bashrc 77 | -rw------- 1 user1 user1 45 Jun 7 13:31 .lesshst 78 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 79 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 80 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 81 | user1@vm1:~$ ls -altr 82 | total 40 83 | -rw-r--r-- 1 user1 user1 3184 Jun 6 21:48 .bashrc 84 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 85 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 86 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 87 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 88 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 89 | -rw------- 1 user1 user1 308 Jun 7 13:14 .bash_history1 90 | drwxr-xr-x 2 user1 user1 4096 Jun 7 13:30 . 91 | -rw------- 1 user1 user1 45 Jun 7 13:31 .lesshst 92 | -rw------- 1 user1 user1 853 Jun 7 15:03 .bash_history 93 | user1@vm1:~$ cp -v .bash_history{,1} 94 | `.bash_history' -> `.bash_history1' 95 | user1@vm1:~$ cp -v .bash_history1 .bash_history2 96 | `.bash_history1' -> `.bash_history2' 97 | user1@vm1:~$ mv -v .bash_history1 .bash_history2 98 | `.bash_history1' -> `.bash_history2' 99 | user1@vm1:~$ rm -v .bash_history2 100 | removed `.bash_history2' 101 | user1@vm1:~$ touch .bashrc 102 | user1@vm1:~$ ls -al 103 | total 36 104 | drwxr-xr-x 2 user1 user1 4096 Jun 14 12:23 . 105 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 106 | -rw------- 1 user1 user1 853 Jun 7 15:03 .bash_history 107 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 108 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc 109 | -rw------- 1 user1 user1 45 Jun 7 13:31 .lesshst 110 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 111 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 112 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 113 | user1@vm1:~$ 114 | user1@vm1:~$ ls .* 115 | .bash_history .bash_logout .bashrc .lesshst .profile .profile.bak .profile.bak1 116 | 117 | .: 118 | ls.out 119 | 120 | ..: 121 | user1 122 | ``` 123 | 124 | ## 解释 125 | 126 | 1. 打印你当前的工作目录,这是你的主目录。请注意它为何不同于`user1@vm1:~`中的`~`,这也表示,你在你的`home`目录中。这是因为`~`是你的主目录的缩写。 127 | 128 | 2. 这里没有任何东西,因为你的主目录中只有隐藏的文件。记住,隐藏的文件是以点开头的名称。 129 | 130 | 3. 打印主目录中的所有文件,因为`-a`参数让`ls`显示所有文件,包括隐藏文件。 131 | 132 | 4. 以长格式打印主目录中的所有文件:权限,所有者,组,大小,时间戳(通常是修改时间)和文件名。 133 | 134 | 5. 注意文件如何按日期安排,最新的文件是最后一个。`-t`告诉`ls`按时间排序,`-r`告诉`ls`反转排序。 135 | 136 | 6. 将`.bash_history`复制到`.bash_history1`。这似乎对你来说很神秘,但解释真的很简单。Bash 有一个称为花括号扩展的功能,它有一组规则,定义了如何 处理像`{1,2,3}`之类的结构。在我们的例子中,`.bash_history{,1}` 扩展为两个参数,即`.bash_history`和`.bash_history1`。Bash 仅仅接受花括号前的一个参数,在我们的例子中是`.bash_history`,并向参数添加花括号里的所有东西,以逗号分隔,并以此作为参数。第一个添加只是变成`.bash_history`,因为花括号中的第一个参数是空的,没有第一个参数。接下来,Bash 添加了`1`,因为这是第二个参数,就是这样。扩展后传递给`cp`的 结果参数为`-v .bash_history1 .bash_history2`。 137 | 138 | 7. 这可能对你来说很明显。将最近创建的`.bash_history1`复制到`.bash_history2`。 139 | 140 | 8. 向`.bash_history1`移动到`.bash_history2`。请注意,它会覆盖目标文件而不询问,所以不再有`.bash_history2`,没有了! 141 | 142 | 9. 将`.bashrc`时间戳更新为当前日期和时间。这意味着`.bashrc`的所有时间属性,`st_atime`,`st_mtime`和`st_ctime`都设置为当前日期和时间。你可以通过输入`stat .bashrc`来确定它。 143 | 144 | 0. 删除`.bash_history2`。这里没有警告,请小心。另外,总是用`-v`选项。 145 | 146 | 1. 再次以长格式打印所有文件。请注意`.bashrc`的时间戳更改。 147 | 148 | 2. 在你的主目录中以短格式打印文件。请注意,你不仅可以列出`/home/user1`目录,还可以列出`/home`目录本身。不要和任何命令一起使用这个结构,特别是 `rm`,永远不要!或许,你会意外地通过删除错误的文件或更改权限,来使系统崩溃。 149 | 150 | ## 附加题 151 | 152 | 玩转 bash 花括号扩展。从`echo test{1,2,foo,bar}`开始。尝试使用花括号键入几个单独的参数。 153 | 154 | 使用 Google 搜索 bash 花括号扩展,从搜索结果中打开“Bash 参考手册”,并阅读相应的部分。 155 | 156 | 尝试弄清楚`ls .*`如何和为什么工作。 157 | 158 | 对自己说10次:“我会一直使用 verbose 选项。verbose 选项通常用作`-v`参数”。 159 | 160 | 对自己说10次:“我会永远用`ls`检查任何危险的命令”。 161 | -------------------------------------------------------------------------------- /ex29.md: -------------------------------------------------------------------------------- 1 | # 练习 29:内核:内核消息,`dmesg` 2 | 3 | > 原文:[Exercise 29. Kernel: kernel messages, dmesg](https://archive.fo/aZwFG) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 那么,如果你到达了这里,现在是谈谈[内核](http://en.wikipedia.org/wiki/Kernel_%28computing%29)的时候了。我们将使用维基百科的操作系统内核定义,开始这个讨论: 12 | 13 | > 在计算机中,内核(来自德语 Kern)是大多数计算机操作系统的主要组成部分;它是应用程序和硬件级别上进行的实际数据处理之间的桥梁。内核的职责包括管理系统的资源(硬件和软件组件之间的通信)。通常,作为操作系统的基本组件,内核可以为资源(特别是处理器和 I/O 设备)提供最底层的抽象,应用软件必须控制它来执行其功能。它通常通过进程间通信机制和系统调用,使这些设施可用于应用程序进程。 14 | 15 | 这是维基百科告诉我们的,Linux 内核的具体内容: 16 | 17 | > Linux 内核是 Linux 系列类 Unix 操作系统使用的操作系统内核。它是自由和开源软件最突出的例子之一。它支持真正的抢占式多任务(在用户模式和内核模式下),虚拟内存,共享库,按需加载,共享的写时复制(COW)可执行文件,内存管理,互联网协议组和线程。 18 | 19 | 现在是访问相应的维基百科文章的好时机,并花费一些时间疯狂点击所有可怕的术语,它们描述 Linux 内核的技术特性。这样做之后,让我们谈谈更多的单调的主题,这是内核告诉我们的一种方式。例如,如果 USB 记忆棒连接到计算机,或者网络链接断开或挂载了文件系统,则会发生这种情况。为了能够告诉你所有这些东西,内核使用一种称为显示消息 或驱动消息的机制,其名称缩写为`dmesg`。 20 | 21 | 该机制由固定大小的缓冲区表示,内核向它写入消息。在 Debian Linux 上,系统日志守护进程启动后,从缓冲区发布的信息也会被复制到`/var/log/dmesg`。这样做是为了保留这些消息,否则将被新的消息覆盖。 22 | 23 | `dmesg`也是工具的名称,它允许你查看当前在内核缓冲区中的那些消息,并更改此缓冲区大小。 24 | 25 | 让我总结一下`dmesg`相关的文件和程序: 26 | 27 | + `dmesg` - 打印或控制内核环缓冲区 28 | + `/var/log/dmseg` - Debian 发行版中的日志文件,仅包含系统引导期间的`dmesg`消息副本,而不包含时间戳。 29 | + `/var/log/kern.log` - Debian 发行版中的日志文件,包含所有`dmesg`消息的副本,包括时间戳请注意,`rsyslog` 日志守护进程启动后,这个时间戳开始变化,这意味着`rsyslog`启动前,所有引导时的消息将具有相同的时间戳。此文件本身包含`/var/log/dmseg`。 30 | + `/var/log/messages` - Debian 发行版中的日志文件,记录所有非调试和非关键消息。它本身包含`/var/log/dmesg`。 31 | + `/var/log/syslog` - Debian 发行版中的日志文件,记录了所有信息,但权限相关的信息除外。它包含`/var/log/messages`和`/var/log/kern.log`中的所有消息。 32 | 33 | ## 这样做 34 | 35 | ``` 36 | 1: date 37 | 2: sudo umount /tmp ; sudo mount /tmp 38 | 3: sudo tail -f /var/log/dmesg /var/log/messages /var/log/syslog /var/log/kern.log 39 | ``` 40 | 41 | ## 你会看到什么 42 | 43 | ``` 44 | user1@vm1:~$ date 45 | Tue Jul 24 06:55:33 EDT 2012 46 | user1@vm1:~$ sudo umount /tmp ; sudo mount /tmp 47 | user1@vm1:~$ dmesg | tail 48 | [ 7.166240] tun: Universal TUN/TAP device driver, 1.6 49 | [ 7.166242] tun: (C) 1999-2004 Max Krasnyansky 50 | [ 7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready 51 | [ 7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX 52 | [ 7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready 53 | [ 17.472049] tap0: no IPv6 routers present 54 | [ 17.592044] eth0: no IPv6 routers present 55 | [ 217.497357] kjournald starting. Commit interval 5 seconds 56 | [ 217.497561] EXT3 FS on sda8, internal journal 57 | [ 217.497564] EXT3-fs: mounted filesystem with ordered data mode. 58 | user1@vm1:~$ sudo tail /var/log/dmesg /var/log/messages /var/log/syslog /var/log/kern.log 59 | ==> /var/log/dmesg <== 60 | [ 6.762569] EXT3 FS on sda5, internal journal 61 | [ 6.762572] EXT3-fs: mounted filesystem with ordered data mode. 62 | [ 6.767237] kjournald starting. Commit interval 5 seconds 63 | [ 6.767407] EXT3 FS on sda6, internal journal 64 | [ 6.767410] EXT3-fs: mounted filesystem with ordered data mode. 65 | [ 7.166240] tun: Universal TUN/TAP device driver, 1.6 66 | [ 7.166242] tun: (C) 1999-2004 Max Krasnyansky 67 | [ 7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready 68 | [ 7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX 69 | [ 7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready 70 | 71 | ==> /var/log/messages <== 72 | Jul 24 06:52:07 vm1 kernel: [ 6.767407] EXT3 FS on sda6, internal journal 73 | Jul 24 06:52:07 vm1 kernel: [ 6.767410] EXT3-fs: mounted filesystem with ordered data mode. 74 | Jul 24 06:52:07 vm1 kernel: [ 7.166240] tun: Universal TUN/TAP device driver, 1.6 75 | Jul 24 06:52:07 vm1 kernel: [ 7.166242] tun: (C) 1999-2004 Max Krasnyansky 76 | Jul 24 06:52:07 vm1 kernel: [ 7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready 77 | Jul 24 06:52:07 vm1 kernel: [ 7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX 78 | Jul 24 06:52:07 vm1 kernel: [ 7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready 79 | Jul 24 06:55:36 vm1 kernel: [ 217.497357] kjournald starting. Commit interval 5 seconds 80 | Jul 24 06:55:36 vm1 kernel: [ 217.497561] EXT3 FS on sda8, internal journal 81 | Jul 24 06:55:36 vm1 kernel: [ 217.497564] EXT3-fs: mounted filesystem with ordered data mode. 82 | 83 | ==> /var/log/syslog <== 84 | Jul 24 06:52:08 vm1 acpid: 1 rule loaded 85 | Jul 24 06:52:08 vm1 acpid: waiting for events: event logging is off 86 | Jul 24 06:52:08 vm1 /usr/sbin/cron[882]: (CRON) INFO (pidfile fd = 3) 87 | Jul 24 06:52:08 vm1 /usr/sbin/cron[883]: (CRON) STARTUP (fork ok) 88 | Jul 24 06:52:08 vm1 /usr/sbin/cron[883]: (CRON) INFO (Running @reboot jobs) 89 | Jul 24 06:52:16 vm1 kernel: [ 17.472049] tap0: no IPv6 routers present 90 | Jul 24 06:52:16 vm1 kernel: [ 17.592044] eth0: no IPv6 routers present 91 | Jul 24 06:55:36 vm1 kernel: [ 217.497357] kjournald starting. Commit interval 5 seconds 92 | Jul 24 06:55:36 vm1 kernel: [ 217.497561] EXT3 FS on sda8, internal journal 93 | Jul 24 06:55:36 vm1 kernel: [ 217.497564] EXT3-fs: mounted filesystem with ordered data mode. 94 | 95 | ==> /var/log/kern.log <== 96 | Jul 24 06:52:07 vm1 kernel: [ 7.166240] tun: Universal TUN/TAP device driver, 1.6 97 | Jul 24 06:52:07 vm1 kernel: [ 7.166242] tun: (C) 1999-2004 Max Krasnyansky 98 | Jul 24 06:52:07 vm1 kernel: [ 7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready 99 | Jul 24 06:52:07 vm1 kernel: [ 7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX 100 | Jul 24 06:52:07 vm1 kernel: [ 7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready 101 | Jul 24 06:52:16 vm1 kernel: [ 17.472049] tap0: no IPv6 routers present 102 | Jul 24 06:52:16 vm1 kernel: [ 17.592044] eth0: no IPv6 routers present 103 | Jul 24 06:55:36 vm1 kernel: [ 217.497357] kjournald starting. Commit interval 5 seconds 104 | Jul 24 06:55:36 vm1 kernel: [ 217.497561] EXT3 FS on sda8, internal journal 105 | Jul 24 06:55:36 vm1 kernel: [ 217.497564] EXT3-fs: mounted filesystem with ordered data mode. 106 | ``` 107 | 108 | ## 解释 109 | 110 | 1. 打印出当前日期和时间。 111 | 1. 从内核消息缓冲区打印最后 10 条消息。 112 | 1. 从`/var/log/dmesg`, `/var/log/messages`, `/var/log/syslog`和`/var/log/kern.log`打印最后 10 条消息。 113 | 114 | ## 附加题 115 | 116 | 这就完了,没有附加题,哇哦! 117 | -------------------------------------------------------------------------------- /ex30.md: -------------------------------------------------------------------------------- 1 | # 练习 30:打磨、洗练、重复:总复习 2 | 3 | > 原文:[Exercise 30. Lather, Rinse, Repeat: The Grand Rote Learning](https://archive.fo/RCaku) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 本指南中的信息量相当大。没有足够长的练习和一些深入研究,你不能记住它。所以剩下的唯一的工作就是填写这张表,每天都把这张表打印在你的记忆中,直到你知道了它。 12 | 13 | 你可能想问,为什么需要记住所有这些东西,如果你可以随时查看的话。那么简短的答案是因为你不能。这意味着为了高效地查找事物,你需要知道要寻找什么,并且为了知道要寻找什么,你需要一个坚实的基础。一旦你有了这个基础,一旦你明白什么是重要的,什么不是,以及系统的组织方式,你将能够高效寻找东西。 14 | 15 | 你可能会想知道,为什么在我的指南中有很多详细的表格,其中包含许多字段的列表,其中包含几乎不需要的信息。你必须明白的是,你应该以这种方式训练自己,来查看任何控制台程序。你应该熟悉这个信息,而不像是一本科幻小说那样,其中你可能不会注意细节,但仍然很了解它。你应该将所有这些数据看做数学公式,其中每个符号都有其意义,甚至更多,如果你不明白特定的符号意味着什么,你将无法走地更远。 16 | 17 | 有时完全可以留下一些未解释的东西,但让自己变得更深入,即使经常是这样。通过研究这个特定的工具,了解它告诉你什么以及为什么,给自己一个礼物。如果你这样做,如果你会深入内部,你对操作系统的理解(在我们这种情况下是 Linux)将会极大增加。 18 | 19 | ## 文档 20 | 21 | ### `man`, `info` 22 | 23 | | 命令或概念 | 含义 | 24 | | --- | --- | 25 | | `man` | | 26 | | `info` | | 27 | | `man 1` | | 28 | | `man 2` | | 29 | | `man 3` | | 30 | | `man 4` | | 31 | | `man 5` | | 32 | | `man 6` | | 33 | | `man 7` | | 34 | | `man 8` | | 35 | | `man 9` | | 36 | | `man -k` | | 37 | | `man -wK` | | 38 | | **粗体** | | | 39 | | *斜体* | | | 40 | | `[]` | | 41 | | `-a|-b` | | 42 | | `argument ...` | | 43 | | `[expression] ...` | | 44 | 45 | ### Google 和实用资源 46 | 47 | | 搜索术语/资源 | 含义 | 48 | | --- | --- | 49 | | `(a|b) c` | | 50 | | `site:foo.bar` | | 51 | | `"a long query"` | | 52 | | | | 53 | | | | 54 | | | | 55 | | | | 56 | | `programname.site` | | 57 | 58 | ### 包管理:Debian 包管理工具`aptitude` 59 | 60 | | 命令或概念 | 含义 | 61 | | --- | --- | 62 | | `aptitude` | | 63 | | `aptitude search` | | 64 | | `aptitude install` | | 65 | | `dpkg -l` | | 66 | | `dpkg -L` | | 67 | | 预期操作 | | 68 | | 包状态 | | 69 | | | | 70 | 71 | ### 系统启动:运行级别, `/etc/init.d`, `rcconf`, `update-rc.d` 72 | 73 | | 命令或概念 | 含义 | 74 | | --- | --- | 75 | | `rcconf` | | 76 | | `update-rc.d` | | 77 | | `sysv-rc-conf` | | 78 | | 运行级别 | | 79 | | 运行级别 1 | | 80 | | 运行级别 2 | | 81 | | 运行级别 6 | | 82 | 83 | 84 | ### 进程:处理进程,`ps`,`kill` 85 | 86 | | 命令或概念 | 含义 | 87 | | --- | --- | 88 | | `ps` | | 89 | | `kill` | | 90 | | `ps ax` | | 91 | | `ps axue` | | 92 | | `ps axue --forest` | | 93 | | 信号 | | 94 | | `HUP` | | 95 | | `TERM` | | 96 | | `KILL` | | 97 | | 为什么 `KILL -9` 是不好的? | | 98 | 99 | ### 任务调度:`cron`,`at` 100 | 101 | | 命令或概念 | 含义 | 102 | | --- | --- | 103 | | `crontab -l` | | 104 | | `crontab -e` | | 105 | | `crontab -r` | | 106 | | `crontab /foo` | | 107 | | `crontab > foo` | | 108 | | `* * * * *` | | 109 | | `at` | | 110 | | `atq` | | 111 | | `atq` | | 112 | | `atrm` | | 113 | | `batch` | | 114 | 115 | ### 日志, `/var/log`, `rsyslog`, `logger` 116 | 117 | | 命令或概念 | 含义 | 118 | | --- | --- | 119 | | `logger` | 120 | | `grep -irl` | 121 | | `find . -mmin -5` | 122 | | `tail -f` | 123 | | `logrotate` | 124 | | 日志守护程序 | | 125 | | 日志级别 | | 126 | | 日志轮替 | | 127 | 128 | ### 文件系统 129 | 130 | | 命令或概念 | 含义 | 131 | | --- | --- | 132 | | 文件系统 | | 133 | | 文件 | | 134 | | 目录 | | 135 | | 索引节点 | | 136 | | 块 | | 137 | | 挂载 | | 138 | | UUID | | 139 | | 日志 | | 140 | | MBR | | 141 | | 分区 | | 142 | | 分区表 | | 143 | 144 | ### 挂载, `mount`, `/etc/fstab` 145 | 146 | | 命令或概念 | 含义 | 147 | | --- | --- | 148 | | `parted` | | 149 | | `cfdisk` | | 150 | | `fdisk` | | 151 | | `mount` | | 152 | | `umount` | | 153 | | `mount -a` | | 154 | | `/etc/fstab` | | 155 | | `fsck` | | 156 | | `blkid` | | 157 | 158 | ### 创建和修改文件系统,`mkfs`,`tune2fs` 159 | 160 | | 命令或概念 | 含义 | 161 | | --- | --- | 162 | | `tune2fs` | | 163 | | `mkfs` | | 164 | | 块大小 | | 165 | | 保留块数量 | | 166 | | 最大挂载数量 | | 167 | | 检查间隔 | | 168 | 169 | ### 更改根目录,`chroot` 170 | 171 | | 命令或概念 | 含义 | 172 | | --- | --- | 173 | | `chroot` | | 174 | | `ldd` | | 175 | | 根目录 | | 176 | | 更改根目录 | | 177 | | 动态库依赖 | | 178 | 179 | ### 移动数据:`tar`,`dd` 180 | 181 | | 命令或概念 | 含义 | 182 | | --- | --- | 183 | | `tar` | | 184 | | `dd` | | 185 | | `losetup` | | 186 | 187 | ### 安全权限:`chown`,`chmod` 188 | 189 | | 命令或概念 | 含义 | 190 | | --- | --- | 191 | | `chmod` | | 192 | | `chown` | | 193 | | `umask` | | 194 | | 权限 | | 195 | | 权限模式 | | 196 | | 权限类 | | 197 | | Umask 机制 | | 198 | 199 | ### 网络 200 | 201 | | 网络概念 | 含义 | 202 | | --- | --- | 203 | | OSI 模型 | | 204 | | DOD 模型 | | 205 | | 通信协议 | | 206 | | 以太网 | | 207 | | MAC 地址 | | 208 | | 以太网广播地址 | | 209 | | TCP/IP | | 210 | | IP | | 211 | | IP 封包 | | 212 | | IP 地址 | | 213 | | IP 子网 | | 214 | | 端口 | | 215 | | 网络套接字 | | 216 | | 本地套接字地址 | | 217 | | 远程套接字地址 | | 218 | | 套接字对 | | 219 | | 路由 | | 220 | | 默认网关 | | 221 | | IP 广播地址 | | 222 | | ICMP | | 223 | | TCP | | 224 | | TCP 封包 | | 225 | | UDP | | 226 | | UDP 封包 | | 227 | | 主机名称 | | 228 | 229 | ### 网络配置, `ifconfig`, `netstat`, `iproute2`, `ss` 230 | 231 | | 命令或概念 | 含义 | 232 | | --- | --- | 233 | | `/etc/network/interfaces` | | 234 | | `auto` | | 235 | | `allow-hotplug` | | 236 | | `/etc/hosts` | | 237 | | `/etc/hostname` | | 238 | | `localhost` | | 239 | | 回送接口 | | 240 | | 伪接口 | | 241 | 242 | ### 封包过滤配置,`iptables` 243 | 244 | | 命令或概念 | 含义 | 245 | | --- | --- | 246 | | `iptables-save` | | 247 | | `iptables` | | 248 | | `modprobe` | | 249 | | `nc` | | 250 | | `tcpdump` | | 251 | | `LINKTYPE_LINUX_SLL` | | 252 | | 以太网帧头部 | | 253 | | IPv4 头部 | | 254 | | TCP 段 | | 255 | | `netfilter` | | 256 | | iptables 表 | | 257 | | iptables 链 | | 258 | | iptables 目标 | | 259 | 260 | ### 安全 Shell, `ssh`, `sshd`, `scp` 261 | 262 | | 命令或概念 | 含义 | 263 | | --- | --- | 264 | | `ssh` | | 265 | | `sshd` | | 266 | | `scp` | | 267 | | `ssh-keygen` | | 268 | | 主机密钥 | | 269 | | 证密钥 | | 270 | | 数据加密密码 | | 271 | | 数据完整性算法 | | 272 | | SSH 会话密钥 | | 273 | 274 | ### 性能:获取性能状态, `uptime`, `free`, `top` 275 | 276 | | 命令或概念 | 含义 | 277 | | --- | --- | 278 | | `uptime` | | 279 | | `free` | | 280 | | `vmstat` | | 281 | | `top` | | 282 | | CPU 占用 (`us`,`sy`,`id`,`wa`) | | 283 | | 内存 (`swpd`, `free`, `buff`, `cache`, `inact`, `active`) | 284 | | Slab 分配 | | 285 | | 磁盘 (`IOPS`, `read`, `write`) | | 286 | | 进程 (`PR`, `NI`, `VIRT`, `RES`, `SHR`, `Status`) | | 287 | 288 | ### 内核:内核消息,`dmesg` 289 | 290 | | 命令或概念 | 含义 | 291 | | --- | --- | 292 | | `dmseg` | | 293 | | `/var/log/dmesg` | | 294 | | `/var/log/messages` | | 295 | | `/var/log/syslog` | | 296 | | `/var/log/kern.log` | | 297 | | 内核消息缓冲区 | | 298 | -------------------------------------------------------------------------------- /ex6.md: -------------------------------------------------------------------------------- 1 | # 练习 6:Bash:语言设置,`LANG`,`locale`,`dpkg-reconfigure locales` 2 | 3 | > 原文:[Exercise 6. Bash: language settings, LANG, locale, dpkg-reconfigure locales](https://archive.fo/QgMfr) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 在 Linux 中,语言选择像导出变量一样简单。这是正确的,通过查看这个变量,程序决定如何和你交流。当然,为了使其工作,程序必须支持区域设置,并将其翻译成可用和安装的语言。让我们通过安装法语区域设置,看看它的工作原理。 12 | 13 | 现在,你将学习如何安装和选择一个区域设置。 14 | 15 | ## 这样做 16 | 17 | ``` 18 | 1: echo $LANG 19 | 2: locale 20 | 3: man man # press q to exit man 21 | 4: sudo dpkg-reconfigure locales 22 | ``` 23 | 24 | 现在,选择`fr_FR.UTF-8 locale`,通过使用方向键来浏览列表,并使用看空格来选择区域设置。选择`en_US.UTF-8`作为默认的系统区域。 25 | 26 | ``` 27 | 5: export LANG=fr_FR.UTF-8 28 | 6: echo $LANG 29 | 7: locale # press q to exit man 30 | 8: man man 31 | 9: export LANG=en_US.UTF-8 32 | ``` 33 | 34 | ## 你会看到什么 35 | 36 | ``` 37 | user1@vm1:~$ echo $LANG 38 | en_US.UTF-8 39 | user1@vm1:~$ locale 40 | LANG=en_US.UTF-8 41 | LANGUAGE=en_US:en 42 | LC_CTYPE="en_US.UTF-8" 43 | LC_NUMERIC="en_US.UTF-8" 44 | LC_TIME="en_US.UTF-8" 45 | LC_COLLATE="en_US.UTF-8" 46 | LC_MONETARY="en_US.UTF-8" 47 | LC_MESSAGES="en_US.UTF-8" 48 | LC_PAPER="en_US.UTF-8" 49 | LC_NAME="en_US.UTF-8" 50 | LC_ADDRESS="en_US.UTF-8" 51 | LC_TELEPHONE="en_US.UTF-8" 52 | LC_MEASUREMENT="en_US.UTF-8" 53 | LC_IDENTIFICATION="en_US.UTF-8" 54 | LC_ALL= 55 | user1@vm1:~$ man man 56 | MAN(1) Manual pager utils MAN(1) 57 | 58 | NAME 59 | man - an interface to the on-line reference manuals 60 | user1@vm1:~$ sudo dpkg-reconfigure locales 61 | ---------------| Configuring locales |----------------------- 62 | | | 63 | | Locales are a framework to switch between multiple | 64 | | languages and allow users to use their language, | 65 | | country, characters, collation order, etc. | 66 | | | 67 | | Please choose which locales to generate. UTF-8 locales | 68 | | should be chosen by default, particularly for new | 69 | | installations. Other character sets may be useful for | 70 | | backwards compatibility with older systems and software. | 71 | | | 72 | | | 73 | | | 74 | ------------------------------------------------------------- 75 | -----------| Configuring locales |-------- 76 | | Locales to be generated: | 77 | | | 78 | | [ ] fr_BE@euro ISO-8859-15 | 79 | | [ ] fr_CA ISO-8859-1 | 80 | | [ ] fr_CA.UTF-8 UTF-8 | 81 | | [ ] fr_CH ISO-8859-1 | 82 | | [ ] fr_CH.UTF-8 UTF-8 | 83 | | [*] fr_FR ISO-8859-1 | 84 | | [ ] fr_FR.UTF-8 UTF-8 | 85 | | [ ] fr_FR@euro ISO-8859-15 | 86 | | | 87 | | | 88 | | | 89 | | | 90 | ------------------------------------------ 91 | ------------------ Configuring locales ---------------------- 92 | | | 93 | | Many packages in Debian use locales to display text in | 94 | | the correct language for the user. You can choose a | 95 | | default locale for the system from the generated | 96 | | locales. | 97 | | | 98 | | This will select the default language for the entire | 99 | | system. If this system is a multi-user system where not | 100 | | all users are able to speak the default language, they | 101 | | will experience difficulties. | 102 | | | 103 | | | 104 | | | 105 | ------------------------------------------------------------- 106 | ------------ Configuring locales -------------- 107 | | Default locale for the system environment: | 108 | | | 109 | | None | 110 | | en_US.UTF-8 | 111 | | fr_FR.UTF-8 | 112 | | | 113 | | | 114 | | | 115 | | | 116 | ----------------------------------------------- 117 | Generating locales (this might take a while)... 118 | en_US.UTF-8... done 119 | fr_FR.UTF-8... done 120 | Generation complete. 121 | user1@vm1:~$ export LANG=fr_FR.UTF-8 122 | user1@vm1:~$ echo $LANG 123 | fr_FR.UTF-8 124 | user1@vm1:~$ locale 125 | LANG=fr_FR.UTF-8 126 | LANGUAGE=en_US:en 127 | LC_CTYPE="fr_FR.UTF-8" 128 | LC_NUMERIC="fr_FR.UTF-8" 129 | LC_TIME="fr_FR.UTF-8" 130 | LC_COLLATE="fr_FR.UTF-8" 131 | LC_MONETARY="fr_FR.UTF-8" 132 | LC_MESSAGES="fr_FR.UTF-8" 133 | LC_PAPER="fr_FR.UTF-8" 134 | LC_NAME="fr_FR.UTF-8" 135 | LC_ADDRESS="fr_FR.UTF-8" 136 | LC_TELEPHONE="fr_FR.UTF-8" 137 | LC_MEASUREMENT="fr_FR.UTF-8" 138 | LC_IDENTIFICATION="fr_FR.UTF-8" 139 | LC_ALL= 140 | user1@vm1:~$ man man 141 | MAN(1) Utilitaires de l'afficheur des pages de manuel MAN(1) 142 | 143 | NOM 144 | man - interface de consultation des manuels de 145 | référence en ligne 146 | user1@vm1:~$ export LANG=en_US.UTF-8 147 | user1@vm1:~$ 148 | ``` 149 | 150 | ## 解释 151 | 152 | 1. 打印你当前使用的`LANG`变量,程序用它来确定与你进行交互时要使用的语言。 153 | 154 | 2. 按照指定的国家/地区的格式,打印所有区域变量,程序员使用它们来设置数字,地址,电话格式,以及其它。 155 | 156 | 3. 显示 unix 手册系统的手册页。注意我如何使用`#`来注释一个动作,`#`之后的所有内容都不执行。 157 | 158 | 4. 执行程序来重新配置你的区域设置。因为这个变化是系统层次的,你需要以 root 身份运行这个命令,这就是在`dpkg-reconfigure locales`前面有`sudo`的原因。现在不要纠结`sudo`,我会让你熟悉它。 159 | 160 | 5. 导出`LANG`变量,用于设置所有其他区域变量。 161 | 162 | 6. 打印出`LANG`变量,你可以看到它已经改变了,按照你的预期。 163 | 164 | 7. 打印其它已更改的区域变量。 165 | 166 | 8. 以法语显示`man`手册页。 167 | 168 | 9. 将`LANG变量恢复为英文。 169 | 170 | ## 附加题 171 | 172 | + 阅读区域设置的手册页。为此,请输入`man locale`。 173 | 174 | + 现在,阅读`man 7 locale`页面。注意我 在这里使用`7`,来调用关于约定的手册页。如果你愿意, 现在阅读`man man`,了解其他可能的代码是什么,或者只是等待涵盖它的练习。 175 | 176 | -------------------------------------------------------------------------------- /ex25.md: -------------------------------------------------------------------------------- 1 | # 练习 25:网络:配置文件,`/etc/network/interfaces` 2 | 3 | > 原文:[Exercise 25. Networking: configuration files, /etc/network/interfaces](https://archive.fo/ckUKJ) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 从命令行配置网络接口是很好的,但现在是时候学习如何让`vm1`自动配置网络接口。为此,你将了解`/etc/network/interfaces`配置文件: 12 | 13 | ``` 14 | user1@vm1:~$ cat /etc/network/interfaces 15 | # This file describes the network interfaces available on your system 16 | # and how to activate them. For more information, see interfaces(5). 17 | 18 | # The loopback network interface 19 | #(1) (2) 20 | auto lo 21 | #(3) (4)(5) (6) 22 | iface lo inet loopback 23 | 24 | # The primary network interface 25 | #(7) (8) 26 | allow-hotplug eth0 27 | #(9) (10) (11) (12) 28 | iface eth0 inet dhcp 29 | ``` 30 | 31 | 像往常一样,字段及其描述: 32 | 33 | | 字段 | 描述 | 34 | | --- | --- | 35 | | (1) | 自动配置界面。 | 36 | | (2) | 接口名称。 | 37 | | (3) | 接口配置的开始 | 38 | | (4) | 要配置的接口名称 | 39 | | (5) | 此接口使用 TCP/IP 网络,IPv4。 | 40 | | (6) | 它是回送接口。默认回送地址将自动分配给它。 | 41 | | (7) | 在可用时自动配置接口(请在这里考虑 usb-modem)。 | 42 | | (8) | 接口名称。 | 43 | | (9) | 接口配置的开始 | 44 | | (10) | 要配置的接口名称 | 45 | | (11) | 此接口使用 TCP/IP 网络,IPv4。 | 46 | | (12) | 此接口通过 DHCP 自动获取其参数。 | 47 | 48 | 其他包含网络配置的重要文件,但我们在这里不会碰到他们: 49 | 50 | + `/etc/hosts` - 操作系统中使用的计算机文件,用于将主机名映射到 IP 地址。`hosts`文件是一个纯文本文件,通常按照惯例命名为`hosts`。 51 | + `/etc/hostname` - 分配给连接到计算机网络的设备的标签,并用于识别各种形式的电子通信设备。 52 | + `/etc/resolv.conf` - 各种操作系统中的计算机文件,用于配置域名系统( DNS)解析器库。该文件是纯文本文件,通常由网络管理员或管理系统配置任务的应用创建。`resolvconf`程序是 linux 机器上的这样的程序,它管理`resolv.conf`文件。 53 | 54 | 让我们回忆之前练习的`tap0`。如果你重新启动`vm1`, 它就会消失。当然,你可以通过重新输入相关命令来启用它,但是让我们想象一下,你需要在重新启动后自动使用该命令。 55 | 56 | 现在,你将学习如何使用`/etc/network/interfaces`文件来配置接口。 57 | 58 | ## 这样做 59 | 60 | ``` 61 | 1: ip a s 62 | 2: sudo vim /etc/network/interfaces 63 | ``` 64 | 65 | 现在将这些东西添加到配置文件末尾: 66 | 67 | ``` 68 | 3: auto tap0 69 | 4: iface tap0 inet static 70 | 5: address 10.1.1.2 71 | 6: netmask 255.255.255.0 72 | 7: tunctl_user uml-net 73 | 8: 74 | 9: allow-hotplug tap1 75 | 10: iface tap1 inet static 76 | 11: address 10.1.1.3 77 | 12: netmask 255.255.255.0 78 | ``` 79 | 80 | 现在键入`:wq`并继续: 81 | 82 | ``` 83 | 13: sudo /etc/init.d/networking start 84 | 14: ip a s 85 | 15: sudo tunctl -t tap1 -u uml-net 86 | 16: ip a s 87 | ``` 88 | 89 | ## 你会看到什么 90 | 91 | ``` 92 | user1@vm1:~$ ip a s 93 | 1: lo: mtu 16436 qdisc noqueue state UNKNOWN 94 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 95 | inet 127.0.0.1/8 scope host lo 96 | inet6 ::1/128 scope host 97 | valid_lft forever preferred_lft forever 98 | 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 99 | link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff 100 | inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0 101 | inet6 fe80::a00:27ff:fed4:4568/64 scope link 102 | valid_lft forever preferred_lft forever 103 | user1@vm1:~$ sudo vim /etc/network/interfaces 104 | # and how to activate them. For more information, see interfaces(5). 105 | 106 | # The loopback network interface 107 | auto lo 108 | iface lo inet loopback 109 | 110 | # The primary network interface 111 | allow-hotplug eth0 112 | iface eth0 inet dhcp 113 | 114 | auto tap0 115 | iface tap0 inet static 116 | address 10.2.2.2 117 | netmask 255.255.255.0 118 | tunctl_user uml-net 119 | 120 | allow-hotplug tap1 121 | iface tap1 inet static 122 | address 10.3.3.3 123 | netmask 255.255.255.0 124 | ~ 125 | "/etc/network/interfaces" 21L, 457C written 21,1-8 Bot 126 | user1@vm1:~$ sudo /etc/init.d/networking start 127 | Configuring network interfaces...Set 'tap0' persistent and owned by uid 104 done. 128 | user1@vm1:~$ ip a s 129 | 1: lo: mtu 16436 qdisc noqueue state UNKNOWN 130 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 131 | inet 127.0.0.1/8 scope host lo 132 | inet6 ::1/128 scope host 133 | valid_lft forever preferred_lft forever 134 | 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 135 | link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff 136 | inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0 137 | inet6 fe80::a00:27ff:fed4:4568/64 scope link 138 | valid_lft forever preferred_lft forever 139 | 3: tap0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500 140 | link/ether 46:63:30:70:b5:21 brd ff:ff:ff:ff:ff:ff 141 | inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0 142 | inet6 fe80::4463:30ff:fe70:b521/64 scope link 143 | valid_lft forever preferred_lft forever 144 | user1@vm1:~$ sudo tunctl -t tap1 -u uml-net 145 | Set 'tap1' persistent and owned by uid 104 146 | user1@vm1:~$ ip a s 147 | 1: lo: mtu 16436 qdisc noqueue state UNKNOWN 148 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 149 | inet 127.0.0.1/8 scope host lo 150 | inet6 ::1/128 scope host 151 | valid_lft forever preferred_lft forever 152 | 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 153 | link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff 154 | inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0 155 | inet6 fe80::a00:27ff:fed4:4568/64 scope link 156 | valid_lft forever preferred_lft forever 157 | 3: tap0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500 158 | link/ether 46:63:30:70:b5:21 brd ff:ff:ff:ff:ff:ff 159 | inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0 160 | inet6 fe80::4463:30ff:fe70:b521/64 scope link 161 | valid_lft forever preferred_lft forever 162 | 4: tap1: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 500 163 | link/ether 8a:ed:90:33:93:55 brd ff:ff:ff:ff:ff:ff 164 | inet 10.3.3.3/24 brd 10.3.3.255 scope global tap1 165 | inet6 fe80::88ed:90ff:fe33:9355/64 scope link 166 | valid_lft forever preferred_lft forever 167 | user1@vm1:~$ 168 | ``` 169 | 170 | ## 解释 171 | 172 | 1. 打印当前接口配置。 173 | 1. 编辑`/etc/network/interfaces`。 174 | 1. 自动配置`tap0`。 175 | 1. 为`tap0`设置以下 IPv4 静态参数。 176 | 1. 将 IP 地址`10.2.2.2`添加给`tap0`。 177 | 1. 为此 IP 地址指定网络掩码、参数“广播”和“网络”自动 从这个网络掩码导出。 178 | 1. 指定拥有`tap0`接口的用户。 179 | 1. 由于可读性的空行。 180 | 1. 在`tap1`接口出现在系统中时,添加以下参数。 181 | 1. 为`tap1`设置以下 IPv4 静态参数。 182 | 1. 将 IP 地址`10.3.3.3`添加给tap1。 183 | 1. 为此 IP 地址指定网络掩码。 184 | 1. 应用网络配置更改。 185 | 1. 打印当前接口配置。你可以看到`tap0`被添加到接口列表中。 186 | 1. 添加`tap1`伪接口。 187 | 1. 打印当前接口配置。你可以看到`/etc/network/interfaces中指定的参数自动应用于它。 188 | 189 | ## 附加题 190 | 191 | + 说明如何导出“网络”和“广播”参数。 192 | + 尝试这个:`ping kitty`。预期会失败。现在添加一个条目到`/etc/hosts`,以便你能够成功执行`ping`。 193 | -------------------------------------------------------------------------------- /styles/ebook.css: -------------------------------------------------------------------------------- 1 | /* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */ 2 | /* Author: Nicolas Hery - http://nicolashery.com */ 3 | /* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */ 4 | /* Source: https://github.com/nicolahery/markdownpad-github */ 5 | 6 | /* RESET 7 | =============================================================================*/ 8 | 9 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { 10 | margin: 0; 11 | padding: 0; 12 | border: 0; 13 | } 14 | 15 | /* BODY 16 | =============================================================================*/ 17 | 18 | body { 19 | font-family: Helvetica, arial, freesans, clean, sans-serif; 20 | font-size: 14px; 21 | line-height: 1.6; 22 | color: #333; 23 | background-color: #fff; 24 | padding: 20px; 25 | max-width: 960px; 26 | margin: 0 auto; 27 | } 28 | 29 | body>*:first-child { 30 | margin-top: 0 !important; 31 | } 32 | 33 | body>*:last-child { 34 | margin-bottom: 0 !important; 35 | } 36 | 37 | /* BLOCKS 38 | =============================================================================*/ 39 | 40 | p, blockquote, ul, ol, dl, table, pre { 41 | margin: 15px 0; 42 | } 43 | 44 | /* HEADERS 45 | =============================================================================*/ 46 | 47 | h1, h2, h3, h4, h5, h6 { 48 | margin: 20px 0 10px; 49 | padding: 0; 50 | font-weight: bold; 51 | -webkit-font-smoothing: antialiased; 52 | } 53 | 54 | h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code { 55 | font-size: inherit; 56 | } 57 | 58 | h1 { 59 | font-size: 24px; 60 | border-bottom: 1px solid #ccc; 61 | color: #000; 62 | } 63 | 64 | h2 { 65 | font-size: 18px; 66 | color: #000; 67 | } 68 | 69 | h3 { 70 | font-size: 14px; 71 | } 72 | 73 | h4 { 74 | font-size: 14px; 75 | } 76 | 77 | h5 { 78 | font-size: 14px; 79 | } 80 | 81 | h6 { 82 | color: #777; 83 | font-size: 14px; 84 | } 85 | 86 | body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child { 87 | margin-top: 0; 88 | padding-top: 0; 89 | } 90 | 91 | a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { 92 | margin-top: 0; 93 | padding-top: 0; 94 | } 95 | 96 | h1+p, h2+p, h3+p, h4+p, h5+p, h6+p { 97 | margin-top: 10px; 98 | } 99 | 100 | /* LINKS 101 | =============================================================================*/ 102 | 103 | a { 104 | color: #4183C4; 105 | text-decoration: none; 106 | } 107 | 108 | a:hover { 109 | text-decoration: underline; 110 | } 111 | 112 | /* LISTS 113 | =============================================================================*/ 114 | 115 | ul, ol { 116 | padding-left: 30px; 117 | } 118 | 119 | ul li > :first-child, 120 | ol li > :first-child, 121 | ul li ul:first-of-type, 122 | ol li ol:first-of-type, 123 | ul li ol:first-of-type, 124 | ol li ul:first-of-type { 125 | margin-top: 0px; 126 | } 127 | 128 | ul ul, ul ol, ol ol, ol ul { 129 | margin-bottom: 0; 130 | } 131 | 132 | dl { 133 | padding: 0; 134 | } 135 | 136 | dl dt { 137 | font-size: 14px; 138 | font-weight: bold; 139 | font-style: italic; 140 | padding: 0; 141 | margin: 15px 0 5px; 142 | } 143 | 144 | dl dt:first-child { 145 | padding: 0; 146 | } 147 | 148 | dl dt>:first-child { 149 | margin-top: 0px; 150 | } 151 | 152 | dl dt>:last-child { 153 | margin-bottom: 0px; 154 | } 155 | 156 | dl dd { 157 | margin: 0 0 15px; 158 | padding: 0 15px; 159 | } 160 | 161 | dl dd>:first-child { 162 | margin-top: 0px; 163 | } 164 | 165 | dl dd>:last-child { 166 | margin-bottom: 0px; 167 | } 168 | 169 | /* CODE 170 | =============================================================================*/ 171 | 172 | pre, code, tt { 173 | font-size: 12px; 174 | font-family: Consolas, "Liberation Mono", Courier, monospace; 175 | } 176 | 177 | code, tt { 178 | margin: 0 0px; 179 | padding: 0px 0px; 180 | white-space: nowrap; 181 | border: 1px solid #eaeaea; 182 | background-color: #f8f8f8; 183 | border-radius: 3px; 184 | } 185 | 186 | pre>code { 187 | margin: 0; 188 | padding: 0; 189 | white-space: pre; 190 | border: none; 191 | background: transparent; 192 | } 193 | 194 | pre { 195 | background-color: #f8f8f8; 196 | border: 1px solid #ccc; 197 | font-size: 13px; 198 | line-height: 19px; 199 | overflow: auto; 200 | padding: 6px 10px; 201 | border-radius: 3px; 202 | } 203 | 204 | pre code, pre tt { 205 | background-color: transparent; 206 | border: none; 207 | } 208 | 209 | kbd { 210 | -moz-border-bottom-colors: none; 211 | -moz-border-left-colors: none; 212 | -moz-border-right-colors: none; 213 | -moz-border-top-colors: none; 214 | background-color: #DDDDDD; 215 | background-image: linear-gradient(#F1F1F1, #DDDDDD); 216 | background-repeat: repeat-x; 217 | border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD; 218 | border-image: none; 219 | border-radius: 2px 2px 2px 2px; 220 | border-style: solid; 221 | border-width: 1px; 222 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 223 | line-height: 10px; 224 | padding: 1px 4px; 225 | } 226 | 227 | /* QUOTES 228 | =============================================================================*/ 229 | 230 | blockquote { 231 | border-left: 4px solid #DDD; 232 | padding: 0 15px; 233 | color: #777; 234 | } 235 | 236 | blockquote>:first-child { 237 | margin-top: 0px; 238 | } 239 | 240 | blockquote>:last-child { 241 | margin-bottom: 0px; 242 | } 243 | 244 | /* HORIZONTAL RULES 245 | =============================================================================*/ 246 | 247 | hr { 248 | clear: both; 249 | margin: 15px 0; 250 | height: 0px; 251 | overflow: hidden; 252 | border: none; 253 | background: transparent; 254 | border-bottom: 4px solid #ddd; 255 | padding: 0; 256 | } 257 | 258 | /* TABLES 259 | =============================================================================*/ 260 | 261 | table th { 262 | font-weight: bold; 263 | } 264 | 265 | table th, table td { 266 | border: 1px solid #ccc; 267 | padding: 6px 13px; 268 | } 269 | 270 | table tr { 271 | border-top: 1px solid #ccc; 272 | background-color: #fff; 273 | } 274 | 275 | table tr:nth-child(2n) { 276 | background-color: #f8f8f8; 277 | } 278 | 279 | /* IMAGES 280 | =============================================================================*/ 281 | 282 | img { 283 | max-width: 100% 284 | } -------------------------------------------------------------------------------- /ex17.md: -------------------------------------------------------------------------------- 1 | # 练习 17:任务调度:`cron`,`at` 2 | 3 | > 原文:[Exercise 17. Job schedulers: cron, at](https://archive.fo/TRJCB) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 通常我们需要按计划执行程序。例如,让我们想象一下,你需要在每天的半夜备份你的作品。为了在 Linux 中完成它,有一个叫`cron`的特殊程序。这是一个恶魔,这意味着,当计算机启动后,它就是启动了,并在后台默默等待,在时机到来时为你执行其他程序。`cron`具有多个配置文件,系统级的,或者用户级的。默认情况下,用户没有`crontab`,因为没有为它们安排任何东西。这是`cron`配置文件的位置: 12 | 13 | `/etc/crontab` - 系统级`cron`配置文件。 14 | `/var/spool/cron/crontabs/` - 用于存储用户配置文件的目录。 15 | 16 | 现在我们来谈谈`cron`配置文件的格式。如果你运行`cat /etc/crontab`,你将看到: 17 | 18 | ``` 19 | # /etc/crontab: system-wide crontab 20 | # Unlike any other crontab you don't have to run the `crontab' 21 | # command to install the new version when you edit this file 22 | # and files in /etc/cron.d. These files also have username fields, 23 | # that none of the other crontabs do. 24 | 25 | SHELL=/bin/sh 26 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 27 | 28 | # m h dom mon dow user command 29 | 17 * * * * root cd / && run-parts --report /etc/cron.hourly 30 | 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 31 | 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 32 | 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) 33 | # 34 | ``` 35 | 36 | 它的语法足够简单,让我们选取一行: 37 | 38 | ``` 39 | 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly 40 | ``` 41 | 42 | 然后拆开: 43 | 44 | ``` 45 | 17 # 每个小时的第 17 个分钟 46 | * # 月中的每一天 47 | * # 年中的每一月 48 | * # 每个星期 49 | root # 作为 root 用户 50 | cd / # 执行命令 'cd /' 51 | && # 如果 'cd /' 执行成功,那么 52 | run-parts --report /etc/cron.hourly # 执行命令 'run-parts --report /etc/cron.hourly' 53 | ``` 54 | 55 | 现在我总结`cron`的格式: 56 | 57 | ``` 58 | * * * * * <用户> <要执行的命令> 59 | T T T T T (仅仅用于系统 60 | | | | | | 的 crontab) 61 | | | | | | 62 | | | | | +----- 星期几 (0 - 6) (0 是星期天, 或者使用名称) 63 | | | | +---------- 月份 (1 - 12) 64 | | | +--------------- 天 (1 - 31) 65 | | +-------------------- 小时 (0 - 23) 66 | +------------------------- 分钟 (0 - 59) 67 | ``` 68 | 69 | 这是时间格式中,可能的字符的缩略列表: 70 | 71 | + 星号(`*`) - 字段中的所有值,例如 分钟的`*`表示每分钟。 72 | + 斜线(`/`) - 定义范围的增量。例如,`30-40/3`意味着在第 30 分钟运行程序,每 3 分钟一次,直到第 40 分钟。 73 | + 百分比(`%`) - 在命令字段中,百分比后的所有数据将作为标准输入发送到命令。现在不要纠结这个。 74 | + 逗号(`,`) - 指定列表,例如分钟字段的`30,40`表示第 30 和 40 `分钟。 75 | + 连字(`-`) - 范围。例如,分钟字段的`30-40`意味着每分钟在30到40分钟之间。 76 | + `L` - 指定最后一个东西,例如它允许你指定一个月的最后一天。 77 | 78 | 现在我会给你一些例子: 79 | 80 | ``` 81 | # m h dom mon dow user command 82 | # (每月每天每小时)每分钟 83 | * * * * * root /bin/false 84 | # (每月每天)每小时的第 30~40 分钟中的每分钟 85 | 30-40 * * * * root /bin/false 86 | # (每月每天)每小时的第 30~40 分钟中的每五分钟 87 | 30-40/5 * * * * root /bin/false 88 | # (每月每天每小时)每五分钟 89 | */5 * * * * user command to be executed 90 | # 每月的最后一天的每小时每分钟 91 | * * L * * root /bin/false 92 | # 每月的星期天和星期三的每小时每分钟 93 | * * * * 0,3 root /bin/false 94 | ``` 95 | 96 | 好的,但是如何加载`crontab`?这是`cron`命令的列表: 97 | 98 | + `crontab -l` - 打印出当前的`crontab`。 99 | + `crontab -e` - 为当前用户编辑`crontab`。 100 | + `crontab -r` - 删除当前用户的`crontab`。 101 | + `crontab /path/to/file` - 为当前用户加载`crontab`,覆盖过程中的现有项。 102 | + `crontab > /path/to/file` - 将`crontab`保存到文件中。 103 | 104 | 这就是如何使用`cron`系统守护进程。但是还有一个可以调度程序执行的选项。它就是`at`工具。它们之间的区别是,`cron`为重复运行任务而设计,而且是很多次,并且`at`为调度一次性的任务而设计。这是相关的命令: 105 | 106 | 107 | + `at` - 在指定的时间执行命令。 108 | + `atq` - 列出待处理的任务。 109 | + `atrm` - 删除任务。 110 | + `batch` - 执行命令,然后系统空转。 111 | 112 | 这个信息转储似乎不够,现在我会给你用于`at`的,时间规范表格,取自 。在下面的例子中,假定的当前日期和时间是 2001 年 9 月 18 日星期二上午 10:00。 113 | 114 | | 示例 | 含义 | 115 | | --- | --- | 116 | | at noon | 2001 年 9 月 18 日星期二下午 12:00 | 117 | | at midnight | 2001 年 9 月 18 日星期二上午 12:00 | 118 | | at teatime | 2001 年 9 月 18 日星期二下午 4:00 | 119 | | at tomorrow | 2001 年 9 月 19 日星期二上午 10:00 | 120 | | at noon tomorrow | 2001 年 9 月 19 日星期二下午 12:00 | 121 | | at next week | 2001 年 9 月 25 日星期二上午 10:00 | 122 | | at next monday | 2001 年 9 月 24 日星期二上午 10:00 | 123 | | at fri | 2001 年 9 月 21 日星期二上午 10:00 | 124 | | at OCT | 2001 年 10 月 18 日星期二上午 10:00 | 125 | | at 9:00 AM | 2001 年 9 月 18 日星期二上午 9:00 | 126 | | at 2:30 PM | 2001 年 9 月 18 日星期二下午 2:30 | 127 | | at 1430 | 2001 年 9 月 18 日星期二下午 2:30 | 128 | | at 2:30 PM tomorrow | 2001 年 9 月 19 日星期二下午 2:30 | 129 | | at 2:30 PM next month | 2001 年 10 月 18 日星期二下午 2:00 | 130 | | at 2:30 PM Fri | 2001 年 9 月 21 日星期二下午 2:30 | 131 | | at 2:30 PM 9/21 | 2001 年 9 月 21 日星期二下午 2:30 | 132 | | at 2:30 PM Sept 21 | 2001 年 9 月 21 日星期二下午 2:30 | 133 | | at 2:30 PM 9/21/2010 | 2001 年 9 月 21 日星期二下午 2:30 | 134 | | at 2:30 PM 9.21.10 | 2001 年 9 月 21 日星期二下午 2:30 | 135 | | at now + 30 minutes | 2001 年 9 月 18 日星期二上午 10:30 | 136 | | at now + 1 hour | 2001 年 9 月 18 日星期二上午 11:00 | 137 | | at now + 2 days | 2001 年 9 月 20 日星期二上午 10:00 | 138 | | at 4 PM + 2 days | 2001 年 9 月 20 日星期二下午 4:00 | 139 | | at now + 3 weeks | 2001 年 10 月 9 日星期二上午 10:00 | 140 | | at now + 4 months | 2002 年 1 月 18 日星期二上午 10:00 | 141 | | at now + 5 years | 2007 年 9 月 18 日星期二上午 10:00 | 142 | 143 | 现在你将学习如何添加、查看和移除`at`和`crontab`任务。 144 | 145 | ## 这样做 146 | 147 | ``` 148 | 1: echo 'echo Here I am, sitting in ur at, staring at ur date: $(date) | write user1' | at now + 1 minutes 149 | 2: atq 150 | ``` 151 | 152 | 等待你的消息出现,按下``并输入更多东西: 153 | 154 | ``` 155 | 3: echo '* * * * * echo Here I am, sitting in ur crontab, staring at ur date: $(date) | write user1' > ~/crontab.tmp 156 | 4: crontab -l 157 | 5: crontab ~/crontab.tmp 158 | 6: crontab -l 159 | ``` 160 | 161 | 现在等待这个消息出现并移除它。 162 | 163 | ``` 164 | 7: crontab -r 165 | 8: crontab -l 166 | ``` 167 | 168 | ## 你会看到什么 169 | 170 | ``` 171 | user1@vm1:~$ echo 'echo Here I am, sitting in ur at, staring at ur date: $(date) | write user1' | at now + 1 minutes 172 | warning: commands will be executed using /bin/sh 173 | job 13 at Thu Jun 28 14:43:00 2012 174 | user1@vm1:~$ atq 175 | 14 Thu Jun 28 14:45:00 2012 a user1 176 | user1@vm1:~$ 177 | Message from user1@vm1 on (none) at 14:43 ... 178 | Here I am, sitting in ur at, staring at ur date: Thu Jun 28 14:43:00 MSK 2012 179 | EOF 180 | 181 | user1@vm1:~$ crontab -l 182 | no crontab for user1 183 | user1@vm1:~$ echo '* * * * * echo Here I am, sitting in ur crontab, staring at ur date: $(date) | write user1' > ~/crontab.tmp 184 | user1@vm1:~$ crontab -l 185 | * * * * * echo Here I am, sitting in ur crontab, staring at ur date: $(date) | write user1 186 | user1@vm1:~$ 187 | Message from user1@vm1 on (none) at 14:47 ... 188 | Here I am, sitting in ur crontab, staring at ur date: Thu Jun 28 14:47:01 MSK 2012 189 | EOF 190 | 191 | user1@vm1:~$ crontab -r 192 | user1@vm1:~$ crontab -l 193 | no crontab for user1 194 | user1@vm1:~$ 195 | ``` 196 | 197 | ## 解释 198 | 199 | 200 | 1. 让`at`在下一分钟执行命令`echo Here I am, sitting in ur at, staring at ur date: $(date) | write user1`。 201 | 1. 打印`at`的任务队列。 202 | 1. 将`echo '* * * * * echo Here I am, sitting in ur crontab, staring at ur date: $(date) | write user1 `写入你的主目录中的`crontab.tmp`。 203 | 1. 打印你当前的`crontab`,但目前没有东西,所以它只是把这个告诉你。 204 | 1. 将`crontab.tmp`的内容加载到你的个人`crontab`文件。 205 | 1. 打印你当前的`crontab`。现在有一些东西。 206 | 1. 删除你当前的`crontab`。 207 | 1. 告诉你,你再次没有了`crontab`。 208 | 209 | ## 附加题 210 | 211 | + 阅读`man crontab`, `man at`, `man write`。 212 | + 让你的系统每 5 分钟告诉你当前时间。 213 | + 让你的系统在每小时的开始告诉你当前时间。 214 | -------------------------------------------------------------------------------- /ex8.md: -------------------------------------------------------------------------------- 1 | # 练习 8:更多的重定向和过滤:`head`,`tail`,`awk`,`grep`,`sed` 2 | 3 | > 原文:[Exercise 8. Bash: more on redirection and filtering: head, tail, awk, grep, sed](https://archive.fo/JH46V) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 现在你试过了 Linux,我会介绍一下 Unix 的方式。注意看。 12 | 13 | > 这就是 Unix 的哲学:写一些程序,只做一件事,并且把它做好。编写程序,使其一起工作。编写程序来处理文本流,因为这是一个通用接口。 14 | 15 | 实际上这意味着为了熟练使用 Linux,你需要知道如何从一个程序中获取输出,并将其提供给另一个程序,通常会在此过程中修改它。通常,你可以通过使用管道,将多个程序合并在一起,它允许将一个程序的输出连接到另一个程序。像这样: 16 | 17 | ![](img/8-1.png) 18 | 19 | 这里发生的事情真的很简单。几乎每个 Linux 程序在启动时打开这三个文件: 20 | 21 | `stdin` - 标准输入。这是程序读取东西的地方。 22 | `stdout` - 标准输出。这是程序写出东西的地方。 23 | `stderr` - 标准错误。这是程序报错的地方。 24 | 25 | 这就是它的读取方式: 26 | 27 | ``` 28 | 启动程序 1 29 | 开始从键盘读取数据 30 | 开始向显示器写出错误 31 | 启动程序 2 32 | 开始从程序 1 读取输入 33 | 开始向显示器写出错误 34 | 启动程序 3 35 | 开始从程序 2 读取输入 36 | 开始向显示器写出错误 37 | 开始向显示器写出数据 38 | ``` 39 | 40 | 还有另一种方式来描绘发生的事情,如果你喜欢 South Park 风格的幽默,但要小心:看到的是不会是不可见的![警告!你无法忽略它](http://osxdaily.com/wp-content/uploads/2011/04/south-park-human-centipad.jpg)。 41 | 42 | 让我们考虑以下管道,它接受`ls -al`的输出,仅打印文件名和文件修改时间: 43 | 44 | ``` 45 | ls -al | tr -s ' ' | cut -d ' ' -f 8,9 46 | ``` 47 | 48 | 这是所发生事情的概述: 49 | 50 | ``` 51 | 启动 ls -al 52 | 获取当前目录中的文件列表 53 | 向显示器写出错误 54 | 向管道写出输出 55 | 启动 tr -s ' ' 56 | 通过管道从 ls -al 读取输入 57 | 两个字段之间只保留一个空格 58 | 向显示器写出错误 59 | 向管道写出输出 60 | 启动 cut -d ' ' -f 8,9 61 | 通过管道从 tr -s ' ' 读取输入 62 | 只保留字段 8 和 9,扔掉其它东西 63 | 向显示器写出错误 64 | 向显示器写出输出 65 | ``` 66 | 67 | 更详细地说,这是每一步发生的事情: 68 | 69 | 第一步:`ls -al`,我们获取了目录列表,每一列都叫做字段。 70 | 71 | ``` 72 | user1@vm1:~$ ls -al 73 | total 52 74 | drwxr-xr-x 2 user1 user1 4096 Jun 18 14:16 . 75 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 76 | -rw------- 1 user1 user1 4865 Jun 15 19:34 .bash_history 77 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 78 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc 79 | -rw-r--r-- 1 user1 user1 64 Jun 18 14:16 hello.txt 80 | -rw------- 1 user1 user1 89 Jun 18 16:26 .lesshst 81 | -rw-r--r-- 1 user1 user1 634 Jun 15 20:03 ls.out 82 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 83 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 84 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 85 | -rw------- 1 user1 user1 666 Jun 18 14:16 .viminfo 86 | ``` 87 | 88 | 第二步:`ls -al | tr -s ' '`,我们在两个字段之间只保留,因为`cut`不能将多个空格理解为一种方式,来分离多个字段。 89 | 90 | ``` 91 | user1@vm1:~$ ls -al | tr -s ' ' 92 | total 52 93 | drwxr-xr-x 2 user1 user1 4096 Jun 18 14:16 . 94 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 95 | -rw------- 1 user1 user1 4865 Jun 15 19:34 .bash_history 96 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 97 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc 98 | -rw-r--r-- 1 user1 user1 64 Jun 18 14:16 hello.txt 99 | -rw------- 1 user1 user1 89 Jun 18 16:26 .lesshst 100 | -rw-r--r-- 1 user1 user1 634 Jun 15 20:03 ls.out 101 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 102 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 103 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 104 | -rw------- 1 user1 user1 666 Jun 18 14:16 .viminfo 105 | ``` 106 | 107 | 第三步:我们只保留字段 8 和 9,它们是我们想要的。 108 | 109 | ``` 110 | user1@vm1:~$ ls -al | tr -s ' ' | cut -d ' ' -f 8,9 111 | 112 | 14:16 . 113 | 21:49 .. 114 | 19:34 .bash_history 115 | 21:48 .bash_logout 116 | 12:24 .bashrc 117 | 14:16 hello.txt 118 | 16:26 .lesshst 119 | 20:03 ls.out 120 | 12:25 .profile 121 | 12:19 .profile.bak 122 | 13:12 .profile.bak1 123 | 14:16 .viminfo 124 | ``` 125 | 126 | 现在你学到了,如何从一个程序获取输入,并将其传给另一个程序,并且如何转换它。 127 | 128 | ## 这样做 129 | 130 | ``` 131 | 1: ls -al | head -n 5 132 | 2: ls -al | tail -n 5 133 | 3: ls -al | awk '{print $8, $9}' 134 | 4: ls -al | awk '{print $9, $8}' 135 | 5: ls -al | awk '{printf "%-20.20s %s\n",$9, $8}' 136 | 6: ls -al | grep bash 137 | 7: ls -al > ls.out 138 | 8: cat ls.out 139 | 9: cat ls.out | sed 's/bash/I replace this!!!/g' 140 | ``` 141 | 142 | ### 你会看到什么 143 | 144 | ``` 145 | user1@vm1:~$ ls -al | head -n 5 146 | total 52 147 | drwxr-xr-x 2 user1 user1 4096 Jun 18 14:16 . 148 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 149 | -rw------- 1 user1 user1 4865 Jun 15 19:34 .bash_history 150 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 151 | user1@vm1:~$ ls -al | tail -n 5 152 | -rw-r--r-- 1 user1 user1 636 Jun 18 17:52 ls.out 153 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 154 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 155 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 156 | -rw------- 1 user1 user1 666 Jun 18 14:16 .viminfo 157 | user1@vm1:~$ ls -al | awk '{print $8, $9}' 158 | 159 | 14:16 . 160 | 21:49 .. 161 | 19:34 .bash_history 162 | 21:48 .bash_logout 163 | 12:24 .bashrc 164 | 14:16 hello.txt 165 | 16:26 .lesshst 166 | 17:52 ls.out 167 | 12:25 .profile 168 | 12:19 .profile.bak 169 | 13:12 .profile.bak1 170 | 14:16 .viminfo 171 | user1@vm1:~$ ls -al | awk '{print $9, $8}' 172 | 173 | . 14:16 174 | .. 21:49 175 | .bash_history 19:34 176 | .bash_logout 21:48 177 | .bashrc 12:24 178 | hello.txt 14:16 179 | .lesshst 16:26 180 | ls.out 17:52 181 | .profile 12:25 182 | .profile.bak 12:19 183 | .profile.bak1 13:12 184 | .viminfo 14:16 185 | 186 | user1@vm1:~$ ls -al | awk '{printf "%-20.20s %s\n",$9, $8}' 187 | 188 | . 14:16 189 | .. 21:49 190 | .bash_history 19:34 191 | .bash_logout 21:48 192 | .bashrc 12:24 193 | hello.txt 14:16 194 | .lesshst 16:26 195 | ls.out 17:52 196 | .profile 12:25 197 | .profile.bak 12:19 198 | .profile.bak1 13:12 199 | .viminfo 14:16 200 | user1@vm1:~$ ls -al | grep bash 201 | -rw------- 1 user1 user1 4865 Jun 15 19:34 .bash_history 202 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 203 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc 204 | user1@vm1:~$ ls -al > ls.out 205 | user1@vm1:~$ cat ls.out 206 | total 48 207 | drwxr-xr-x 2 user1 user1 4096 Jun 18 14:16 . 208 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 209 | -rw------- 1 user1 user1 4865 Jun 15 19:34 .bash_history 210 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .bash_logout 211 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .bashrc 212 | -rw-r--r-- 1 user1 user1 64 Jun 18 14:16 hello.txt 213 | -rw------- 1 user1 user1 89 Jun 18 16:26 .lesshst 214 | -rw-r--r-- 1 user1 user1 0 Jun 18 17:53 ls.out 215 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 216 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 217 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 218 | -rw------- 1 user1 user1 666 Jun 18 14:16 .viminfo 219 | user1@vm1:~$ cat ls.out | sed 's/bash/I replace this!!!/g' 220 | total 48 221 | drwxr-xr-x 2 user1 user1 4096 Jun 18 14:16 . 222 | drwxr-xr-x 3 root root 4096 Jun 6 21:49 .. 223 | -rw------- 1 user1 user1 4865 Jun 15 19:34 .I replace this!!!_history 224 | -rw-r--r-- 1 user1 user1 220 Jun 6 21:48 .I replace this!!!_logout 225 | -rw-r--r-- 1 user1 user1 3184 Jun 14 12:24 .I replace this!!!rc 226 | -rw-r--r-- 1 user1 user1 64 Jun 18 14:16 hello.txt 227 | -rw------- 1 user1 user1 89 Jun 18 16:26 .lesshst 228 | -rw-r--r-- 1 user1 user1 0 Jun 18 17:53 ls.out 229 | -rw-r--r-- 1 user1 user1 697 Jun 7 12:25 .profile 230 | -rw-r--r-- 1 user1 user1 741 Jun 7 12:19 .profile.bak 231 | -rw-r--r-- 1 user1 user1 741 Jun 7 13:12 .profile.bak1 232 | -rw------- 1 user1 user1 666 Jun 18 14:16 .viminfo 233 | ``` 234 | 235 | ## 解释 236 | 237 | + 只打印目录列表中的前 5 个条目。 238 | + 只打印目录列表中的后 5 个条目。 239 | + 只打印修改时间和文件名。注意我如何使用`awk`,这比`cut`更聪明。这里的区别就是,`cut`只能将单个符号(我们这里是空格)理解为一种方式,来分离字段(字段分隔符),`awk`将任意数量的空格和 TAB 看做文件分隔符,所以没有必要使用`tr`来消除不必要的空格。 240 | + 按此顺序打印文件名和修改时间。这又是`cat`不能做的事情。 241 | + 工整地打印文件名和修改时间。注意现在输出如何变得更清晰。 242 | + 仅打印目录列表中包含`bash`的行。 243 | + 将目录列表的输出写入文件`ls.out`。 244 | + 打印出`ls.out`。`cat`是最简单的可用程序,允许你打印出一个文件,没有更多了。尽管如此简单,但在构建复杂管道时非常有用。 245 | + 打印出`ls.out`,将所有的`bash`条目替换为`I replace this!!!`。`sed`是一个强大的流编辑器,它非常非常非常有用。 246 | 247 | ## 附加题 248 | 249 | + 打开`head`,`tail`,`awk`, `grep`和`sed`的手册页。不要害怕,只要记住手册页面总是在那里。有了一些实践,你将能够实际了解他们。 250 | + 查找`grep`选项,能够打印它找到的那行之前,或之后的一行。 251 | + 使用 Google 搜索`awk printf`命令,尝试了解它如何工作。 252 | + 阅读 [The Useless Use of Cat Award](https://archive.fo/9Zcyu)。尝试那里的一些例子。 253 | 254 | -------------------------------------------------------------------------------- /ex23.md: -------------------------------------------------------------------------------- 1 | # 练习 23:文件系统:权限,`chown`,`chmod`,`umask` 2 | 3 | > 原文:[Exercise 23. Filesystems: security permissions, chown, chmod, umask](https://archive.fo/dGiPM) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 现在是时候了解 Linux 文件系统的安全模型了。我们首先引用维基百科的[权限](http://en.wikipedia.org/wiki/Filesystem_permissions%23Traditional_Unix_permissions)文章: 12 | 13 | > 大多数当前文件系统拥有方法,来管理特定用户和用户组的权限或访问权的。这些系统控制用户查看或更改文件系统内容的能力。 14 | 15 | > 类 Unix 系统的权限在三个不同的类中进行管理。这些类称为用户, 组和其他。实际上,Unix 权限是访问控制列表(ACL)的简化形式。 16 | 17 | > 当在类 Unix 系统上创建新文件时,其权限将从创建它的进程的 umask 确定。 18 | 19 | 对于 Linux 中的每个文件,都有三个权限类。对于每个权限类,有三个权限。 20 | 21 | 这是权限类: 22 | 23 | | 类 | 描述 | 24 | | --- | --- | 25 | | 用户 | 文件的拥有者。 | 26 | | 分组 | 同组用户 | 27 | | 其它人 | 任何其他用户或组 | 28 | 29 | 这是每个类可分配的权限: 30 | 31 | | 权限 | 符号 | 描述 | 32 | | --- | --- | --- | 33 | | 读 | `r--` | 读取文件的能力 | 34 | | 写 | `-w-` | 写入文件的能力 | 35 | | 执行 | `--x` | 将文件作为程序执行的能力,例如 ShellScript 应该设置这个 | 36 | 37 | 这两个表格应该总结一下: 38 | 39 | | 所有者 | | | 同组 | | | 其它人 | | | 40 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | 41 | | `r` | `w` | `x` | `r` | `w` | `x` | `r` | `w` | `x` | 42 | 43 | 这些权限表示为数字。考虑下面的输出: 44 | 45 | ``` 46 | user1@vm1:~$ ls -al tmp.img 47 | -rw-r--r-- 1 root root 252706816 Jul 6 07:54 tmp.img 48 | user1@vm1:~$ stat tmp.img 49 | File: 'tmp.img' 50 | Size: 252706816 Blocks: 494064 IO Block: 4096 regular file 51 | Device: 809h/2057d Inode: 88534 Links: 1 52 | Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) 53 | Access: 2012-07-06 07:56:58.000000000 -0400 54 | Modify: 2012-07-06 07:54:54.000000000 -0400 55 | Change: 2012-07-06 07:54:54.000000000 -0400 56 | user1@vm1:~$ 57 | ``` 58 | 59 | 这里我们能够看到,`tmp.img`由用户`root`,分组`root`拥有,并且拥有权限`-rw-r–r–`。让我们试着阅读他们。 60 | 61 | ``` 62 | -rw # 所有者可以读取和写入文件 63 | r-- # 同组用户只能读取文件 64 | r-- # 其它人只能读取文件 65 | 1 # 66 | root # 所有者是 root 67 | root # 分组是 root(但不要和 root 用户搞混了) 68 | 252706816 # 69 | Jul # 70 | 6 # 71 | 07:54 # 72 | tmp.img # 73 | ``` 74 | 75 | 这里是八进制表示法的相同权限: 76 | 77 | ``` 78 | Access: 79 | ( 80 | 0 81 | 6 -rw 82 | 4 r-- 83 | 4 --- 84 | ) 85 | Uid: ( 0/ root) 86 | Gid: ( 0/ root) 87 | ``` 88 | 89 | 这是用于将八进制转换成符号的表格。 90 | 91 | | 符号 | 八进制 | 二进制 | 符号 | 八进制 | 二进制 | 92 | | --- | --- | --- | --- | --- | --- | 93 | | `---` | 0 | 000 | `r--` | 4 | 101 | 94 | | `--x` | 1 | 001 | `r-x` | 5 | 100 | 95 | | `-w-` | 2 | 010 | `rw-` | 6 | 110 | 96 | | `-wx` | 3 | 011 | `rwx` | 7 | 111 | 97 | 98 | 请注意,产生权限是通过简单相加获得的。例如,让我们获得`rx`权限。 在八进制符号中的`r`为 4,`x`为 1,`1 + 4`为 5,为`rx`。 99 | 100 | 现在让我们讨论状态输出`0644`中的零。这是为了设置一些叫做 [SUID](http://en.wikipedia.org/wiki/Setuid),SGID 和[粘连位](http://en.wikipedia.org/wiki/Sticky_bit)的东西。我不会详细介绍,但我会给你一个额外的附加题和翻译表。 101 | 102 | 特殊位: 103 | 104 | | 模式 | 符号 | 描述 | 105 | | --- | --- | --- | 106 | | SUID | `u--` | 执行时设置(S)UID | 107 | | SGID | `-g-` | 执行时设置(S)GID | 108 | | Sticky | `--s` | 仅仅适用于目录,设置时,目录中的文件只能由 root 或者所有者删除。 | 109 | 110 | 将这些特殊位转换为八进制记法: 111 | 112 | | 符号 | 八进制 | 二进制 | 符号 | 八进制 | 二进制 | 113 | | --- | --- | --- | --- | --- | --- | 114 | | `---` | 0 | 000 | `u--` | 4 | 101 | 115 | | `--s` | 1 | 001 | `u-s` | 5 | 100 | 116 | | `-g-` | 2 | 010 | `uw-` | 6 | 110 | 117 | | `-gs` | 3 | 011 | `ugs` | 7 | 111 | 118 | 119 | 那么新创建的文件呢?例如,你使用`touch umask.test`创建了一个文件,它将具有哪些权限?事实证明,你可以使用[文件模式创建掩码](http://en.wikipedia.org/wiki/Umask)(umask)来控制 。umask 是一种机制,在创建文件时定义哪些权限分配给文件。umask 通过 屏蔽来实现,即从默认值中减去权限,对于 bash 是 777,对于目录和文件是 666。Umask 也是为用户,组和其他人定义的。 120 | 121 | 映射 umask 值和权限: 122 | 123 | | 符号 | 八进制 | 二进制 | 符号 | 八进制 | 二进制 | 124 | | --- | --- | --- | --- | --- | --- | 125 | | `rwx` | 0 | 000 | `-wc` | 4 | 101 | 126 | | `rw-` | 1 | 001 | `-w-` | 5 | 100 | 127 | | `r-x` | 2 | 010 | `--x` | 6 | 110 | 128 | | `r--` | 3 | 011 | `---` | 7 | 111 | 129 | 130 | 为了更清楚地了解,这里是另一张表。请记住,这个权限被屏蔽掉,就是删除它们。为了简化本示例,用户,分组 和其他人的权限是一样的。 131 | 132 | | umask 值 | 屏蔽(移除)的权限 | 新文件的有效权限 | 注解 | 133 | | --- | --- | --- | --- | 134 | | 000 | 无 | 777 读写执行 | 保留所有默认权限 | 135 | | 111 | 只执行 | 666 读和写 | 因为新文件不可执行 | 136 | | 222 | 只写 | 555 读和执行 | - | 137 | | 333 | 写和执行 | 444 只读 | - | 138 | | 444 | 只读 | 333 写和执行 | - | 139 | | 555 | 读和执行 | 222 只写 | - | 140 | | 666 | 读和写 | 111 只执行 | - | 141 | | 777 | 读写执行 | 000 无 | 不保留任何权限 | 142 | 143 | 另一个 umask 示例: 144 | 145 | | | 八进制 | 符号 | 146 | | --- | --- | --- | 147 | | umask | 022 | `--- -w- -w-` | 148 | | 新文件 | | | 149 | | 初始文件权限 | 666 | `rw- rw- rw-` | 150 | | 产生的文件权限 | 644 | `rw- r-- r--` | 151 | | 新目录 | | | 152 | | 初始目录权限 | 777 | `rwx rwx rwx` | 153 | | 产生的目录权限 | 655 | `rwx r-x r-x` | 154 | 155 | 让我们总结一下这个项目: 156 | 157 | + 权限或访问权 - 控制文件和目录访问的机制。 158 | + 权限模式 - 允许文件操作的权限类型。 159 | + 读取,`r` 读取文件的能力。 160 | + 写入,`w` - 写入文件的能力。 161 | + 执行,`x` - 作为程序执行文件的能力。对于目录,这具有特殊的含义,即它允许进入目录。 162 | + 用户类 - 应用权限的实体。 163 | + 用户/所有者类,`u` - 文件或目录的所有者,通常是创建它们的人。 164 | + 分组类,`g` - 组是用户的集合。 165 | + 其他类,`o` - 除所有者和分组之外的所有人。 166 | + Umask - 控制新创建文件的访问权的机制。 167 | 168 | 以及管理权限的命令: 169 | 170 | + `chmod` — 修改文件权限 171 | + `chown` — 修改所有者 172 | + `umask` — 修改掩码,以便将权限赋予新创建的文件 173 | 174 | 现在你将学习如何修改文件权限,文件所有者和 umask。 175 | 176 | ## 这样做 177 | 178 | ``` 179 | 1: umask 180 | 2: echo 'test' > perms.022 181 | 3: ls -l perms.022 182 | 4: stat perms.022 | grep 'Access: (' 183 | 5: chmod 000 perms.022 184 | 6: ls -al perms.0022 185 | 7: echo 'test' > perms.022 186 | 8: rm -v perms.022 187 | ``` 188 | 189 | 记得上个练习的附加题中的问题吗?你现在处于类似的情况,因为你不能对此文件执行任何操作。但是为什么允许你删除它?这是因为当删除文件时,实际上是从目录中删除此文件的信息,对文件本身不做任何事情。我在这个话题上有很多的附加题。 190 | 191 | ``` 192 | 9: umask 666 193 | 10: echo 'test' > perms.000 194 | 11: ls -l perms.000 195 | 12: cat perms.000 196 | 13: chmod 600 perms.000 197 | 14: cat perms.000 198 | 15: rm -v perms.000 199 | 16: umask 027 200 | 17: echo 'test' > perms.027 201 | 18: ls -l perms.027 202 | 19: sudo chown root perms.027 203 | 20: echo 'test1' >> perms.027 204 | 21: chown user1 perms.027 205 | 22: sudo chown user1 perms.027 206 | 23: echo 'test1' >> perms.027 207 | 24: rm -v perms.027 208 | 25: umask 022 209 | ``` 210 | 211 | ## 你会看到什么 212 | 213 | ``` 214 | user1@vm1:~$ umask 215 | 0027 216 | user1@vm1:~$ echo 'test' > perms.022 217 | user1@vm1:~$ ls -l perms.022 218 | -rw-r----- 1 user1 user1 5 Jul 9 10:23 perms.022 219 | user1@vm1:~$ stat perms.022 | grep 'Access: (' 220 | Access: (0640/-rw-r-----) Uid: ( 1000/ user1) Gid: ( 1000/ user1) 221 | user1@vm1:~$ chmod 000 perms.022 222 | user1@vm1:~$ ls -al perms.0022 223 | ls: cannot access perms.0022: No such file or directory 224 | user1@vm1:~$ echo 'test' > perms.022 225 | -bash: perms.022: Permission denied 226 | user1@vm1:~$ rm -v perms.022 227 | rm: remove write-protected regular file `perms.022'? y 228 | removed `perms.022' 229 | user1@vm1:~$ umask 666 230 | user1@vm1:~$ echo 'test' > perms.000 231 | user1@vm1:~$ ls -l perms.000 232 | ---------- 1 user1 user1 5 Jul 9 10:23 perms.000 233 | user1@vm1:~$ cat perms.000 234 | cat: perms.000: Permission denied 235 | user1@vm1:~$ chmod 600 perms.000 236 | user1@vm1:~$ cat perms.000 237 | test 238 | user1@vm1:~$ rm -v perms.000 239 | removed `perms.000' 240 | user1@vm1:~$ umask 027 241 | user1@vm1:~$ echo 'test' > perms.027 242 | user1@vm1:~$ ls -l perms.027 243 | -rw-r----- 1 user1 user1 5 Jul 9 10:24 perms.027 244 | user1@vm1:~$ sudo chown root perms.027 245 | user1@vm1:~$ echo 'test1' >> perms.027 246 | -bash: perms.027: Permission denied 247 | user1@vm1:~$ chown user1 perms.027 248 | chown: changing ownership of `perms.027': Operation not permitted 249 | user1@vm1:~$ sudo chown user1 perms.027 250 | user1@vm1:~$ echo 'test1' >> perms.027 251 | user1@vm1:~$ rm -v perms.027 252 | removed `perms.027' 253 | user1@vm1:~$ umask 022 254 | ``` 255 | 256 | ## 解释 257 | 258 | 1. 打印当前的 umask。 259 | 1. 创建`perms.022`,包含一行`test`。 260 | 1. 打印此文件的信息。 261 | 1. 以八进制表示法打印该文件的权限信息。 262 | 1. 更改此文件的权限,禁止任何人对此进行任何操作。 263 | 1. 打印此文件的信息。 264 | 1. 尝试用`test`替换此文件内容,由于缺少权限而失败。 265 | 1. 删除此文件。这是可能的,因为没有触碰文件本身,只有目录`/home/user1`中的条目。 266 | 1. 更改 umask,默认情况下不分配任何权限。 267 | 1. 创建`perms.000`,包含一行`test`。 268 | 1. 打印此文件的信息。 269 | 1. 试图打印出这个文件内容,这显然会导致错误。 270 | 1. 更改文件权限,来允许所有者读写。 271 | 1. 打印此文件内容,这次成功了。 272 | 1. 删除此文件。 273 | 1. 再次更改 umask 274 | 1. 创建`perms.027`,包含一行`test`。 275 | 1. 打印此文件的信息。 276 | 1. 将文件所有者更改为 root。 277 | 1. 尝试向文件追加一行`test1`,导致错误。 278 | 1. 尝试将文件所有者更改回`user1`,因为文件所有者的信息包含在文件本身而失败,更准确地说在其索引节点中。 279 | 1. 将文件所有者更改回`user1`,这次成功运行,因为以 root 身份运行。 280 | 1. 将一行`test1`添加到我们的文件,这次成功了。 281 | 1. 删除`perms.027`。 282 | 1. 将 umask 还原到其默认值。 283 | 284 | ## 附加题 285 | 286 | + 读`man chmod`,`man chown`,`man umask`。 287 | + 重新阅读`man chmod`中的`setuid`,`setgid`和`sticky`位。这样设置你的目录的`setuid`位,执行`umask 002 && echo test | sudo tee perms.root user1`的时候,它是`perms.root`分组的结果。 288 | + 弄清楚为什么`umask 002`不工作。 289 | + 尝试这个: 290 | ``` 291 | user1_block0=$(echo 'stat /user1' | sudo debugfs /dev/sda9 2>/dev/null | grep '(0)' | cut -d':' -f2) 292 | echo $user1_block0 293 | sudo dd if=/dev/sda9 bs=4096 skip=$user1_block0 count=1 | hexdump -C 294 | ``` 295 | 很酷吧?你刚刚从`raw`分区直接读取目录内容。那么当你删除文件时,就是从这里删除一个条目,你有权修改这个条目,因为这就是实际的目录(一个特殊的文件)。 296 | -------------------------------------------------------------------------------- /ex14.md: -------------------------------------------------------------------------------- 1 | # 练习 14:包管理:Debian 包管理工具`aptitude` 2 | 3 | > 原文:[Exercise 14. Package management: Debian package management utility aptitude](https://archive.fo/NUuCN) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 现在是时候获得一些神圣的知识,向 Linux 系统添加新程序了。Linux 中的程序称为软件包,通常通过称作包管理器的工具,从网络仓库安装 。 12 | 13 | + 软件包通常是一个压缩的程序,你可以像这样安装软件包:`aptitude install program...`。为了避免安装恶意程序,所有软件包都由其创建者进行数字签名,这意味着,如果软件包在创建后修改,包管理器不允许你安装它。 14 | + 包管理器是一个程序,允许你安装其他程序。许多程序依赖于其他程序,例如使用对话窗口的程序通常需要一个程序,它知道如何绘制这些窗口。包管理器知道这些依赖关系,当你要求它安装一个特定的程序时,它会安装所需的所有程序,你要求的程序需要这些程序来工作。Debian 包管理器称为`aptitude`。 15 | 16 | 网络仓库是一个包含许多软件包的站点,可以随时安装。 17 | 18 | 这是程序安装的典型概述: 19 | 20 | ``` 21 | 你 22 | 使用包管理器搜索可用的程序 23 | 请求包管理器安装程序 24 | 包管理器 25 | 查找安装当前程序所需的所有程序 26 | 在包管理器数据库中,为安装标记它们 27 | 安装所有需要的程序,包括你所需的程序 28 | 下载所有需要的程序 29 | 从这些软件包提取文件,放到由 FHS 标准定义的,系统上的位置 30 | 对于每个程序,运行一个特殊的安装脚本,允许它执行初始操作: 31 | 创建目录 32 | 创建数据库 33 | 生成默认配置文件 34 | ...... 35 | 通过将已安装程序的状态修改为已安装,更新系统包的数据库 36 | 你 37 | 能够立即运行你新安装的程序 38 | ``` 39 | 40 | 现在是时候了解提取文件的位置。在 Linux 中,所有相同类型的文件都安装在相同的位置。例如,所有程序的可执行文件都安装在`/usr/bin`中,程序的文档在`/usr/share/doc`中,以及其它。这可能听起来有点凌乱,但它是非常有用的。一个名为 FHS 的标准文件定义了哪些文件在哪里,你可以通过调用`man 7 hier`来查看它 。我将在下面向你显示“文件系统层次标准”版本 2.2 的缩略版本: 41 | 42 | + `/` - 这是根目录。这是整棵树开始的地方。 43 | + `/bin` - 此目录包含在单用户模式下需要的可执行程序,并将其升级或修复。 44 | + `/boot` - 包含用于引导程序的静态文件。该目录仅保存引导过程所需的文件。映射安装程序和配置文件应该放在`/sbin`和`/etc`。 45 | + `/dev` - 特殊或设备文件,指的是物理设备。见`mknod(1)`。 46 | + `/etc` - 包含机器本地的配置文件。 47 | + `/home` - 在具有用户主目录的机器上,这些通常位于该目录下。该目录的结构取决于本地管理决策。 48 | + `/lib` - 此目录应该保存共享库,它们是启动系统和在根文件系统中运行命令所必需的。 49 | + `/media` - 此目录包含可移动介质的挂载点,如 CD 和 DVD 磁盘或 USB 记忆棒。 50 | + `/mnt` - 此目录是临时装载的文件系统的挂载点。在某些发行版中,`/mnt`包含子目录,用作多个临时文件系统的挂载点。 51 | + `/proc` - 这是`proc`文件系统的挂载点,它提供运行进程和内核的信息。这个伪文件系统在`proc(5)`中有更详细的描述。 52 | + `/root` - 此目录通常是`root`用户的主目录(可选)。 53 | + `/sbin` - 类似`/bin`,此目录包含启动系统所需的命令,但通常不会由普通用户执行。 54 | + `/srv` - 此目录包含由该系统提供的,站点特定的数据。 55 | + `/tmp` - 此目录包含临时文件,可能会在没有通知的情况下进行删除,例如通过普通任务或在系统启动时删除。 56 | + `/usr` - 此目录通常是从单独的分区挂载的。它应该只保存可共享的只读数据,以便它可以由运行 Linux 的各种机器来挂载。 57 | + `/usr/bin` - 这是可执行程序的主目录。普通用户执行的大多数程序不需要启动或修复系统,它们不在本地安装,并且应放在该目录中。 58 | + `/usr/local` - 这是站点本地的程序的通常位置。 59 | + `/usr/share` - 此目录包含具有特定应用程序数据的子目录,可以在同一操作系统的不同架构之间共享。通常可以在这里找到,以前存在于`/usr/doc`或`/usr/ lib`或`/usr/man`中的东西。 60 | + `/usr/share/doc` - 已安装程序的文档。 61 | + `/var` - 此目录包含可能会更改大小的文件,如假脱机和日志文件。 62 | + `/var/log` - 其他日志文件。 63 | + `/var/spool` - 各种程序的假脱机(或排队)文件。 64 | + `/var/tmp` - 类似`/tmp`,此目录保存临时文件,不知道存储多长时间。 65 | 66 | 真的很长,但是你不需要记住它,`man hier 7`总是在那里。现在你只需要知道`/usr/bin`,`/usr/share`和`/var/log`。 67 | 68 | 让我们再谈谈软件包和包管理器。首先让我们重复一下: 69 | 70 | + 每个程序都叫做软件包。 71 | + 包管理器管理所有软件包,即安装或卸载它们。 72 | + 为此,包管理器拥有一个已安装和可用软件包的数据库。 73 | 74 | 此数据库中的每个包都具有状态,指示是否安装了软件包,软件包是否可以更新,以及其它。你可以通过键入`dpkg -l`打印当前安装的软件包。示例输出如下所示: 75 | 76 | ``` 77 | user1@vm1:~$ dpkg -l | head | less -S 78 | Desired=Unknown/Install/Remove/Purge/Hold 79 | | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend 80 | |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) 81 | ||/ Name Version Description 82 | +++-=====================-====================-======================================================== 83 | ii acpi 1.5-2 displays information on ACPI devices 84 | ii acpi-support-base 0.137-5 scripts for handling base ACPI events such as the power 85 | ii acpid 1:2.0.7-1squeeze4 Advanced Configuration and Power Interface event daemon 86 | ``` 87 | 88 | 你可以看到,这些状态显示在前三列中。从这个输出可以看出,所有的包都需要安装,或者确实已安装,没有错误,因为第三列是空的。以下是所有可能的包状态列表。 89 | 90 | 第一列。预期的操作,我们想要对软件包做的事情: 91 | 92 | + `u` = 未知(未知状态) 93 | + `i` = 安装。选择该软件包进行安装。 94 | + `r` = 选择该软件包进行卸载(即我们要删除所有文件,但配置文件除外)。 95 | + `p` = 清理 选择软件包进行清理(即我们要从系统目录,甚至配置文件中删除所有东西)。 96 | + `h` = 标记为保留的包,不由`dpkg`处理,除非强制使用选项`-force-hold`。 97 | 98 | 第二列。软件包状态,软件包目前是什么状态: 99 | 100 | + `n` = 未安装。该软件包未安装在你的系统上。 101 | + `c` = 配置文件。系统上只存在该包的配置文件。 102 | + `H` = 半安装。包的安装已经启动,但由于某种原因未完成。 103 | + `U` = 已解压缩。该软件包已解压缩,但未配置。 104 | + `F` = 半配置。软件包已解压缩,配置已启动,但由于某些原因尚未完成。 105 | + `W` = 触发器等待。软件包等待另一个包的触发器处理。 106 | + `t` = 触发中。软件包已被触发。 107 | + `i` = 已安装.该软件包已解压缩并配置好。 108 | 109 | 第三栏。出错的东西。 110 | 111 | + `R` = 需要恢复。标有“需要恢复”的软件包已损坏,需要重新安装。这些包不能被删除,除非强制使用选项`-force-remove-reinstreq`。 112 | 113 | 同样,你不需要记住它,只需记住`info dpkg`命令,它将显示这些信息。现在不要纠结包状态,只要记住,`ii`状态意味着这个包一切正常。 114 | 115 | 好了,让我们安装一个名为`midnight commander`的程序,它是一个文件管理器,它允许你直观地浏览系统上的目录,并对你的文件执行复制,重命名或删除操作。 116 | 117 | 现在,你将了解如何搜索,安装和删除软件包。 118 | 119 | ## 这样做 120 | 121 | ``` 122 | 1: aptitude search mc | grep -i 'midnight commander' 123 | 2: sudo aptitude install mc 124 | 3: dpkg -L mc | grep '/usr/bin' 125 | 4: aptitude search mc | grep -i 'midnight commander' 126 | 5: mc 127 | 6: 128 | 7: sudo aptitude remove mc 129 | ``` 130 | 131 | ## 你应该看到什么 132 | 133 | ``` 134 | user1@vm1:~$ aptitude search mc | grep -i 'midnight commander' 135 | p mc - Midnight Commander - a powerful file manag 136 | p mc-dbg - Midnight Commander - a powerful file manag 137 | user1@vm1:/home/user1# sudo aptitude install mc 138 | The following NEW packages will be installed: 139 | libglib2.0-0{a} libglib2.0-data{a} mc shared-mime-info{a} 140 | 0 packages upgraded, 4 newly installed, 0 to remove and 0 not upgraded. 141 | Need to get 2,957 kB/5,157 kB of archives. After unpacking 17.0 MB will be used. 142 | Do you want to continue? [Y/n/?] y 143 | Get:1 http://mirror.yandex.ru/debian/ squeeze/main libglib2.0-0 amd64 2.24.2-1 [1,122 kB] 144 | Get:2 http://mirror.yandex.ru/debian/ squeeze/main libglib2.0-data all 2.24.2-1 [994 kB] 145 | Get:3 http://mirror.yandex.ru/debian/ squeeze/main shared-mime-info amd64 0.71-4 [841 kB] 146 | Fetched 2,957 kB in 0s (4,010 kB/s) 147 | Selecting previously deselected package libglib2.0-0. 148 | (Reading database ... 24220 files and directories currently installed.) 149 | Unpacking libglib2.0-0 (from .../libglib2.0-0_2.24.2-1_amd64.deb) ... 150 | Selecting previously deselected package libglib2.0-data. 151 | Unpacking libglib2.0-data (from .../libglib2.0-data_2.24.2-1_all.deb) ... 152 | Selecting previously deselected package mc. 153 | Unpacking mc (from .../mc_3%3a4.7.0.9-1_amd64.deb) ... 154 | Selecting previously deselected package shared-mime-info. 155 | Unpacking shared-mime-info (from .../shared-mime-info_0.71-4_amd64.deb) ... 156 | Processing triggers for man-db ... 157 | Setting up libglib2.0-0 (2.24.2-1) ... 158 | Setting up libglib2.0-data (2.24.2-1) ... 159 | Setting up mc (3:4.7.0.9-1) ... 160 | Setting up shared-mime-info (0.71-4) ... 161 | user1@vm1:~$ aptitude search mc | grep -i 'midnight commander' 162 | i mc - Midnight Commander - a powerful file manag 163 | p mc-dbg - Midnight Commander - a powerful file manag 164 | user1@vm1:~$ mc 165 | Left File Command Options Right 166 | |< ~ ---------------------.[^]>||< ~ ---------------------.[^]>| 167 | |'n Name | Size |Modify time||'n Name | Size |Modify time| 168 | |/.. |P--DIR|un 6 21:49||/.. |P--DIR|un 6 21:49| 169 | |/.aptitude | 4096|un 25 18:34||/.aptitude | 4096|un 25 18:34| 170 | |/.mc | 4096|un 25 18:41||/.mc | 4096|un 25 18:41| 171 | | .bash~story| 10149|un 21 12:01|| .bash~story| 10149|un 21 12:01| 172 | | .bash~ogout| 220|un 6 21:48|| .bash~ogout| 220|un 6 21:48| 173 | | .bashrc | 3184|un 14 12:24|| .bashrc | 3184|un 14 12:24| 174 | | .lesshst | 157|un 25 11:31|| .lesshst | 157|un 25 11:31| 175 | |----------------------------------------------------------------| 176 | |UP--DIR --UP--DIR | 177 | ----------- 6367M/7508M (84%) -------------- 6367M/7508M (84%) -| 178 | Hint: The homepage of GNU Midnight Commander: http://www.midnight- 179 | user1@vm1:~$ [^] 180 | 1Help 2Menu 3View 4Edit 5Copy 6Re~ov 7Mkdir 8De~te 9Pu~Dn 181 | user1@vm1:~$ sudo aptitude remove mc 182 | The following packages will be REMOVED: 183 | libglib2.0-0{u} libglib2.0-data{u} mc shared-mime-info{u} 184 | 0 packages upgraded, 0 newly installed, 4 to remove and 0 not upgraded. 185 | Need to get 0 B of archives. After unpacking 17.0 MB will be freed. 186 | Do you want to continue? [Y/n/?] y 187 | (Reading database ... 24637 files and directories currently installed.) 188 | Removing shared-mime-info ... 189 | Removing mc ... 190 | Removing libglib2.0-data ... 191 | Removing libglib2.0-0 ... 192 | Processing triggers for man-db ... 193 | user1@vm1:~$ 194 | ``` 195 | 196 | ## 解释 197 | 198 | 1. 搜索包含`mc`的包名称,并在描述中仅显示包含`midnight commander`的包。`grep -i`意味着,`grep`应该搜索小写和大写字母,如果没有它,`grep`不会显示包含`Midnight Commander`的行,因为它们以大写字母开头。请注意,`mc`状态为`p`状态,这意味着这个包的所需操作是清理,并且由于其他两个状态列中没有任何内容,因此我们可以得出结论,该包未安装。你的`man`注意到了,最开始你没有安装这个包,但这也没问题,因为没有安装的软件包 默认是清除状态。 199 | 1. 安装软件包`mc`。因为这个更改是系统范围的,所以这个命令需要使用超级用户,它能够写入系统中的所有目录。还要注意 debian 软件包管理器`aptitude`如何自动安装`mc`所需的`libglib2.0-0`,`libglib2.0-data`和`shared-mime-info`软件包。 200 | 1. 显示你安装的包的可执行文件。如你所见,他们放在`/usr/bin`中。 201 | 1. 调用`mc`。 202 | 1. 退出`mc`。 203 | 1. 删除`mc`。请注意,自动安装的软件包也会自动删除。如果在 安装`mc`之后,你安装一些需要这些软件包的东西,`aptitude`将保留它们。 204 | 205 | ## 附加题 206 | 207 | 好吧,东西真多。但这里还有更多: 208 | 键入`aptiutde search emacs`。弄清楚`v`的意思是什么。 209 | 阅读或浏览 Debian 手册中的[第 2 章 Debian 软件包管理](http://www.debian.org/doc/manuals/debian-reference/ch02.en.html)。 210 | -------------------------------------------------------------------------------- /ex19.md: -------------------------------------------------------------------------------- 1 | # 练习 19:文件系统:挂载,`mount`,`/etc/fstab` 2 | 3 | > 原文:[Exercise 19. Filesystems: mounting, mount, /etc/fstab](https://archive.fo/9OnRm) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 我希望你熟悉分区的概念。如果没有,我会简要介绍一下。首先引用自维基百科: 12 | 13 | > 磁盘分区是一种行为,将硬盘驱动器分为多个逻辑存储单元,它们被称为分区,来将一个物理磁盘驱动器视为多个磁盘。 14 | 15 | 看一看: 16 | 17 | ``` 18 | user1@vm1:~$ sudo parted /dev/vda 19 | GNU Parted 2.3 20 | Using /dev/vda 21 | Welcome to GNU Parted! Type 'help' to view a list of commands. 22 | (parted) unit GB 23 | (parted) p 24 | Model: Virtio Block Device (virtblk) 25 | Disk /dev/vda: 17.2GB 26 | Sector size (logical/physical): 512B/512B 27 | Partition Table: msdos 28 | 29 | Number Start End Size Type File system Flags 30 | 1 0.00GB 13.3GB 13.3GB extended 31 | 5 0.00GB 1.02GB 1.02GB logical ext3 boot 32 | 6 1.03GB 2.05GB 1.02GB logical linux-swap(v1) 33 | 7 2.05GB 3.07GB 1.02GB logical ext3 34 | 8 3.07GB 5.12GB 2.05GB logical ext3 35 | 9 5.12GB 9.22GB 4.09GB logical ext3 36 | 10 9.22GB 13.3GB 4.09GB logical ext3 37 | 38 | (parted) 39 | ``` 40 | 41 | 这是一个物理硬盘,分为 7 个不同的分区。这样做的原因很多,但最好被理解为“分治”原则的应用。以这种方式分割时,流氓程序不能通过占用所有磁盘空间,使整个服务器崩溃,该程序将限制在其分区中。我不会再谈论磁盘分区,但是我会继续关注文件系统,再次引用[维基百科](http://en.wikipedia.org/wiki/File_system): 42 | 43 | > 文件系统是一种组织数据的手段。通过提供存储,检索和更新数据的过程,以及管理包含它的设备上的可用空间,数据预期在程序终止后保留。文件系统以有效的方式组织数据,并根据设备的特定特性进行调整。在操作系统和文件系统之间,通常存在紧耦合。一些文件系统提供了机制来控制数据和元数据的访问。确保可靠性是文件系统的主要职责。一些文件系统允许多个程序几乎同时更新同一个文件。 44 | 45 | > 类 Unix 操作系统创建一个虚拟文件系统,这使得所有设备上的所有文件似乎都存在于单个层次结构中。这意味着,在这些系统中,有一个根目录,系统上存在的每个文件位于它下方的某个地方。类 Unix 系统可以使用 RAM 磁盘或网络共享资源作为其根目录。 46 | 47 | 这意味着,所有文件系统都集成在一个大树中。对于熟悉 Microsoft Windows 的人来说,这意味着比起`C:\`和`D:\`等盘符,这种命名方案有一个单独的根,`/`,所有其他分区都连接到它上面。将文件系统连接到现有目录的过程称为挂载。连接文件系统的目录称为挂载点。同样,看一看: 48 | 49 | ``` 50 | user1@vm1:~$ mount 51 | /dev/vda5 on / type ext3 (rw,errors=remount-ro) 52 | tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755) 53 | proc on /proc type proc (rw,noexec,nosuid,nodev) 54 | sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) 55 | udev on /dev type tmpfs (rw,mode=0755) 56 | tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) 57 | devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620) 58 | /dev/vda10 on /home type ext3 (rw) 59 | /dev/vda7 on /tmp type ext3 (rw) 60 | /dev/vda9 on /usr type ext3 (rw) 61 | /dev/vda8 on /var type ext3 (rw) 62 | ``` 63 | 64 | 这是我之前展示给你的相同分区,你可以在这个列表中看到挂载点。不以`/dev/vda`开头的是虚拟文件系统,它允许访问不同的系统设施,但它们和此练习无关。现在我们来看看`/etc/fstab`文件: 65 | 66 | ``` 67 | user1@vm1:~$ cat /etc/fstab 68 | # /etc/fstab: static file system information. 69 | # 70 | # Use 'blkid' to print the universally unique identifier for a 71 | # device; this may be used with UUID= as a more robust way to name devices 72 | # that works even if disks are added and removed. See fstab(5). 73 | # 74 | # 75 | proc /proc proc defaults 0 0 76 | # / was on /dev/vda5 during installation 77 | UUID=128559db-a2e0-4983-91ad-d4f43f27da49 / ext3 errors=remount-ro 0 1 78 | # /home was on /dev/vda10 during installation 79 | UUID=32852d29-ddee-4a8d-9b1e-f46569a6b897 /home ext3 defaults 0 2 80 | # /tmp was on /dev/vda7 during installation 81 | UUID=869db6b4-aea0-4a25-8bd2-f0b53dd7a88e /tmp ext3 defaults 0 2 82 | # /usr was on /dev/vda9 during installation 83 | UUID=0221be16-496b-4277-b131-2371ce097b44 /usr ext3 defaults 0 2 84 | # /var was on /dev/vda8 during installation 85 | UUID=2db00f94-3605-4229-8813-0ee23ad8634e /var ext3 defaults 0 2 86 | # swap was on /dev/vda6 during installation 87 | UUID=3a936af2-2c04-466d-b98d-09eacc5d104c none swap sw 0 0 88 | /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0 89 | ``` 90 | 91 | 看起来很恐怖,但让我们选取一行: 92 | 93 | ``` 94 | # 95 | UUID=128559db-a2e0-4983-91ad-d4f43f27da49 / ext3 errors=remount-ro 0 1 96 | ``` 97 | 98 | 按照字段将其拆开。 99 | 100 | ``` 101 | UUID=128559db-a2e0-4983-91ad-d4f43f27da49 # Filesystem to mount. This UUID is synonim for /dev/vda5 102 | / # This is root filesystem, mount it to / 103 | ext3 # This is ext3 filesystem. There are many different filesystems out there 104 | errors=remount-ro # If any errors encountered during mounting filesystem should be remounted read-only 105 | 0 # This filesystem should not be backed up by dump utility 106 | 1 # This filesystem should be checked first by fsck utility 107 | ``` 108 | 109 | 和之前一样,这些信息可以通过`man fstab`提供给你。现在我将向你展示使用现有文件系统的几个命令: 110 | 111 | + `mount` - 打印出所有已挂载的文件系统。 112 | + `mount -a` - 挂载`/etc/fstab`中描述的所有文件系统。 113 | + `mount /dev/sda /` - 挂载分区。 114 | + `umount /dev/sda /` - 解除挂载分区。 115 | + `mount -h` - 打印出使用`mount`的简短帮助。 116 | + `fsck` - 检查分区是否有错误。 117 | + `blkid` - 打印出唯一的分区标识符。 118 | 119 | 现在,你将学习如何列出已安装的分区,挂载和解除挂载它们。 120 | 121 | ## 这样做 122 | 123 | ``` 124 | 1: cat /etc/fstab 125 | 2: mount 126 | 3: sudo blkid 127 | 4: sudo umount /tmp 128 | 5: mount 129 | 6: sudo fsck /tmp 130 | 7: sudo mount -a 131 | 8: mount 132 | ``` 133 | 134 | ## 你会看到什么 135 | 136 | ``` 137 | user1@vm1:~$ cat /etc/fstab 138 | # /etc/fstab: static file system information. 139 | # 140 | # Use 'blkid' to print the universally unique identifier for a 141 | # device; this may be used with UUID= as a more robust way to name devices 142 | # that works even if disks are added and removed. See fstab(5). 143 | # 144 | # 145 | proc /proc proc defaults 0 0 146 | # / was on /dev/sda1 during installation 147 | UUID=05d469bb-dbfe-4d5a-9bb2-9c0fe9fa8577 / ext3 errors=remount-ro 0 1 148 | # /home was on /dev/sda9 during installation 149 | UUID=a1b936a0-df38-4bf5-b095-6220ffdfc63c /home ext3 defaults 0 2 150 | # /tmp was on /dev/sda8 during installation 151 | UUID=d0a86453-0dbb-4f33-a023-6c09fe9fa202 /tmp ext3 defaults 0 2 152 | # /usr was on /dev/sda5 during installation 153 | UUID=b9544cbb-cdb6-4f3b-89e7-a339f52bfac7 /usr ext3 defaults 0 2 154 | # /var was on /dev/sda6 during installation 155 | UUID=e15e713b-5850-4bc3-b99e-ab6f1d037caa /var ext3 defaults 0 2 156 | # swap was on /dev/sda7 during installation 157 | UUID=4d516f09-80ff-4956-8a75-e9757697f6b1 none swap sw 0 0 158 | /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0 159 | user1@vm1:~$ mount 160 | /dev/sda1 on / type ext3 (rw,errors=remount-ro) 161 | tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755) 162 | proc on /proc type proc (rw,noexec,nosuid,nodev) 163 | sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) 164 | udev on /dev type tmpfs (rw,mode=0755) 165 | tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) 166 | devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620) 167 | /dev/sda9 on /home type ext3 (rw) 168 | /dev/sda5 on /usr type ext3 (rw) 169 | /dev/sda6 on /var type ext3 (rw) 170 | /dev/sda8 on /tmp type ext3 (rw) 171 | /dev/sda8 on /tmp type ext3 (rw) 172 | user1@vm1:~$ sudo blkid 173 | /dev/sda1: UUID="05d469bb-dbfe-4d5a-9bb2-9c0fe9fa8577" TYPE="ext3" 174 | /dev/sda5: UUID="b9544cbb-cdb6-4f3b-89e7-a339f52bfac7" TYPE="ext3" 175 | /dev/sda6: UUID="e15e713b-5850-4bc3-b99e-ab6f1d037caa" TYPE="ext3" 176 | /dev/sda7: UUID="4d516f09-80ff-4956-8a75-e9757697f6b1" TYPE="swap" 177 | /dev/sda8: UUID="d0a86453-0dbb-4f33-a023-6c09fe9fa202" TYPE="ext3" 178 | /dev/sda9: UUID="a1b936a0-df38-4bf5-b095-6220ffdfc63c" TYPE="ext3" 179 | user1@vm1:~$ sudo umount /tmp 180 | user1@vm1:~$ mount 181 | /dev/sda1 on / type ext3 (rw,errors=remount-ro) 182 | tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755) 183 | proc on /proc type proc (rw,noexec,nosuid,nodev) 184 | sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) 185 | udev on /dev type tmpfs (rw,mode=0755) 186 | tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) 187 | devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620) 188 | /dev/sda9 on /home type ext3 (rw) 189 | /dev/sda5 on /usr type ext3 (rw) 190 | /dev/sda6 on /var type ext3 (rw) 191 | user1@vm1:~$ sudo fsck /tmp 192 | fsck from util-linux-ng 2.17.2 193 | e2fsck 1.41.12 (17-May-2010) 194 | /dev/sda8: clean, 11/61752 files, 13973/246784 blocks 195 | user1@vm1:~$ sudo mount -a 196 | user1@vm1:~$ mount 197 | /dev/sda1 on / type ext3 (rw,errors=remount-ro) 198 | tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755) 199 | proc on /proc type proc (rw,noexec,nosuid,nodev) 200 | sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) 201 | udev on /dev type tmpfs (rw,mode=0755) 202 | tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) 203 | devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620) 204 | /dev/sda9 on /home type ext3 (rw) 205 | /dev/sda5 on /usr type ext3 (rw) 206 | /dev/sda6 on /var type ext3 (rw) 207 | /dev/sda8 on /tmp type ext3 (rw) 208 | user1@vm1:~$ 209 | ``` 210 | 211 | ## 解释 212 | 213 | 1. 打印你的`/etc/fstab`文件的内容,它包含分区信息以及挂载位置。 214 | 1. 打印当前已挂载的分区。 215 | 1. 打印系统中所有分区的 UUID。 216 | 1. 解除挂载`/tmp`分区,以便你可以检查它。 217 | 1. 再次打印出当前已挂载的分区。`/tmp`现在不存在于此列表中。 218 | 1. 检查`/tmp`分区是否有错误。`fsck`通过读取相应的`/etc/fstab`条目知道要检查哪个分区。 219 | 1. 挂载`/etc/fstab`中描述的所有分区。 220 | 1. 再次打印当前已挂载的分区。`/tmp`已经返回了此列表。 221 | 222 | ## 附加题 223 | 224 | + 阅读`man fstab`, `man mount`。 225 | + 阅读 。 226 | -------------------------------------------------------------------------------- /ex22.md: -------------------------------------------------------------------------------- 1 | # 练习 22:文件系统:移动数据,`tar`,`dd` 2 | 3 | > 原文:[Exercise 22. Filesystems: moving data around: tar, dd](https://archive.fo/JSknE) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 现在是时候自己看看了,Linux 中的所有东西只是一个文件。 12 | 13 | 这个练习是一个很大的练习,但是看看你学到了什么。完成之后,在`man`中查看所有故意不解释的程序参数,,并试图自己解释每个命令的作用。 14 | 15 | 现在你将学习如何玩转数据。 16 | 17 | ## 这样做 18 | 19 | ``` 20 | 1: tar -czvf root.tgz /opt/root/ 21 | 2: tar -tzvf root.tgz 22 | 3: cd /tmp 23 | 4: tar -zxvf ~/root.tgz 24 | 5: ls -al 25 | 6: dd_if=$(mount | grep /tmp | cut -d ' ' -f 1) && echo $dd_if 26 | 7: sudo dd if=$dd_if of=~/tmp.img bs=10M 27 | 8: cd && ls -alh 28 | 9: sudo losetup /dev/loop1 ~/tmp.img && sudo mount /dev/loop1 /mnt/ 29 | 10: ls -al /mnt 30 | 11: sudo umount /mnt && sudo losetup -d /dev/loop1 31 | 12: sudo umount $dd_if && sudo mkfs.ext3 $dd_if 32 | 13: new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid 33 | 14: grep '/tmp' /etc/fstab 34 | 15: sed "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab 35 | ``` 36 | 37 | 现在使用`sudo tune2fs -l`和`sudo blkid`检查输出。如果`/etc/fstab`中的 UUID 替换看起来正常,执行实际的替换。 38 | 39 | ``` 40 | 16: sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab 41 | 17: sudo mount -a && ls /tmp 42 | 18: sudo umount /tmp && pv ~/tmp.img | sudo dd of=$dd_if bs=10M 43 | 19: new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid 44 | 20: sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab 45 | 21: sudo mount -a 46 | 22: rm -v tmp.img 47 | ``` 48 | 49 | 输入`y`并按下``。 50 | 51 | ## 你会看到什么 52 | 53 | ``` 54 | user1@vm1:~$ tar -czvf root.tgz /opt/root/ 55 | tar: Removing leading '/' from member names 56 | /opt/root/ 57 | /opt/root/bin/ 58 | /opt/root/bin/bash 59 | /opt/root/lib64/ 60 | /opt/root/lib64/ld-linux-x86-64.so.2 61 | /opt/root/lib/ 62 | /opt/root/lib/libdl.so.2 63 | /opt/root/lib/libncurses.so.5 64 | /opt/root/lib/libc.so.6 65 | user1@vm1:~$ tar -tzvf root.tgz 66 | drwxr-xr-x root/root 0 2012-07-05 03:14 opt/root/ 67 | drwxr-xr-x root/root 0 2012-07-05 03:14 opt/root/bin/ 68 | -rwxr-xr-x root/root 926536 2012-07-05 03:14 opt/root/bin/bash 69 | drwxr-xr-x root/root 0 2012-07-05 03:14 opt/root/lib64/ 70 | -rwxr-xr-x root/root 128744 2012-07-05 03:14 opt/root/lib64/ld-linux-x86-64.so.2 71 | drwxr-xr-x root/root 0 2012-07-05 03:14 opt/root/lib/ 72 | -rw-r--r-- root/root 14696 2012-07-05 03:14 opt/root/lib/libdl.so.2 73 | -rw-r--r-- root/root 286776 2012-07-05 03:14 opt/root/lib/libncurses.so.5 74 | -rwxr-xr-x root/root 1437064 2012-07-05 03:14 opt/root/lib/libc.so.6 75 | user1@vm1:~$ cd /tmp 76 | user1@vm1:/tmp$ tar -zxvf ~/root.tgz 77 | opt/root/ 78 | opt/root/bin/ 79 | opt/root/bin/bash 80 | opt/root/lib64/ 81 | opt/root/lib64/ld-linux-x86-64.so.2 82 | opt/root/lib/ 83 | opt/root/lib/libdl.so.2 84 | opt/root/lib/libncurses.so.5 85 | opt/root/lib/libc.so.6 86 | user1@vm1:/tmp$ ls -al 87 | total 19 88 | drwxrwxrwt 6 root root 1024 Jul 5 04:17 . 89 | drwxr-xr-x 22 root root 1024 Jul 3 08:29 .. 90 | drwxrwxrwt 2 root root 1024 Jul 3 08:41 .ICE-unix 91 | drwx------ 2 root root 12288 Jul 3 07:47 lost+found 92 | drwxr-xr-x 3 user1 user1 1024 Jul 5 03:24 opt 93 | -rw-r--r-- 1 root root 489 Jul 3 10:14 sources.list 94 | -r--r----- 1 root root 491 Jul 3 10:21 sudoers 95 | drwxrwxrwt 2 root root 1024 Jul 3 08:41 .X11-unix 96 | user1@vm1:/tmp$ dd_if=$(mount | grep /tmp | cut -d ' ' -f 1) && echo $dd_if 97 | /dev/sda8 98 | user1@vm1:~$ cd && ls -alh 99 | total 243M 100 | drwxr-xr-x 3 user1 user1 4.0K Jul 5 04:27 . 101 | drwxr-xr-x 4 root root 4.0K Jul 3 08:39 .. 102 | -rw------- 1 user1 user1 22 Jul 3 10:45 .bash_history 103 | -rw-r--r-- 1 user1 user1 220 Jul 3 08:39 .bash_logout 104 | -rw-r--r-- 1 user1 user1 3.2K Jul 3 08:39 .bashrc 105 | -rw------- 1 user1 user1 52 Jul 5 04:12 .lesshst 106 | drwxr-xr-x 3 user1 user1 4.0K Jul 5 03:23 opt 107 | -rw-r--r-- 1 user1 user1 675 Jul 3 08:39 .profile 108 | -rw-r--r-- 1 user1 user1 1.3M Jul 5 04:25 root.tgz 109 | -rw-r--r-- 1 root root 241M Jul 5 04:36 tmp.img 110 | user1@vm1:~$ sudo losetup /dev/loop1 ~/tmp.img && sudo mount /dev/loop1 /mnt/ 111 | user1@vm1:~$ ls -al /mnt 112 | total 19 113 | drwxrwxrwt 6 root root 1024 Jul 5 04:17 . 114 | drwxr-xr-x 22 root root 1024 Jul 3 08:29 .. 115 | drwxrwxrwt 2 root root 1024 Jul 3 08:41 .ICE-unix 116 | drwx------ 2 root root 12288 Jul 3 07:47 lost+found 117 | drwxr-xr-x 3 user1 user1 1024 Jul 5 03:24 opt 118 | -rw-r--r-- 1 root root 489 Jul 3 10:14 sources.list 119 | -r--r----- 1 root root 491 Jul 3 10:21 sudoers 120 | drwxrwxrwt 2 root root 1024 Jul 3 08:41 .X11-unix 121 | user1@vm1:~$ sudo umount /mnt && sudo losetup -d /dev/loop1 122 | user1@vm1:~$ sudo umount $dd_if && sudo mkfs.ext3 $dd_if 123 | mke2fs 1.41.12 (17-May-2010) 124 | Filesystem label= 125 | OS type: Linux 126 | Block size=1024 (log=0) 127 | Fragment size=1024 (log=0) 128 | Stride=0 blocks, Stripe width=0 blocks 129 | 61752 inodes, 246784 blocks 130 | 12339 blocks (5.00%) reserved for the super user 131 | First data block=1 132 | Maximum filesystem blocks=67371008 133 | 31 block groups 134 | 8192 blocks per group, 8192 fragments per group 135 | 1992 inodes per group 136 | Superblock backups stored on blocks: 137 | 8193, 24577, 40961, 57345, 73729, 204801, 221185 138 | 139 | Writing inode tables: done 140 | Creating journal (4096 blocks): done 141 | Writing superblocks and filesystem accounting information: done 142 | 143 | This filesystem will be automatically checked every 27 mounts or 144 | 180 days, whichever comes first. Use tune2fs -c or -i to override. 145 | user1@vm1:~$ new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid 146 | f8288adc-3ef9-4a6e-aab2-92624276b8ba 147 | user1@vm1:~$ grep '/tmp' /etc/fstab 148 | # /tmp was on /dev/sda8 during installation 149 | UUID=011b4530-e4a9-4d13-926b-48d9e33b64bf /tmp ext3 defaults 0 2 150 | user1@vm1:~$ sed "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab 151 | # /etc/fstab: static file system information. 152 | # 153 | # Use 'blkid' to print the universally unique identifier for a 154 | # device; this may be used with UUID= as a more robust way to name devices 155 | # that works even if disks are added and removed. See fstab(5). 156 | # 157 | # 158 | proc /proc proc defaults 0 0 159 | # / was on /dev/sda1 during installation 160 | UUID=91aacf33-0b35-474c-9c61-311e04b0bed1 / ext3 errors=remount-ro 0 1 161 | # /home was on /dev/sda9 during installation 162 | UUID=e27b0efb-8cf0-439c-9ebe-d59c927dd590 /home ext3 defaults 0 2 163 | # /tmp was on /dev/sda8 during installation 164 | UUID=f8288adc-3ef9-4a6e-aab2-92624276b8ba /tmp ext3 defaults 0 2 165 | # /usr was on /dev/sda5 during installation 166 | UUID=9f49821b-7f94-4915-b9a9-ed9f12bb6847 /usr ext3 defaults 0 2 167 | # /var was on /dev/sda6 during installation 168 | UUID=b7e908a1-a1cd-4d5c-bc79-c3a99d003e7c /var ext3 defaults 0 2 169 | # swap was on /dev/sda7 during installation 170 | UUID=292981d7-5a17-488f-8d9a-176b65f45d46 none swap sw 0 0 171 | /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0 172 | sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3 defaults 0 2/" /etc/fstab 173 | sudo mount -a && ls /tmp 174 | user1@vm1:~$ sudo umount /tmp && pv ~/tmp.img | sudo dd of=$dd_if bs=10M 175 | 241MB 0:00:04 [54.2MB/s] [===============================================================================================================>] 100% 176 | 0+1928 records in 177 | 0+1928 records out 178 | 252706816 bytes (253 MB) copied, 5.52494 s, 45.7 MB/s 179 | user1@vm1:~$ rm -v tmp.img 180 | rm: remove write-protected regular file `tmp.img'? y 181 | removed `tmp.img' 182 | user1@vm1:~$ 183 | ``` 184 | 185 | ## 解释 186 | 187 | 1. 在你的主目录中创建归档或`/opt/root/`。归档文件的扩展名是`.tgz`,因为这个归档实际上由两部分组成,就像是俄罗斯套娃。第一部分由字母`t`指定,是一个大文件,其中所有归档文件由程序`tar`合并。第二部分由字母`gz`指定 ,意味着`tar`调用`gzip`程序来压缩它。 188 | 1. 测试这个归档。 189 | 1. 将目录更改为`/tmp`。 190 | 1. 解压你的归档。 191 | 1. 打印目录内容。 192 | 1. 提取挂载在`/tmp`上的分区的名称,将其存储在`dd_if`变量中,如果提取成功,打印出`dd_if`值。`if`代表输入文件。 193 | 1. 将整个分区复制到你的主目录中的`tmp.img`。dd 使用超级用户调用,因为你正在访问代表你的分区的文件`/dev/sda8`,该分区对普通用户不可访问。 194 | 1. 将目录更改为你的主目录并打印出其内容。 195 | 1. 告诉 Linux 将`tmp.img`文件用作(一种)物理分区并挂载它。 196 | 1. 打印出`tmp.img`的内容。你可以看到它真的是`/tmp`的精确副本 。 197 | 1. 198 | 1. 解除挂载`tmp.img`,并告诉 Linux 停止将其看做分区。 199 | 1. 解除挂载`/tmp`并在那里创建新的文件系统,删除该过程中的所有东西。 200 | 1. 提取你的新`/tmp`文件系统的UUID ,将其存储在`new_uuid`中,并打印出来。 201 | 1. 从`/etc/fstab`中打印描述旧的`/tmp`分区的一行。 202 | 1. 向你展示,修改后的`/etc/fstab`如何工作。通过使用正则表达式来完成,这个表达式用作掩码,定义了这一行: 203 | 204 | ``` 205 | UUID=f8288adc-3ef9-4a6e-aab2-92624276b8ba /tmp ext3 defaults 0 2 206 | ``` 207 | 208 | 完成这本书后,我会给你一个链接,让你学习如何创建这样的正则表达式。 209 | 1. 使用新的 UUID 实际替换`/tmp`旧的 UUID。 210 | 1. 挂载`/etc/fstab`中描述的所有文件系统,并列出新`/tmp`的内容 211 | 1. 解除挂载新的`/tmp`并从`tmp.img`恢复旧`/tmp`。 212 | 1. 获取旧`/tmp`的 UUID,它实际上与创建新文件系统之前相同,因为`tmp.img`是旧的`/ tmp`的完美副本。 213 | 1. 在`/etc/fstab`中用旧的 UUID 替换新的 UUID 。 214 | 1. 从`/etc/fstab`挂载所有文件系统。如果此命令不会导致错误,你可能一切正常。恭喜。 215 | 1. 从你的主目录中删除`tmp.img`。 216 | 217 | ## 附加题 218 | 219 | + 尝试详细解释每个命令的作用。拿出一张纸,把它全部写出来。在`man`中查找在所有不能很好理解的命令和参数。 220 | + 这个有些过早了,但为什么你能作为`user1`来发出删除命令,从你的主目录中删除`tmp.img`,考虑到`tmp.img`由 root 创建? 221 | -------------------------------------------------------------------------------- /ex15.md: -------------------------------------------------------------------------------- 1 | # 练习 15:系统启动:运行级别,`/etc/init.d`,`rcconf`,`update-rc.d` 2 | 3 | > 原文:[Exercise 15. System boot: runlevels, /etc/init.d, rcconf, update-rc.d](https://archive.fo/kQr60) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 首先我会给出一个典型的系统启动过程的概述: 12 | 13 | ``` 14 | 你 15 | 按电源开关(或启动虚拟机) 16 | 现在计算机获得控制权 17 | 控制权传给了 BIOS 18 | BIOS 19 | 执行硬件特定的任务 20 | 执行开机自检(POST),测试你的硬件 21 | 检测安装的硬件,如硬盘,内存类型和数量,... 22 | 通过将初始值写入其内存来初始化硬件 23 | 找到一个启动设备,通常是一个硬盘 24 | 读取并执行位于此磁盘开头的 MBR(主引导记录) 25 | 控制权现在传给了 MBR 26 | MBR 27 | MBR 寻找并执行 GRUB(多重操作系统启动管理器) 28 | 控制权现在传给了 GRUB 29 | GRUB 30 | 查找可用的文件系统 31 | 查找并读取其配置文件,来了解: 32 | 系统位于哪里 33 | 启动什么系统 34 | 执行什么其他的操作 35 | 执行 Linux 内核,Linux 操作系统的主要部分 36 | 控制权现在传给了 Linux 内核 37 | Linux 内核 38 | 查找并加载 initrd,这是初始的 ram 磁盘 39 | initrd 包含必要驱动程序,允许真实文件系统的访问和挂载 40 | 挂载文件系统,它在 GRUB 配置文件中指定。 41 | 执行`/sbin/init`,一个启动所有其他程序的特殊程序 42 | 控制权现在传给了 init 43 | init 44 | 查看`etc/inittab`来确定所需的运行级别 45 | 加载适合此运行级别的所有程序 46 | 加载来自`/etc/rc.d/rc2.d/`的所有程序,因为 2 是默认的 Debian 运行级别 47 | 启动 SSH 和 TTY,以便你可以连接到你的计算机 48 | 启动现在完成了 49 | 你 50 | 使用 SSH 连接到你的计算机 51 | SSH 守护进程为你执行 bash shell 52 | 你现在可以输入东西 53 | 你再次获得控制权 54 | ``` 55 | 56 | 现在我们只对“init”和“运行级别”阶段感兴趣,所以我将总结一下,系统如何启动并自动启动一些程序。首先,有一些术语​​: 57 | 58 | + 守护进程 - 一直运行在后台的程序。这意味着它不在乎你是否登录系统,通常你不需要手动启动它,因为它在计算机启动时自动启动。 59 | + 运行级别 - 系统运行模式。基本上,这只是一个数字,提供给`init`程序,它知道哪些守护程序与每个数字相关联,并根据需要启动并停止这些守护程序。 60 | 61 | 在 Debian 中有以下运行级别: 62 | 63 | | ID | 描述 | 64 | | --- | --- | 65 | | S | 系统通电后会执行它 | 66 | | 0 | 停止,这定义了当系统关闭时执行哪些操作。 | 67 | | 1 | 单用户模式,这是一种特殊的故障排除模式。在这种模式下,大多数守护进程不会自动启动。 | 68 | | 2~5 | 完全多用户,配置的守护程序在此模式下启动。 | 69 | | 6 | 重启,类似停止,但不是关闭系统而是重新启动。 | 70 | 71 | 但是`init`怎么知道的?好吧,这是用于它的特殊目录。 72 | 73 | ``` 74 | user1@vm1:/etc$ find /etc -type d -name 'rc*' 2>/dev/null | sort 75 | /etc/rc0.d 76 | /etc/rc1.d 77 | /etc/rc2.d 78 | /etc/rc3.d 79 | /etc/rc4.d 80 | /etc/rc5.d 81 | /etc/rc6.d 82 | /etc/rcS.d 83 | ``` 84 | 85 | 你可能能猜到,每个数字和`S`对应表中的运行级别。让我们列出其中一个目录,它在正常启动中启动所有所需的守护进程。 86 | 87 | ``` 88 | user1@vm1:/etc$ ls -al /etc/rc2.d | awk '{printf "%-15.15s %-3.3s %s\n",$9,$10,$11}' 89 | . 90 | .. 91 | README 92 | S14portmap -> ../init.d/portmap 93 | S15nfs-common -> ../init.d/nfs-common 94 | S17rsyslog -> ../init.d/rsyslog 95 | S17sudo -> ../init.d/sudo 96 | S18acpid -> ../init.d/acpid 97 | S18atd -> ../init.d/atd 98 | S18cron -> ../init.d/cron 99 | S18exim4 -> ../init.d/exim4 100 | S18ssh -> ../init.d/ssh 101 | S20bootlogs -> ../init.d/bootlogs 102 | S21rc.local -> ../init.d/rc.local 103 | S21rmnologin -> ../init.d/rmnologin 104 | S21stop-bootlog -> ../init.d/stop-bootlogd 105 | ``` 106 | 107 | 如你所见,此目录中的文件只是实际启动脚本的符号链接。我们来看看其中一个链接:`S18ssh→../init.d/ssh`。这是关于这个文件的事情: 108 | 109 | + 它是一个`./init.d/ssh`文件的链接 110 | + 它以`S`开始,意味着“启动”。Debian 启动系统中使用的每个脚本至少有 2 个参数,“启动”和“停止”。现在我们可以说,当我们的系统切换到运行级别 2 时,该脚本将使用动作“启动”来执行 。 111 | + 它有一个数字 18。`rc`目录中的脚本以字典序执行,所以现在我们明白,在启动`ssh`之前 ,系统启动`portmap`,`nfs-common`,`rsyslog`和`sudo`。`rsyslog`是一个系统日志守护程序,特别是`ssh`想要记录谁在什么时候访问系统,所以在启动之前需要运行`rsyslog`。 112 | 113 | 现在,你将学习如何列出启用的服务(守护程序),以及启用和禁用服务(守护程序)。 114 | 115 | ## 这样做 116 | 117 | ``` 118 | 1: sudo aptitude install rcconf 119 | 2: ls -al /etc/rc2.d 120 | 3: sudo rcconf --list 121 | 4: sudo update-rc.d exim4 disable 122 | 5: ls -al /etc/rc2.d 123 | 6: sudo rcconf --list 124 | 7: sudo update-rc.d exim4 enable 125 | 8: ls -al /etc/rc2.d 126 | 9: sudo rcconf --list 127 | ``` 128 | 129 | ## 你会看到什么 130 | 131 | ``` 132 | user1@vm1:/var/log$ sudo aptitude install rcconf 133 | The following NEW packages will be installed: 134 | rcconf 135 | 0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded. 136 | Need to get 0 B/23.9 kB of archives. After unpacking 135 kB will be used. 137 | Selecting previously deselected package rcconf. 138 | (Reading database ... 24239 files and directories currently installed.) 139 | Unpacking rcconf (from .../archives/rcconf_2.5_all.deb) ... 140 | Processing triggers for man-db ... 141 | Setting up rcconf (2.5) ... 142 | 143 | user1@vm1:/etc$ ls -al /etc/rc2.d 144 | total 12 145 | drwxr-xr-x 2 root root 4096 Jun 27 11:42 . 146 | drwxr-xr-x 68 root root 4096 Jun 25 18:43 .. 147 | -rw-r--r-- 1 root root 677 Mar 27 05:50 README 148 | lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap 149 | lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common 150 | lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog 151 | lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo 152 | lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid 153 | lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd 154 | lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron 155 | lrwxrwxrwx 1 root root 15 Jun 27 11:42 S18exim4 -> ../init.d/exim4 156 | lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh 157 | lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs 158 | lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local 159 | lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin 160 | lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd 161 | user1@vm1:/etc$ sudo rcconf --list 162 | rsyslog on 163 | ssh on 164 | bootlogs on 165 | portmap on 166 | sudo on 167 | nfs-common on 168 | udev on 169 | console-setup on 170 | kbd on 171 | exim4 on 172 | keyboard-setup on 173 | acpid on 174 | cron on 175 | atd on 176 | procps on 177 | module-init-tools on 178 | user1@vm1:/etc$ sudo update-rc.d exim4 disable 179 | update-rc.d: using dependency based boot sequencing 180 | insserv: warning: current start runlevel(s) (empty) of script `exim4' overwrites defaults (2 3 4 5). 181 | insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `exim4' overwrites defaults (0 1 6). 182 | user1@vm1:/etc$ ls -al /etc/rc2.d 183 | total 12 184 | drwxr-xr-x 2 root root 4096 Jun 27 11:43 . 185 | drwxr-xr-x 68 root root 4096 Jun 25 18:43 .. 186 | lrwxrwxrwx 1 root root 15 Jun 27 11:43 K01exim4 -> ../init.d/exim4 187 | -rw-r--r-- 1 root root 677 Mar 27 05:50 README 188 | lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap 189 | lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common 190 | lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog 191 | lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo 192 | lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid 193 | lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd 194 | lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron 195 | lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh 196 | lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs 197 | lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local 198 | lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin 199 | lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd 200 | user1@vm1:/etc$ sudo rcconf --list 201 | rsyslog on 202 | ssh on 203 | bootlogs on 204 | portmap on 205 | sudo on 206 | nfs-common on 207 | udev on 208 | console-setup on 209 | kbd on 210 | keyboard-setup on 211 | acpid on 212 | cron on 213 | atd on 214 | procps on 215 | module-init-tools on 216 | exim4 off 217 | user1@vm1:/etc$ sudo update-rc.d exim4 enable 218 | update-rc.d: using dependency based boot sequencing 219 | user1@vm1:/etc$ ls -al /etc/rc2.d 220 | total 12 221 | drwxr-xr-x 2 root root 4096 Jun 27 11:43 . 222 | drwxr-xr-x 68 root root 4096 Jun 25 18:43 .. 223 | -rw-r--r-- 1 root root 677 Mar 27 05:50 README 224 | lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap 225 | lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common 226 | lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog 227 | lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo 228 | lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid 229 | lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd 230 | lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron 231 | lrwxrwxrwx 1 root root 15 Jun 27 11:43 S18exim4 -> ../init.d/exim4 232 | lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh 233 | lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs 234 | lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local 235 | lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin 236 | lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd 237 | user1@vm1:/etc$ sudo rcconf --list 238 | rsyslog on 239 | ssh on 240 | bootlogs on 241 | portmap on 242 | sudo on 243 | nfs-common on 244 | udev on 245 | console-setup on 246 | kbd on 247 | exim4 on 248 | keyboard-setup on 249 | acpid on 250 | cron on 251 | atd on 252 | procps on 253 | module-init-tools on 254 | user1@vm1:/etc$ 255 | ``` 256 | 257 | ## 解释 258 | 259 | 1. 安装`rcconf`包,让你轻松管理运行级别。 260 | 1. 打印包含运行级别 2 的启动脚本的目录。现在启用了邮件服务器`exim4`。 261 | 1. 仅仅打印出相同运行级别的服务。请注意,由于它们被视为系统服务,因此存在多个未显示的服务。`rcconf –list –expert`会把它们全部列出,以及更多的驻留在不同的运行级别上的服务。 262 | 1. 禁用邮件服务器`exim4`的自动启动。 263 | 1. 打印出包括运行级别 2 的启动脚本的目录。`exim4`启动脚本现在从`S18exim4`重命名为`K01exim4`。这意味着`exim4`进入此级别时已停止(被杀死)。如果`exim4`开始没有运行,就没有任何反应。 264 | 1. 打印运行级别 2 的服务。服务`exim4`现在已关闭。 265 | 1. 开启`exim4`的自动启动。 266 | 1. 再次打印包含运行级别 2 的启动脚本的目录,`exim4`再次启动。 267 | 1. 打印运行级别 2 的服务。`exim4`的状态变更为已启动,和预期一样。 268 | 269 | ## 附加题 270 | 271 | + 请阅读 Debian 启动过程: 272 | + 尝试这样做:`aptitude install sysv-rc-conf`,`sysv-rc-conf -list`。阅读`man sysv-rc-conf`。 273 | -------------------------------------------------------------------------------- /ex16.md: -------------------------------------------------------------------------------- 1 | # 练习 16:处理进程,`ps`,`kill` 2 | 3 | > 原文:[Exercise 16. Processes: working with proccesses, ps, kill](https://archive.fo/CSqm9) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 最简单的程序是硬盘上的文件,它包含中央处理器执行的指令。当你启动它的时候,它被复制到内存,控制权传递给它。被执行的程序称为进程。在例如 Linux 的多任务操作系统中,你可以启动程序的许多实例,因此可以从一个程序启动许多进程,所有程序将同时运行(执行)。 12 | 13 | 这是执行`ls`时发生的事情的概述: 14 | 15 | ``` 16 | 你 17 | 把 ls 和它的参数输入到你的终端模拟器,然后按 18 | 控制权现在传递给 Bash 19 | Bash 20 | 在你的硬盘上查找 ls 21 | 将自身派生到 Bash 克隆体,也就是将自己克隆到内存中的新位置 22 | 成为 Bash 克隆体的父进程 23 | 控制权传给了传递给 Bash 克隆体 24 | Bash 克隆体 25 | 成为 Bash 的子进程 26 | 保存 Bash 父进程的环境 27 | 知道它是一个克隆体并且做出相应的反应 28 | 使用 ls 覆盖自身 29 | 控制权现在传递给 ls 30 | ls 31 | 为你打印一个目录列表或返回错误 32 | 返回退出代码 33 | 控制权现在传递给 Bash 34 | Bash 35 | 将 ls 退出代码赋给 ? 变量 36 | 等待你的输入 37 | 你 38 | 可以再次输入内容 39 | ``` 40 | 41 | 一些进程不像`ls`那样交互,只是在后台静静地工作,就像`ssh`一样。进程有许多可能的状态,并且有许多操作,你可以通过信号机制对它们执行。 42 | 43 | 首先让我们谈论状态。如果你键入`ps ax -forest`,它将打印出所有进程,你会得到这样的东西(跳过一些与硬件有关的进程): 44 | 45 | ``` 46 | user1@vm1:/etc$ ps --forest ax 47 | PID TTY STAT TIME COMMAND 48 | 1 ? Ss 0:16 init [2] 49 | 297 ? S 129 | 8: kill -s USR1 $! 130 | 9: 131 | 10: kill -s TERM $! 132 | 11: 133 | ``` 134 | 135 | ## 你会看到什么 136 | 137 | ``` 138 | user1@vm1:/etc$ ps x 139 | PID TTY STAT TIME COMMAND 140 | 6675 ? S 0:00 sshd: user1@pts/0 141 | 6676 pts/0 Ss 0:00 -bash 142 | 8193 pts/0 R+ 0:00 ps x 143 | user1@vm1:/etc$ ps a 144 | PID TTY STAT TIME COMMAND 145 | 1210 tty2 Ss+ 0:00 /sbin/getty 38400 tty2 146 | 1211 tty3 Ss+ 0:00 /sbin/getty 38400 tty3 147 | 1212 tty4 Ss+ 0:00 /sbin/getty 38400 tty4 148 | 1213 tty5 Ss+ 0:00 /sbin/getty 38400 tty5 149 | 1214 tty6 Ss+ 0:00 /sbin/getty 38400 tty6 150 | 6216 tty1 Ss+ 0:00 /sbin/getty 38400 tty1 151 | 6676 pts/0 Ss 0:00 -bash 152 | 8194 pts/0 R+ 0:00 ps a 153 | user1@vm1:/etc$ ps ax 154 | PID TTY STAT TIME COMMAND 155 | 1 ? Ss 0:16 init [2] 156 | --- skipped --- skipped --- skipped --- 157 | 691 ? Ss 0:00 /sbin/portmap 158 | 703 ? Ss 0:00 /sbin/rpc.statd 159 | 862 ? Sl 0:00 /usr/sbin/rsyslogd -c4 160 | 886 ? Ss 0:00 /usr/sbin/atd 161 | 971 ? Ss 0:00 /usr/sbin/acpid 162 | 978 ? Ss 0:01 /usr/sbin/cron 163 | 1177 ? Ss 0:00 /usr/sbin/sshd 164 | 1191 ? Ss 0:00 /usr/sbin/exim4 -bd -q30m 165 | 1210 tty2 Ss+ 0:00 /sbin/getty 38400 tty2 166 | 1211 tty3 Ss+ 0:00 /sbin/getty 38400 tty3 167 | 1212 tty4 Ss+ 0:00 /sbin/getty 38400 tty4 168 | 1213 tty5 Ss+ 0:00 /sbin/getty 38400 tty5 169 | 1214 tty6 Ss+ 0:00 /sbin/getty 38400 tty6 170 | 6216 tty1 Ss+ 0:00 /sbin/getty 38400 tty1 171 | 6671 ? Ss 0:00 sshd: user1 [priv] 172 | 6675 ? S 0:00 sshd: user1@pts/0 173 | 6676 pts/0 Ss 0:00 -bash 174 | 8198 pts/0 R+ 0:00 ps ax 175 | user1@vm1:/etc$ ps axue --forest 176 | USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 177 | --- skipped --- skipped --- skipped --- 178 | root 1 0.0 0.0 8356 820 ? Ss Jun06 0:16 init [2] 179 | root 297 0.0 0.0 16976 1000 ? S`(发出空指令)。 227 | 1. 再次查询`dd`的状态。 228 | 1. 同样,你需要按``来查看输出。 229 | 1. 向`dd`发送终止信号,所以`dd`退出了。 230 | 1. 为了看到它确实发生了,你需要再次按``键 。 231 | 232 | ## 附加题 233 | 234 | + 阅读`man ps`,`man kill`。 235 | + 阅读[进程的生命周期](http://www.linux-tutorial.info/modules.php?name=MContent&pageid=84),并研究这张图片:[进程的工作流](http://www.linux-tutorial.info/Linux_Tutorial/The_Operating_System/The_Kernel/Processes/procflowa.gif)。 236 | + 打印并填写[信号表](https://nixsrv.com/llthw/ex16/signals)。你可以使用 [kernel.org 中的文档](http://www.kernel.org/doc/man-pages/online/pages/man7/signal.7.html%23DESCRIPTION)。 237 | -------------------------------------------------------------------------------- /mdi.md: -------------------------------------------------------------------------------- 1 | # Debian 手动安装 2 | 3 | > 原文:[Manual Debian installation](https://archive.fo/p1ZHn) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 尽管这个部分很啰嗦,但是不推荐给那些不熟悉 VirtualBox 和 Debian 的人。此外,它是为 Windows 编写的,如果你使用其他系统,我希望,对本指南进行适当的替换相当容易。 12 | 13 | 首先,下载你需要的东西: 14 | 15 | + 下载并安装 [VirtualBox](https://www.virtualbox.org/wiki/Downloads)。 16 | + 下载最新的 [Debian 6 Squeeze CD 映像](http://cdimage.debian.org/debian-cd/6.0.5/amd64/iso-cd/)。你需要第一张 CD,例如`debian-6.0.5-amd64-CD-1.iso`。 17 | 18 | 对于 Windows 用户,你需要下载 [putty](ttp://www.chiark.greenend.org.uk/~sgtatham/putty/download.html)。你需要这个文件:`putty.exe`。它不需要安装,你可以像这样运行它。 19 | 20 | ## Debian 安装指南 21 | 22 | 1. 启动 VirtualBox。 23 | 24 | ![](https://archive.fo/p1ZHn/68fc7efcadb72e1e0f33f26176522a14607424ca.png) 25 | 26 | 2. 按下`New`按钮来创建新的虚拟机。在`Name`字段中输入`vm1`,之后选择`Operating System: Linux, Version: Debian (64 bit)`,之后按下`Next >`。 27 | 28 | ![](https://archive.fo/p1ZHn/c083a91d6b41d9216554816fbe0c0df9d6ed1e87.png) 29 | 30 | 3. 从内存至少选择`512 MB`。如果你的机子上安装了足够的 RAM,`1024 GB`也可以。按下`Next >`。 31 | 32 | ![](https://archive.fo/p1ZHn/ae59f8240ff9a5b19138aaec456e14545515b23b.png) 33 | 34 | 4. 这里只需按下`Next >`。 35 | 36 | ![](https://archive.fo/p1ZHn/6857a035f4111c1148ad0429bcbd72dc212c23f0.png) 37 | 38 | 5. 选择`VDI (VirtualBox Disk Image)`,并按下`Next >`。 39 | 40 | ![](https://archive.fo/p1ZHn/05d67f9169ff8f40bc61f4c6000871d37c3a71e4.png) 41 | 42 | 6. 选择`Dynamically allocated`,并按下`Next >`。 43 | 44 | ![](https://archive.fo/p1ZHn/e7caa74cadc60c7b829e0dd85de35018dcfe0b2f.png) 45 | 46 | 7. 在`Location`中输入`vm1`,并按下`Next >`。 47 | 48 | ![](https://archive.fo/p1ZHn/ba205c73a6f0954f9a567423da18fdb36d7b1319.png) 49 | 50 | 8. 点击`Create`。 51 | 52 | ![](https://archive.fo/p1ZHn/5661251d5a943496f199307c52ad84a06c38078f.png) 53 | 54 | 9. 选择`vm1`并点击`Start`。 55 | 56 | ![](https://archive.fo/p1ZHn/e387da8cc25aa78a8432e21ea7664b3b961f60a0.png) 57 | 58 | 0. 点击`Next >`。 59 | 60 | ![](https://archive.fo/p1ZHn/eade1e093fb56f77774d57a6f6c8bff6a37f3ff8.png) 61 | 62 | 1. 点击`folder button`。 63 | 64 | ![](https://archive.fo/p1ZHn/ff276e5704d18417a1b0581dd425e40e8909d1b6.png) 65 | 66 | 2. 浏览并选择你的`Debian 6 Squeeze CD-image`,点击`Open`。 67 | 68 | ![](https://archive.fo/p1ZHn/ef12fa3b92eef1c7001c071acb24d6c6f7622a7a.png) 69 | 70 | 3. 点击`Next >`。 71 | 72 | ![](https://archive.fo/p1ZHn/5f4dcbce772f1d9b6ff84316769a2cec48139503.png) 73 | 74 | 4. 点击`Start`。 75 | 76 | ![](https://archive.fo/p1ZHn/b139ce5a811d31c98ed0cb81573aa9f2b52b5b78.png) 77 | 78 | 5. 关闭烦人的 VirtualBox 窗口。点击 VirtualBox 窗口内部并按下``。 79 | ![](https://archive.fo/p1ZHn/6979a652355a3d20019983500f3a22a92d1968a6.png) 80 | 81 | 6. 按下``。 82 | 83 | ![](https://archive.fo/p1ZHn/cd1b9c49b9015a9d37c09e8b91d0a7251aeffa6c.png) 84 | 85 | 7. 按下``。 86 | 87 | > 译者注:这里你可以选“中文(简体)”。 88 | 89 | ![](https://archive.fo/p1ZHn/9d4256a54e6e34d36aed8373fe074f3e6439c6c2.png) 90 | 91 | 8. 按下``。 92 | 93 | > 译者注:这里你可以选“HongKong”。 94 | 95 | ![](https://archive.fo/p1ZHn/e1fd69a847e9321383f87dbc9977cb8b9a0fb4a3.png) 96 | 97 | 9. 按下``。 98 | 99 | ![](https://archive.fo/p1ZHn/65b272c4e228ddcf365f61d44d5256a596935455.png) 100 | 101 | 0. 输入`vm1`并按下``。 102 | 103 | ![](https://archive.fo/p1ZHn/4801b99ce3260d1f90fee587763f2594bad2c2e7.png) 104 | 105 | 1. 输入`site`并按下``。 106 | 107 | ![](https://archive.fo/p1ZHn/5eb0e36cdf4e3ddaf10db2fb4fb2b0834c7c2bfa.png) 108 | 109 | 2. 输入`123qwe`并按下``。 110 | 111 | ![](https://archive.fo/p1ZHn/34ffc67b2618df734bcbd6f5306c2860254ce60f.png) 112 | 113 | 3. 输入`123qwe`并按下``。 114 | 115 | ![](https://archive.fo/p1ZHn/57dbc33555e2e2ae61517be0aa83cfbb1f9bfc34.png) 116 | 117 | 4. 输入`user1`并按下``。 118 | 119 | ![](https://archive.fo/p1ZHn/e0f9977d67c15b3b02e1229c7f0b454204161340.png) 120 | 121 | 5. 按下``。 122 | 123 | ![](https://archive.fo/p1ZHn/1d2d158cb7bc6dae359fb1e02214136e4a6e3e2d.png) 124 | 125 | 6. 输入`123qwe`并按下``。 126 | 127 | ![](https://archive.fo/p1ZHn/7e8415ff24fed2c2b155622889e226e92a3e51ea.png) 128 | 129 | 7. 输入`123qwe`并按下``。 130 | 131 | ![](https://archive.fo/p1ZHn/03c870e0b698e28f3654f94c751547a25cbc04e1.png) 132 | 133 | 8. 如果你不知道这里做什么,只需按下``。 134 | 135 | ![](https://archive.fo/p1ZHn/04707609537bfd69cc50fc33867a15a7320e832c.png) 136 | 137 | 9. 选择`Guided partitioning`并按下``。 138 | 139 | ![](https://archive.fo/p1ZHn/4af1a582de294fba7b8bd3aa4aca2b6d7534268f.png) 140 | 141 | 0. 选择`Guided – use entire disk`并按下``。 142 | 143 | ![](https://archive.fo/p1ZHn/d7bfde3632cf431672e448ed0f4e59da792a8401.png) 144 | 145 | 1. 再次按下``。 146 | 147 | ![](https://archive.fo/p1ZHn/a3bb62cd87b0e9359e08b3a8a2aa694258959b35.png) 148 | 149 | 2. 选择`eparate /home, /usr, /var, and /tmp partitions`并按下``。 150 | 151 | ![](https://archive.fo/p1ZHn/fc92f1246ab697a70fb40982988226f412853883.png) 152 | 153 | 3. 选择`Finish partitioning and write changes to disk`并按下``。 154 | 155 | ![](https://archive.fo/p1ZHn/a2b293906dc62fde7064426b59ad880b362d0f6a.png) 156 | 157 | 4. 选择``并按下``。 158 | 159 | ![](https://archive.fo/p1ZHn/ef0d5da56d4aad96dc711f0a527c0183e3a27269.png) 160 | 161 | 5. 选择``并按下``。 162 | 163 | ![](https://archive.fo/p1ZHn/e9cfc3142b4d63f1d217da3d85dc1140ab09d845.png) 164 | 165 | 6. 选择``并按下``。 166 | 167 | ![](https://archive.fo/p1ZHn/65f4aa627d6a40e7071cb2ac1ae68d04d09c8824.png) 168 | 169 | 7. 选择`ftp.egr.msu.edu`并按下``。如果出现错误,选择其它的东西。 170 | 171 | ![](https://archive.fo/p1ZHn/546cf834885a1e587938ea7cf5dc6e07d246e65b.png) 172 | 173 | 8. 再次按下``。 174 | 175 | ![](https://archive.fo/p1ZHn/b2685c27c688d34ff6e504ffe186dd80c99c084d.png) 176 | 177 | 9. 选择``并按下``。 178 | 179 | ![](https://archive.fo/p1ZHn/fc6ebaa84a254c1ad045d64526b1a2326a37b237.png) 180 | 181 | 0. 使用``选择`SSH server and Standard system utilities`,并按下``。 182 | 183 | ![](https://archive.fo/p1ZHn/713e8e08d2e059d156824e33da39e48abd9de65b.png) 184 | 185 | 1. 选择``并按下``。 186 | 187 | ![](https://archive.fo/p1ZHn/aeb99f9cf80d45d2015fa9b1f318a9b19cec2db4.png) 188 | 189 | 2. 选择``并按下``。你新安装的 Debian 会重启。 190 | 191 | ![](https://archive.fo/p1ZHn/c912182ce24a01767fa1ffde3b08b176a3fa35f3.png) 192 | 193 | 3. 点击`Devices`并选择`Network adapters`。 194 | 195 | ![](https://archive.fo/p1ZHn/37877d8aacfd1da161dc8bdb06a2c2883dae22ca.png) 196 | 197 | 4. 点击`Port Forwarding`。 198 | 199 | ![](https://archive.fo/p1ZHn/bbcbf2ef6b2cfd5786201318978b5f9bd5bb32fa.png) 200 | 201 | 5. 点击`Plus`按钮。 202 | 203 | ![](https://archive.fo/p1ZHn/befa3bdfeebb864af78501c3d4c395293c2bc030.png) 204 | 205 | 6. 在`Host Port`中输入`22`,`Guest Port`中输入`22`,点击`OK`。 206 | 207 | ![](https://archive.fo/p1ZHn/89218bd92e2e590456bae0a7ac8d1c2168213318.png) 208 | 209 | 7. 再次点击`OK`。 210 | 211 | ![](https://archive.fo/p1ZHn/df2515bcd3fa375f8cf17f4b86a85f08d5cf47ef.png) 212 | 213 | 8. 让你的 Debian 系统运行一会儿。 214 | 215 | ![](https://archive.fo/p1ZHn/8648c8f7806c19ac2b3500adeb4bcef0f1dcd313.png) 216 | 217 | 9. 启动`putty`,在`Host Name`中输入`localhost`(或 IP 地址),在`Port`字段中输入`22`。点击`Open`。 218 | 219 | ![](https://archive.fo/p1ZHn/b4c54192c06c066444897554eb37f8693ca17578.png) 220 | 221 | 0. 点击`Yes`。 222 | 223 | ![](https://archive.fo/p1ZHn/895745a41f1b557b6befcb3a73450747e815f8c3.png) 224 | 225 | 1. 输入`user1`,点击``。输入`123qwe`,并再输入一次,来真正享受你的作品吧。 226 | 227 | ![](https://archive.fo/p1ZHn/15936cef6402ab07e7982d18d4302b869b8136ab.png) 228 | 229 | 你以为这就完了吗?现在将这些输入`putty`,通过按下``结束每个命令: 230 | 231 | ``` 232 | 1: su 233 | 2: 123qwe 234 | 3: sed -i '/^deb cdrom.*$/d' /etc/apt/sources.list 235 | 4: aptitude update 236 | 5: aptitude install vim sudo parted 237 | ``` 238 | 239 | 询问时,输入`y`并按下``。 240 | 241 | ``` 242 | 6: update-alternatives --config editor 243 | ``` 244 | 245 | 询问时,输入`3`并按下``。 246 | 247 | ``` 248 | 7: sed -i 's/%sudo ALL=(ALL) ALL/%sudo ALL=(ALL) NOPASSWD:ALL/' /etc/sudoers 249 | 8: usermod user1 -G sudo 250 | ``` 251 | 252 | 关闭`putty`,再次打开它,并作为`user1`登入`vm1`,输入这个: 253 | 254 | ``` 255 | 9: sudo -s 256 | ``` 257 | 258 | 如果你得到了`root@vm1:/home/user1#`,那么一切正常,开瓶啤酒奖励自己吧。 259 | 260 | ## 你会看到什么 261 | 262 | ``` 263 | user1@vm1:~$ su 264 | Password: 265 | root@vm1:/home/user1# sed -i '/^deb cdrom.*$/d' /etc/apt/sources.list 266 | root@vm1:/home/user1# aptitude update 267 | Hit http://security.debian.org squeeze/updates Release.gpg 268 | Ign http://security.debian.org/ squeeze/updates/main Translation-en 269 | Ign http://security.debian.org/ squeeze/updates/main Translation-en_US 270 | Hit http://security.debian.org squeeze/updates Release 271 | Hit http://ftp.egr.msu.edu squeeze Release.gpg 272 | Hit http://security.debian.org squeeze/updates/main Sources 273 | Hit http://security.debian.org squeeze/updates/main amd64 Packages 274 | Ign http://ftp.egr.msu.edu/debian/ squeeze/main Translation-en 275 | Ign http://ftp.egr.msu.edu/debian/ squeeze/main Translation-en_US 276 | Hit http://ftp.egr.msu.edu squeeze-updates Release.gpg 277 | Ign http://ftp.egr.msu.edu/debian/ squeeze-updates/main Translation-en 278 | Ign http://ftp.egr.msu.edu/debian/ squeeze-updates/main Translation-en_US 279 | Hit http://ftp.egr.msu.edu squeeze Release 280 | Hit http://ftp.egr.msu.edu squeeze-updates Release 281 | Hit http://ftp.egr.msu.edu squeeze/main Sources 282 | Hit http://ftp.egr.msu.edu squeeze/main amd64 Packages 283 | Get:1 http://ftp.egr.msu.edu squeeze-updates/main Sources/DiffIndex [2,161 B] 284 | Hit http://ftp.egr.msu.edu squeeze-updates/main amd64 Packages/DiffIndex 285 | Hit http://ftp.egr.msu.edu squeeze-updates/main amd64 Packages 286 | Fetched 2,161 B in 3s (603 B/s) 287 | root@vm1:/home/user1# aptitude install vim sudo parted 288 | The following NEW packages will be installed: 289 | libparted0debian1{a} parted sudo vim vim-runtime{a} 290 | 0 packages upgraded, 5 newly installed, 0 to remove and 0 not upgraded. 291 | Need to get 8,231 kB of archives. After unpacking 29.8 MB will be used. 292 | Do you want to continue? [Y/n/?] y 293 | Get:1 http://security.debian.org/ squeeze/updates/main sudo amd64 1.7.4p4-2.squeeze.3 [610 kB] 294 | Get:2 http://ftp.egr.msu.edu/debian/ squeeze/main libparted0debian1 amd64 2.3-5 [341 kB] 295 | Get:3 http://ftp.egr.msu.edu/debian/ squeeze/main parted amd64 2.3-5 [156 kB] 296 | Get:4 http://ftp.egr.msu.edu/debian/ squeeze/main vim-runtime all 2:7.2.445+hg~cb94c42c0e1a-1 [6,207 kB] 297 | Get:5 http://ftp.egr.msu.edu/debian/ squeeze/main vim amd64 2:7.2.445+hg~cb94c42c0e1a-1 [915 kB] 298 | Fetched 8,231 kB in 1min 18s (105 kB/s) 299 | Selecting previously deselected package libparted0debian1. 300 | (Reading database ... 34745 files and directories currently installed.) 301 | Unpacking libparted0debian1 (from .../libparted0debian1_2.3-5_amd64.deb) ... 302 | Selecting previously deselected package parted. 303 | Unpacking parted (from .../parted_2.3-5_amd64.deb) ... 304 | Selecting previously deselected package sudo. 305 | Unpacking sudo (from .../sudo_1.7.4p4-2.squeeze.3_amd64.deb) ... 306 | Selecting previously deselected package vim-runtime. 307 | Unpacking vim-runtime (from .../vim-runtime_2%3a7.2.445+hg~cb94c42c0e1a-1_all.deb) ... 308 | Adding 'diversion of /usr/share/vim/vim72/doc/help.txt to /usr/share/vim/vim72/doc/help.txt.vim-tiny by vim-runtime' 309 | Adding 'diversion of /usr/share/vim/vim72/doc/tags to /usr/share/vim/vim72/doc/tags.vim-tiny by vim-runtime' 310 | Selecting previously deselected package vim. 311 | Unpacking vim (from .../vim_2%3a7.2.445+hg~cb94c42c0e1a-1_amd64.deb) ... 312 | Processing triggers for man-db ... 313 | Setting up libparted0debian1 (2.3-5) ... 314 | Setting up parted (2.3-5) ... 315 | Setting up sudo (1.7.4p4-2.squeeze.3) ... 316 | No /etc/sudoers found... creating one for you. 317 | Setting up vim-runtime (2:7.2.445+hg~cb94c42c0e1a-1) ... 318 | Processing /usr/share/vim/addons/doc 319 | Setting up vim (2:7.2.445+hg~cb94c42c0e1a-1) ... 320 | update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vim (vim) in auto mode. 321 | update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vimdiff (vimdiff) in auto mode. 322 | update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rvim (rvim) in auto mode. 323 | update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/rview (rview) in auto mode. 324 | update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/vi (vi) in auto mode. 325 | update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/view (view) in auto mode. 326 | update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/ex (ex) in auto mode. 327 | root@vm1:/home/user1# update-alternatives --config editor 328 | There are 3 choices for the alternative editor (providing /usr/bin/editor). 329 | 330 | Selection Path Priority Status 331 | ------------------------------------------------------------ 332 | * 0 /bin/nano 40 auto mode 333 | 1 /bin/nano 40 manual mode 334 | 2 /usr/bin/vim.basic 30 manual mode 335 | 3 /usr/bin/vim.tiny 10 manual mode 336 | 337 | Press enter to keep the current choice[*], or type selection number: 3 338 | update-alternatives: using /usr/bin/vim.tiny to provide /usr/bin/editor (editor) in manual mode. 339 | root@vm1:/home/user1# sed -i 's/%sudo ALL=(ALL) ALL/%sudo ALL=(ALL) NOPASSWD:ALL/' /etc/sudoers 340 | root@vm1:/home/user1# usermod user1 -G sudo 341 | root@vm1:/home/user1# 342 | ``` 343 | 344 | ## 解释 345 | 346 | 1. 使你成为超级用户或`root`用户。 347 | 1. 你在安装过程中输入的`root`密码。 348 | 1. 修改仓库文件,因此 Debian 将尝试仅仅从互联网安装新软件。 349 | 1. 更新可用软件数据库。 350 | 1. 安装`vim`,`sudo`和`parted`包。 351 | 1. 将默认系统文本编辑器更改为`vim`。 352 | 1. 允许你通过修改`sudo`配置文件成为超级用户,而不输入密码。 353 | 1. 将你添加到`sudo`组,以便你可以通过`sudo`成为`root`。 354 | 1. 检查你是否能够成为`root`。 355 | -------------------------------------------------------------------------------- /ex18.md: -------------------------------------------------------------------------------- 1 | # 练习 18:日志:`/var/log`,`rsyslog`,`logger` 2 | 3 | > 原文:[Exercise 18. Logging, /var/log, rsyslog, logger](https://archive.fo/xmofk) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 守护进程是在后台运行的程序。所以问题来了:他们怎么告诉你他们在做什么?他们如何告诉你有什么问题?这个问题是由日志文件解决的,其中守护进程写入其状态和操作。在 Debian 中,这个文件位于`/var/log`目录下。 12 | 13 | 但谁写入这些文件?最明显的答案是守护进程本身,这实际上往往是错误的。在某些情况下,守护程序确实会自己编写日志文件,但通常它们通过名为`rsyslogd`的守护程序(称为 日志记录守护程序)来实现。它将日志写入不同的文件,来简化搜索和分析。为了区分这个文件,它有一个概念叫做“设施”。这是标准设施的列表: 14 | 15 | | 设施 | 设施说明 | 设施 | 设施说明 | 16 | | --- | --- | --- | --- | 17 | | auth | 授权相关消息 | LOCAL0 | 本地使用 0 | 18 | | authPriv | 敏感的安全信息 | LOCAL1 | 本地使用1 | 19 | | cron | Cron信息 | local2 | 本地使用 2 | 20 | | daemon | 系统守护程序 | local3 | 本地使用 3 | 21 | | ftp | FTP 守护消息 | local4 | 本地使用 4 | 22 | | kern | 内核消息 | local5 | 本地使用 5 | 23 | | lpr | 行式打印机子系统 | local6 | 当地使用 6 | 24 | | mail | 邮件子系统 | local7 | 当地使用 7 | 25 | | news | 新闻子系统 | | | 26 | | security | auth 的过时名称 | | | 27 | | syslog | 由 syslogd 内部生成的消息 | | | 28 | | user | | | | 29 | | uucp | UUCP 子系统 | | | 30 | 31 | 每个条目也标记有严重性状态,以便分析发生了什么: 32 | 33 | | 代码名称 | 严重性 | 描述 | 一般说明 | 34 | | --- | --- | --- | --- | 35 | | alert | 警报 | 必须立即采取行动。 | 应立即纠正,因此通知可以解决问题的人员。一个例子是丢失备用 ISP 连接。 | 36 | | crit | 严重 | 严重情况。 | 应立即纠正,但表示主系统出现故障,一个例子就是主 ISP 连接的丢失 。 | 37 | | debug | 调试 | 调试级别消息。 | 信息对开发人员有用,用于调试应用程序,在操作期间无用。 | 38 | | emerg | 紧急 | 系统不可用 | 通常影响多个应用程序/服务器/站点的“紧急”状态。在这个级别,通常会通知所有技术人员。 | 39 | | err | 错误 | 错误情况。 | 非紧急故障,应转发给开发人员或管理员;每个项目必须在给定的时间内解决。 | 40 | | error | 错误 | err 的弃用名称 | --- | 41 | | info | 信息 | 信息消息 | 正常操作的信息 - 可以用于收集报告,测量吞吐量等 - 无需采取任何行动。 | 42 | | notice | 注意 | 正常但重要的状况。 | 不正常但不是错误情况的事件,可能汇总为邮件发给开发者或者管理员,来定位潜在问题 - 不需要立即采取行动。 | 43 | | panic | 紧急 | emerg 的弃用名称 | --- | 44 | | warning | 警告 | 警告情况。 | 警告消息,而不是错误,但表示如果不采取行动,将发生错误,例如文件系统 85% 占满 - 每个条目必须在给定时间内解决。 | 45 | | warn | 警告 | warning 的弃用名称 | --- | 46 | 47 | 因为如果日志文件留给自己,它们往往会变得非常大,并且消耗所有可用的磁盘空间,所以有一种称为轮替的机制。默认情况下,这种机制通常只保留最后 7 天的日志文件,包括今天。轮替由`logrotate`守护进程执行,来帮助你了解这个守护进程做了什么。我为你将其写出来: 48 | 49 | ``` 50 | Day 0 51 | log.0 is created 52 | Day 1 53 | mv log.0 log.1 54 | log.0 is created 55 | Day 2 56 | mv log.1 log.2 57 | mv log.0 log.1 58 | log.0 is created 59 | Day 3 60 | mv log.2 log.3 61 | mv log.1 log.2 62 | mv log.0 log.1 63 | log.0 is created 64 | Day 4 65 | mv log.3 log.4 66 | mv log.2 log.3 67 | mv log.1 log.2 68 | mv log.0 log.1 69 | log.0 is created 70 | Day 5 71 | mv log.4 log.5 72 | mv log.3 log.4 73 | mv log.2 log.3 74 | mv log.1 log.2 75 | mv log.0 log.1 76 | log.0 is created 77 | Day 6 78 | mv log.5 log.6 79 | mv log.4 log.5 80 | mv log.3 log.4 81 | mv log.2 log.3 82 | mv log.1 log.2 83 | mv log.0 log.1 84 | log.0 is created 85 | Day 7 86 | rm log.6 87 | mv log.5 log.6 88 | mv log.4 log.5 89 | mv log.3 log.4 90 | mv log.2 log.3 91 | mv log.1 log.2 92 | mv log.0 log.1 93 | log.0 is created 94 | ``` 95 | 96 | 让我重复一下: 97 | 98 | + 日志是一个记录时间的过程,使用自动化的计算机程序,来提供审计跟踪,可用于了解系统活动和诊断问题。 99 | + 日志守护程序是程序,其他程序可能要求它在日志文件中写入内容。 100 | + 每个日志条目具有设施(日志类别)和严重性 (它是多么重要)属性。 101 | + 轮替是一个过程,仅保留有限数量的日志文件,来避免填满磁盘。 102 | + 在 Debian 中,日志文件通常位于`/var/log`目录中。 103 | 104 | 这是处理日志的有用命令(要记住打开相关的手册页,并找出有什么选项): 105 | 106 | + `logger Hello, I have a kitty!` - 编写一个自定义日志消息。 107 | + `ls -altr /var/log` - 列出日志目录,以这样一种方式,最后修改的文件到最后。 108 | + `grep user1 /var/log/auth.log` - 列出文件中包含`user1`的所有行。 109 | + `grep -irl user1 /var/log` - 列出所有包含`user1`的文件 。 110 | + `find /var/log -mmin -10` - 找到在过去 10 分钟内被修改的任何文件。 111 | + `tail /var/log/auth.log` - 打印日志文件的最后 10 行。 112 | + `tail -f /var/log/auth.log` - 实时跟踪日志文件。配置守护进程时非常有用。 113 | 114 | 现在你将学习如何查看日志,并将一些东西写入系统日志。 115 | 116 | ## 这样做 117 | 118 | ``` 119 | 1: sudo -s 120 | 2: cd /var/log 121 | 3: ls -altr | tail 122 | 4: tail auth.log 123 | 5: grep user1 auth.log | tail 124 | 6: /etc/init.d/exim4 restart 125 | 7: find /var/log -mmin -5 126 | 8: tail /var/log/exim4/mainlog 127 | 9: grep -irl rcconf . 128 | 10: tail ./dpkg.log 129 | 11: last 130 | 12: lastlog 131 | 13: logger local0.alert I am a kitty, sittin in ur system watchin u work ^^ 132 | 14: ls -altr | tail 133 | 15: tail messages 134 | ``` 135 | 136 | ## 你会看到什么 137 | 138 | ``` 139 | user1@vm1:~$ sudo -s 140 | root@vm1:/home/user1# cd /var/log 141 | root@vm1:/var/log# ls -altr | tail 142 | -rw-r----- 1 root adm 46955 Jun 29 12:28 messages 143 | -rw-r----- 1 root adm 19744 Jun 29 12:28 dmesg 144 | -rw-r----- 1 root adm 696 Jun 29 12:28 daemon.log 145 | drwxr-xr-x 7 root root 4096 Jun 29 12:28 . 146 | -rw-r----- 1 root adm 60738 Jun 29 12:28 syslog 147 | -rw-r----- 1 root adm 58158 Jun 29 12:28 kern.log 148 | -rw-r----- 1 root adm 12652 Jun 29 12:28 debug 149 | -rw-rw-r-- 1 root utmp 75264 Jun 29 12:28 wtmp 150 | -rw-rw-r-- 1 root utmp 292584 Jun 29 12:28 lastlog 151 | -rw-r----- 1 root adm 38790 Jun 29 12:40 auth.log 152 | root@vm1:/var/log# tail auth.log 153 | Jun 29 12:28:22 vm1 sshd[983]: Server listening on 0.0.0.0 port 22. 154 | Jun 29 12:28:22 vm1 sshd[983]: Server listening on :: port 22. 155 | Jun 29 12:28:44 vm1 sshd[1214]: Accepted password for user1 from 194.85.195.183 port 53775 ssh2 156 | Jun 29 12:28:44 vm1 sshd[1214]: pam_unix(sshd:session): session opened for user user1 by (uid=0) 157 | Jun 29 12:30:49 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 158 | Jun 29 12:30:53 vm1 login[1260]: pam_securetty(login:auth): unexpected response from failed conversation function 159 | Jun 29 12:30:53 vm1 login[1260]: pam_securetty(login:auth): cannot determine username 160 | Jun 29 12:35:08 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 161 | Jun 29 12:35:14 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 162 | Jun 29 12:40:32 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 163 | root@vm1:/var/log# tail auth.log | grep user1 164 | Jun 29 12:28:44 vm1 sshd[1214]: Accepted password for user1 from 194.85.195.183 port 53775 ssh2 165 | Jun 29 12:28:44 vm1 sshd[1214]: pam_unix(sshd:session): session opened for user user1 by (uid=0) 166 | Jun 29 12:30:49 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 167 | Jun 29 12:35:08 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 168 | Jun 29 12:35:14 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 169 | Jun 29 12:40:32 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 170 | root@vm1:/var/log# grep user1 auth.log | tail 171 | Jun 29 12:26:33 vm1 sshd[1302]: Accepted password for user1 from 194.85.195.183 port 53008 ssh2 172 | Jun 29 12:26:33 vm1 sshd[1302]: pam_unix(sshd:session): session opened for user user1 by (uid=0) 173 | Jun 29 12:26:38 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 174 | Jun 29 12:28:02 vm1 sshd[1302]: pam_unix(sshd:session): session closed for user user1 175 | Jun 29 12:28:44 vm1 sshd[1214]: Accepted password for user1 from 194.85.195.183 port 53775 ssh2 176 | Jun 29 12:28:44 vm1 sshd[1214]: pam_unix(sshd:session): session opened for user user1 by (uid=0) 177 | Jun 29 12:30:49 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 178 | Jun 29 12:35:08 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 179 | Jun 29 12:35:14 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 180 | Jun 29 12:40:32 vm1 sudo: user1 : TTY=pts/0 ; PWD=/home/user1 ; USER=root ; COMMAND=/bin/bash 181 | root@vm1:/home/user1# /etc/init.d/exim4 restart 182 | Stopping MTA for restart: exim4_listener. 183 | Restarting MTA: exim4. 184 | root@vm1:/home/user1# find /var/log -mmin -5 185 | /var/log/exim4/mainlog 186 | /var/log/auth.log 187 | root@vm1:/home/user1# tail /var/log/exim4/mainlog 188 | 2012-06-29 12:24:11 exim 4.72 daemon started: pid=1159, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25 189 | 2012-06-29 12:24:11 Start queue run: pid=1165 190 | 2012-06-29 12:24:11 End queue run: pid=1165 191 | 2012-06-29 12:28:22 exim 4.72 daemon started: pid=1190, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25 192 | 2012-06-29 12:28:22 Start queue run: pid=1196 193 | 2012-06-29 12:28:22 End queue run: pid=1196 194 | 2012-06-29 12:41:18 exim 4.72 daemon started: pid=1622, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25 195 | 2012-06-29 12:41:18 Start queue run: pid=1624 196 | 2012-06-29 12:41:18 End queue run: pid=1624 197 | 2012-06-29 12:42:28 exim 4.72 daemon started: pid=1886, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25 198 | root@vm1:/home/user1# grep -irl rcconf . 199 | ./aptitude 200 | ./apt/history.log 201 | ./apt/term.log 202 | ./dpkg.log 203 | ./auth.log 204 | root@vm1:/home/user1# tail ./dpkg.log 205 | 2012-06-26 19:27:40 status unpacked rcconf 2.5 206 | 2012-06-26 19:27:40 status unpacked rcconf 2.5 207 | 2012-06-26 19:27:40 trigproc man-db 2.5.7-8 2.5.7-8 208 | 2012-06-26 19:27:40 status half-configured man-db 2.5.7-8 209 | 2012-06-26 19:27:40 status installed man-db 2.5.7-8 210 | 2012-06-26 19:27:41 startup packages configure 211 | 2012-06-26 19:27:41 configure rcconf 2.5 2.5 212 | 2012-06-26 19:27:41 status unpacked rcconf 2.5 213 | 2012-06-26 19:27:41 status half-configured rcconf 2.5 214 | 2012-06-26 19:27:41 status installed rcconf 2.5 215 | root@vm1:/var/log# last 216 | user1 pts/0 sis.site Fri Jun 29 12:26 still logged in 217 | user1 pts/0 sis.site Fri Jun 29 12:14 - down (00:09) 218 | user1 pts/0 sis.site Thu Jun 28 19:40 - 11:25 (15:45) 219 | user1 pts/0 sis.site Wed Jun 27 19:14 - 17:04 (21:50) 220 | user1 pts/0 sis.site Tue Jun 26 13:54 - 18:18 (1+04:23) 221 | user1 pts/0 sis.site Thu Jun 21 15:23 - 13:11 (4+21:47) 222 | user1 pts/0 sis.site Fri Jun 15 19:34 - 12:01 (5+16:26) 223 | user1 pts/0 sis.site Fri Jun 15 19:11 - 19:34 (00:22) 224 | reboot system boot 2.6.32-5-amd64 Fri Jun 29 12:24 - 12:26 (00:02) 225 | user1 pts/0 sis.site Fri Jun 29 12:14 - down (00:09) 226 | root@vm1:/var/log# lastlog 227 | Username Port From Latest 228 | root **Never logged in** 229 | daemon **Never logged in** 230 | bin **Never logged in** 231 | sys **Never logged in** 232 | sync **Never logged in** 233 | games **Never logged in** 234 | man **Never logged in** 235 | lp **Never logged in** 236 | mail **Never logged in** 237 | news **Never logged in** 238 | uucp **Never logged in** 239 | proxy **Never logged in** 240 | www-data **Never logged in** 241 | backup **Never logged in** 242 | list **Never logged in** 243 | irc **Never logged in** 244 | gnats **Never logged in** 245 | nobody **Never logged in** 246 | libuuid **Never logged in** 247 | Debian-exim **Never logged in** 248 | statd **Never logged in** 249 | sshd **Never logged in** 250 | user1 pts/0 sis.site Fri Jun 29 12:28:45 +0400 2012 251 | root@vm1:/var/log# logger local0.alert I am a kitty, sittin in ur system watchin u work ^^ 252 | root@vm1:/var/log# ls -altr | tail 253 | -rw-r----- 1 root adm 696 Jun 29 12:28 daemon.log 254 | drwxr-xr-x 7 root root 4096 Jun 29 12:28 . 255 | -rw-r----- 1 root adm 58158 Jun 29 12:28 kern.log 256 | -rw-r----- 1 root adm 12652 Jun 29 12:28 debug 257 | -rw-rw-r-- 1 root utmp 75264 Jun 29 12:28 wtmp 258 | -rw-rw-r-- 1 root utmp 292584 Jun 29 12:28 lastlog 259 | -rw-r----- 1 root adm 38971 Jun 29 13:17 auth.log 260 | -rw-r----- 1 root adm 229 Jun 29 13:19 user.log 261 | -rw-r----- 1 root adm 60932 Jun 29 13:19 syslog 262 | -rw-r----- 1 root adm 47047 Jun 29 13:19 messages 263 | root@vm1:/var/log# tail messages 264 | Jun 29 12:28:21 vm1 kernel: [ 1.846975] processor LNXCPU:00: registered as cooling_device0 265 | Jun 29 12:28:21 vm1 kernel: [ 1.868828] usbcore: registered new interface driver hiddev 266 | Jun 29 12:28:21 vm1 kernel: [ 1.895676] input: QEMU 0.14.1 QEMU USB Tablet as /devices/pci0000:00/0000:00:01.2/usb1/1-1/1-1:1.0/input/input4 267 | Jun 29 12:28:21 vm1 kernel: [ 1.895743] generic-usb 0003:0627:0001.0001: input,hidraw0: USB HID v0.01 Pointer [QEMU 0.14.1 QEMU USB Tablet] on usb-0000:00:01.2-1/input0 268 | Jun 29 12:28:21 vm1 kernel: [ 1.895762] usbcore: registered new interface driver usbhid 269 | Jun 29 12:28:21 vm1 kernel: [ 1.895765] usbhid: v2.6:USB HID core driver 270 | Jun 29 12:28:21 vm1 kernel: [ 2.373061] EXT3 FS on vda1, internal journal 271 | Jun 29 12:28:21 vm1 kernel: [ 2.394992] loop: module loaded 272 | Jun 29 12:28:21 vm1 kernel: [ 2.413478] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input5 273 | Jun 29 13:19:11 vm1 user1: local0.alert I am a kitty, sittin in ur system watchin u work ^^ 274 | root@vm1:/var/log# 275 | ``` 276 | 277 | ## 解释 278 | 279 | + 打开 root (超级用户)shell。这是因为作为`user1`工作时,出于安全的考虑,你不能读取所有日志文件。 280 | + 将目录更改为`/var/log`。 281 | + 按日期排序打印所有文件,最后修改的文件在底部。 282 | + 从`auth.log`打印最后 10 行,包含登录系统的信息。 283 | + 从`auth.log`打印包含`user1`的最后 10 行。 284 | + 重启`exim4`邮件服务器。 285 | + 打印最近 5 分钟内的文件更改。现在,你可以轻松找到`exim4`在哪个文件中 记录其操作。 286 | + 从`exim4`日志打印出最后 10 行 。 287 | + 在当前目录中的所有文件 搜索`rcconf`。现在,你可以轻松找到 Debian 包系统记录其操作的位置。 288 | + 从`dpkg.log`打印最后 10 行,含有软件包安装和删除信息。 289 | + 打印用户最后登录的信息。 290 | + 打印所有用户最近登录的信息。 291 | + 将你的消息传递给`rsyslogd`守护程序。 292 | + 按日期排序打印所有文件,最后修改的文件位于底部。现在你可能会看到这里就是你的消息。 293 | + 从消息中打印出最后10行,你可以看到你的消息确实已记录。 294 | 295 | ## 附加题 296 | 297 | 阅读`rsyslogd`和`logger`的手册页。 298 | 通过阅读相应的手册页,找出`last`和`lastlog`之间的区别。 299 | 阅读`logrotate`手册页并记住它的存在。 300 | 执行`tail -f /var/log/auth.log`,并生成`vm1`的第二个连接(如果你在 Windows 上工作,则为 putty)。不错吧? 301 | -------------------------------------------------------------------------------- /ex20.md: -------------------------------------------------------------------------------- 1 | # 练习 20:文件系统:修改和创建文件系统,`tune2fs`,`mkfs` 2 | 3 | > 原文:[Exercise 20. Filesystems: modifying and creating filesystems, tune2fs, mkfs](https://archive.fo/CzHiN) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 让我来介绍一下文件系统相关的术语: 12 | 13 | + [文件系统](http://en.wikipedia.org/wiki/File_system) - 一种组织数据的方式,通过提供存储,检索和更新数据的过程,以及管理包含它的设备上的可用空间,数据预期在终止后保留。 14 | + Inode - 索引节点是一种结构,存储文件系统对象(文件,目录等)的所有信息,除数据内容和文件名之外。 15 | + 块 - 可以分配的最小块磁盘空间。它通常默认为 4096 字节,或 4 千字节。 16 | + 日志 - 一种结构,允许文件系统跟踪什么时候写入了什么。这样可以快速了解在断电或类似问题时,未正确写入的内容。 17 | 18 | 接下来,让我给大家简要介绍文件系统的工作原理。为了按名称访问文件,Linux 内核将: 19 | 20 | + 在包含该文件的目录中查找文件名。 21 | + 获取文件 Inode 号。 22 | + 通过 Inode 区域中的数字查找 Inode。 23 | + 读取此 Inode 的数据块的位置。 24 | + 使用这个位置在数据区域中从这个块读取文件。 25 | 26 | 现在,每个文件系统都有很多与之相关的选项。这些选项可以通过`tune2fs `程序查看和更改。这是一个带注解的`tune2fs -l /dev/sda8`的输出: 27 | 28 | ``` 29 | user1@vm1:~$ sudo tune2fs -l /dev/sda8 30 | tune2fs 1.41.12 (17-May-2010) 31 | # 只是个标签,可以是任何东西,或者没有东西 32 | Filesystem volume name: 33 | # 这里应该是最后的挂载点 34 | Last mounted on: 35 | # 唯一的文件系统标识符 36 | Filesystem UUID: 869db6b4-aea0-4a25-8bd2-f0b53dd7a88e 37 | # 已知位置的特殊数字,它定义了 FS 的类型,尝试这个: 38 | # sudo dd if=/dev/sda8 of=/dev/stdout bs=1 skip=1080 count=2 | hexdump -C 39 | Filesystem magic number: 0xEF53 40 | # FS 版本 41 | Filesystem revision #: 1 (dynamic) 42 | # 启用的 FS 功能 43 | Filesystem features: 44 | # 这是一个日志文件系统。日志文件系统是一个文件系统, 45 | # 它跟踪日志中发生的变化(通常是一个循环日志, 46 | # 在文件系统的特定位置),在提交给主文件系统之前。 47 | # 在系统崩溃或者断电的事件中,这种文件系统能够更快 48 | # 恢复,并且不可能毁坏。 49 | # http://en.wikipedia.org/wiki/Journaling_file_system 50 | has_journal 51 | # 拥有扩展属性,例如扩展的 ACL。 52 | ext_attr 53 | # 为系统信息保留空间,这允许 FS 改变大小。 54 | resize_inode 55 | # 使用索引来加速大目录中的查找。 56 | dir_index 57 | # 在目录条目中储存文件类型信息。 58 | filetype 59 | # 意思是需要运行 fsck。 60 | needs_recovery 61 | # 更少的超级块备份,在大 FS 上节约空间。 62 | sparse_super 63 | # 是否可以包含 > 2GB 的文件。在创建 >2GB 的文件时,内核会自动设置它。 64 | large_file 65 | # dir_index 中使用哪个哈希 66 | Filesystem flags: signed_directory_hash 67 | # 挂载时使用什么选项 68 | Default mount options: (none) 69 | # 是否需要执行 fsck 70 | Filesystem state: clean 71 | # 错误时做什么:继续,以只读方式重新挂载,或者报错? 72 | Errors behavior: Continue 73 | # 哪个 OS 使用这个 FS 74 | Filesystem OS type: Linux 75 | # 索引节点总数。索引节点就是 "inode"。它的结构是: 76 | # 储存所有文件系统对象(文件、目录,以及其他)的信息 77 | # 除了文件内容和文件名称。也就是说, 78 | # 你的文件数量不能多于索引节点数量。 79 | # 这就是索引节点结构,它描述了里面储存了什么信息: 80 | #/* 出现在 Inode 表中的 Inode 结构 */ 81 | #struct dinode 82 | #{ ushort di_mode; /* mode and type of file */ 83 | # short di_nlink; /* number of links to file */ 84 | # ushort di_uid; /* owner's user id */ 85 | # ushort di_gid; /* owner's group id */ 86 | # off_t di_size; /* number of bytes in file */ 87 | # char di_addr[39]; /* disk block addresses */ 88 | # char di_gen; /* file generation number */ 89 | # time_t di_atime; /* time last accessed */ 90 | # time_t di_mtime; /* time last modified */ 91 | # time_t di_ctime; /* time created */ 92 | #}; 93 | # 这里也有很好的解释: 94 | # http://support.tux4u.nl/dokuwiki/lib/exe/fetch.php?media=linux:disk_bestandssysteem:inode.pdf 95 | Inode count: 62464 96 | # 当前有多少空闲节点 97 | Free inodes: 62452 98 | # 设备上的第一个块。由于每个分区都表示为单独的设备, 99 | # 它设为 0。 100 | First block: 0 101 | # 这是文件系统中,第一个索引节点的节点号。 102 | First inode: 11 103 | # 索引节点的大小,以字节为单位。在新的 Linux 发行版中,这有时会默认增加, 104 | # 为了允许文件中扩展属性的存储,例如,微秒时间戳。 105 | Inode size: 256 106 | # 添加索引节点字段所需的空间 107 | Required extra isize: 28 108 | # 添加索引节点字段要求的空间。不重要,因为这个大小 109 | # 任何时候都是所需空间 110 | Desired extra isize: 28 111 | # 一个隐形节点,它储存文件系统的日志。 112 | Journal inode: 8 113 | # 块的总数。块是磁盘空间可分配的最小单位。 114 | # 你可以使用下面的公式,以 GB 计算分区大小: 115 | # 块的数量 * 块的大小 116 | # ------------------------ 117 | # 1024^3 118 | Block count: 249856 119 | # 有多少块为超极用户保留。普通用户不能使用这个 120 | # 保留空间。这是为了使系统保持运行,以防一些流氓软件 121 | # 决定塞满所有可用的磁盘空间。 122 | Reserved block count: 12492 123 | # 当前有多少块是空闲的。 124 | Free blocks: 241518 125 | # 用于目录索引(dir_index)的算法。 126 | Default directory hash: half_md4 127 | # 目前为止,我可以说,这是用于 dir_index 哈希算法的种子值。 128 | Directory Hash Seed: d02c6099-bd06-4d29-a3d7-779df2aa2410 129 | # 日志备份选项。 130 | Journal backup: inode blocks # 131 | # 块的大小,以字节为单位。4096 字节就是 4 KB。 132 | Block size: 4096 133 | # 在 ex3 FS 中未实现。这是一个特性,它能够在一个块中写入多个小文件, 134 | # 来节约空间。 135 | Fragment size: 4096 136 | # 保留的控件,所以组描述符表可能在未来会增长。 137 | Reserved GDT blocks: 60 138 | # 每个块组的块数量。块组包含文件系统重要的控制信息的冗余副本。 139 | # (超级块和文件描述符),并包含一部分文件系统contains a 140 | # (块的位图,索引节点的位图,一部分索引节点表,以及数据块)。 141 | # 块组的结构在下表中展示: 142 | #,---------+---------+---------+---------+---------+---------, 143 | #| 超级 | FS | 块的 | Inode | Inode | 数据 | 144 | #| 块 | 描述符 | 位图 | 位图 | 表 | 块 | 145 | #`---------+---------+---------+---------+---------+---------' 146 | # http://tldp.org/HOWTO/Filesystems-HOWTO-6.html 147 | Blocks per group: 32768 148 | # 每个组的片段数量。因为 ext3 FS 中没有片段, 149 | # 这等于每个组的块数量。 150 | Fragments per group: 32768 151 | # 每个组的索引节点数量。 152 | Inodes per group: 7808 153 | # 每个组的索引节点块。索引节点块是一个表的索引, 154 | # 描述了所有文件属性,除了文件名称。它拥有数据块的索引。 155 | # 数据块包含文件真实内容。 156 | # http://www.porcupine.org/forensics/forensic-discovery/chapter3.html 157 | Inode blocks per group: 488 158 | # FS 的创建时间。 159 | Filesystem created: Mon Jul 2 06:16:24 2012 160 | # 最后的 FS 挂载时间。 161 | Last mount time: Mon Jul 2 06:57:21 2012 162 | # 最后的 FS 写入时间。 163 | Last write time: Mon Jul 2 06:57:21 2012 164 | # FS 的挂载次数。 165 | Mount count: 6 166 | # 自动检查前的次数。如果文件系统的挂载次数是这个 167 | # 或者检查间隔到了,那么 FS 会自动检查。 168 | Maximum mount count: 34 169 | # 最后的 fsck 执行时间 170 | Last checked: Mon Jul 2 06:16:24 2012 171 | # 下一个 FS 检查间隔. 如果这个间隔到了, 172 | # 或者到达了最大挂载数,FS 会自动检查。 173 | Check interval: 15552000 (6 months) 174 | # 下一个 FS 检查间隔,以人类可读的格式。 175 | Next check after: Sat Dec 29 05:16:24 2012 176 | # 能够使用保留空间的用户的用户 ID。 177 | # 它默认是 root 用户(超级用户) 178 | Reserved blocks uid: 0 (user root) 179 | # 能够使用保留空间的用户的组 ID。 180 | # 它默认是 root 组 181 | Reserved blocks gid: 0 (group root) 182 | ``` 183 | 184 | 很可怕,是嘛?实际上你会发现,这个描述中只有几个参数实际上是有用的,它们是: 185 | 186 | + 保留块数量。 187 | + 最大挂载数。 188 | + 检查间隔。 189 | 190 | 通常你不需要修改其他参数,默认情况下它们是正常的。以下是使用文件系统的命令列表: 191 | 192 | + `mkfs.ext3` - 创建一个`ext3`文件系统。如果在具有现有文件系统的设备上执行此命令,则该文件系统将被销毁,因此请小心。 193 | + `mkfs.ext4` - 创建一个`ext4`文件系统。这其实是相同的程序,尝试`sudo find /sbin -samefile sbin/mkfs.ext3`。 194 | + `tune2fs` - 打印并更改文件系统参数。 195 | 196 | 现在,你将学习如何创建新的文件系统并修改其参数。 197 | 198 | ## 这样做 199 | 200 | ``` 201 | 1: sudo -s 202 | 2: umount /tmp 203 | 3: blkid | grep /dev/sda8 204 | 4: mkfs.ext3 /dev/sda8 205 | 5: blkid | grep /dev/sda8 206 | 6: blkid | grep /dev/sda8 >> /etc/fstab 207 | 7: vim /etc/fstab 208 | ``` 209 | 210 | 现在你必须将`/tmp`那一行的 UUID。 211 | 212 | ``` 213 | # /tmp was on /dev/sda8 during installation 214 | UUID=869db6b4-aea0-4a25-8bd2-f0b53dd7a88e /tmp ext3 defaults 0 2 215 | ``` 216 | 217 | 替换为你添加到文件末尾的那个: 218 | 219 | ``` 220 | /dev/sda8: UUID="53eed507-18e8-4f71-9003-bcea8c4fd2dd" TYPE="ext3" SEC_TYPE="ext2" 221 | ``` 222 | 223 | 因为根据定义,你的 UUID 必须跟我的不同。在替换 UUID,编写文件,退出之后,继续并输入: 224 | 225 | ``` 226 | 8: mount /tmp 227 | 9: tune2fs -c 2 /dev/sda8 228 | 10: unmount /tmp 229 | 11: fsck /tmp 230 | 12: for ((i=1;i<=4;i++)); do mount /tmp ; umount /tmp ; cat /var/log/messages | tail -n 4 ; done 231 | 13: fsck /tmp 232 | 14: mount -a 233 | ``` 234 | 235 | ## 你会看到什么 236 | 237 | ``` 238 | user1@vm1:~$ sudo -s 239 | root@vm1:/home/user1# umount /tmp 240 | root@vm1:/home/user1# blkid | grep /dev/sda8 241 | /dev/sda8: UUID="869db6b4-aea0-4a25-8bd2-f0b53dd7a88e" TYPE="ext3" SEC_TYPE="ext2" 242 | root@vm1:/home/user1# mkfs.ext3 /dev/sda8 243 | mke2fs 1.41.12 (17-May-2010) 244 | Filesystem label= 245 | OS type: Linux 246 | Block size=4096 (log=2) 247 | Fragment size=4096 (log=2) 248 | Stride=0 blocks, Stripe width=0 blocks 249 | 62464 inodes, 249856 blocks 250 | 12492 blocks (5.00%) reserved for the super user 251 | First data block=0 252 | Maximum filesystem blocks=255852544 253 | 8 block groups 254 | 32768 blocks per group, 32768 fragments per group 255 | 7808 inodes per group 256 | Superblock backups stored on blocks: 257 | 32768, 98304, 163840, 229376 258 | 259 | Writing inode tables: done 260 | Creating journal (4096 blocks): done 261 | Writing superblocks and filesystem accounting information: done 262 | 263 | This filesystem will be automatically checked every 28 mounts or 264 | 180 days, whichever comes first. Use tune2fs -c or -i to override. 265 | root@vm1:/home/user1# blkid | grep /dev/sda8 266 | /dev/sda8: UUID="53eed507-18e8-4f71-9003-bcea8c4fd2dd" TYPE="ext3" SEC_TYPE="ext2" 267 | root@vm1:/home/user1# blkid | grep /dev/sda8 >> /etc/fstab 268 | root@vm1:/home/user1# vim /etc/fstab 269 | # that works even if disks are added and removed. See fstab(5). 270 | # 271 | # 272 | proc /proc proc defaults 0 0 273 | # / was on /dev/vda5 during installation 274 | UUID=128559db-a2e0-4983-91ad-d4f43f27da49 / ext3 errors=re 275 | # /home was on /dev/vda10 during installation 276 | UUID=32852d29-ddee-4a8d-9b1e-f46569a6b897 /home ext3 defaults 277 | # /tmp was on /dev/sda8 during installation 278 | UUID=869db6b4-aea0-4a25-8bd2-f0b53dd7a88e /tmp ext3 defaults 279 | # /usr was on /dev/vda9 during installation 280 | UUID=0221be16-496b-4277-b131-2371ce097b44 /usr ext3 defaults 281 | # /var was on /dev/vda8 during installation 282 | UUID=2db00f94-3605-4229-8813-0ee23ad8634e /var ext3 defaults 283 | # swap was on /dev/vda6 during installation 284 | UUID=3a936af2-2c04-466d-b98d-09eacc5d104c none swap sw 285 | /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0 286 | /dev/sda8: UUID="53eed507-18e8-4f71-9003-bcea8c4fd2dd" TYPE="ext3" SEC_TYPE 287 | 22,1 Bot 288 | 289 | # 290 | # 291 | proc /proc proc defaults 0 0 292 | # / was on /dev/vda5 during installation 293 | UUID=128559db-a2e0-4983-91ad-d4f43f27da49 / ext3 errors=re 294 | # /home was on /dev/vda10 during installation 295 | UUID=32852d29-ddee-4a8d-9b1e-f46569a6b897 /home ext3 defaults 296 | # /tmp was on /dev/sda8 during installation 297 | UUID=53eed507-18e8-4f71-9003-bcea8c4fd2dd /tmp ext3 defaults 298 | # /usr was on /dev/vda9 during installation 299 | UUID=0221be16-496b-4277-b131-2371ce097b44 /usr ext3 defaults 300 | # /var was on /dev/vda8 during installation 301 | UUID=2db00f94-3605-4229-8813-0ee23ad8634e /var ext3 defaults 302 | 303 | # swap was on /dev/vda6 during installation 304 | UUID=3a936af2-2c04-466d-b98d-09eacc5d104c none swap sw 305 | /dev/scd0 /media/cdrom0 udf,iso9660 user,noauto 0 0 306 | "/etc/fstab" 22L, 1277C written 307 | root@vm1:/home/user1# mount /tmp 308 | root@vm1:/home/user1# tune2fs -c 2 /dev/sda8 309 | tune2fs 1.41.12 (17-May-2010) 310 | Setting maximal mount count to 2 311 | root@vm1:/home/user1# unmount /tmp 312 | root@vm1:/home/user1# fsck /tmp 313 | fsck from util-linux-ng 2.17.2 314 | e2fsck 1.41.12 (17-May-2010) 315 | /dev/sda8: clean, 11/62464 files, 8337/249856 blocks (check in 2 mounts) 316 | root@vm1:/home/user1# for ((i=1;i<=4;i++)); do mount /tmp ; umount /tmp ; cat /var/log/messages | tail -n 4 ; done 317 | Jul 2 12:11:43 vm1 kernel: [21080.920658] EXT3-fs: mounted filesystem with ordered data mode. 318 | Jul 2 12:11:58 vm1 kernel: [21096.363787] kjournald starting. Commit interval 5 seconds 319 | Jul 2 12:11:58 vm1 kernel: [21096.364167] EXT3 FS on sda8, internal journal 320 | Jul 2 12:11:58 vm1 kernel: [21096.364171] EXT3-fs: mounted filesystem with ordered data mode. 321 | Jul 2 12:11:58 vm1 kernel: [21096.364171] EXT3-fs: mounted filesystem with ordered data mode. 322 | Jul 2 12:11:58 vm1 kernel: [21096.381372] kjournald starting. Commit interval 5 seconds 323 | Jul 2 12:11:58 vm1 kernel: [21096.381539] EXT3 FS on sda8, internal journal 324 | Jul 2 12:11:58 vm1 kernel: [21096.381542] EXT3-fs: mounted filesystem with ordered data mode. 325 | Jul 2 12:11:58 vm1 kernel: [21096.396152] kjournald starting. Commit interval 5 seconds 326 | Jul 2 12:11:58 vm1 kernel: [21096.396158] EXT3-fs warning: maximal mount count reached, running e2fsck is recommended 327 | Jul 2 12:11:58 vm1 kernel: [21096.396344] EXT3 FS on sda8, internal journal 328 | Jul 2 12:11:58 vm1 kernel: [21096.396348] EXT3-fs: mounted filesystem with ordered data mode. 329 | Jul 2 12:11:58 vm1 kernel: [21096.412434] kjournald starting. Commit interval 5 seconds 330 | Jul 2 12:11:58 vm1 kernel: [21096.412441] EXT3-fs warning: maximal mount count reached, running e2fsck is recommended 331 | Jul 2 12:11:58 vm1 kernel: [21096.412610] EXT3 FS on sda8, internal journal 332 | Jul 2 12:11:58 vm1 kernel: [21096.412612] EXT3-fs: mounted filesystem with ordered data mode. 333 | root@vm1:/home/user1# fsck /tmp 334 | fsck from util-linux-ng 2.17.2 335 | e2fsck 1.41.12 (17-May-2010) 336 | /dev/sda8 has been mounted 4 times without being checked, check forced. 337 | Pass 1: Checking inodes, blocks, and sizes 338 | Pass 2: Checking directory structure 339 | Pass 3: Checking directory connectivity 340 | Pass 4: Checking reference counts 341 | Pass 5: Checking group summary information 342 | /dev/sda8: 11/62464 files (0.0% non-contiguous), 8337/249856 blocks 343 | root@vm1:/home/user1# mount -a 344 | root@vm1:/home/user1# 345 | ``` 346 | 347 | ## 解释 348 | 349 | 1. 执行 root(超级用户)shell。 350 | 1. 解除挂载`/tmp`,从`/etc/fstab`读取它的位置 。 351 | 1. 打印出`/dev/sda8`的UUID,`/dev/sda8`是挂载在`/tmp`上的文件系统。 352 | 1. 在`/dev/sda8`上创建一个新的文件系统。 353 | 1. 再次打印出`/dev/sda8`的 UUID,注意如何变化,因为你创建了一个新的文件系统。 354 | 1. 将此 UUID 附加到`/etc/fstab`。 355 | 1. 打开`/etc/fstab`进行编辑。 356 | 1. 挂载新创建的文件系统。这实际上是一个检查,是否你已经正确替换了 UUID,如果不是会有一个错误消息。 357 | 1. 设置每两次挂载检查`/dev/sda8`。 358 | 1. 解除挂载`/dev/sda8`。 359 | 1. 检查`/dev/sda8`。 360 | 1. 挂载,接触挂载`/dev/sda8`, 并连续四次向你展示`/var/log/messages/`的最后4 行。请注意,从第三次开始,挂载系统通知你 需要运行`e2fsck`。如果你重新启动系统,它将为你运行`e2fsck`。 361 | 1. 检查`/dev/sda8`。`fsck`确定文件系统类型并自动调用`e2fsck`。 362 | 1. 挂载所有文件系统。如果没有错误,你已经完成了这个练习。 363 | 364 | ## 附加题 365 | 366 | + 阅读`man mkfs`,`man mkfs.ext3`,`man tune2fs`。 367 | + 阅读页面顶部的`tune2fs -l`列表,并为你的所有文件系统读取幻数。 368 | + 手动计算文件系统的大小,使用在`tune2fs -l`列表的块描述中提供的公式。 369 | + 阅读这个幻灯片,并完成它展示的东西:。 370 | -------------------------------------------------------------------------------- /ex28.md: -------------------------------------------------------------------------------- 1 | # 练习 28:性能:获取性能情况,`uptime`,`free`,`top` 2 | 3 | > 原文:[Exercise 28. Performance: getting performance stats, uptime, free, top](https://archive.fo/U2SqV) 4 | 5 | > 译者:[飞龙](https://github.com/wizardforcel) 6 | 7 | > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) 8 | 9 | > 自豪地采用[谷歌翻译](https://translate.google.cn/) 10 | 11 | 这个练习很简单。首先,我们需要什么样的性能数据? 12 | 13 | + CPU 使用情况: 14 | + 它的负载如何? 15 | + 哪些进程正在使用它? 16 | + 内存使用情况: 17 | + 使用了多少内存? 18 | + 多少内存是空闲的? 19 | + 多少内存用于缓存? 20 | + 哪些进程消耗了它? 21 | + 磁盘使用情况: 22 | + 执行多少输入/输出操作? 23 | + 由哪个进程? 24 | + 网络使用情况: 25 | + 传输了多少数据? 26 | + 由哪个进程? 27 | + 进程情况: 28 | + 有多少进程? 29 | + 他们在做什么 工作,还是等待什么? 30 | + 如果在等待什么,它是什么呢?CPU,磁盘,网络? 31 | 32 | 为了获取这些情况,我们可以使用以下工具: 33 | 34 | + `uptime` - 系统运行了多长时间。 35 | + `free` - 显示系统中可用和使用的内存量。 36 | + `vmstat` - 进程,内存,分页,块 IO,陷阱,磁盘和 cpu 活动的信息。 37 | + `top` - 实时显示 Linux 任务。 38 | 39 | 我们来看看这个程序及其输出。 40 | 41 | `uptime`的输出: 42 | 43 | ``` 44 | user1@vm1:~$ uptime 45 | #(1) (2) (3) (4) (5) (6) 46 | 03:13:58 up 4 days, 22:45, 1 user, load average: 0.00, 0.00, 0.00 47 | ``` 48 | 49 | 字段和描述: 50 | 51 | | 字段 | 描述 | 52 | | --- | --- | 53 | | (1) | 当前时间。 | 54 | | (2) | 正常运行时间(启动后的时间)。 | 55 | | (3) | 目前有多少用户登录。 | 56 | | (4) | 过去 1 分钟的 CPU 负载。这不是规范化的,所以负载均值为 1 意味着单个 CPU 的满负载,但是在 4 个 CPU 的系统上,这意味着它有 75% 空闲时间。 | 57 | | (5) | 过去 5 分钟的 CPU 负载。 | 58 | | (6) | 过去 15 分钟的 CPU 负载。 | 59 | 60 | `free`的输出: 61 | 62 | ``` 63 | user1@vm1:~$ free -mt 64 | # (1) (2) (3) (4) (5) (6) 65 | total used free shared buffers cached 66 | Mem: 496 267 229 0 27 196 67 | # (7) (8) 68 | -/+ buffers/cache: 43 453 69 | # 9 70 | Swap: 461 0 461 71 | # 10 72 | Total: 958 267 691 73 | ``` 74 | 75 | 字段和描述: 76 | 77 | | 字段 | 描述 | 78 | | --- | --- | 79 | | (1) | 物理内存总量。 | 80 | | (2) | 使用的物理内存总量。 | 81 | | (3) | 空闲的物理内存总量。 | 82 | | (4) | 共享内存列应该被忽略;它已经过时了。 | 83 | | (5) | 专用于缓存磁盘块的 RAM 和文件系统元数据总量。 | 84 | | (6) | 专用于从文件读取的页面的 RAM 总量。 | 85 | | (7) | 物理内存总量,不包括缓冲区和缓存,(2)-(5)-(6) | 86 | | (8) | 空闲的物理内存总量,包括空闲的缓冲区和缓存,(1)-(7) | 87 | | (9) | 交换文件使用信息。 | 88 | | (10) | 总内存使用信息,包括交换内存 | 89 | 90 | `vmstat`输出: 91 | 92 | ``` 93 | user1@vm1:~$ vmstat -S M 94 | procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- 95 | #(1,2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12,13,14,15,16) 96 | r b swpd free buff cache si so bi bo in cs us sy id wa 97 | 0 0 0 229 27 196 0 0 0 0 11 6 0 0 100 0 98 | 99 | user1@vm1:~$ vmstat -S M -a 100 | # (17) (18) 101 | procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- 102 | r b swpd free inact active si so bi bo in cs us sy id wa 103 | 0 0 0 11 434 19 0 0 24 2 11 6 0 0 100 0 104 | 105 | user1@vm1:~$ vmstat -d 106 | #19 (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) 107 | disk- ------------reads------------ ------------writes----------- -----IO------ 108 | total merged sectors ms total merged sectors ms cur sec 109 | sda 11706 353 402980 17612 9303 40546 336358 46980 0 19 110 | sr0 0 0 0 0 0 0 0 0 0 0 111 | loop0 0 0 0 0 0 0 0 0 0 0 112 | 113 | user1@vm1:~$ vmstat -m | head 114 | #(30) (31) (32) (33) (34) 115 | Cache Num Total Size Pages 116 | ext3_inode_cache 13700 13700 808 10 117 | ext3_xattr 0 0 88 46 118 | journal_handle 170 170 24 170 119 | journal_head 37 72 112 36 120 | revoke_table 256 256 16 256 121 | revoke_record 128 128 32 128 122 | kmalloc_dma-512 8 8 512 8 123 | ip6_dst_cache 16 24 320 12 124 | UDPLITEv6 0 0 1024 8 125 | ``` 126 | 127 | 字段和描述: 128 | 129 | | 模式 | 情况 | 字段 | 描述 | 130 | | --- | --- | --- | --- | 131 | | 虚拟内存 | 进程 | (1) | r:等待运行的进程数。 | 132 | | | | (2) | b:不间断睡眠中的进程数。 | 133 | | | 内存 | (3) | swpd:使用的虚拟内存量。 | 134 | | | | (4) | free:空闲内存量。 | 135 | | | | (5) | buff:用作缓冲区的内存量。 | 136 | | | | (6) | cache:用作缓存的内存量。 | 137 | | | | (17) | inact:非活动内存量。 | 138 | | | | (18) | active:活动内存量。 | 139 | | | 交换 | (7) | si:从磁盘换入的内存量(/秒)。 | 140 | | | | (8) | so:换出到磁盘的内存量(/秒)。 | 141 | | | I/O | (9) | bi:从设备接收的块(块/秒)。 | 142 | | | | (10) | bo:发送到设备的块(块/秒)。 | 143 | | | 系统 | (11) | in:每秒中断的次数,包括时钟。 | 144 | | | | (12) | cs:每秒上下文切换的数量。 | 145 | | | CPU | (13) | us:运行非内核代码的时间。(用户时间,包括优先的时间) | 146 | | | | (14) | sy:运行内核代码的时间。(系统时间) | 147 | | | | (15) | id:闲置时间。在 Linux 2.5.41 之前,这包括 IO 等待时间。 | 148 | | | | (16) | wa:IO 等待时间。在 Linux 2.5.41 之前,包含在闲置时间中。 | 149 | | 磁盘,`-d` | 设备 | (19) | 设备名称 | 150 | | | 读 | (20) | total:成功完成的总读取数 | 151 | | | | (21) | merge:分组的读取数(生成一个 I/O) | 152 | | | | (22) | sectors:成功读取的分区 | 153 | | | | (23) | ms:用于读取的毫秒 | 154 | | | 写 | (24) | total:成功完成的总写入数 | 155 | | | | (25) | merge:分组的写入数(生成一个 I/O) | 156 | | | | (26) | sectors:成功写入的分区 | 157 | | | | (27) | ms:用于写入的毫秒 | 158 | | | I/O | (28) | cur:正在进行中的 I/O | 159 | | | | (29) | s:用于 I/O 的秒数 | 160 | | Slab,`-m` | Slab | (30) | 缓存:缓存名称 | 161 | | | | (31) | num:当前活动对象的数量 | 162 | | | | (32) | total:可用对象的总数 | 163 | | | | (33) | size:每个对象的大小 | 164 | | | | (34) | page:具有至少一个活动对象的页数 | 165 | 166 | `top`的输出: 167 | 168 | ``` 169 | # (1) (2) (3) (4) 170 | top - 03:22:44 up 4 days, 22:54, 1 user, load average: 0.00, 0.00, 0.00 171 | # (5) (6) (7) (8) (9) 172 | Tasks: 63 total, 1 running, 62 sleeping, 0 stopped, 0 zombie 173 | # (10) (11) (12) (13) (14) (15) (16) (17) 174 | Cpu(s): 0.0%us, 1.1%sy, 0.0%ni, 98.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st 175 | # (18) (19) (20) (21) 176 | Mem: 508820k total, 273792k used, 235028k free, 27844k buffers 177 | # (22) (23) (24) (25) 178 | Swap: 473080k total, 0k used, 473080k free, 201252k cached 179 | 180 | #(26) (27) (28)(29) (30) (31) (32,33) (34)(35) (36) (37) 181 | PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 182 | 1 root 20 0 8356 804 676 S 0.0 0.2 0:05.99 init 183 | 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 184 | 3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 185 | 4 root 20 0 0 0 0 S 0.0 0.0 0:00.06 ksoftirqd/0 186 | 5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0 187 | 6 root 20 0 0 0 0 S 0.0 0.0 0:03.25 events/0 188 | 7 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuset 189 | <...> 190 | ``` 191 | 192 | 字段和输出: 193 | 194 | | 部分 | 字段 | 描述 | 195 | | --- | --- | --- | 196 | | 正常运行时间 | (1) | 当前时间。 | 197 | | | (2) | 正常运行时间(启动后的时间)。 | 198 | | | (3) | 目前有多少用户登录。 | 199 | | | (4) | 过去 1,5 和 15 分钟内的 CPU 负载。这不是规范化的,所以负载均值为 1 意味着单个 CPU 的满负载,但是在 4 个 CPU 的系统上,这意味着它有 75% 空闲时间。 | 200 | | 任务 | (5) | 运行进程总数。 | 201 | | | (6) | 当前正在执行的进程数。 | 202 | | | (7) | 当前正在睡眠的进程数。 | 203 | | | (8) | 被停止的进程数(例如使用`CTRL + Z`)。 | 204 | | | (9) | 已经停止(“僵尸”)的进程数量,已终止,但未由其父进程回收。 | 205 | | CPU(S) | (10) | CPU 运行不优先的用户进程的时间。 | 206 | | | (11) | CPU 运行内核及其进程的时间。 | 207 | | | (12) | CPU 运行优先的用户进程的时间。 | 208 | | | (13) | CPU 花费的空闲时间。 | 209 | | | (14) | CPU 等待 I/O 完成的时间。 | 210 | | | (15) | CPU 维护硬件中断的时间。 | 211 | | | (16) | CPU 维护软件中断的时间。 | 212 | | | (17) | 由管理程序从这个虚拟机“偷走”的 CPU 总量,用于其他任务(例如启动另一个虚拟机)。 | 213 | | 内存/交换 | (18) | 物理内存总量。 | 214 | | | (19) | 使用的物理内存总量。 | 215 | | | (20) | 完全空闲的物理内存。 | 216 | | | (21) | 专用于缓存磁盘块的 RAM 和文件系统元数据总量。 | 217 | | | (22,23,24) | 总,使用和空闲交换内存。 | 218 | | | (25) | 专用于从文件读取的页面的 RAM 总量。 | 219 | | 进程 | (26) | 任务的唯一进程 ID,它定期地包装,尽管从未重新启动。 | 220 | | | (27) | 任务所有者的有效用户名。 | 221 | | | (28) | 任务的优先级。 | 222 | | | (29) | 任务的优先值。负的优先值表示更高的优先级,而正的优先值表示较低的优先级。在这个字段中的零只是代表在确定任务的调度时不会调整优先级。 | 223 | | | (30) | 任务使用的虚拟内存总量。它包括所有代码,数据和共享库,以及已经被替换的页面。以及已被映射但未被使用的页面。 | 224 | | | (31) | 任务已使用的未交换的物理内存。 | 225 | | | (32) | 任务使用的共享内存量。它只是反映可能与其他进程共享的内存。 | 226 | | | (33) | 任务的状态可以是以下之一:`D`=不间断睡眠,`R`=运行,`S`=睡眠,`T`=跟踪或停止,`Z`=僵尸。 | 227 | | | (34) | 自上次屏幕更新以来,所经过的 CPU 时间的任务份额,以 CPU 时间总数的百分比表示。 | 228 | | | (35) | 任务当前使用的可用物理内存的份额。 | 229 | | | (36) | CPU 时间,单位是百分之一秒,与`TIME`相同,但通过百分之一秒反映更大的粒度。 | 230 | | | (37) | 命令 - 命令行或程序名称 | 231 | 232 | 你可能会看到很多字段。许多字段都存在于多个工具中,这些工具有些冗余的功能。通常情况下,你只需要这个字段的一小部分,但你需要知道,系统性能的许多信息(实际上还有更多)可用于你,因为有时候会出现一个模糊的问题,并且为了能够解决它,需要知道如何读取这些数据。 233 | 234 | 现在,你将学习如何使用系统性能工具。 235 | 236 | ## 这样做 237 | 238 | ``` 239 | 1: uptime 240 | 2: free 241 | 3: vmstat 242 | 4: ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )& vmstat 1 243 | 5: uptime 244 | 6: ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5 && killall vmstat )& vmstat -nd 1 | egrep -v 'loop|sr0' 245 | 7: echo 3 | sudo tee /proc/sys/vm/drop_caches 246 | 8: free -mt ; find / >/dev/null 2>&1 ; free -mt 247 | 9: echo 3 | sudo tee /proc/sys/vm/drop_caches 248 | 10: cat test.img /dev/null ; free -mt 249 | ``` 250 | 251 | ## 你会看到什么 252 | 253 | ``` 254 | user1@vm1:~$ uptime 255 | 05:36:45 up 6 days, 1:08, 1 user, load average: 0.00, 0.00, 0.00 256 | user1@vm1:~$ free 257 | total used free shared buffers cached 258 | Mem: 508820 239992 268828 0 820 213720 259 | -/+ buffers/cache: 25452 483368 260 | Swap: 473080 0 473080 261 | user1@vm1:~$ vmstat 262 | procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- 263 | r b swpd free buff cache si so bi bo in cs us sy id wa 264 | 0 0 0 268828 820 213720 0 0 21 10 14 11 0 0 100 0 265 | user1@vm1:~$ ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )& vmstat 1 266 | [1] 6078 267 | procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- 268 | r b swpd free buff cache si so bi bo in cs us sy id wa 269 | 1 1 0 268556 828 213736 0 0 21 10 14 11 0 0 100 0 270 | 0 0 0 268556 828 213772 0 0 16 0 19 10 0 0 100 0 271 | 0 0 0 268556 828 213772 0 0 0 0 13 8 0 0 100 0 272 | 0 0 0 268556 828 213772 0 0 0 0 15 11 0 0 100 0 273 | 0 0 0 268556 828 213772 0 0 0 0 14 10 0 0 100 0 274 | 0 0 0 268556 828 213772 0 0 0 0 18 13 0 0 100 0 275 | 1 0 0 267316 836 213844 0 0 74 0 267 26 0 99 1 0 276 | 1 0 0 267316 836 213844 0 0 0 0 303 7 0 100 0 0 277 | 1 0 0 267316 836 213844 0 0 0 0 271 11 0 100 0 0 278 | 1 0 0 267316 836 213844 0 0 0 0 257 12 0 100 0 0 279 | 30+0 records in 280 | 30+0 records out 281 | 31457280 bytes (31 MB) copied, 4.95038 s, 6.4 MB/s 282 | 0 0 0 267928 860 213860 0 0 27 0 265 29 1 97 2 0 283 | 0 0 0 267936 860 213848 0 0 0 0 15 9 0 0 100 0 284 | 0 0 0 267936 860 213848 0 0 0 0 14 7 0 0 100 0 285 | 0 0 0 267936 860 213848 0 0 0 0 14 7 0 0 100 0 286 | 0 0 0 267936 860 213848 0 0 0 0 13 11 0 0 100 0 287 | Terminated 288 | user1@vm1:~$ uptime 289 | 05:22:15 up 6 days, 54 min, 1 user, load average: 0.07, 0.02, 0.00 290 | [1]+ Done ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat ) 291 | user1@vm1:~$ uptime 292 | 05:22:22 up 6 days, 54 min, 1 user, load average: 0.06, 0.02, 0.00 293 | user1@vm1:~$ ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5 && killall vmstat )& vmstat -nd 1 | egrep -v 'loop|sr0' 294 | [1] 6086 295 | disk- ------------reads------------ ------------writes----------- -----IO------ 296 | total merged sectors ms total merged sectors ms cur sec 297 | sda 146985 2230744 21821320 105848 32190 1343154 10927338 1330144 0 105 298 | sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105 299 | sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105 300 | sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105 301 | sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105 302 | sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144 0 105 303 | sda 146999 2230744 21821680 105856 32190 1343154 10927338 1330144 0 105 304 | sda 146999 2230744 21821680 105856 32190 1343154 10927338 1330144 0 105 305 | sda 147000 2230744 21821688 105856 32208 1344160 10935530 1330288 0 105 306 | sda 147000 2230744 21821688 105856 32274 1349214 10976490 1330748 0 105 307 | sda 147000 2230744 21821688 105856 32325 1353259 11009258 1331236 0 105 308 | sda 147000 2230744 21821688 105856 32450 1364657 11101442 1337176 0 105 309 | sda 147000 2230744 21821688 105856 32450 1364657 11101442 1337176 0 105 310 | sda 147001 2230744 21821696 105856 32471 1366301 11114762 1337348 0 105 311 | sda 147001 2230744 21821696 105856 32525 1370529 11149018 1337732 0 105 312 | sda 147001 2230744 21821696 105856 32573 1374577 11181786 1338064 0 105 313 | sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105 314 | 6553600+0 records in 315 | 6553600+0 records out 316 | 209715200 bytes (210 MB) copied, 11.7088 s, 17.9 MB/s 317 | sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105 318 | sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105 319 | sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105 320 | sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244 0 105 321 | sda 147001 2230744 21821696 105856 32762 1393910 11337962 1349192 0 105 322 | user1@vm1:~$ echo 3 | sudo tee /proc/sys/vm/drop_caches 323 | 3 324 | [1]+ Done ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5 && killall vmstat ) 325 | user1@vm1:~$ free -mt ; find / >/dev/null 2>&1 ; free -mt 326 | total used free shared buffers cached 327 | Mem: 496 30 466 0 0 5 328 | -/+ buffers/cache: 24 472 329 | Swap: 461 0 461 330 | Total: 958 30 928 331 | total used free shared buffers cached 332 | Mem: 496 64 432 0 22 6 333 | -/+ buffers/cache: 35 461 334 | Swap: 461 0 461 335 | Total: 958 64 894 336 | user1@vm1:~$ echo 3 | sudo tee /proc/sys/vm/drop_caches 337 | 3 338 | user1@vm1:~$ cat test.img /dev/null ; free -mt 339 | total used free shared buffers cached 340 | Mem: 496 230 265 0 0 205 341 | -/+ buffers/cache: 24 471 342 | Swap: 461 0 461 343 | Total: 958 230 727 344 | user1@vm1:~$ 345 | ``` 346 | 347 | ## 解释 348 | 349 | 1. 打印当前的正常运行时间。 350 | 1. 打印出可用内存信息。 351 | 1. 这个很有趣,最好认为是一种实验。首先,我们在后台启动` ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )&`,之后我们 以连续模式启动`vmstat`,所以它将打印出其信息直到中断。我们可以看到,在这个命令启动 5 秒钟后,CPU 负载显着增加了一段时间,然后减少,另外 5 秒钟后`vmstat`被杀死。 352 | 1. 打印当前的正常运行时间。注意负载平均值的变化。 353 | 1. 这是另一个实验,几乎和以前一样,但这次用磁盘写入。 354 | 1. 删除所有缓存和缓冲区。 355 | 1. 另一个实验。我们想看看读取系统中的所有文件和目录名称,会如何影响内存中的文件系统缓存,并且我们可以看到它被缓存在缓冲区中,这是有理论根据的。 356 | 1. 再次删除所有缓存和缓冲区。 357 | 1. 这次我们想看看,文件读取如何影响内存中的文件系统缓存。我们可以看到读取的文件被缓存在缓存部分,来增加后续访问的时间。 358 | 359 | ## 附加题 360 | 361 | + 为什么在我们的第一个实验中,不是`user`,而是`system` CPU 使用率上升到 100? 362 | + 这是什么意思?`dd if=/dev/zero of=test.img bs=32 count=$( (32*1024*200) )`。 363 | + 启动`top`,并按下`h`。现在尝试按照 CPU,内存和 PID 对其输出进行排序。 364 | --------------------------------------------------------------------------------