当我们在Unix Shell中的提示符下键入 vi 时, 我们可以使用Vim编辑器。
现在,壳牌公司要求另一个流程。
AFAIk我在书中读到一个进程无法修改另一个进程。 那么Linux中的Shell如何允许我们在终端中打开Vim?
我很困惑,如果shell实际上是否正在访问Vim的地址空间。
答案 0 :(得分:0)
shell只是将Vim的终端文件描述符连接到它自己的终端文件描述符,传递数据。
您可能听说过“标准输入”,“标准输出”等文件描述符。当使用终端仿真器(如XTerm或你使用的任何东西)时,它提供在其中运行的shell,它接收一个键击流,并解释shell发送给终端的数据(颜色等)并显示它们
当你启动Vim时,shell会启动它的进程并为该进程提供一个输入和输出流。输入流与shell接收的相同,即终端上键入的所有内容都由shell接收,然后shell将其发送给Vim。 Vim发送到其输出流的所有内容都由shell接收,然后发送到终端。
基本上,双向数据流如下所示:
terminal emulator <====> shell <====> vim
答案 1 :(得分:0)
Unix中只有一种方法可以启动用户进程 - fork(2)
系统调用。它创建了调用进程的精确副本,不同之处在于调用的返回值 - 父进程/调用者中新进程的进程id(pid
),子进程为零。操作系统通过父进程ID 属性维护此父子关系(例如,参见ps -f
的输出)。
幕后发生的事情是操作系统内核重复调用者的整个虚拟内存空间(此处有更多详细信息,google用于写入时复制页面映射和{{1} })。除非通过共享内存机制(如mmap(2)
进行专门设置,否则无法从一个地址空间直接访问另一个地址空间。父进程可以wait(2)
让其子进程终止。
我不打算进入process groups,sessions并控制终端。这需要一幅好照片。请查看APUE book进行详尽解释。
execve(2)
系统调用将当前进程映像替换为文件中的某个可执行文件。
现在,shell已将vfork
,stdin
和stdout
连接到terminal emulator,从控制台上的login(1)
进程继承,或动态分配通过网络守护程序(如stderr
)或窗口管理器(X)。当你在shell中键入sshd
时,它vi
然后fork
s exec
程序,然后/bin/vi
为它。新进程继承了打开的文件描述符,并且能够通过ioctl(2)
通过它们操作终端伪设备。
当您输入类似wait
的内容时,实际上是以管道开始的 - 这是留给读者的练习:)
我在这里略过了许多有趣的细节,但希望这可以作为一个简短的介绍。