终端的输入是否通过 bash 进程路由到当前正在运行的程序中,或者终端是否与 bash 进程“断开连接”并连接到新程序,以防止 bash 拦截或干扰?
bash 只是在后台冻结,等待您开始关闭的程序,还是正在执行某些操作?
当我关闭终端窗口时,我是否向 bash 发送信号,后者又向前台进程发送信号以关闭它们?或者我是否向前台进程发送了一个信号,该信号向上传播到 bash?
终端的输入是否通过 bash 进程路由到当前正在运行的程序,或者终端是否与 bash 进程“断开”并连接到新程序,以防止 bash 拦截或干扰?
两者都不。假设一个没有管道或重定向的简单前台命令...来自用户的输入和返回给用户的输出不会通过 bash 路由。但 bash 并不能阻止干扰,bash 根本就不会尝试干扰。
当程序打开任何文件或终端时,它会收到一个用于读取和写入的文件描述符。 子进程继承父进程的打开文件描述符集的副本。
当您在终端输入内容时,它会通过标准输入传递给进程。当它向用户写入内容时,它会写入 stdout 或 stderr。Stdin、stdout 和 stderr 都是具有可预测 ID 的文件描述符:根据 POSIX 标准,它们分别编号为 0 1 2。因此,当 bash 运行程序时,它首先使用fork创建子进程,并且子进程自动继承相同的 stdin、stdout 和 stderr FD。因此,孩子将自动读取和写入完全相同的终端。
请注意,“运行程序”是通过调用fork然后调用execve来完成的。管道和重定向是通过在 fork 和 execve 之间调用dup2替换 stdin、stdout 和 stderr 来实现的。
所以“程序”可以直接从与 bash 相同的终端读取。这不会阻止 bash 或其他任何东西读取和写入同一终端。如果 bash 确实尝试这样做,可能会造成混乱。多个进程写入会导致所有内容都以不可预测的顺序写入。多个进程读取会导致一些字节(击键)进入一个进程,而另一些则进入另一个进程。
bash 是否只是在后台冻结,等待您开始关闭的程序,还是正在做一些事情?
它有效地冻结。更准确地说,它在等待。据我所知,它显式调用waitpid()
or wait3()
(取决于您运行 shell 的 Unix)等待子进程终止。
当我关闭终端窗口时,我是否向 bash 发送信号,而 bash 又向前台进程发送信号以关闭它们?或者我是否向前台进程发送信号,该信号向上传播到 bash?
抱歉,我无法立即记住这种行为。我相信关闭终端 [窗口] 通常会杀死正在运行的进程,即使它不读取或写入任何内容,所以我不相信它是基于导致 EOF 的终端读取。我相信关闭终端会产生信号。如果找到正确的答案,我会编辑答案。
我确实知道有些孩子可以有效地拦截键盘中断键序列,防止 bash 接收它们。我不确定这是否意味着他们正在拦截信号或只是禁止终端一起生成信号。