##################################################

目录

初识 VI

VI 是什么

先演示一遍怎么使用 vi 编辑器编辑文本文件

VI 基操

详解三种模式

输入模式

编辑模式

底行模式

BSD 的前世今生

MULTICS 的遗憾

QED 与 UNIX 的诞生

C 语言的诞生

UNIX 出世

扎根伯克利

csh 的诞生

BSD 与神器 VI/VIM 的诞生

一个人抱着协议书就写出了 TCP/IP 协议栈

通过 ed/ex 来理解编辑器本质

关于 ed 编辑器

初识 ed

ed 总结

编辑器本质

摸索 ex

ex 总结

VI/VIM 与 Emacs 的编辑器圣战

结束语


##################################################

初识 VI

——————————

VI 是什么

linuxer 都清楚 linux 系统的一切皆文件概念 而且人手一份 VI/VIM

UNIX 系统也是一样 只不过很少有人知道 vi 是怎么来的?

反人类的 vi 被安装在所有的 UNIX 系统以及类 UNIX 系统上

是一款超棒的文本编辑器!

这里使用的是 vi 而不是 vim

vi 是所有 UNIX/ 类 UNIX 系统的内置编辑器 很多软件的默认编辑接口都是直接调用 vi

vim 是 vi 的高级版

vi 是单纯的文本编辑器

而 vim 是强大的程序编辑器!支持代码高亮,甚至可以配置成 IDE 环境!

——————————

先演示一遍怎么使用 vi 编辑器编辑文本文件

    秉承着 DFTN 原则
Demo first then nag我们先演示 再叨叨大家不用上网查 dftn 是个什么鬼原则因为这是我自己定义的

%%%%%

lilian 身份登入 BSD 系统后开始布置实验环境:

实验环境

在家目录下创建一个实验目录 test_txt 后 touch 一个空文件 1.txt

%%%%%

现在使用 vi 编辑器进行编辑 默认是命令模式:
        看左下角的状态栏 表示源文件还未被更改

1.txt : unmodified: line 1

1.txt :未经修改的:行 1

unmodified

ESC 输入

:version

查看 vi 版本信息:

version

%%%%%

按下 i 进入编辑模式:

i 编辑

输入内容

Hello,BSD!

Hello,BSD!

%%%%%

按下 ESC 键返回命令模式再输入

:wq

保存退出:

:wq

回车后提示有一行十一个字符被改变 就是保存成功了的意思:

1.txt: 1 lines, 11 characters.

1.txt: 1 行, 11 字符。

使用 cat 查看文本文件内容:

characters

操作成功!

%%%%%

如果 vi 的目标文件不存在那就会新建目标文件:

新建编辑一个文件:

新建编辑一个文件

状态栏提示这是一个新文件:

new file

编辑并保存退出:

编辑并保存退出

回车后提示:

2.txt: new file: 1 lines, 11 characters.

2.txt:新文件:1 行, 11 字符。

好家伙又是十一个字符,我保证是巧合,内容我都是随便打的!

当前目录下出现编辑的文件 查看内容正是编辑的内容:

回车后操作

##################################################

VI 基操

——————————

详解三种模式

三种模式:

底行模式

编辑模式

输入模式

顾名思义 输入模式就是让你输入内容 当你按下 a、i、o 等按键时就会进入输入模式

又被称之为 插入模式、录入模式

底行模式就是命令行模式 为什么叫底行??你看 vi 最底下哪一行是不是状态栏!!!

又被称之为 命令行模式、末行模式

编辑模式就是让你可以对文档进行一些编辑操作 例如拷贝和删除!

又被称之为 工作模式、命令模式

三者通过 ESC 键切换!

刚进入 vi 便是处于编辑模式 此时输入 i 便进入输入模式输入

然后按下 ESC 处于编辑模式 输入冒号变成底行模式可以输入命令 例如保存退出!

正是由于这三种模式才让 vi 得到了绝大多数人的认可!

可能一开始你会觉得这比较反人类 但是习惯了会发现真的贼顺手!

要想高效率地操作文本 就必须先搞清这三种模式的操作区别以及模式之间的切换方法:

Edit Mode/编辑模式    让你进行一系列操作 例如控制光标移动 还可以进行 复制、粘贴、删除、查找 等等
Insert Mode/输入模式    正常的文本内容录入 可以让你输入内容
EX Mode/底行模式    保存或退出文档 以及设置编辑环境

使用 vi 打开文件时 如果文件存在就会直接打开

如果文件不存在就会在相应目录创建一个同名空文件再打开

而文件中的 ~ 代表空行

除了输入文本以外 所有的操作都在编辑模式下进行

在每次运行编辑器时都默认进入编辑模式

需要切换到输入模式下进行文档编写工作

而在编写完毕后又要返回编辑模式再进入底行模式进行保存退出

下面列出命令不是很全 但是绝对够用了!

——————————

输入模式

从编辑模式进入输入模式输入内容有四种方式:

a    从光标所在的后一个字符位置开始输入
i    从光标所在的字符位置进入输入模式
o    从光标所在行的下一行进入
O    从光标所在行的上一行进入
ESC    返回编辑模式

——————————

编辑模式

在这边对文件进行编辑操作

    光标按键:
k    上
j    下
h    左
l    右
Ctrl g    在底行列出当前行的位置屏幕按键:
Page Up    向下翻滚一屏
Page Down    向上翻滚一屏
Ctrl b    向上翻滚一屏
Ctrl f    向下翻滚一屏
Ctrl u    向上翻滚半屏
Ctrl d    向下翻滚半屏
Ctrl w    如果分屏则依次切换窗口屏幕操作按键:
p    将之前 dd 或 yy 进缓冲区的数据粘贴到当前光标处的下一行
P    与 p 相反 Shift p 是在当前光标所在行的上一行粘贴
dd    删除/剪切 光标所在整行
Ndd    删除/剪切 从光标处开始的 N 行
yy    复制光标所在整行
Nyy    复制从光标处开始的 N 行x    删除光标所在的字符
X    删除光标所在的前一个字符r    输入替换当前光标所在 字母/符号/数字
R    从光标处开始覆盖输入
Nr    N 表示一个数字 表示替换当前位置后重复追加几次撤销按键:
u    撤销上一步的操作
.    小点点就比较 NB 了 按一下就相当于 Ctrl Z 快捷键返回上一步操作可以一直返回 但是这个操作是不可逆的!定位按键:
n    如果搜索命令进行后则光标跳转定位到下一个字符串或字符
N    如果搜索命令进行后则光标跳转定位到上一个 字符串/字符
NG    光标定位移动 N 为数字 G 为 Shfit g 数字加 G 会将光标移动到指定行开头
G    直接按下大写的 g 会将光标定位到最后一行开头
Home    按下 Home 键会将光标定位到光标所在行的开头
End    按下 End 键会将光标定位到光标所在行的结尾

注意 Ndd 命令

如果行数不匹配就不会给予执行

如果你 10dd 但是从当前行开始往下数到底只有 9 行

就不会进行操作 除非命令的行数小于或等于 9 行

yy 命令也是跟 dd 一样的原理

u 撤销只能撤销一步

同 Windows 下的 Notepad 一样只能记忆上一步

——————————

底行模式

这里的命令都是以符号开头

    保存及退出:
:w    保存
:w!    强制保存
:q    退出
:q!    强制退出  不会修改文件内容
:wq    保存并退出
:wq!    强制保存退出
:x    写入文件并退出
:e!    放弃所有修改,从上次保存文件时进度再编辑 需要确认
ZZ    快速保存退出 就是按住 Shift 再按两下 z
:N_1,N_3 w File_1    将行 N_1 到 N_2 的内容行复制保存到当前目录新建的 File_1 文件
:N_1,N_3wq ./File_1    将行 N_1 到 N_2 的内容行复制保存到当前目录新建的  File_1 文件并退出 vi 编辑器关于行号命令:
:set nu    显示行号
:set nonu    不显示行号
:N    N 是一个整数 表示光标跳转到 N 行查找命令:
/S    S 表示字符串或字符 在文本中从上至下搜索该字符串
?S    在文本中从下至上搜索该字符串 此时 n/方向上 N/方向下替换命令:
:s/Str_1/Str_2    若有匹配的字符串 则将当前光标所在行的第一个 Str_1 替换成 Str_2
:s/Str_1/Str_2/g    若有匹配的字符串 将当前光标所在行的所有 Str_1 替换成 Str_2
:%s/Str_1/Str_2/g    若有匹配的字符串 将整个文件中的所有 Str_1 替换成 Str_2
:N_1,N_2s/Str_1/Str_2/g    从 N_1 行到 N_2 行之间所有的 Str_1 替换成 Str_2
:N_1,N_2s/Str_1/Str_2/gc    从 N_1 行到 N_2 行之间所有的 Str_1 替换成 Str_2 后需要确认
:N_1,$s/Str_1/Str2/g    从 N_1 行到最后一行之间所有的 Str_1 替换成 Str_2分屏命令:
vs    左右分屏 同时显示两个文件 并且共用缓冲区就是说两个窗口可以互相粘贴什么的 使用 Ctrl w 切屏
N    上下分屏 其她同 vs

——————————

看到这里 如果你认真都操作了一遍 会有一种如释重负的感觉 恭喜你踏入管理员行列!

如果连 vi 都不敢用那你还能干嘛……

看完这一小节应该可以做到:

vi 编辑单个文件

vi 编辑多个文件

vi 同时编辑多文件

两个文件交换数据

vi 确实是个神仙编辑器 不是吗?

##################################################

BSD 的前世今生

——————————

MULTICS 的遗憾

上世纪 57 年十月 前苏联发射了第一颗人造卫星。

美国总统瞬间将经费向科学技术倾泻,于是 Advanced Research Projects Agency/ARPA/美国高等研究计划署成立。

APPA 有力推动了电子计算机的发展。

在大型计算机发展的六零年代 MIT 最先实现了

Compatible Time-Sharing System/CTSS/兼容分时系统

1963 年麻省理工的 J. C. R. Licklider 教授推动了 MAC 计划 以 IBM 的大型计算机做为主体,连接了将近 160 台终端机!

这些终端机就四散在学区以及教职员的家中,可以让 30 位 使用者同时共享计算机资源。

这项计划到了 1965 年便不堪负荷,于是

麻省理工学院

决定开发更大型的分时计算机系统。

这个计划就是

MULTiplexed Information and Computing System/MULTICS/多路信息与计算系统

史上最为庞大的分时计算机系统,企图连接 1000 部终端机并支持 300 位用户同时上线的分时计算机系统!

MULTICS 分时操作系统标志

她面临的是操作系统的分时观念还在各学术与研究机构探索成形中且计算机硬件亦需重新设计的双重挑战。

显然不是一家组织能完成的 于是先找了

IBM

公司,但是人家也抽不出人手来……

巧了这时候美国通用电气公司

General Electric Company

正在发展大型主机,这个公司就是爱迪生创办的奇异公司,一眼就看到了机会,极力邀请 MIT 参加E 她们的 GE 645 大型主机计划,好嘛,机器硬件不缺了,就差软件了。

接着 MIT 又找上没计算机却人才辈出的

Bell Telephone Laboratories/贝尔电话实验室

来承包软件工程,软件方面也全了!

于是乎 MULTICS 在 65 年便由 麻省理工学院、通用电气公司、贝尔电话实验室 三个组织强强强联合共同发展!

本以为这么多精英和高手聚集在一起,先进系统应该很容易就出来了吧,没想到啊。

三家一路铿铿锵锵不抛弃不放弃努力奋斗四年后,仍然没有达到预先设计规划好的理念……

精疲力竭的贝尔实验室退出后,半成品 MULTICS 还是被安装在了 GE 645 大型计算机上供 MIT 使用。

    爱迪生都不禁感慨了:
有哥在,全都是意外,竟然没有一项是在计划中的!忽悠了别人一辈子然后被自己忽悠了……

后来 MULTICS 被嘲讽地解释为

Many Unnecessarily Large Table In Core Simultaneously/许多不必要的大表同时出现在内核中

从大型计算机鼎沸开始的 1965 年到最为辉煌的 1969 年这期间,如果 MULTICS 成功的话绝对可以助长当时已经普遍被计算机权威人士视为理想的 计算机公用事业,最起码可以让大型计算机的发展与资源集中的应用模式不至于会在 1970 年代初期就迅速萎缩,至少能让当时的大型计算机的应用规模大上 10 倍左右!

然而 MULTICS 失败了

她严重地打击了当时依赖大型计算机主机的计算机公用事业业者在发展上的信心;更由于没有相似的计划后继进行,使得集中式的大型计算机主机没有明显的使用效能提升,而加速催化计算器工业的转变,以寻找新的道路。

——————————

QED 与 UNIX 的诞生

1966 年 贝尔实验室聘用了 Ken Thompson

这家伙刚刚在加州大学伯克利分校完成了电气工程和计算机科学的硕士学位!

