文件 / 用户 / 手册
一种认识 Linux 操作系统(服务)的方式
了解这些系统程序 / 指令(System Program)是如何使用的
学习系统调用(System Call)
编写自己的系统程序
文件 / File
在 Linux 操作系统里,“一切都是文件”。而文件的“打开”等状态,是用文件描述符表示的。
自驱式学习
Linux 提供了完善且清晰的用户手册(Manual),可以帮助我们自驱地学习如何使用该操作系统。我们可以使用指令在 Manual 中进行关键字搜索,以获取我们需要的指令及语法。
我们可以使用
man <name>
查询某个指令 / API 的手册,同时可以使用man man
获取 Linux Manual 更详细的用法。注意:Server 版本的 Linux 发行版中,出于空间资源的考虑,系统默认删除了很多详尽的说明或者不常用的指令文档,所以请尽量使用 Desktop 版本进行 Linux 学习。
如何解决“如何打开文件”这个问题?
尝试使用 Linux Manual 进行搜索:man -k file | grep open | grep \(2\)
。该指令的含义是:在 Manual 中搜索 "file" 关键词,并过滤保留包含 "open" 的条目,再次过滤保留包含 (2) 的条目(即 Manual 的第二章)
管道(Pipe):
|
符号,又称管道操作符,它的功能是将它左边程序输出的内容输入到右边的程序中,即为左右两个程序建立一个“管道”,实现 I/O Redirection。
如果你的 man -k
不能正常工作,不要急,往下看。
在终端中浏览大量内容
在传统的 UNIX 操作系统环境中,由于缺少 GUI ,只能显示一个屏幕大小的文本内容。为了解决这个问题,Linux 提供了诸如 less
,more
等辅助显示大量文本的工具。通过与|
配合可以很轻松地在屏幕范围内浏览大量文本。
less
和 more
都是用来浏览无法在一个屏幕显示完全的大文件的工具。more
是一个很古老的指令,顾名思义,他只能“more”,即只支持向下翻页。与 more
不同的是,less
不仅可以向下翻页,同时也可以向上翻页。不过,很多现代的 Linux 发行版在执行 more
指令的时候自动执行 less
,或是提供了一个更接近 less
的 more
以方便用户使用。
相关链接:https://unix.stackexchange.com/questions/81129/what-are-the-differences-between-most-more-and-less
编程:仿写 cat 指令
cat
指令是 Linux 中一个非常常用的指令,其接收若干个文件作为参数,功能是将这些文件的内容按顺序合并并打印。
语言提示:参数列表
相信很多学过 C 语言的同学,都见过如下代码:
int main ()
但实际上,main 函数的完整原型是这样的:
int main (int argc, char* argv[])
argc
是 arguments count 的缩写,表示该可执行程序收到的参数个数,argv
是 argument value 的缩写,是收到的参数构成的数组列表。
当你的程序需要接收用户传递的参数时,可以使用 argc
判断用户传递的参数个数是否正确,然后使用 argv
获取用户传入的参数。以 cp
(复制)指令为例: cp -r ~/Desktop/test-folder ~/Documents/
,那些用空格分隔开的就是程序的参数,也就是 argv
。这个语句为 cp
传入了 -r
,~/Desktop/test-folder
和 ~/Documents/
三个参数。
需要注意的是,argc
的起始值是 1,即没有任何参数传入的时候 argc
的值为 1。因为程序本身会作为 argv[0]
被传入程序中。比如 cp
的 argv[0]
就是 "cp"
。
代码实现
思路
思路很简单:获取参数列表 —> 打开文件(暂时不考虑异常情况)-> 逐个字符输出 -> 关闭文件 -> 打开下一个文件 ...
实现
编程:仿写 cp 指令
语言提示:buffer
buffer(缓冲区)
buffer的大小会影响二进制流传递的效率。
语言提示:文件操作
文件操作及系统调用
文件操作
对于一个文件的操作,无外乎以下四种:打开、关闭、写入、读取。Linux Manual 给出了非常清晰的关于文件 open / close / write / read 操作的文档说明,不妨使用上边提到的man -k
尝试搜索一下。我们也会在下边的编程练习中给出提示。
我们之前提到过,在 Linux 中,“万物皆文件”。在 Linux 中,对设备、SOCKET等进行的一系列开、关、读、写操作归根结底都是在对其对应的文件进行操作。而这些文件的“打开状态”等一系列状态都是通过文件描述符表示的。这就引出了一个新的问题:系统是如何通过文件描述符描述一个文件的?
[WIP: file description]
用户 / User
思考:系统如何表示 / 记录“一个用户登录了”?
从指令出发
Linux 为我们提供了一个指令,用来查看当前在线的用户列表:who
。它是怎么实现的呢?不妨先在 Manual 里边看一看:
man who
- who [OPTION]... [ FILE | ARG1 ARG2 ]
可以看到,who 接收一组参数,除了配置参数外,还包含一个文件(或者两个额外参数)。如果你的 Linux 拥有完整的 Manual ,你应该会看到如下片段:
If FILE is not specified, use /var/run/utmp. /var/log/wtmp as FILE is common.
也就是说,如果没有指定 FILE 的话,系统会默认从上述两个文件中读取用户登录日志。自此,我们可以猜想,Linux 通过修某个文件来记录用户的登录状态。[WIP]
从文件出发
我们之前提到过,在 Linux 中,“万物皆文件”。所以关于用户的一系列信息,自然也离不开文件。事实上,用户的信息被分散的保存在了以下几个文件中:
/etc/passwd - 保存用户的基本信息
/etc/shadow - 保存用户密码
/var/run/utmp - 保存用户登录记录
[WIP]
对于用户来说,这些文件的敏感度极高,我们一定不希望自己的信息被其他用户看到。为了对在这些文件上进行的操作进行干预和控制,Linux 设计了一套非常精妙的权限控制系统 - 基于 ACL(Access Control Lists)的权限控制。
初窥 Linux 权限控制系统
[WIP]
编程:仿写 who 指令
手册 / Manual
man -k 与 whatis database
man -k
之前提到,man -k
可以用来在 Manual 中搜索我们想找的关键字。而它又是如何做到快速索引整个 Linux Manual 的呢?不妨使用man man
指令查看一下关于 Linux Manual 的文档,找到-k
参数的说明:
Equivalent to apropos.
然后继续man apropos
apropos - search the whatis database for strings
看来这个指令是在一个叫做 whatis database 的数据库中搜索信息的。所以,接下来的问题就是:what is whatis & what is whatis database。
whatis & whatis database
我们继续在 Manual 中查询:man whatis
whatis - search the whatis database for complete words.
似曾相识吧。先不去追究strings
和complete words
的区别,我们继续往下看:
whatis searches a set of database files containing short descriptions of system commands for keywords and displays the result on the standard out-put.
看来这个 a set of databases 指的就是 whatis database 了,它是一个包含了系统指令的关键词的简述的数据库。所以索引这个数据库,就可以在 Manual 中很快的找到我们需要的信息了。
那些没有提供 whatis database 的 Linux 发行版,基本都提供了makewhatis
指令,用来让用户创建 whatis database。如果执行man -k
的时候没有成功,不妨试一下makewhatis
。
Last updated