该程序是一个最小的文本编辑器,无法通过使用-ed
发送中断来退出,而是打印错误消息“?”到控制台。为什么收到中断后不直接退出呢?当然,没有理由说一个神秘的错误消息在这里比退出更有用。这种行为导致许多新用户进行以下交互:CtrlCed
$ ed hello ? help ? exit ? quit ? ^C ? ^C ? ? ? ^D $ su # rm -f /bin/ed
这种悲惨的浪费是很容易避免的,只要ed
同意被打断即可。
另一个表现出类似行为的顽固程序less
似乎也没有太多理由被忽视C-c
。为什么这些程序不直接接受提示呢?
答案1
答案2
这Unix V7ed(1)
源代码是一个原始的 1,762 行 C 程序,只有几条注释,其中之一就是这个极具启发性的头注释:
/*
* Editor
*/
鉴于源代码本身不提供任何基本原理,您只能从程序的作者那里获取它。
ed
最初写的是作者:Ken Thompson 在 PDP-11 组装中,但它被移植到C丹尼斯·里奇,他为 Unix 创建了 C,然后用它使 Unix 可移植到非 PDP 机器。唉,里奇博士不再回答这些问题了。
我对代码的阅读表明,这样做是为了尝试保留核心内已编辑文档的副本。您会注意到其他文本编辑器也不会在Ctrl-C.
以下是ed
的作用Ctrl-C:
onintr()
{
signal(SIGINT, onintr);
putchr('\n');
lastc = '\n';
error(Q);
}
(是的,凯瑞C。我们不需要返回类型说明符或参数声明。)
翻译成英文ed
:
重新注册信号处理程序。
写出一个新行并记住它是通过全局变量²执行的
lastc
。调用该
error()
函数,其中著名地?
从用户的角度来看,它的作用只不过是 print 。
换句话说,它是在说:“你并不是真的想这么做,是吗?”
脚注:
Unix 没有收到自动重置信号直到 4.3BSD,于 20 世纪 80 年代中期发布。请参阅“与其他系统的比较”下的第一个要点。
ed.c
有大约六十全局变量!
答案3
ed
与其他交互式程序一样,使用Ctrl+C来中断程序本身的任务。
这与正常情况非常相似,正常情况下它会中断在 shell 中运行的任务 - 一个命令。
从用户的角度来看,这两种变体非常相似。信号的处理是不同的:通常情况下,信号SIGINT
被发送到前台进程,一个正在运行的命令,命令通过退出来处理它。
在 的情况下ed
,信号被发送到前台进程,即ed
实例。如果 中有任务正在运行ed
,则会被中断并显示提示。如果没有正在运行的任务,则不会发生任何更改。
请注意 shell 也不会在Ctrl+上退出C,就像 一样ed
。并且它确实在Ctrl+上退出D。再次,就像ed
答案4
ed
需要关心三个信号:
INT
HUP
QUIT
POSIX 规范ed
关于这些说如下:
SIGINT
该
ed
实用程序应中断其当前活动,将字符串写入?\n
标准输出,然后返回命令模式(请参阅扩展描述部分)。
SIGHUP
如果缓冲区不为空并且自上次写入以来已发生更改,则
ed
实用程序应尝试将缓冲区的副本写入文件中。首先,ed.hup
应使用当前目录中命名的文件;如果失败,则应使用环境变量ed.hup
指定的目录中指定的文件。HOME
在任何情况下,ed
实用程序都应退出,而不将文件写入当前记住的路径名,也不返回到命令模式。
SIGQUIT
实用
ed
程序应忽略此事件。
因此,无论您使用什么实现ed
,它都符合 POSIX 关于INT
信号(即Ctrl+C发送的内容)的规范。
在这方面,编辑器的行为就像一个交互式 shell,它也不会在收到信号后终止INT
。其他编辑器,如vi
和 也nano
做同样的事情。