在伯克利期间 Ken 使用一个名为 QED 的文本编辑器 该编辑器在 1965 到 1966 年间被开发用于伯克利分时系统

Ken 到贝尔实验室上班后做的第一件事就是为麻省理工学院兼容分时系统重写了这个编辑器

然后又为后来又为 MULTICS 项目重写了另一个版本的 QED 在过程中还对程序进行了扩展

以便用户可以在文件中搜索某一行 并使用正则表达式进行替换!

与伯克利的分时系统一样,由麻省理工学院、通用电气和贝尔实验室合作的 Multics 项目试图创建一个可行的商业分时操作系统。

最终 AT&T 认为这个项目毫无进展而退出。

虽然 MULTICS 计划失败了,却也让参与该计划的软件工程师们得到相当宝贵经验。

在没有分时系统的情况下 Thompson 和贝尔实验室资深研究员 Dennis Ritchie 开始怀念分时系统所提供的

交互式计算的感觉

于是着手创建二人自己的版本

该版本最终发展成为 UNIX

1969 年 8 月,在妻子和幼子外出去加州度假时 Thompson  给

操作系统

Shell 终端

ED 编辑器

汇编程序

分别分配了一个星期 将新系统的基本组件组合在一起!

这个编辑器被称为 ed  她是基于 QED 的,但并不完全是 QED 的复现。

Thompson 决定放弃某些 QED 的功能,弱化了对常规的表达式的支持,因此 ed 只能理解相对简单的正则表达式。

QED 允许用户打开多个缓冲区同时编辑多个文件,但是 ed 一次只使用一个缓冲区。

QED 可以执行包含命令的缓冲区,而 ed 则不能。

这些简化可能是必要的。

Dennis Ritchie 曾说过去掉 QED 的高级正则表达式是 并不大的损失

ed 现在是 POSIX 规范的一部分 所以如果你有一个符合 POSIX 的系统那么你的电脑上就安装了 ed  !!!

现在许多 ed 命令都是 Vim 的一部分,因此这就值得摆弄一番了。

例如你必须使用 w 命令来写入磁盘缓冲区,必须使用 q 命令来退出编辑器。

ed 名字来自于 editor 编辑器

1969 年贝尔实验室的 计算器科学研究中心/Computing Science Research Center 成员退出 MULTICS 计划时,其实自家也没有一套完善便利的交谈式计算器服务环境。
        刚好败下阵来的 MULTICS 参与员们可以为了改善程序设计环境努力。

​        当时 Ken Thompson、Dennis Ritchie 和其同事们在写一个新的文件系统架构,这个文件系统也就是早期的 UNIX 操作系统文件系统的前身。

Ken Thompson 正忙着使用 Fortran 语言将原本在 Multics 系统中开发的 Space Travel game/太空旅游游戏 移植到 GECOS System 上开发。

那时候 GECOS System 大型计算机的 CPU 时间相当昂贵,一秒就要 75 块美金!而且同时控制 spaceship/宇宙飞船 的效果不甚理想,就是说性能差,飞船开不起来!

为了能好好玩个游戏 Ken Thompson 不得不寻找替代的开发环境……

​        后来 ta 看上了一台很少被人使用的 Digital Equipment Corporation PDP-7 迷你计算机:

当时 PDP-7 使用的 是 Graphic-II 显示器具有不错的图形处理能力!

于是 Ken Thompson 便与 Dennis Ritchie 连手将程序设计转移到 PDP-7 型计算机上。

在移转工作环境的同时为了得到较好的发展环境,便共同动手设计一套包含 File System、Process Subsystem 及一小组 Utility 的操作系统!因为就 2 个人嘛,所以这系统仅能支持 2 个用户使用……这边是 UNIX 的前身!

UNIX

由于贝尔实验室对于 MULTICS 计划失败的阴霾还未消散

所以 Brian Kernighan 这位仁兄开玩笑地戏称这套新的操作系统为

UNiplexed Information and Computing System/单一信息和计算系统

缩写为 UNICS

之后大家取谐音便叫她为

UNIX

没想到这个开玩笑的名字会被人叫到今天!!!

UNIX

——————————

C 语言的诞生

事实上 UNIX 系统在当时仅是私下的被使用,也并没有得到多大的重视。

一直到 1971 年的一个正式的计划 UNIX 才正式被搬上台面。

1970 年 当时贝尔实验室的 Patent department/专利部 缺一套文书处理系统 为了设计开发的需要买了一台 PDP-11

当 时 PDP-11 计算机的交机过程并不顺利,处理器先到,硬盘则多等了好几个月。

当 PDP-11 一切准备妥当后,便将 UNIX 移植到拥有 512K bytes 硬盘的 PDP-11/20 型计算机上,并在此系统之下开发了一套文书处理工具。

而这套工具 便是后来 nroff / troff 的前身。

那时的 UNIX 提供 16K bytes 给系统 8K bytes 给使用程序,档案最大的极限是 64K bytes

而此套含有文书处理工具的系统,也正式获得贝尔实验室的专利部门采用,系统名称被编为

First Edition/第一版

在 UNIX 移植成功后 Thompson 用 B 语言为她添加了 Fortran Compiler/ Fortran 编译器

但因为 B 语言属于一种 解译语言/interpretive language 执行效率并不是很好

于是 Ritchie 又将编译程序改成成可产生机器码并且允许定义数据形态及结构

Ritchie 称她为 C 语言!

#include <stdio.h>int main ( void ) {printf ( "Hello,World!" );return 0;
}

1973 年又用 C 语言改写全部 UNIX 原始程序

UNIX 于是首度出现正式版本 V5/第五版

——————————

UNIX 出世

1973 年 UNIX 出现她的第一个正式版本 V 5

UNIX–V5 诞生后贝尔实验室的里奇和汤普森决定让用户正式试用 UNIX 系统

用户是三位贝尔专利办公室的打字员 而她们的试用非常成功!

专利办公室决定正式使用 UNIX 并大力支持两位开发者的工作。

于是 UNIX 慢慢地在贝尔实验室内部蔓延开来,装机数也变成了 25 部之多。

UNIX 的最初成功很大一部分归功于 PDP-11

当时贝尔实验室对计算机需求增加的很快 贝尔的工程师们急需多通道编程和分时系统 而 PDP-11 是最佳选择

汤普森说:

这是一台具有很好的辅助功能的计算机

可靠、体积小、便宜,是当时硬件的最佳选择

但贝尔的工程师无法在上面使用 DEC 的软件时

就到处寻找

听说有 UNIX 就毫不犹豫地选择了她!

UNIX 自此在贝尔实验室的内部和外部慢慢地成长。

UNIX 是一个很少有的没有被管理层要求快速上市的软件,从研发到正式发布 UNIX 历经了十年的时间。

UNIX 已经被用户熟悉了,也被研发人员改进了很多,同时也获得了大量用户的赞许。

里奇和汤普森刚完成 UNIX 的时候 UNIX很少有人知道。

实验室之外的人是 1973 年 10 月在 IBM 的操作系统研讨会上才知道 UNIX 这个东西。

虽然 1973 年 UNIX 在贝尔实验室的装机数为 25 但是由于当时的贝尔实验室实际上是掌控在

美国电信电话公司/AT&T

及其子公司

西方电器公司

的手上

实验室主要是负责研究改进西方电器公司制造的和 AT&T 在贝尔系统中使用的电信设备同时根据军方合同从事与国防有关的研发工作

而 AT&T 本身由于有反托拉斯法的限制并不能从事于任何有关计算机方面的销售

AT&T 的主管阶层们对于当时 UNIX 的发展并没有太多的兴趣

这导致就连贝尔内部对于 UNIX 也不是太在意。

不过为了应付实验室内各部门日益增加的 UNIX 使用者与相关技术支持需求还是成立了

UNIX System Group/UNIX 系统研发小组/USG

但该组织也仅只是为贝尔实验室内部的研发项目提供技术上的支持,并未赋予继续发展的任务,从未从事研发。

当然该小组也负责对外发放 UNIX 执照。

由此可知当时的 UNIX 发展全靠 AT&T 的工程师们自身的努力,这种研发没有组织及系统性可言,而用户和研发人员都是工程师……可想而知对于普通用户来说这系统是多么的难用,于是乎种下了 UNIX 日后较难以被一般人所接受的命运。

1974 年 Thompson 与 Ritchie 共同在 Communications of the ACM 发表 了一篇 UNIX 论文

UNIX Time-Sharing System/UNIX分时系统

得到相当大的回响!

这是 UNIX 第一次对贝尔实验室之外的影响

第二年 UNIX V6 发布!

1975 年 UNIX 发表的 V6/第六版 其提供的强大功能更胜过当时最昂贵的大型计算机的操作系统!

其最大特点是以高级语言写成,仅需要做很少的程序的修改便可移植到不同的计算机平台上!!

UNIX V6 还附有完整的程序原始码!!!

从此,在 1976 年 UNIX 正式从贝尔实验室内部传播到各大学及研究机构。

此年  UNIX 因提供

良好的程序发展环境

网络传输服务/网络功能

实时性/Real-Time Services

而被大多数电话公司采用

Interactive System Corporation/互动系统公司 更因为 Value Added Reseller/增值转销商/VAR  将 UNIX 用于办公室自动化环境而成为第一家应用 UNIX 操作系统的公司。

同年 UNIX 亦被修改并第一次装到 Interdata 8/32 型计算机上。

这也是 UNIX 操作系统首次安装在非 PDP 型的计算机上。

自此 UNIX 系统开始逐渐被移植改装到各型微处理机及新计算机上!

到此时 UNIX 才被装到了各种不同的计算机上。

加州大学伯克利分校/UC Berkeley 也就是依据这个 V6 版本开始研究并加以发展

并在 1977 年发表 1 BSD

1st Berkeley Software Distribution/第一次伯克利软件发行

版本的 UNIX OS

其后续的发展更为 UNIX OS 贡献良多且影响深远!

也就是这一年 UNIX 对于计算机硬件取得了真正独立,这也是贝尔实验室大多数工程师喜欢她的重要原因

1977 是 UNIX 发展史上重要的一步。

当时,里奇和汤普森尝试着把一个软件从 UNIX 机转到另一个计算机上

二人发现把一个软件从一台计算机转到另一台不同型号的计算机上实在是很麻烦!

还不如把整个系统从一台计算机转到另一台不同型号的计算机上来的容易。

于是两个老头决定把整个系统转移过去!这样就不用去和软件的差异打交道了。

于是从 UNIX 的 内核/Kernal 着手,确认那些需要重写的依赖于计算机机型的部分。

没曾想,竟然仅仅只有 10% 的 UNIX 内核需要重写!!!

90% 的 UNIX 内核,包括 文件系统、硬盘的供需次序、内存管理 等等功能都是独立于计算机机型的!

初期的 UNIX 是用汇编语言写的,为了能让 UNIX 在不同的计算机上工作 UNIX 必须用高级语言重写。

当时在计算机科学领域里一致认为用高级语言写操作系统是低效而又不实际的。

为了具有汇编语言的效率就不得不提前面说的里奇和汤普森合力发明的 C

C 语言具有高级语言语法和汇编语言的效率,能直接操作内存和输入输出系统而不需要用汇编语言!

C 语言能定义数据结构,操作比特和字符!!

C 语言比汇编语言简单的多!!!

有了 C 语言后 UNIX 才真的成为独立于计算机硬件的操作系统 C 语言也因此成了最受欢迎的系统编程语言!

1978 年 UNIX 发表了对今日影响最重大的 UNIX 第七版

UNIX Time-Sharing System,Seventh Edition/UNIX 分时系统,第七版

也就是 V7

此版本包含

Fortran 77 compiler/Fortran 77 编译器

Bourne Shel

文件处理工具 nroff/troff、roff、 MS mocro 等

UNIX-to-UNIX-file-Copy/用来支持两台 UNIX 机器间的文件传输

数据处理工具 AWK、SED 等强悍工具

除错工具 ADB

程序开发工具 MAKE

Lexical analyzer generator/词法分析器生成器 如 LEX、YACC 等

简单的绘图工具

支持 C 语言

支持 LINT verifier

主要运行于 PDP-11 及 Interdata 8/32 型计算机上。

在当时那个年代来说其系统的架构与功能已经是相当的完备的了。

Bourne Shell 的原作者称她为

improvement over all preceding and following Unices/改进之前和之后的所有 Unices 系统

在今日也有人称这个版本是

last true Unix/最后一个真正的 Unix 版本

由此可见 V7 在 UNIX 发展里程上的扮演了相当重要的基石角色

不久 DEC 公司推出了一款 32-bit supermini 主机 VAX

搭配的 VAX 的 操作系统叫做 VMS

这款迷你级计算机的硬件无可挑剔 直到今日她的稳定度仍是被诸多老一辈的系统管理员所赞许的

硬件虽然 NB 但是 DEC 自带的 VMS 操作系统让贝尔实验室的工程师们大失所望,想象一下你拿着现在先进的苹果电脑去安装上世纪的 DOS 系统……

