论文名: The Evolution of the Unix Time-sharing System — Dannis M. Ritchie
丹尼斯 - 里奇 回顾了与 肯 - 汤普森 等在贝尔实验室发明 Unix 的历程, 而后介绍了一下 Unix 中最重要的几个局部, 包含:
文件系统
- i-list: 一个由 i-nodes 组成的数组, 每个 i-node 形容一个文件. i-node 里蕴含文件的元数据: 例如保护模式, 类型和大小, 以及内容所在的物理地位.
- 目录: 一种非凡的文件, 蕴含了一系列的文件名以及相干的 i-number.(我感觉 i-number 应该就是 i-node 的 ID 吧)
- 非凡的文件用于形容设施. 特定的 i-number 对应特定的设施.
过程管制机制
shell 执行命令的大略的步骤是这样:
- shell 从终端读取命令
- 新建一个过程
- 子过程执行命令
- 同时, shell 开始期待直到子过程执行结束
- shell 回到第一步
感觉挺乏味的, 我用 elixir 模仿了一下:
defmodule MF.PC do
def loop do
cmd = IO.read(:line)
pid = self()
spawn(fn ->
exec(cmd, pid)
end)
wait()
end
defp exec(cmd, pid) do
send(pid, {:done, String.upcase(cmd)})
end
defp wait do
receive do
{:done, msg} ->
IO.puts(msg)
loop()
end
end
end
无论输出什么, 都返回大写的输出.
iex(2)> MF.PC.loop
hello
HELLO
how are u
HOW ARE U
fine
FINE
good bye
GOOD BYE
好吧, 挺无聊的, 只是了解一下 Unix 里过程消息传递的模式.
论文里提到很好玩的一个 bug, 就是一开始 chdir 命令, 也就是 cd
, 也是像下面那样执行的, 后果, 只有子过程的工作目录变更了, 对 shell 自身齐全不起作用. 所以他们把 cd
变为非凡命令, 只在以后过程里执行.
论文里还提到一个乏味的 bug, 如果在一个脚本文件 “comfile” 里有如下命令:
ls
who
而后咱们在 shell 里执行:
sh comfile >output
料想的后果是 ls
和 who
的执行后果被顺次写入到 output 文件中. 但实际上, 因为最后 unix 将文件的 io 指针保留在了执行 “ 关上文件 ” 的过程里, 也就是主 shell 过程, 而执行写入操作的, 是咱们用 sh
命令开启的子 shell, 所以文件的 io 指针始终没有变动, 导致 who
的输入把 ls
的输入笼罩了. 为了修复这个问题, 他们在零碎中增加了一个表, 保留了全副的关上状态的文件的 io 指针.
说个题外话, 我忽然想到在 elixir 里如同不能指定文件的写入地位, 查了一下是能够的:
iex(4)> :file.read_file "comfile"
{:ok, "ls\nwho\n"}
iex(5)> {:ok, device} = :file.open "comfile", [:raw, :write]
{:ok,
{:file_descriptor, :prim_file,
%{
handle: #Reference<0.1011150086.1394212882.243351>,
owner: #PID<0.110.0>,
r_ahead_size: 0,
r_buffer: #Reference<0.1011150086.1394212865.243949>
}}}
iex(6)> :file.pwrite(device, 1, 'hello')
:ok
iex(7)> :file.read_file "comfile"
{:ok, <<0, 104, 101, 108, 108, 111>>}
iex(8)> <<104, 101, 108, 108, 111>>
"hello"
最初是还提到了一下管道操作符 |
和 C 语言的来历.