├── .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 | 
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 | 
43 |
44 | + 点击`Import`
45 |
46 | 
47 |
48 | + 选择`vm1`并点击`Start`
49 |
50 | 
51 |
52 | + 等待`vm1`启动
53 |
54 | 
55 |
56 | + 启动`putty`,在`Host Name`或者`IP Address`中输入`localhost`。之后点击`Open`
57 |
58 | 
59 |
60 | + 输入`user1`, ``, `123qwe`, ``。
61 |
62 | 
63 |
64 | + 恭喜,你现在登入了`vm1`。
65 |
66 | 
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 | 
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 | 
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`。你看,它有作用!真的是那么简单 是一种机制,允许你告诉程序,将其来自键入输入和/或到显示器的输出,重定向到另一个文件。为此,你可以使用这些特殊命令,然后启动程序:
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 | 
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 风格的幽默,但要小心:看到的是不会是不可见的。
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 | 
25 |
26 | 2. 按下`New`按钮来创建新的虚拟机。在`Name`字段中输入`vm1`,之后选择`Operating System: Linux, Version: Debian (64 bit)`,之后按下`Next >`。
27 |
28 | 
29 |
30 | 3. 从内存至少选择`512 MB`。如果你的机子上安装了足够的 RAM,`1024 GB`也可以。按下`Next >`。
31 |
32 | 
33 |
34 | 4. 这里只需按下`Next >`。
35 |
36 | 
37 |
38 | 5. 选择`VDI (VirtualBox Disk Image)`,并按下`Next >`。
39 |
40 | 
41 |
42 | 6. 选择`Dynamically allocated`,并按下`Next >`。
43 |
44 | 
45 |
46 | 7. 在`Location`中输入`vm1`,并按下`Next >`。
47 |
48 | 
49 |
50 | 8. 点击`Create`。
51 |
52 | 
53 |
54 | 9. 选择`vm1`并点击`Start`。
55 |
56 | 
57 |
58 | 0. 点击`Next >`。
59 |
60 | 
61 |
62 | 1. 点击`folder button`。
63 |
64 | 
65 |
66 | 2. 浏览并选择你的`Debian 6 Squeeze CD-image`,点击`Open`。
67 |
68 | 
69 |
70 | 3. 点击`Next >`。
71 |
72 | 
73 |
74 | 4. 点击`Start`。
75 |
76 | 
77 |
78 | 5. 关闭烦人的 VirtualBox 窗口。点击 VirtualBox 窗口内部并按下``。
79 | 
80 |
81 | 6. 按下``。
82 |
83 | 
84 |
85 | 7. 按下``。
86 |
87 | > 译者注:这里你可以选“中文(简体)”。
88 |
89 | 
90 |
91 | 8. 按下``。
92 |
93 | > 译者注:这里你可以选“HongKong”。
94 |
95 | 
96 |
97 | 9. 按下``。
98 |
99 | 
100 |
101 | 0. 输入`vm1`并按下``。
102 |
103 | 
104 |
105 | 1. 输入`site`并按下``。
106 |
107 | 
108 |
109 | 2. 输入`123qwe`并按下``。
110 |
111 | 
112 |
113 | 3. 输入`123qwe`并按下``。
114 |
115 | 
116 |
117 | 4. 输入`user1`并按下``。
118 |
119 | 
120 |
121 | 5. 按下``。
122 |
123 | 
124 |
125 | 6. 输入`123qwe`并按下``。
126 |
127 | 
128 |
129 | 7. 输入`123qwe`并按下``。
130 |
131 | 
132 |
133 | 8. 如果你不知道这里做什么,只需按下``。
134 |
135 | 
136 |
137 | 9. 选择`Guided partitioning`并按下``。
138 |
139 | 
140 |
141 | 0. 选择`Guided – use entire disk`并按下``。
142 |
143 | 
144 |
145 | 1. 再次按下``。
146 |
147 | 
148 |
149 | 2. 选择`eparate /home, /usr, /var, and /tmp partitions`并按下``。
150 |
151 | 
152 |
153 | 3. 选择`Finish partitioning and write changes to disk`并按下``。
154 |
155 | 
156 |
157 | 4. 选择``并按下``。
158 |
159 | 
160 |
161 | 5. 选择``并按下``。
162 |
163 | 
164 |
165 | 6. 选择``并按下``。
166 |
167 | 
168 |
169 | 7. 选择`ftp.egr.msu.edu`并按下``。如果出现错误,选择其它的东西。
170 |
171 | 
172 |
173 | 8. 再次按下``。
174 |
175 | 
176 |
177 | 9. 选择``并按下``。
178 |
179 | 
180 |
181 | 0. 使用``选择`SSH server and Standard system utilities`,并按下``。
182 |
183 | 
184 |
185 | 1. 选择``并按下``。
186 |
187 | 
188 |
189 | 2. 选择``并按下``。你新安装的 Debian 会重启。
190 |
191 | 
192 |
193 | 3. 点击`Devices`并选择`Network adapters`。
194 |
195 | 
196 |
197 | 4. 点击`Port Forwarding`。
198 |
199 | 
200 |
201 | 5. 点击`Plus`按钮。
202 |
203 | 
204 |
205 | 6. 在`Host Port`中输入`22`,`Guest Port`中输入`22`,点击`OK`。
206 |
207 | 
208 |
209 | 7. 再次点击`OK`。
210 |
211 | 
212 |
213 | 8. 让你的 Debian 系统运行一会儿。
214 |
215 | 
216 |
217 | 9. 启动`putty`,在`Host Name`中输入`localhost`(或 IP 地址),在`Port`字段中输入`22`。点击`Open`。
218 |
219 | 
220 |
221 | 0. 点击`Yes`。
222 |
223 | 
224 |
225 | 1. 输入`user1`,点击``。输入`123qwe`,并再输入一次,来真正享受你的作品吧。
226 |
227 | 
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 |
--------------------------------------------------------------------------------