所以大家宁愿依旧使用 UNIX OS

为了解决问题,于是 John Reiser/约翰·里瑟 和 Tom London/汤姆·伦敦 以 V7 为基础把 UNIX OS 转移到 VAX 计算机上使用

这个版本被大家称为 UNIX V32

因为 DEC 的 PDF-11 型计算机是 16-bit 所以为了转移的方便性而把 32-bit 的 VAX 当成是大一点的 PDP-11

为了提高执行效率 V32 放弃使用 VAX 硬件提供的一项功能 paging 这就是虚拟内存。

但即便是如此 V32 也能支持 4Gb 的地址!!!

DEC 的 VMS OS 有支持 paging/内存分页 功能

也由于 V32 舍弃这项功能所以 V32 没有虚拟内存的功能

就这样没有支持 paging/页面调度 功能的 V32 终于被安装在 VAX 的机器上运作!

很快, V32 就被广泛地安装在 VAX 机器上。。

而 VMS 这个系统就连自家都不想用,,于是 DEC 在 1984 年左右推出来自己的 UNIX 系统叫做

ULTRIX

好了讲老古董讲的太多了 现在说说 BSD UNIX 。

——————————

扎根伯克利

UNIX 从 Bell Labs 到 Berkeley 发展成 BSD 绝对离不开三个人:

Ken Thompson        将 UNIX 精神带到伯克利

Bob Fabry        将 UNIX 带到伯克利

Bill Joy        BSD 创始人

1971 年,一个 17 岁的少年 Joy 考进了密西根大学。

然后……便不可救药的迷上了计算机。。。

“比尔还是个孩子的时候,就想知道一切事物的运作方式。”,少年的父亲威廉姆曾这么说。

Joy 是高中班里公认 最用功的学生 学习像是在玩命。

比尔原本的梦想是当一个数学家,但很快就犹豫了起来,因为被计算机中心迷住了。

Bill 在整个大学生涯中都在编程!几乎全部时间都住在北校区,因为机房在北校区,二十四小时都开机!

事实证明 高手都是从疯魔起步!

因为计算机非常昂贵 所以学校只給每位学员一定机时,像上网吧一样,超时强制下线。

直到 Joy 发现一个 BUG !开机时不是要输入上机时间吗,如果不输入数字而是一个字母,那么就不会被系统踢下线!!
        于是这家伙从那以后每天夜里都偷偷钻进机房疯狂编程……一直干到凌晨才回来。

    比尔 · 乔伊:
学校会给每个人一个里面有点钱的账户,但是用的很快。
你登陆时要输入你想使用多长时间计算机。
比如说,她们给你一个小时的钱,这就是你所有能用的时长。
但是,如果你输入 "时间就是" 然后随便敲个字母
比如 "时间就是K"
她们就不会收你的钱!
然后你可以永远坐在那儿用电脑……

后来,进入伯克利大学的比尔更加夸张,深深沉迷于编程之中,用键盘发明了一个让毕业导师都觉得不可能完成的飞行程序,还创造出了 30 年后依旧让无数程序员膜拜着用的几大神作。

进入伯克利后,比尔终于有了一台终端机。

所以,熬夜到凌晨 2、3 点是家常便饭,然后比尔会突然昏睡般倒在键盘上。

    比尔 · 乔伊:
你知道,当我倒在键盘上的时候,会不断输入相同的字符。
于是电脑就不断发出 "滴 —— 滴 —— 滴" 的声音。
这样几次之后,真该上床睡觉了。
所以,大概有一万小时左右吧。
这个数字应该是我当年花在编程上的时间……

比尔自己感觉,从不精通到和编程融为一体花了 2 个学期。

再之后就走上了不断创造神作的道路。

最终位列史上最牛逼的十位编程达人之首,的许多敲代码的经历也都成了传说。

单薄的瘦高个,凌乱的亚麻色头发 这便是青年时期的 Bill Joy/William Nelson Joy :

神人镇楼

要说 UNIX 与 伯克利大学的故事,很早以前 K&R 在一场操作系统原理的座谈会上遇到了伯克利的 鲍勃·法布里 教授。

K&R

1973 年 11 月 Ken Thompson 和 Dennis Ritchie 在 印第安纳 普渡/Purdue 大学有一场操作系统原理座谈会。

会场上还坐着一位 伯克利大学/U.C. Berkeley 教授 Bob Fabry

​        而当天 K&R 所发表的 UNIX 立刻引起这位鲍勃教授的极大兴趣!老教授激动的直嘬牙花子。

因为当时的伯克利还是处在使用大型计算机主机、批处理执行程序的阶段 还没有像 UNIX 这样的

交谈式作业环境/互动式开发环境

会后 ta 便决定将 UNIX 带回伯克利!

于是伯克利的

计算器科学系

数学系

统计系

三个系凑巴凑巴合买了一台 PDP-11/45 准备用来迎接 UNIX !!!!!!!!!!

1974 年 1 月 Bell Labs/贝尔实验室 給伯克利寄来了一卷 V-4 的磁带

学生 Keith Standiford/纪茨·斯丹迪福特 便开始安装 V4 。

不出意外的跟我们第一次碰操作系统时一个样儿!装不上还不知道自己错哪了,,

斯坦迪福德安装时碰到了问题,无奈之下便向贝尔实验室求援

而人在新泽西州的 Thompson/汤普森 通过伯克利这端速度只有 300-baud 的调制解调器在在线进行侦错和指导安装……汗颜 自家的 Modem 实在是有点丢人啊……

在 UNIX 的发展史上,这是贝尔实验室与伯克利的第一次接触!

完成除错后 V4 便顺利地在柏克莱这台新买的 PDP-11/45 计算机上工作了!!!

因为当时这台机器是三个系合买的,计算器科学系好不容易装上了 UNIX 却碰到数学与统计系所要使用

DEC's RSTS system/DEC 的 RSTS 系统

所以在一阵协调后 UNIX 与 DEC 的 RSTS 系统以 8:16 小时的比例分配供三个系所轮流使用。

一段时日后具有人性化交互式的 UNIX 在性能上的表现得到绝多数学生们喜爱!

纷纷将自己的作业计划时段转向 UNIX 的八小时 而一天占了 16 个小时的批处理时段却乏人问津……

对 UNIX 的需求在伯克利迅速增长,当时 Eugene Wong 与 Michael Stonebraker 教授看到 UNIX 提供的效果后

便打算将 INGRES 数据库计划从原先批处理的计算机环境转移到 UNIX 系统上面

在 1974 年还为该执行计划特意添购了一台新的 PDP-11/40 计算机 从上面安装了 V5

这个计划也就是伯克利的第一个将作业环境转移到 UNIX 的案子。

UNIX 作业环境的需求在伯克利大学迅速地成长

为了应付需求 Michael Stonebraker 与 Bob Fabry 教授决定再申请购买两台 PDP-11/45 ……终于踏上了改革开放的道路!

1975 年初 DEC 推出 PDP-11/70 价格差不多等于两台 PDP-11/45 但功能绝对强过 PDP-11/45 !

所以伯克利便决定改购买一台 PDP-11/70 。

这是一台神器的机器 —— 让两个神人从此相遇

PDP-11/70 让汤普森遇到了乔伊以及后来产生的 1 BSD

这一事件是UNIX发展史上的标志性事件

当这台机器在 1975 年终运达柏克莱时 Thompson 立刻受邀回母校伯克利当客座教授 科目就是 UNIX

同年秋天一位密歇根大学毕业生 比尔·乔伊 来到了伯克利 !

Thompson 在校期间与 Jeff Schriebman 和 Bob Kridle 一起动手将新版的 V-6 安装在 PDP-11/70 上!

正是这台 PDP-11/70 机器引来了 Ken Thompson 还碰上 Bill Joy 以及日后产生了 1 BSD

她就宛如是一块 UNIX 史上的地标,沿袭自 Bell Labs 竖立在 Berkeley 承先启后并开创新局

一听说母校买了超强计算机老家伙迫不及待了就屁颠屁颠跑回来玩……

比尔·乔伊:

老大不小了还跟我们小孩抢电脑!不要脸啊!!!……

1976 年在伯克利分校 “冒充” 大学教授的 Ken Thomphson :

客座教授牌 肯·汤普森

这个冒牌教授不仅讲解理论,还在晚上带着大家阅读一行行的 UNIX 内核代码 向大家解释为什么这么做

每个晚上,学生们都围绕在 Ken Thomphson 周围,瞪着一双双求知的大眼睛,聆听 UNIX 创始人的教诲……

就连 Bill Joy 都不去 “网吧” 非法上网了,而是来朝圣!

这可是 UNIX 之父啊,我在 ta 老人家下面听课可实在是太幸福了!

就这样 Ken 成功在伯克利大学激发了学生们的黑客精神!

        我们以后以 UNIX 精神概指,简称 U 客!

——————————

csh 的诞生

1975 秋 UNIX 光环加身的  Ken Thompson 休了一个长假,从贝尔验室回到了自己的母校 —— 加州大学伯克利分校!

在伯克利分校 Ken 把 UNIX 安装到了最新的机器 PDP 11/70 上面,并且开设了一门 UNIX 的课程 ta 要在母校当一年的教授!

她长这个样子:

PDP 11/70

PDP-11 是计算机历史上最为著名的计算机之一

是数字设备公司迪吉多电脑 Digital Equipment Corporation/DEC 从 1960 年代早期到 1990 年代中期制造的系列产品之一

PDP-11 是一款在 1970 年上市至 1990 年代发售的小型机 当时售价为 10800 美元 当时唯一的 16 位计算机……

PDP 11/35

而 PDP-11/70 是 PDP-11/45 的增强版 支持 4 MiB 内存与 2 KiB 缓存!!!在当时已经很强了好吧!!噗

通过 大容量总线/Massbus 可以获取更快的输入输出设备连接。

PDP 11/70

好巧不巧 Bill Joy 这时候也到伯克利报道,忽然发现 UNIX 的发明人 Ken Thompson 到学校开了一门课 —— 剖析 UNIX !!!

所以 Bill 当时就入迷了。。。

用 ssh 连接到代理后通过邮件中给定的用户就可以登入 PDP-11/70 了

按照邮件的提示,首次登录后我们应该

passwd

修改密码

PDP-11 机器支持运行多种操作系统

例如 UNIX v7 这是最后一版自由使用的 UNIX 这也是贝尔实验室制造的真正正统的 UNIX 系统

UNIX, Version 7 这次不是手打了而是直接开抄! :

Bokjan@Bokjan-MBP ~> ssh pdp1170@tty.livingcomputermuseum.org
Last login: Tue Feb 28 10:26:59 2017 from 104.131.158.221
NetBSD 7.0_STABLE (GENERIC.201608020750Z)
Trying 199.59.106.27...
Connected to pdp1170.
Escape character is 'off'.Password OK*****************************************************************
*                                                               *
*      T h e   L i v i n g   C o m p u t e r   M u s e u m      *
*                                                               *
*            DEC-DataSystem 570 (PDP-11/70) MissPiggy           *
*                                                               *
*      Unauthorized access to this machine is prohibited.       *
* Use of this system is limited to authorized individuals only. *
*                All activity is monitored.                     *
*                                                               *
*   To request an account on this system, please visit us at    *
*                                                               *
*             http://www.LivingComputerMuseum.com/              *
*                                                               *
*****************************************************************login: bokjan
Password:
$ passwd
Changing password for bokjan
Old password:
New password:
Retype new password:
$  

由于年代久远 即便我们能够熟练使用现代类 UNIX 操作系统

上手 Version 7 UNIX 时也一定是非常陌生的 古老的程序、匮乏的命令令人有些无从下手……

甚至就连最基本的 vi 都没有!vi 是 1976 年首次发布的但是这个是 1989 年的系统:

$ vi
vi: not found

系统自带的文本编辑器性质工具是 ed 由 Ken Thompson 于 1971 年首次发布。

ED 确实较难操作 与现在的图形界面文本编辑器甚至是终端下的 Vim 和 Emacs 都不同

你只能通过命令编辑而并不能看到这个文件里的东西被改成了什么样!!!

例如:

a
ed is the standard Unix text editor.
This is line number two.
.
2i.
,l
3s/two/three/
,l
w text
q

在这一顿操作中将如下内容写入了 text 文件并显示出来:

ed is the standard Unix text editor.This is line number two.

好家伙 这也太……好在还有 echo 命令搭配重定向操作文件:

$ echo "something" > a.txt
$ cat a.txt
something

通过这个方法费老大劲才能实现 Hello World 程序并运行:

$ echo "#include <stdio.h>" > a.txt
$ echo "int main(void)" >> a.txt
$ echo "{" >> a.txt
$ echo "puts("Hello PDP-11");" >> a.txt
$ echo "}" >> a.txt
$ cat a.c
#include <stdio.h>
int main(void)
{
puts("Hello PDP-11");
}
$ cc a.c
$ ./a.out
Hello PDP-11

