如何正确启动程序并能够在稍后阶段重定向其运行输出(stdout 和 stderr)?

如何正确启动程序并能够在稍后阶段重定向其运行输出(stdout 和 stderr)?

问题很简单:我发现有可能很有用打开(和关闭)我需要的每个时刻某个正在运行的程序的输出。更准确地说,我希望能够自由地将它们的标准输出(和错误)从当前 shell 重定向到另一个 shell、重定向/dev/null到文件或返回到原始 shell。

我寻找一些直接(且安全)的东西,利用我所知道的事实提前我将打开和关闭输出。我也发表一个答案。


下面是我的第一次尝试。假设我在 35 号外壳工作。

$ who am I                     # the command line to ask where am I
myuser  pts/35  ...            # The answer 

我的尝试从指向该终端的符号链接开始

ln -s /dev/pts/35  MyOutput  # The command to link

这个想法是启动程序并将重定向设置为该链接

./Execute_program > MyOutput

它有效,它将输出重定向到我的终端,但是当我发出更改链接的命令时,

ln -sf  /dev/null  MyOutput

链接发生变化,但重定向不会改变我多么希望。它不会因正在运行的进程而改变。如果我以相同的方式启动一个新程序,重定向将遵循链接的新规定。
如果我再次开始并将输出链接设置/dev/null为按预期抑制,但当我再次更改链接时,重定向不会更改。
如果我做一个链接到一个链接,我会得到相同的结果。使用hard link不会改变情况。

可悲的是shell 在启动时扩展命令行。

是否有可能以类似的方式完成这项工作,或者我是否可以找到如何与链接已更改的进程(或 PPID 进程)进行通信?


笔记:

这是“如何重定向正在运行的进程的输出?”系列的一个问题,但它并不是从这一点开始的“Ops 我启动了程序,但忘记重定向输出。现在我想这样做”,但从相反的角度来看:“我如何启动一个程序,其明确的目标是在稍后阶段将输​​出重定向到其他地方?”。

当不可能(或不方便)修改程序的源代码时,我打算使用这样的过程。
可以disown处理、使用screen并从一个屏幕传输到另一个屏幕...或者使用调试器来拦截进程...所有这些解决方案都可以通过大量的经验和努力来发挥作用,但其中一些解决方案也呈现一定比例的风险。

答案1

我通过mkfifo创建一个命名管道找到了一个解决方案,或者先进先出
就像创建符号链接一样简单,并且可以使用 shell 允许的所有重定向。

mkfifo MyOutput

ls -l给出

0 prw-r--r-- 1 My_username My_username  0 May 11 17:45 MyOut|

我可以通过重定向到该链接来启动该程序

./Execute_program > MyOutput  &  cat MyOutput 

并且输出开始在终端上流动。

如果我按ctrl+c我会中断流程,但不会中断正在运行的进程(我必须使用类似kill pid或 的东西kill %1来执行此操作)。
当第二次我会问先进先出要在终端上转储(再次使用cat MyOutput),它将开始转储该时刻的输出。

注意和警告:

  • 直到我不会要求FIFOs它的转储将保存所有输出。
    正如我第一次问的那样,它会冲走全部。
  • 我可以重定向(或附加)到另一个文件cat MyOutput >> NewRealFile
  • cat MyOutput我也可以从另一个终端使用!
  • 警告:如果我要求 2 个不同的程序(或实例)将输出重定向到相同的FIFOs通量将被合并(没有先验区分该行来自哪个程序的方法)。
  • 警告:如果我询问两次或多次(可能来自不同的终端),它将为每个请求提供一行,将输出拆分给请求者。也许有一个安全的解决方法......

答案2

如果我正确理解你的问题:

script 1>>~/out.fifo 2>>~/error.fifo 

然后要监视你可以执行以下操作:

watch cat ~/out.fifo

您可以使用真实文件而不是 Fifos

script 1>/tmp/$0-out 2>/tmp/$0-error

然后 tail -f 它们,当您再次运行脚本时它们将被替换。

我更喜欢第二种方法,或者只使用多路复用器(即屏幕或本周流行的转世)

screen -t "name" bash -c 'script'

然后

screen -r

“监视”并按 ctrl+ad 分离。

如果您想在运行后查看输出,请确保在脚本末尾暂停。

答案3

如果我是你,我只是将输出重定向到一个文件,然后当我想查看输出时尾部该文件...如果你认为输出会相当长,你可能想限制该文件的大小,或者如果您认为输出会相当快,则将文件写入内存而不是磁盘上,但如何做这些事情是另一个问题。

相关内容