动态重定向输出 - 在 Linux 中看起来不可能,为什么?

动态重定向输出 - 在 Linux 中看起来不可能,为什么?

我尝试过网络搜索,但没有通过动态搜索 Linux 重定向输出找到答案。据我了解,输出说 stdout 通过使用文件描述符 1 工作:

$ ls -l /proc/pid/fd/1
lrwx------ 1 user1 user1 64 Sep 27 13:37 1 -> /dev/pts/1

有一些与proc文件系统一起工作的 Unix 命令,例如ls这里,tee可以写入文件,cat可以读取。为什么对于例如Linux,没有实现用户可以通过ln -sin手动更改这些链接bash? (当我尝试时出现错误"No such file or directory")。实施起来会不会很困难?proc实用程序的程序员是如何决定应该与哪个实用程序一起工作的?

答案1

为什么对于 Linux 等系统,用户可以通过 bash 中的 ln -s 手动更改这些链接?

因为proc文件系统只显示内部内核状态。在某些情况下,您实际上可以通过将内容写入特定文件来影响内核状态,但我想不出可以移动内容的单个示例。

实施起来会不会很困难?

内核是开源的,你可以自己看看并决定(“难”与你的编程经验有关)。

还要考虑如果您正在修改的进程正在向标准输出写入内容,会发生什么情况。还要考虑安全影响。

然而,据我估计,对上游内核进行此类修改的机会可能非常低。

实用程序的程序员是如何决定哪个实用程序应该与 proc 一起使用的?

/proc是一个虚拟文件系统,因此实现了虚拟文件系统所需的内核功能。各种内核程序员在使用时/proc,通常会尝试以最省力的方式进行编程。

答案2

在 Linux 上,标准输入/输出文件描述符是通过内核系统调用创建的,而不是通过/proc文件系统创建的。

您看到的符号链接/proc并不是用于管道数据的实际手段,而是一种反射内核正在做什么来让进程访问数据。这就是为什么你不能用来ln -s改变它们。

对于您关于动态重定向输出的问题,我不知道有哪个命令可以做到这一点。但这当然是可能的。以下是如何开发此类程序的示例:

  1. 首先,从实现 的功能开始cat。因此,采用标准输入并将其转储到标准输出。这将是一个非交互式应用程序。
  2. 接下来,更改程序以使其具有交互性。一个简单的示例是传输少量输入并等待用户按 ENTER 键。然后再转移一点输入,然后重复。在此阶段,程序能够暂停并做出决定,这对于能够动态重定向输出非常重要。
  3. 最后,修改程序,以便能够接受指定输入和输出的命令。它可以是带有 API、NCURSES UI 等的守护进程。

上述内容当然是说起来容易做起来难。我掩盖了很多重要的细节,但我认为这足以表明动态重定向输出至少是可行的。

答案3

您可以创建一个,而不是改变 stdin 等指向的位置伪终端 (PTY)并通过它重定向输入和输出,以便程序不必知道任何事情发生了变化:事实上,有几个程序就是这样做的(通常称为终端多路复用器.)

您可能知道,您可以从一个终端上的会话断开连接,然后使用诸如 之类的复用器在其他地方重新连接到该会话tmux,但您也可以随时让它通过管道传输标准输入或输出。例如,如果我有一个在tmux窗格内运行的 shell 并发送命令pipe-pane 'cat >>~/test.txt'(取自手册页) 到tmux,现在将附加标准输出,~/test.txt而不更改会话窗格内的任何内容。

答案4

这里的核心误解似乎是,在写入符号链接时更改它会以预期的方式改变任何内容。

不会的。一旦打开实际文件(或设备或管道),所有活动都将与打开的文件相关,忽略发生在例如指向它的符号链接上的任何事情。实际上,这不仅限于符号链接,实际上同样适用于使文件具有名称的“硬”链接:在 unixoid 系统中,您实际上可以移动甚至删除(!)文件(而不是:覆盖它! )表明某个进程已打开,并且该进程在关闭该文件之前不会看到任何更改。

相关内容