sh 太难用了……  Bill Joy 觉得这帮贝尔实验室的科学家们创造的 UNIX 终端在人机交互设计方面太不人性!

都说我反人类 你全家都反人类设计 于是自己就编写了新的 UNIX Shell

这就是大名鼎鼎的 csh !!!

C shell 是一个交互式命令解释器和一种命令编程语言 采用的语法类似于 C 编程语言

shell 是交互式地从终端键盘或者是从一个文件来执行命令的

这个 csh 命令调用了 C shell

当调用 csh 命令时就会执行,这是通过查找根目录和执行命令从用来存储用户化的用户信息

.cshrc

文件中,执行的条件是命令存在。

如果 csh 命令作为一个登录 shell 运行,就会从

.cshrc

.login

文件中执行命令。

因为语法有点类似 C 语言所以才得名 C shell

目前的 UNIX 大部分系统中一般都是 tcsh 是 csh 的增强版,加入了命令补全功能,提供了更加强大的语法支持。

csh 是 Joy 給 UNIX 的第一个贡献!

——————————

BSD 与神器 VI/VIM 的诞生

1975 年一位密歇根大学毕业生 比尔·乔伊/Bill Joy 来到了伯克利

时间久了又犯老毛病了:把机房当网吧上!

由于这个雷打不动的毛病也因此结识了好朋友 恰克·哈里/Chuck Haley

这一下 王八看绿豆 —— 对上了眼,当场结为黄金搭档二人组!

大神的朋友怎么可能是简单货色呢,最起码也得是个小神,没错大名鼎鼎的 tar 就是这货写的!别告诉我你没用过 tar !!

别人喜欢一起泡温泉,而这二人喜欢一起泡机房,无巧不成书,汤普森/Thomphson 也经常来机房插一脚……

那天 Ken Thompson 在 PDP 11/70 机房闲逛的时候随手就在 UNIX 上写了一个不太完善的 Pascal 编译器

这令 Bill Joy 两人大开眼界!原来 U 客是这么玩的啊!

Bill Joy 在用 Pascal 写项目作业的时候,很快便发现了编译器的缺陷

于是暗自也决定做一个 U 客,把这个编译器改好。

于是乎,咔咔两下成功改进了 Pascal 编译器的编译与侦错能力!

然后还还提高了编译与执行速度!

这还不完,在装上 ADM-3 的屏幕后,两个小伙子同时觉得 ed 文字编辑命令不好用,真是英雄所见略同。

但是老顽童可不高兴了,誰说我们写的 ED 不好用的?你们这是不尊重前辈的科技成果!年轻人我们吃过的盐比你喝过的水还多!

老教授拍拍屁股嘟嘟囔囔的走了。

必须要提一下,那时候并没有显示器,大家用的都是 电传打印机 :

电传打印机

电传打字机是随着计算机的发展而出现的一种远距离信息传送器械

电传既具有电话的快速 又具有打字机的准确 尤其是当电文中有资料时 这种优点表现得特别明显。

人们普遍认为电传这种通讯方式除了具备高效性和精确性之外还比电报和电话更为便宜!

与传真有不同区别,电传是一个比较早出现的产品

为在传真机普遍使用以前的通信设备,其原理采用有点近似电报。

早期国家政府单位、国有进出口公司皆普见使用,但现在基本上已经被传真机或因特网所取代。

形状像是一个大号的打印机:

teleprinter

怎么样 够不够大?够不够大?hhh

说一下她的缩写你就知道了 就是

TTY/Teleprinter/TeletypewriterTele-Type

没错 Linux 上的字符终端是不是叫 tty ?!

电传打字机通常由

键盘

收发报器

印字机构

等组成

发报时 按下某一字符键 就能将该字符的信号自动发送到信道

收报时 能自动接收来自信道的电码信号 并打印出相应的字符

装有复凿孔器和自动发报器的电传机能用纸带

收录

存贮

发送

电报

电传机操作方便,通报手续简单,因而得到了广泛的应用。

那时候可还没有 IDE 环境这种概念,都是使用一个叫 ed 的文本编辑器来程序

ed 也是 Ken Thompson 写的但是她实在是不好用

对 Thompson 和 Ritchie 来说 ed 已经足够好了 但是其她人则认为她很难用,而且她被作为一个淋漓尽致地表现 UNIX 对新手敌意的例子而臭名昭著

在 1975 年一个名叫 George Coulouris 的人在伦敦玛丽皇后学院的 UNIX 系统上开发了一个改进版 ed

这位前辈很神奇,因为爸爸是英国演员,出演过公民凯恩!

George Coulouris

Coulouris 利用自己在玛丽女王学院的视频显示器开发自己的编辑器

与 ed 不同的是 Coulouris 的程序允许用户编辑在屏幕中的一行代码通过一次次击键的方式来操作行 想象一下在 vi 中每次编辑一行

Thompson 拜访玛丽女王学院时,看到 Coulouris 已经写好的程序,驳斥 Coulouris 不需要在编辑文件的时候看到她的状态!

受此 “启发” 后 Coulouris 将这个程序命名为 em :

为凡人而生的编辑器

the editor for mortals

这便是 em 的名字来源!

虽然有人写出了 em 但还是达不到易用且强大的理想型编辑器。

好在老教授的一番教导并没浇灭两位少年内心的火焰。

二人组又一个晚上根据相似的 em 命令开发了文字编辑工具指令 ex !!!

1976 年 Coulouris 跑到了伯克利 在那里用了一个夏天的时间在 CS 系访学
         正是 Coulouris 把 em 引入了加州大学伯克利分校。
        这已经是 Ken Thompson 离开伯克利去贝尔实验室工作十年之后的事了。

在伯克利 Coulouris 遇到了毛头小子 Bill Joy
        Coulouris 向研究生 Joy 展示了 em
        Joy 以 Coulouris 的源代码为基础为扩展 ed 建立了一个名为 ex 的改进版 ed

Bill Joy 正是以 Coulouris 的源代码为基础,开始写让自己觉得满意的文字编辑工具

然后 Bill Joy 和 Chuck 改进了 em 把她变成了 en 然后是 eo、ep、ex ……

直到最后为扩展 ed 写了一个名为 ex 的 ed 改进版……

说一下那时候的编辑器

ed、en、ex 等行编辑器跟我们现在用的文本编辑器不同 都是行编辑器

这种行编辑器是非常具有个性的

你绝对不能想象当时的程序员过的都是些什么日子啊:

你想在文档中任意移动光标,选取要编辑的文本段落?

对不起,不行!

你只能以行为单位进行上下移动!

你好不容易定位到了一行,想改这一行的某个词?

对不起,不行!

你得删除这一行,然后重新输入!

Bill Joy 就是使用 ex 这个 “趁手” 的工具 很快就把 Thompson 留下的 “烂摊子” Pascal 编译器给收拾好了

新的 Pascal 编译速度很快,运行起来也很快,深受学生们的喜爱!

一年后 也就是 1976 年夏,汤普森结束了客座教授的工作回到了贝尔实验室。

ta 虽然走了 但是 ta 留下的 U 客精神种子开始生根发芽。

与此同时 Joy 的 Pascal 编译器有着良好的声望,很多人都想要一个拷贝

1977 年早些时候,此时的二人组已经开始探索 UNIX 内核了……然后不出意外的又出了一些修改……

Bill Joy 突发奇想,为什么不把

Pascal 编译器

ex 编辑器

还有后来的 vi 编辑器

以及其她对 UNIX 的增强

一起打成一个新的包,重新分发呢?

又是一年后 也就是 1977 年初 Bill 制作了一卷磁带 上面写着

Berkeley Software Distribution/伯克利软件发行

这就是有名的自从 1969 年 UNIX 在 AT&T 贝尔实验室的诞生到 UCB 的两名在校研究生将其改进为 BSD 版本的:

1 BSD

其中就包含新的:

Pascal 编译器

ex 编辑器

于是 BSD 诞生了!

LOGO_BSD_小恶魔

又又一年后 也就是 1978 年 伯克利又又进了几台新的显示屏 ADM-3a

ADM-3A 是一个早期视频显示终端

在 1976 年引入 她创下了 995 美元的新行业低单价。

这是由制造利尔西格勒并且具有 12 英寸的屏幕显示的 80 个字符 12 个或 24 行。

由于计算机通信速度的快速提高,以及由于需要廉价的操作员控制台而向市场推出的新型小型计算机系统

她很快在商业上取得了成功!

该显示屏支持光标地址显示!

ADM-3A_设备

很多人都不能理解 vi/vim 为什么使用 jkhl 来移动光标

来 先看一下 ADM-3A 的键盘布局:

ADM-3A_设备按键

只有这四个键上印有光标移动箭头!笑死,那时候连方向键都没得的好吗!

1978 年 1.1 版本的 ex 与第 1 个版本的 BSD UNIX 捆绑在一起。
        ex 在很大程度上与 ed 兼容,但她增加了两种模式:

开放模式 这种模式可以使 em 单行编辑成为可能
可见模式 这种模式会占据整个屏幕,并且可以像我们今天所习惯的那样,对整个文件进行实时编辑

自从伯克利大学购买了这批终端 Joy 发现在屏幕上终于支持可以随意移动的光标了!

Bill Joy 欣喜异常,立马重新设计了 ex 增加了

可视化模式

从此 ex 变成了大名鼎鼎的 vi

Bill Joy

Joy 就是在这台机器上完成了一个两极分化极其严重的 vi 编辑器:

喜欢她的人会爱不释手

而不喜欢的会恨之入骨

有一天晚上 Joy 向《 C 编程语言》的作者 Brian Kernighan/布莱恩·柯林汉 展示一个自己正在研发的文本编辑器。

布莱恩·柯林汉
    Joy:“老师你看看我新开发的文本编辑器,她可现在最流行的 ed 好多了!”,Joy 手舞足蹈。“哦?是吗?”。“对的对的 ed 是以行为单位进行编辑,对新手来说非常不直观,我的编辑器使用光标来定位和编辑,这是对 ed 的重大变革。”,Joy 兴奋地说。但是 Brian 开始打瞌睡:“小伙子,我建议你应该停止折腾编辑器,专心完成你的博士学位。”……

很明显 Bill 并没有理会这个建议,幸亏 ta 没有理会,因为这个编辑器就是大名鼎鼎的 vi !

新手进入 vi 以后经常让人手足无措,头晕眼花,连退出都没法退出

在她们看来这个工具极其简陋,需要记忆各种各样的命令,还得在各种模式之间切换。

最后扔下一句:什么破玩意儿!以后再也不碰她了……

比尔·乔伊 曾多次公开说过 要是早知道 vi 会如此受“欢迎”的话宁愿当初没写 vi ……

vi 这个编辑器让无数程序员爱不释手,更让无数程序员从入门到放弃。

还和另外一个神器 Emacs 开启了长达几十年的论战:

到底谁是最好的编辑器?

有个笑话说:

如果让计算机生成随机数呢?

答:

让新手退出 vi !!

和其她编辑器相比 vi 的学习曲线非常搞笑,刚开始时直线上升,然后就平稳了,这是为什么呢:

vi 学习曲线图

答案当然是 —— 用习惯了!噗龇!

    比尔本来还想为 vi 加入一项 Multiple Windows/多视窗 功能,真是屋漏偏逢连夜雨,在 ta 写这部分程序的时候磁带机坏了。。。好家伙老天爷看不下去了,乔伊只好在没有备份的情况下工作,结果好家伙写了一半眼看就要完成了,船迟又遇打头风,这货的硬盘也跟着挂掉了……上帝这顿神操作让 Bill Joy 又迷了,当时整个人都不好了 在无可挽救又没有备份磁带的情况下 Joy 只好放弃了为 vi 增加多视窗功能……

接着不久 Joy 便发现一个问题:

老旧的屏幕装备,还是会被用在其她的计算机上

为了支持上的方便 Joy 针对此现象设计了一个接口用来管理、支持不同的屏幕装备

这个接口就是现在的 termcap !!!

多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的方法

在窗口大小发生变化时,内核就会通知前台进程组

内核为每个终端和伪终端都维护了一个如下的 winsize 结构:

struct winsize {
/*用 ioctl 函数的 TIOCGWINSZ 命令可以取此结构的当前值用 ioctl 的 TIOCSWINSZ 命令可以将此结构的新值存储到内核中 如果此新值与存储在内核中的当前值不同,则将向前台进程组发送 SIGWINCH 信号 默认会被忽略除了存储此结构的当前值以及在此值改变时产生一个信号以外,内核对该结构不进行任何其她操作 对结构中的值进行解释是应用程序的工作*/unsigned short ws_row;    /* rows, in characters/行,以字符为单位 */unsigned short ws_col;    /* columns, in characters/列,以字符为单位 */unsigned short ws_xpixel;    /* horizontal size, pixels (unused)/水平大小,像素(未使用) */unsigned short ws_ypixel;     /* vertical size, pixels (unused)/垂直大小,像素(未使用) */
};

提供这种功能的目的是当窗口大小发生变化时应用程序能得到通知 例如 vi 编辑器

应用程序接收到此信号后,可以获取窗口大小的新值,然后重绘屏幕

termcap 的意思是 终端能力/erminal capability

她涉及文本文件 /etc/termcap 和一套读此文件的例程 主要是为了支持 vi 编辑器而开发的

termcap 文件包含了对各种终端的说明:

终端支持哪些功能 如 行数、列数、是否支持退格

如何使终端执行某些操作 如 清屏、移动光标到指定位置

把这些信息从编译过的程序中取出来并把她们放在易于编辑的文本文件中

这样就使得 vi 编辑器能在很多不同的终端上运行

最后将支持 termcap 文件的例程从 vi 编辑器中抽取出来放在一个单独的 curses 库中

为使这套库可供要进行屏幕处理的任何程序使用,还增加了很多功能 不过 termcap 这种技术并不是很完善

因为当越来越多的终端被加到数据文件中时 为找到一个特定的终端 可能需要花费很长的时间扫描此数据文件。

另外,该数据文件还用两个字符的名字来标识不同的终端属性。

因此出现了 terminfo 以及与其相关的 curses 库。

在 terminfo 中终端说明基本上都是文本说明的编译版本,在运行时易于被快速定位。
        但不论是 termcap 还是 terminfo 她们本身都只提供在各种终端上执行典型操作 例如

清屏

移动光标

等的方法

而不处理 如

更改终端模式

更改终端特殊字符

处理窗口大小

等问题

不过 curses 库能提供某种具体细节方面的帮助 她提供了很多函数,用来

设置原始模式

设置 cbreak 模式

打开和关闭回显

注意 curses 库是为基于字符的哑终端设计的 她们如今大部分已被基于像素的图像终端所代替

当然对于现在来说 termcap 数据库是一个过时的工具 她用来描述以字符为单位的终端和打印机的功能

如今之所以被保留是为了兼容古老的程序 新程序应当使用 terminfo(5) 数据库和相关的库

/etc/termcap 是一个 ASCII 文件 是数据库主控文件 列出了许多不同类型终端的功能

程序可以读取此数据库文件来找到控制实际使用的终端的可视化属性的特定的脱逸字符 escape code

终端的其她方面是 stty 处理的

termcap 数据库按照 TERM 环境变量进行索引

也就是这一年 包含了加强功能的 Pascal 编译器与 vi 编辑器及 termcap 的 2 BSD 发布:

Second Berkeley Software Distribution/ 第二次伯克利软件发行

在那一年至少有 75 部 PDP-11 安装了 2 BSD 在运行

2 BSD 迅速取代了 1 BSD

自此在 DEC PDP-11 系列上执行的 BSD 版本便一直以 2.x BSD 作 为识别。

由于 PDP-11 计算机实在相当长寿,持续到今日仍然在网络上发现过关于 PDP 计算机的网站 似乎到今日她们仍旧在某些地方默默地工作着……

2.x BSD 最近的一次改版是在 1987 年 使用 4.3 BSD 为主架构改写 版本定为 2.10 BSD

乔伊的计算机编程能力无与伦比 业界流行的一个趣闻是年乔伊只花费了一个周末的时间就编写出了 VI 文本编辑器

谷歌董事长 埃里克·施密特/Eric Schmidt 还夸张的表示乔伊编写 BSD 内核也只花费了一个周末的时间!!!

第 2 版 BSD 引入的一个名为 vi 的可执行文件只在可视模式下打开 ex

vi 名字来自于 visual 可视模式 ex/vi 后来称为 vi

就是这个 vi 建立了我们现在使用的 vim 中大多数的约定 但这些约定当时并不是 ed 的一部分

Bill Joy 使用的视频终端是 Lear Siegler ADM-3A 这个键盘没有光标键 而是

jkhl

键来绘制光标键

所以 Bill Joy 在 vi 中就使用这些键来进行光标移动:

Lear Siegler ADM-3A 按键

ADM-3A 键盘上 escape 键位置是今天我们所使用的键盘上的 tab 键

这也就解释了为什么这样一个难以够着的键会被用来实现像退出当前模式这么常见的操作

前缀命令的冒号字符同样也来自 i 在常规模式下即运行 ex 进入的模式使用冒号作为提示

这解决了一个 ed 中被长期诟病的问题,也就是一旦启动之后,没有任何反馈信息向用户致以问候。

在可见模式下,保存和退出需要使用现在仍在使用的经典 wq

以及用于设置选项的 set 命令都是原始 vi 的一部分。

我们今天在 vim 中使用的的基本文本编辑过程 都是 vi 中使用的特性。

vi 是除 ed 之外唯一与 BSD UNIX 捆绑的文本编辑器。

在那个时候 Emacs 可能会花费数百美元 这是在 GNU Emacs 之前

所以 vi 变得非常流行

但是 vi 是 ed 的直接衍生版本,这意味着如果没有 AT&T 的源代码,源代码就不能被修改。

这促使一些人创建了 vi 的开源版本

专门为 vi 爱好者的

ST 编辑器STEVIE 出现于 1987 年

Elvis 出现于 1990 年

nvi 出现于 1994 年

其中一些克隆版本添加了额外的功能,如语法高亮和窗口分离。

尤其是 Elvis 的许多功能被整合到 vim 中,因为许多 Elvis 用户推动了这些功能的加入。

vim 是

改进版 vi

的缩写 而最初代表的是

模拟版 vi

和其她许多 vi 克隆版本 一样 vim 始于在一个无法使用 vi 的平台上复现 vi 的一个尝试

在荷兰 Venlo 一家影印公司工作的软件工程师 Bram Moolenaar 想要为全新的 Amiga 2000 准备一款类似于 vi 的编辑器。

Moolenaar 已经习惯了在大学时使用的 UNIX 系统上的 vi  当时已经对 vi 了如指掌。

所以在 1988 年 Moolenaar 使用当时的 STEVIE vi 克隆版本开始工作。

Bram Moolenaar

Moolenaar 接触到 STEVIE 缘于其曾经出现在一个叫 Fred Fish 的磁盘上。

Fred Fish 是一名美国程序员,每个月都会寄出一张软盘,内含为 Amiga 平台提供的精选可用开源软件。

有点类似于国内曾经的软件指南  任何人只要支付邮费就可以得到一张这样的磁盘。

有若干版本的 STEVIE 曾在 Fred Fish 磁盘上发布。

Moolenaar 使用的 STEVIE 版本在 Fred Fish 256 号磁盘上发布

令人失望的是 Fred Fish 磁盘似乎与 Freddi Fish 海底大冒险游戏 没有任何关系

Moolenaar 喜欢 STEVIE 但很快就注意到其缺失了很多 vi 命令。

因此,在第一次发布 vim 时 Moolenaar 优先考虑了 vi 的兼容性。
        当时已经有其她人编写了一系列的 vi 宏 当运行一个合适的 vi 兼容编辑器时可以求解一个随机生成的迷宫
        Moolenaar 能够让这些宏在 vim 中运行!

1991 年 vim 以

vi 模拟

为名第一次发布于 Fred Fish 591 号磁盘
        Moolenaar 添加了一些特性
        包括多级撤销和解决编译器错误的 quickfix 模式
        这意味着 vim 已经完成了对 vi 的超越

在 1993 年通过 FTP 发布 vim 2.0 之前 vim 都以 vi 模拟 的身份存在。

在众多互联网合作者的帮助下 Moolenaar 稳健地在 vim 中加入了一些功能。
        vim 2.0 引入了对 wrap 选项的支持,以及对长行文本进行水平滚动的支持。
        受到了 vi 克隆 nvi 的启发 vim 3.0 增加了对分割窗口和缓冲区的支持。vim 现在还将每个缓冲区保存到交换文件中以避免程序崩溃造成文件丢失。

vim 支持语法高亮显示第一次出现是在 vim 5.0 中。

与此同时 vim 的受欢迎程度也在不断增长。
        她被移植到 MS-DOS、Windows、Mac 甚至被移植到 UNIX 与原来的 vi 竞争……

2006 年 vim 被 Linux Journal 读者评为最受欢迎的编辑器。
        如今根据 2018 年 Stack Overflow 的开发者调查 vim 仍然是最受欢迎的 文本模式/终端模拟器 编辑器
        受用于 25.8 % 的软件开发人员和 40% 的 Sysadmin/DevOps 人员

在 1980 年代末和整个 1990 年代程序员一度发起了 编辑器战争
        将 Emacs 用户与 vi/vim 用户进行了对比
        虽然 Emacs 肯定仍有一些追随者,但有些人认为编辑器战争已经以 vim 获胜而结束!
        2018 年 Stack Overflow 的开发者调查显示只有 4.1% 的受访者使用 Emacs 也验证了这个事实。

vim 是如何变得如此成功的?显然人们喜欢 vim 所提供的特性。
        vim 背后的悠久历史表明了她的优势远不仅仅体现在其功能集上
        vim 的代码库可以追溯到 1988 年 当时 Moolenaar 开始研究她
        某种程度上要感谢 Bill Joy 和 Bram Moolenaar 对向后兼容性非比寻常的关注才使好的想法逐渐积累起来。
        从这个意义上说 vim 文本编辑器是运行时间最长、最成功的开源项目之一

得益于计算机世界中一些最伟大的思想贡献。

——————————

一个人抱着协议书就写出了 TCP/IP 协议栈

1978 年 比尔·乔伊 在只有一台 VAX 的状况下于 1979 年 1 月在 VAX 上完成了支持虚拟内存的 UNIX !!!

这直接导致了 V32 从此销声匿迹。

不久伯克利的研究人员又加上了 Pascal 然后乔伊又将 2 BSD 上的工具转移了过来

一个首次支持虚拟内存的 UNIX 诞生了 这个版本就是 3 BSD !!!

事情还是来自于 Richard Fateman 教授在使用一台 PDP-10 上进行着自己的 Macsyma 研究计划

好了问题来了,内存不够!需要更大的内存地址来执行程序

所以在 1978 年初她看上了当时迪吉多的 VAX-11/780 新机器 好不容易联合了其她的部门才凑足购买 VAX 的经费

刚开始时机器原本安装的是 VMS 操作系统……呵呵呵,前面说了破系统的性能有多糟糕,,

别的成员实在受不了了,一定要执行 UNIX 操作系统,于是 Fateman 安装上了 V 32

但新问题来了 —— V32 并不支持虚拟内存。

Fateman 便找上了 Domenico Ferrari 教授,希望 ta 与 ta 的研究小组能为 UNIX 加上这项功能。

当时一位学生叫 Ozalp Babaoglu 想到了一些解决的方法似乎可行,但因为牵涉到 VAX 硬件与 UNIX kernal 的问题

于是便找上了 Joy 帮忙,于是乎 Joy 就在只有一台 VAX 的状况下努力奋战着。

1979 年 1 月,在 VAX 上支持虚拟内存的 UNIX 版本终于诞生!! 二人亲手将 V 32 送入历史。

紧接着 Peter Kessler 与 Marshall Kirk McKusick 为这个系统加上了 Pascal 编译器

Joy 则动手将 2 BSD 上自己的那些小工具 ex、vi、C shell 等工具都转移了过来……

这个版本就是 1979 年末发行的 3BSD

3 BSD

一个首次支持

虚拟内存/virtual memory

请求式页面调度/demand paging

页面置换/page replacement

的 UNIX OS

这就是由伯克利发行的第一个操作系统!

1970 年代末,美国国防部高级研究计划机构

Defense Advanced Research Projects Agency/DARPA

正在为

人工智能/Artificial Intelligence/AI

超大规模集成电路/VLSI

计算机视觉/vision research

等研究找寻一个可共同作业的编程环境

硬件首选是 VAX 主机 但是上面配合的操作系统是 VMS ……

因为这样的组合因拥有相当接近 DARPA 需求的功能被列入优先的考量 但是 DARPA 在与 DEC 商谈关于 VMS 的支持事宜之后没有得到满意的答案而倾向于向 UNIX 发展

这里的 UNIX OS 指的就是 32 V 搭配 VAX

这种搭配最大的缺憾就是不支持虚拟内存,而此时收到一封信正好得知 UNIX 已增加了支持虚拟内存的功能……

将 UNIX 带进伯克利的法布里教授写了一份建议书给 DARPA 建议 DARPA 以支持虚拟内存的 3 BSD 为基础进行研发。

好家伙 真是瞌睡来了送枕头!这份建议书立马引起了 DARPA 的高度兴趣而 3 BSD 也获得了 DARPA 成员的好评

自此伯克利大学打败了

卡内基梅隆大学/Carnegie Mellon University

BBN

Bolt Baranek & Newman, Inc.

博尔特·巴拉克和纽曼公司

成功地获得了 DARPA 的资助合约!合约于 1980 年 4 月生效 为期 18 月 此后 DARPA 便以 UNIX 为标准操作系统了。

法布里教授取得 DARPA 合约后依约迅速成立了一个支持的研发机构

CSRG/Computer Systems Research Group/计算机系统研究小组

还找上了 比尔·乔伊 在小组里负责软件开发。

Joy 也没让老家伙失望 迅速以 3 BSD 为基础整合了新功能:

例如

Jim Kulp 的 Job Control/作业控制

auto reboot/自动重启

1K block file system/一千 block 块大小的文件系统

同时也整合入

Pascal compiler/Pascal 编译器

Franz Lisp system/Franz Lisp 系统

enhanced mail handling system/增强型邮件处理系统

这就是 4 BSD !!!

1980 年伯克利发布了 4 BSD

没多久就被安装在近 500 台 VAX 上运行!

DARPA 采用了这个版本作为当时 DARPA 的标准 UNIX 操作系统!这让伯克利跟 Joy 的名声鹊起。

    树大招风 当时 tanford Research Institute/斯坦福大学 的 David Kashtan 写了一份报告该份关于 VMS 与 BSD UNIX 在 VAX 上的执行效率评估报告指出 BSD UNIX 在效率上不如 VMS好家伙又一些老头来挑我的毛病,你以为你是誰,要知道我连 UNIX 之父的话都没听!年轻气盛的 比尔·乔伊 哪里受得了,在得知后二话不说就死磕 前后花了不到一个星期的时间重新调整了 UNIX kernal ……好家伙想到了我们开学头一天补作业然后 Joy 立刻翘着二郎腿也发表了一份报告证明 BSD 在 VAX 上其实是要比 VMS 优越的!!!

这个 Joy 调整过的系统加上 Robert Elz 写的 auto configuration/自动配置 后:

1981 年 6 月这个新版本以 4.1 BSD 的版本发布了!

DARPA 对 4.1 BSD 相当满意 续约了两年 金额为先前合约的 5 倍!

其中一半用于资助开发 BSD UNIX 钱多的相对代价就是要求高

DARPA 对 UNIX 的期望是

更迅速

更有效的文件系统

更大的程序可执行地址可达 multi-gigabyte/千兆字节

弹性的 解译沟通能力/编译能力

整合支持网络能力

为了达成目的 DARPA 成立了一个指导委员会

主要的成员有

伯克利的 Bob Fabry、Bill Joy、Sam Leffler

BBN 公司的 Alan Nemeth、Rob Gurwitz

贝尔实验室的 Dennis Ritchie

史丹佛大学的 Keith Lantz

卡内基梅伦大学 Rick Rashid

麻省理工学院 Bert Halstead

信息科学协会 Dan Lynch

DARPA 的 Duane Adams、Bob Baker

加州洛杉矶大学 Jerry Popek

tcp/ip 协议出来以后,一直都没有人写出一个能用的 tcp/ip 栈

Bill 同学就写了一个放出来了,大家都很诧异,就问 Bill 同学是怎么写的。

Bill 回答说:

我就是一边看着RFC,一边写就好了啊……

其她人唯有吐血而已。

直到很多年以后 BSD上的 tcp/ip 栈还都是网络世界的基石。

Bill Joy 是第一个完整实现 tcp/ip 栈的程序员

当时有一家叫 BBN 的公司曾经参加过 ARPANET 的建设 获得了实现 TCP/IP 协议栈的合同

TCP/IP 协议是互联网的基石, 读过的人都知道,光是理解这些协议就非常不容易,更不用说准确地、高性能地实现她们了。

DARPA 与 BBN 达成协议让 BBN 公司的一组人为 BSD 开发 TCP/IP 协议栈

然后 BBN 把 TCP/IP 协议栈实现以后准备将 Vinton Cerf 和 Bob Kahn 设计的 TCP/IP 协议添加到 Berkeley UNIX 中

Joy 被委派来完成这项任务

不久 Bill Joy 和 Sam Leffler 开始整合 BBN 的 TCP/IP

但是 Bill Joy 对 BBN 程序的执行效率相当的不满意!拒绝将 BBN 的 TCP/IP 协议栈添加到 BSD 内核中!因为在 Joy 的眼中 BBN 的 TCP/IP 实现还远不够好……

少年怒了:“ BBN 写的 TCP/IP 性能太差了!还不如我自己写一个!”……

Bill Joy 说到做到,很快就手写了一个高性能的版本,集成进了BSD

写完 TCP/IP 协议栈还加入了一些网络工具:

rcp

rsh

rlogin

rwho

这群指令因为安全机制上的理由逐渐被另一群新的指令群所取代:

SSH /Secure Shell

这便是

4.1 a BSD

这个版本没有正式发布 仅在 1982 年 4 月开始供内部使用

John Gage 回忆:

BBN 和 DARPA 签署了巨额合同来实现 TCP/IP 协议

然而她们的员工所编写的代码还远没有一个研究生所做的好

于是她们邀请 Joy 参加他们的一个会议

这位研究生直接穿着一件 T-Shirt 就出现了!

她们询问道:“你是如何做到的呢?” ,然后 Joy 回答说:“非常简单,你读一下协议然后就可以编码了。”……

好家伙,原来写一个 TCP/IP 竟然简单,抱着一本协议书,然后编程就行了……一个人打败了一个公司,这让 BBN 非常难堪……

威廉·纳尔逊·乔伊/William Nelson Joy

##################################################

通过 ed/ex 来理解编辑器本质

——————————

关于 ed 编辑器

忽然发现 FreeBSD 13 竟然还保留着 ed 这种旧的工具:

ed 工具

我们都知道 1976 年左右伯克利大学的毕业生 Bill Joy 一开始开发了 ex

然后开发了 vi 作为 ex 的 visual interface/视觉界面

vi 允许一次能看到一屏的文本而非一行 vi 也因此得名

而在当今的 UNIX 系统上,可能没有缺省安装 Emacs 但是肯定会有 vi 所以 edex 编、辑器也必定存在!

我们得以体验上世纪年代的编辑器:

ex 工具

ex 是 ed 的扩展,实际上 vi 构建在 ex 之上

vi 引入了大家所熟悉的全屏编辑模式

随着硬件的发展 UNIX 上许多全屏模式编辑器被开发出来:

pico

nano

joe

jed

jove

但是最为广泛使用的无疑就是 VI :

nvi

elvis

vim

和 Emacs :

GNU Emacs

XEmacs

等等

ed 是功能最简单的文本编辑程序 一次仅能编辑一行而非全屏幕方式的操作。

ed 命令并不是一个常用的命令,一般使用比较多的是 vi 指令

但 ed 文本编辑器对于编辑大文件或对于在 shell 脚本程序中进行文本编辑很有用

如果使用文件名参数调用 ed 则文件的副本将被读入编辑器的缓冲区

然后对该副本进行更改,而不是直接对文件本身进行更改

退出 ed 后,任何未使用 w 命令显式保存的更改都将丢失!

编辑有两种不同的模式:

命令模式 command mode

输入模式 input mode

第一次调用时 ed 处于命令模式

在这种模式下,命令从标准输入中读取并执行以操作编辑器缓冲区的内容。

我真是抽风了想学 ed 想体验一下上世纪编辑

没想到……卧槽我怎么感觉 ed 比 vi 更让我喜欢……………………………………果然我是个念旧的人儿啊……

学完之后感觉在什么紧急状态下都能存活!

——————————

初识 ed

ed 竟然不支持新建文件:

参数不能为不存在的文件

使用 touch 新建一个文件后用 ed 打开:

提示读取了 0 个字节

使用 q 退出:

q 命令退出

%%%%%

使用 ed 打开一个有内容的文件:

    用法示例:
ed    进入内存缓冲区编辑
ed 文件名    将指定文件读取进入缓冲区并编辑
q    退出 ed 编辑器

ed 文件

可以看到读取了 194 个字节

然后便看到 ed 编辑器在空白行等待用户输入。

为什么呢?这样可太不方便了!

除了没有提示符 ed 还不允许你编辑开放缓冲区中那些被其她行围绕的行

更不允许移动光标!

还记得吗 我们说了之前的程序员用的都是电传打印机!那更久之前呢?纯打印机!

这些都是因为 ed 在每次修改的时候都必须重新打印整个文件!!!

在 1969 年 ed 没有任何机制来清除屏幕上的内容,因为压根就没有屏幕!屏幕就是一张纸……

所以现在的 ed 就假装所有已经输出的东西都像是已经用墨水打印出来了。。

%%%%%

我们可以使用 l 命令来打印最后一行 注意不是 1/一 也不是 I/i 而是 L/l

或者使用 l 来打印指定行 以 $ 作为结束符号:

l 打印行

经过实验 发现默认打印最后行 如果想打印指定行 需要在 l 命令之前输入行数 可以使用空格分隔:

打印输出指定行内容

然后发现 l 命令竟然还能做加减法打印 好在不支持减法打印:

    示例用法:
l    打印末行
1l    打印第 1 行
7 l    打印第 7 行
1 7 l    打印第 8 行 即 1+7
9-2 l    打印第 7 行 即 9-2

加减法打印

虽然神奇的能打印出一系列的行,但是大多数时候,你都是在你看不到的文本上操作

因此使用 ed 就是将整个文件读取进内存 然后你每次都只能看到那么一点儿

所以必须尽最大努力去记住每件东西的位置!

好在 ed 还支持打印范围行:

    打印范围行用法:
N_1,N_2 l
N_1,N_2l

打印范围行

%%%%%

创建编辑新文件

创建编辑新文件但没有保存
lilian@FreeBSD:~/test_txt $ ed 6.txt    /* 使用 ed 创建编辑 6.txt */
6.txt: No such file or directory    /* 告诉我们 没有这样的文件或目录  */
a    /* a 表示 append 进入 编辑模式 */
Hello,FreeBSD!
Over.
.    /* 输入完内容后使用 . 退出编辑模式 回到命令模式 */
1p    /* p 命令表示 print 显示指定行 */
Hello,FreeBSD!    /* 可以看到 p 输出没有 $ 结束符号 */
2p    /* print 第二行 */
Over.
1l    /* 使用 l 打印 */
Hello,FreeBSD!$    /* $ 结束符号 */
2l
Over.$
q    /* 注意此时我们仍然在内存中 */
?    /* 因为不是命令模式所以这个命令认不出来,, */
quit
?    /* 现在我们知道 ? 表示没有保存或者命令不认识 */
exit
?    /* 必须使用 w 保存输入的内容 这里我们不保存试试看 */
lilian@FreeBSD:~/test_txt $ /* 我刚刚按下 Ctrl d 退出 */

结果发现并没有创建保存文件:

没有保存

这次我们编辑后使用 w 命令保存文件:

w        /* w 表示 write 写入文件 也就是保存的意思 */

141        /* 命令写入字节数 */

使用 cat 命令查看文件内容发现成功保存创建:

w 保存成功

%%%%%

修改操作

编辑 6.txt 文件 先使用 p 查看内容:

p

使用 c 命令表示 change 从第 1 行开始修改

如果只用修改一行 输入完内容后直接输入点结返回命令模式

不结束继续输入就是继续往后输入 后面的行都会按序往后排

然后查看第一行 然后查看第二行 然后 w 写入

一共写入了 158 个字节:

change

查看编辑前是这样子:

编辑前

编辑后的内容:

编辑后

可以看到我们从第一行开始编辑 新插入了一行也没关系 没有影响后面的内容

%%%%%

读取文件

使用 ed 进入缓冲区后 使用 r 命令表示 read 将指定文件读取进缓冲区来:

read 命令
lilian@FreeBSD:~/test_txt $ ed    /* 进入 ed */
1p    /* 打印第一行 */
?    /* 表示没有内容可供打印 */
r 6.txt    /* 将 6.txt 这个文件 read 进来! */
1p    /* 再次打印第一行 */
12121212++++++++    /* 输出成功 */
q
lilian@FreeBSD:~/test_txt $ 

%%%%%

保存文件

在 w 后面输入文件名就可以将缓冲区内的内容保存到指定文件

这边我们进入 ed 缓冲区后使用 a 命令进入输入模式 随便敲打一番

点返回命令模式 保存内存中的内容到 7.txt 文件

使用 ls 列出目录文件 使用 cat 查看文件内容:

保存文件

%%%%%

追加与插入

    参数解释:
i    插入 将内容插入到目标行的上一行
a    追加 将内容追加到目标行的下一行

我们之前用的一直都是 a 命令 这边就不介绍了 单独测试一下 i 命令

例如 在第 2 行插入内容:

2i

从第二行插入后编辑三行:

2i

这边我们单独输入 w :

w

因为是 read 的 7.txt 所以默认保存到 7.txt 文件:

cat 7.txt

%%%%%

删除行

使用 ed 编辑器编辑 7.txt

1,$        表示查看文件所有内容 从第一行到最后一行

1,$

使用 d 命令删除第 3 行 对比一下发现成功删除:

单行删除

删除前三行 就是从第一行到第三行:

多行删除

新编辑了 8.txt 文件:

8.txt

使用正则表达式全局匹配删除所有空行:

^$        表示空行

    命令
g/^$/d表示用前缀
g全局搜索 这个正则表达式
/^$/并执行删除命令
d

g/^$/d 删除空行

%%%%%

使用正则表达式规则匹配行

输出所有包含 XXX 的行:

g/XXX/命令

下面输出所有包含 4 的行:

搜索匹配后打印行

因为该功能实在太常用了,所以还特地开发了一个 grep 命令 是个类 UNIX 都会存在 grep

但是很多人都不知道 grep 怎么来的!!甚至很多人总是记错 以后你不可能记错了!

将每一行中首个 4 替换成 A :

匹配替换

将每一行中所有出现的 4 替换成 ^ :

全局匹配替换

将每一行中所有出现的 4 替换成 /空/ 也就是变相的删除:

批量匹配删除

匹配到行之后除了使用 s 替换命令还可以使用 a 或者 i 之类的命令对定位的行进行处理

——————————

ed 总结

好了 看到这里我们应该会用 ed 了

以后系统到了最恶劣的环境我们也能进行文字编辑了!

ed 与 vi 最大的区别除了是行编辑以外 ed 仅仅分为命令模式与编辑模式

如果是创建新文件的话,进入程序后除了光标什么都不会显示
        如果是打开已有文件,那么会显示一行文件大小的字节数 然后光标到下一行等待用户输入

启动 ed 后默认进入命令模式,等待用户输入一条条命令 ed 通过执行这些命令,最终达到编辑文件的目的!

使用 a、c、i 等命令进入行编辑

ed 是基于行的文本编辑器,也就是说同时只能显示或编辑文件的某一行

既然是基于行的编辑器,那么 ed 有一个

当前行

的概念,可以使用 n 查看 会打印出当前所在 行号&行内容:

n 查看当前行

默认打开文件后自动跳转至文件末尾 也就是最后一行

在命令模式下输入编辑器不认识的命令,会回显一个问号

?

表示输入错误

当然 ed 最大的就缺点是没有办法修改回车符以前的输错的文字

如果想修改,必须退出当前的输入模式再尝试修改。

如果想退出输入模式,在新行输入点即可!

使用 Mac 系统的同学可以试试在终端里执行 ed

%%%%%

格式

ed 命令的格式是

寻址 命令

%%%%%

寻址

ed 提供了三种寻址方式:

行号

从 1 开始的整数

$ 表示最后一行

范围

范围是由两个地址组成的寻址范围

例如 开始行号,结束行号 或 正则表达式,正则表达式

匹配

选中与正则表达式匹配的行

默认从当前行开始选中第一个匹配的行 如 /XXX/

添加前缀 g 则做全局匹配 如 g/XXX/

%%%%%

ed 常用命令

r    读取文件
n    输出行号与行内容
l    展示行
p    打印行
d    删除行
c    进入编辑模式修改行
i    进入编辑模式插入行
a    进入编辑模式追加行
.    从编辑模式返回命令模式
w    写入保存
q    从命令模式退出 ed
wq    保存退出

%%%%%

定位行 这里我并没有全部测试:

.        当前行
$        文本最后一行
N        文本第 N 行 为数字 允许是 0
-N        从文本当前行数起向前第 N 行
+N        从文本当前行数起向后第 N 行
-        相当于 -1 行地址
+        相当于 +1 行地址
N_1,N_2        表示范围行
,        文本的所有行
;        文本当前行到最后一行
/XXX/        从文本当前行数起下一个匹配 XXX 的行
?XXX?        从文本当前行数起上一个匹配 XXX 的行

%%%%%

其她命令 同样没有全部测试:

u    撤销上一条命令 当前地址也将被设为上一次地址
e    编辑文件
e 文件名    编辑文件并设定文件名
e !cmd      先将 ed 缓冲区清除 替换 cmd 命令的输出
E    强制编辑文件
Q    强制退出 若所作的修改没保存不会警告
h    打印最后一个错误说明
H    开启或关闭错误说明 默认是关闭报错了不输出说明仅仅输出一个问号
2t0    复制第 2 行文本到第 0 行 即第 1 行前
2,4m5    将第 2 到 4 行文本内容移到第 5 行后
r file    把指定文件内容追加到指定行后
r !cal     将 shell 命令 cal 的输出添加到当前行后
r !cmd    把命令的输出追加到指定行后

——————————

编辑器本质

可以看到 ed 编辑器与现代编辑器很不同 ed 其实是一 个编辑命令解释器
        但 ed 编辑器又与现代编辑器很相同 所有编辑器的本质都是在不断执行

寻址 命令

不同类型编辑器之间的差异只是编辑的对象不同:

ed        文本行编辑器 编辑的对象是文本行
Microsoft Word        文档编辑器 编辑的对象是 章节、段落、词句 等文档元素
Sketch        图形编辑器 编辑的对象是点、线、面等图形元素
IntelliJ        IDEA 包含 Java 代码编辑器 编辑的对象是类、方法、语句等 Java 语义元素
jQuery        DOM 编辑器 编辑的对象是 DOM 元素 先用 CSS Selector 寻址 选中要处理的 DOM 元素 再用连缀表达式执行一系列编辑动作

由此可见 编辑器思维无处不在 只要符合

寻址+命令

模式都可称作编辑器 因此万物皆可编辑!

编辑器思维或编辑的本质 用开发者更熟悉的话术来讲就是 CRUD

CRUD

若以后有人质疑开发同学只是在做简单的增删改查,请勇敢地告诉她们:

其实我是在做一个垂直领域的编辑器!

若意识到自己在做的其实是一个编辑器 就能利用编辑器思维快速发现系统能力的短板!

以商品管理系统为例,若商品管理只提供通过 ID 查询商品的功能,就犹如 ed 编辑器只支持用行号来寻址一样……

使用就非常不方便,可以借鉴 ed 通过正则表达式的模式匹配寻址能力

提供通过商品名称等信息来匹配商品、甚至通过商品照片来匹配相似商品的能力

类似的,创建商品能力也可以借鉴编辑器复制粘贴的能力

提供用相似商品快速新建商品的能力,甚至还可以提供从其他平台搬家的能力。

——————————

摸索 ex

ex 是 UNIX 下的一个文本编辑器 vi 就是 ex 的 visual mode/视觉模式

vi 中的 w、q 等命令都是来源于 ex

ex 命令远不止这些,实际上 vi 末行模式中所有以冒号开头的命令 都属于 ex 命令

ex 的命令都是基于行的
        例如早期的 显示器 或者你的 小型计算器 除了行列什么都没有了……

ex 命令用于在 Ex 模式下启动 vi/vim 文本编辑器

进入 ex 模式查看版本信息和帮助:

version-help

%%%%%

进入 ex  模式折腾折腾

查看当前目录的文件:

ls

使用 ex 打开 8.txt :

ex 8.txt

然后我们便进入了类似 vi 单独的末行模式

显示第 3 与 显示最后一行:

只需要输入行号即可

输入 1,3 查看 1 到 3 行:

1,3 范围行显示

查看文件全部行:

1,$ 范围行显示

将第 7 行的 3 替换成 * 这里 s 是 substitute 的缩写

7/s/3/*

将文件中所有的 3 替换成 ^ 符号:

1,$ s/3/^

试着输入 visual 或者 vi 是不是回到了熟悉的 vi 界面?

visual

vi

回到 vi

想要继续使用 ex 就输入冒号 是不是 vi 的末行模式:

ex - vi 末行

为什么我们有了 vi 还要使用 ex ?因为对于大段文本的操作 ex 命令比 vi 末行模式更方便

删除 3~6 行:

3,6 d

不保存退出:

vi 末行退出命令

将 3~6 行放到第 8 行后面 也就是移动到第 8 行后面:

3,6m8

而在 vi 命令下你需要:

3G        /* 定位到第 3 行 */
3dd        /* 从该行剪切后面 3 行 */
8G        /* 定位到第 8 行 */
pp        /* 粘贴过来! */

ex 的优势就体现在这里!

将修改过后的文件保存为当前目录下的 9.txt 文件后退出:

一次处理多个命令

在ex中我们可以用

|

来批处理多条命令
        例如删除 3-6 行后 打印所有包含 3 的行:

6,9 d | g/3/nu

可以看到结果是

当前行

第 3 行

第 5 行

g 的意思是 global/全文 的意思

nu 是 number/行号 的意思

关于定位行号:

.    点表示当前行
$    最后一行
%    每一行
N    直接输入行号即可寻址定位指定行 默认操作是 打印
N_1,N_2    行范围
/XXX/    满足 XXX 的第一行

你可以组合这些使用 例如:

3,$d        从第 3 行删除到最后一行
%d        删掉每一行

.,.+3d        删除当前行及后面 3 行

/3/d        删除包含 3 的第一行

g/3/d        删除包含 3 的每一行

/XXX_1/,/XXX_2/d        删除从 XXX_1 到 XXX_2 的行

在 vi 使中用

/

进行搜索,是不是觉得每次使用

n/N

来查找下一个太慢了?试试 ex 的模式匹配吧 这些正则表达式真的很棒!

%%%%%

保存和退出文件命令集锦

ZZ    懒人必备啊有木有!
q    ex 命令 退出文件 如果有未保存的修改则无法退出
q!    ex 命令 强制退出
x    ex 命令 保存和退出文件
w    ex 命令 写入 即保存文件
w!    ex 命令 强制保存
w 文件名    将文件另存为新文件名
N_1,N_2w 文件    将 N_1 到 N_2 行内容另存为文件指定文件!
N_1,N_2w >> 文件    将 N_1 到 N_2 行追加到 文件 中的内容后面!!
r 文件    将 指定文件 的内容追到到 当前文件 光标所在行后!!!
N_1r /目录_1/目录_2/文件_1    将 /目录_1/目录_2/文件_1 文件的内容追到到当前文件第 N_1 行后!!!!

后面四个简直是编辑神器!

%%%%%

在 vi 使用 ex 命令进行多文件编辑来更清楚地理解公用缓冲区

vi 支持多文件处理 同时处理多文件不仅节省你多次打开和退出 vi 的时间 也可以让你反复利用 vi 的缓存区!

首先打开多个文件:

vi 文件_1 文件_2

看到末行提示 打开了两个文件:

3.txt: 2 files to edit: unmodifred: line 1
3.txt:2 个要编辑的文件:尚未编辑 :1 行

3.txt: 2 files to edit: unmodifred: line 1

使用 n 命令切换到下一个文件:

n

n 成功

args 显示编辑的文件列表:

args

看到有两个文件 而我们正在编辑第二个文件 9.txt :

args 成功

还可以使用 rew 或者 rewind 命令跳到第一个文件:

rew

切换编辑文件成功:

成功跳转

还能使用 N 命令上下分屏:

N

跟 vs 左右分屏一个原理:

上下分屏

也是使用 Ctrl w 切屏:

Ctrl w 切屏

在 3.txt 文件显示行号:

set nu

成功看到行号:

set nu ok

使用 ex 命令复制 2~4 行:

2,4 y

Ctrl w 切换到 9.txt 文件:

切屏

直接按下 p 粘贴到第一行后面:

粘贴

将修改过后的文件保存为当前目录下的 10.txt 文件:

w 10.txt

提示我们创建好了

10.txt: new files : 10 lines, 43 charecters.

10.txt: 新文件:10 行, 43 个字符。

创建成功

强制退出 9.txt 文件:

q!

自动返回 3.txt 文件:

3.txt

打开刚刚新保存的 10.txt 文件 使用上下分屏方式编辑:

N 10.txt

成功:

成功

记住 缓存区是公用的,你可以将第一个文件中选择的内容,通过缓存区拷贝到其她文件中。

%%%%%

set 设置

set 命令可以对 vi 编辑器进行一些设置

使用 set 命令需要进入命令模式

set ic    搜索时忽略大小写
set ai    设置 自动缩进/自动对齐
set noai    取消 自动缩进/自动对齐
set nu    显示行号
set sw    设置缩进的空格数 例如将缩进空格数设置为 8 则 :set sw=8
set wm    设置自动换行 例如设置距离边际 2 个字符时换行则 :set wm=2
set ro    将文件类型改为只读
set term    输出终端类型
set bf    忽略输入的控制字符,如 BEL/响铃、BS/退格、CR/回车 等等

%%%%%

运行 Shell 命令

如何运行 Shell 命令

很简单 命令前面加个感叹号即可

例如,保存文件前,如果希望查看该文件是否存在,那么输入

:! ls

即可列出当前目录下的文件:

:! ls

Press any key to continue [ : to enter more ex command]:

按任意键继续 [: 输入更多 ex 命令]:

如果没有想运行的命令 直接回车就行了

——————————

ex 总结

一路用下来 感觉还真缺不了 ed、ex 这些老程序

ed 族谱

我们可以从 ed 的族谱看出后续的衍生程序都是选择并增量了 ed 的部分能力

比如:

ex-vi-vim        这条分支选择了交互式路线
grep-fgrep-egrep        这条分支选择了模式匹配路线
sed-awk        这条分支选择了脚本化路线

没错 ed 还支持脚本化编辑,就是将输入到终端的编辑命令保存成一个脚本文件

供后续反复运行 好处是可以用相同的编辑命令批量编辑任意多个文件!

——————————

VI/VIM 与 Emacs 的编辑器圣战

我是 vi 的重度用户

使用  Debian 时无论是写 C 代码还是 Java 代码都是在 vi 里一把梭

好处是闭卷笔试时可以直接默写,而用 Eclipse 的同学基本是记不住 JDK API 的全名……

在 vi 底下工作久了后再用 Windows 的 Notepad/记事本 会发现自己经常无意识地按一下 ESC 键切换模式。。。你就能知道为什么说 vi 这种多模式的设计非常反人类—— vi 启动时默认进入的不是编辑模式,当新手用户什么都还没学会时没办法把 vi 当成普通的记事本来用。

如果你希望,当什么都没学会的时候,可以当成最普通的记事本来用,而当需要高级功能时,再通过快捷键等方式呼唤出来,那推荐你去 Emacs 阵营,她们的 Emacs 编辑器恰好符合这个要求。

vi 会强迫用户从一开始就按照她的规则来做事情 而 Emacs 则相对不需要过多前置知识

网络上曾流传过一张编辑器的学习曲线,还蛮贴切的:

编辑器学习曲线图

vi/vim 的前身 ed 源自 UNIX 系统而 Emacs 的前身 TECO 源自 UNIX 系统的前身 没错就是那个遗憾的 Multics 系统:

TECO
Emacs
GUN Emacs
XEmacs

上世纪 70 年代 GNU 的创始人 Richard Stallman 在 MIT 的 AI 实验室打工时发明了 TECO 编辑器
        这个编辑器运行运行在 PDP-10 机器上 与 ed 类似 TECO 也是命令解释器 接收并执行编辑命令 并且也采用单个字符作为命令名称
        比如

l        移动一行

5l        移动 5 行

MIT 那群大佬们想用 TECO 命令完成一些复杂的编辑工作

于是加入了分支判断、循环等功能 但由于先天不足

TECO 最开始设计的时候没有把命令设计成一套完备的编程语言 导致后续改进也很困难
        比如命令名称只能是单个字符,很快字符就不够用了。。。

所谓基础不牢地动山摇,大伙儿都认为需要用一套严谨完备的编程语言替代 TECO 的半成品脚本语言。
        于是有一位叫 Bernie 的教授在 Multics 系统上用 MacLisp 重写了 TECO 并命名为 Emacs
        还为她写了详细的手册教大家如何扩展这个编辑器来满足自己的工作需要

结果这个版本的 Emacs 取得巨大成功
        连 Bernie 的秘书 一个号称自己不懂编程的人 都在照着手册有模有样地写 Lisp 代码来扩展编辑器功能
        这件事儿在实验室引起轰动后 Bernie 为此做了一个总结:

如果有一个应用 一个能帮你做点有用事情的程序

内嵌了 Lisp 并且能通过 Lisp 程序扩充她的功能

对于学习编程而言 这是一种非常不错的入门方式!

那些自认为不会编程的人,这种方式会给她们编写小但有用的程序的机会

让她们在实践中不断成长,直到她们发现自己就是在编程。

Stallman 觉得这个想法简直屌炸天!
        同时她们想把这个好用的 Emacs 版本迁移到 Multics 系统之外的其她系统

但当时只有 Multics 系统上有完备的 Lisp 环境 既有编译器又有解释器

诸如 UNIX 等系统上都没有

这里还有一个小插曲 Java 之父 James Gosling 当年还写了一个能跨平台的 Emacs 版本 叫 Gosmacs

本来社区想来一起完善这个版本,结果 Gosling 把她卖给了一家商业公司

同时她底层的 Lisp 不是一个真实完备的 Lisp 而是一个叫 Mocklisp 的假 Lisp 只是语法上和 Lisp 长得像而已

所以社区最终放弃了这个选项,决定从头开始做一个全新的 Emacs

这也就是 GNU Emacs

Stallman 先用 C 语言开发一个跨平台的 Lisp 解释器 Emacs Lisp 再用 Lisp 实现编辑逻辑
        这样既能在所有平台上用统一的 Lisp 方言来写 Emacs 扩展又能兼顾性能!

GNU Emacs 有一段时间发展比较落后,因为 Stallman 自己一个人忙不过来
        所以社区又创建了一个分支叫 XEmacs 增强了字体抗锯齿等功能。
        后来 GNU Emacs 的维护又变得积极了,把很多 XEmacs 的特性合并回 GNU Emacs
        所以现在 XEmacs 差不多是废弃状态 主流版本还是 GNU Emacs

Emacs 允许用户先把 Emacs 改造成目标对象的个性化编辑器 能认识 目标模型 比如 段落、章节、目录 等

用一句时髦的话讲就是 Emacs 有行业 Know-How

用 Emacs 写 Java 代码,你编辑的是 类、方法、语句……

你用 Emacs 写一篇博客,你编辑的是 段落、句子……

你用 Emacs 写一篇论文,你编辑的是 目录、章节、正文、索引……

vi 从 ed 继承了行编辑器的特性,底层模型是基于 行 的

所以会强行要求所有被编辑的对象适配成她的底层模型

我们 vi 人狠话不多

你用 vi 写 Java 代码,你编辑的是文本行

你用 vi 写一篇博客,你编辑的是文本行

你用 vi 写一篇论文,你编辑的还是文本行

无论你编辑的是 类、函数、段落、目录 还是 任何其她内容

都要先在脑海中翻译成对应的 dd、yy 等面向行的编辑命令

造成这种差异的原因是背后两种不同的设计方法:

自底向上/Bottom Up

自顶向下/Top Down

这两种设计方法的差异并不意味着只是换个顺序写代码,而是系统抽象过程的差异,最终体现在系统扩展性的差异上

硬编码        系统运行时,数据和行为都已写死,不能变化
可配置        系统运行时,数据可动态变化,但行为固定不变
可控制        系统运行时,数据可动态变化,并且由多种预定义的行为可供动态选择
可编程        系统运行时,数据可动态变化,同时行为可在运行过程中动态新增,即用户可重新系统行为

用 Emacs 编辑属于 自底向上 方法

先完善底层 Emacs Lisp 语言

逐步抽象出面向业务的领域特定语言

最终用 DSL 完成编辑任务

例如要编辑 Markdown 文档

就会提供诸如

移动到下一个段落

下一个列表项、表格

下一个单元

等面向 Markdown 领域的特定编辑操作

自底向上的极端是可编程,容易过渡设计,为未来不可能变化的场景提供灵活性,甚至会变成一门通用的编程语言

用 vi 编辑属于自顶向下方法

将编辑任务持续拆分最终拆解到面向行的编辑命令

就像 Java 日常开发,会逐级拆分,最终拆解到 JDK 的 API

自顶向下的极端是硬编码,会过早地把功能限制在当前的需求里,后来的需求只能尽量逼近初始模型

两种设计方法没有绝对的对错,都有各自适用的场景

单一地采用任何一种方法都会有问题,需要根据实际情况在快速实现和系统扩展性之间做权衡。

也正因为没有对错之分,所以编辑器的圣战永远也打不完。

##################################################

结束语

——————————

终于结束了,这几天过的比较匆忙

只需要这一篇三万字的文件就能彻底掌握 ed/ex/vi/BSD/vim 以及她们之间的关系!

——————————

最后的结论是:

如果你能写一个文本编辑器出来那么你就能写一个操作系统!

从 VI 编辑器谈操作系统起源及编辑器本质相关推荐

  1. Linux_linux常用工具---闲杂篇(除了vim, 还有哪些常用的牛逼的编辑器, 并能够横向对比编辑器之间的区别和优缺点.)

    vim自行查找资料, 自行配置插件. 借鉴别人的 " 显示相关 """"""""""&qu ...

  2. python代码编辑器排行榜-写 Python 哪个编辑器 / IDE 最好用?

    不请自来嘻嘻,简单介绍一下几款好用的编写器,希望对你有帮助- 1.IDLE IDLE是开发 python 程序的基本IDE(集成开发环境),具备基本的IDE的功能,是非商业Python开发的不错的选择 ...

  3. R语言使用edit函数在Rsudio中生成数据编辑器(在windows中生成编辑器)、在编辑器中输出需要的数据生成最终的dataframe

    R语言使用edit函数在Rsudio中生成数据编辑器(在windows中生成编辑器).在编辑器中输出需要的数据生成最终的dataframe 目录

  4. js json编辑器_程序员必备编辑器 —— Visual Studio Code

    前言 我刚入行Web前端的时候,我先后使用过Notepad++.Sublime Text. Hbuilder IDE.Webstorm进行Web前端开发,偶然的机会了解到Atom.Visual Stu ...

  5. N个富文本编辑器/基于Web的HTML编辑器

    转自:http://www.cnblogs.com/lingyuan/archive/2010/11/15/1877447.html 基于WEB的HTML 编辑器,WYSIWYG所见即所得的编辑器,或 ...

  6. 浅谈操作系统是如何工作的及简单的进程调度的linux实现

    浅谈操作系统是如何工作的及简单的进程调度的linux实现 1)进程的启动和切换机制 a)进程的启动机制 保存ebp的值到栈, 将esp的值保存在prev->thread.sp,在下一步esp的值 ...

  7. 谈操作系统(linux内核)学习的重要性

    .   内核学习概述 1.1 再谈操作系统(linux内核)学习的重要性 现阶段国内大学的计算机教学情况不容乐观,教材过时或者实用性不够成为我们大学生学业就业或者研究生进行项目研究实践的难题,当前大学 ...

  8. 135微信编辑器html模式,135微信编辑器如何使用 135微信编辑器使用方法教程

    135编辑器是一款在线图文排版工具,打破传统排版方式,通过[秒刷]功能,选中内容(图片.文字),应用样式,快速排版.一些小伙伴想知道135微信编辑器如何使用,下面就让小编为大家介绍一下135微信编辑器 ...

  9. 135编辑器html点击图片播放音乐,135微信编辑器怎样添加音乐 135编辑器添加音乐图文教程...

    软件安装:装机软件必备包 关于电脑装机必须的软件,比如windows office系列办公软件.网页浏览器.杀毒软件.安全防护软件.刻录软件.压缩软件.下载工具.多媒体播放软件.多媒体编辑软件.输入法 ...

  10. 织梦html编辑器,织梦dedecms自带文本编辑器ckeditor更换为kindeditor编辑器带代

    织梦dedecms自带文本编辑器ckeditor更换为kindeditor编辑器带代 日期:2018-12-05 08:31 您的打赏帮助我们变得更好,谢谢支持! 在kindeditor基础上添加了如 ...

最新文章

  1. PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
  2. 考虑用静态工厂方法替代构造器
  3. 聚类算法 距离矩阵_快速且不需要超参的无监督聚类方法
  4. 白鹭本地数据存储操作代码实例
  5. 2021年宣城市高考成绩查询,宣城高考成绩查询入口
  6. oracle创建dblink语句_多个Oracle数据库联合做统计分析
  7. 同样当程序员,产值是比别人多出5倍以上,拿的工资是别人的2/3左右,你是领导你会怎么样妥善处理?...
  8. websocket php apache,PHP第一篇:PHP WebSocket实现前后端数据交互,亲测可用(windows+ apache2.4 +php5.6 )...
  9. Raki的读paper小记:Model Zoo: A Growing “Brain” That Learns Continually
  10. 两个转子的转轮机原理详解与算法实现
  11. vue 项目使用Standardjs进行语法错误检测和修复
  12. 对服务器进行DDoS攻击测试
  13. Win10屏保设置位置在哪里可以找到
  14. SAP PS 第2节 项目状态及字段选择
  15. java网课|面向对象的思想
  16. 网站被篡改导致百度快照被劫持跳转到博彩页面的解决办法
  17. ubuntu下执行sudo命令提示:xx is not in the sudoers file. This incident will be reported.
  18. VR全景拍摄结合更多的市场刚需,为云端生活赋能
  19. 使用markdown玩转代码架构设计
  20. 炎炎夏日,教大家正确选用净水器的8个要点!

热门文章

  1. 短信接口哪家好 凌凯短信接口
  2. 计算机安装pdf打印机驱动,Win7安装Microsoft Print to PDF虚拟打印机的方法
  3. Redhat7系统root用户密码破解
  4. C语言结构体实例演示
  5. 机器学习--文本分析(jieba)
  6. 数字证书及CA相关理解
  7. Python库全家福,基本都齐了
  8. 蚂蚁移动开发平台 mPaaS 3.0 智能化 + 生态化 1
  9. (CFD)投影法求解二维不可压缩N-S方程
  10. Java实现批量ping IP地址