AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 698112
Accepted
Ashark
Ashark
Asked: 2022-04-06 11:10:35 +0800 CST2022-04-06 11:10:35 +0800 CST 2022-04-06 11:10:35 +0800 CST

如何防止子进程干扰bash提示?

  • 772

有问题的应用程序是 DaVinci Resolve。我从终端启动它。当我关闭它时,来自应用程序的消息“Socket Disconnected”被写入终端输出。然后 bash 提示符正常显示。我开始输入新命令,突然在终端“Socket Disconnected”中出现另一条消息。这会干扰我所做的输入。它看起来像这样:

[andrew@unihost ~]$ davinci-resolve
... # Now I exit the application.
Host 'Fusion' Removed
FusionScript Server [37457] Terminated
Socket disconnected
[andrew@unihost ~]$ ls ls Socket disconnected
wtf!!!^C
[andrew@unihost ~]$

视频演示:https ://youtu.be/arcCOjrN7kw

为什么会发生这种情况,有没有办法防止这种情况发生?

我的猜测是主进程有一个子进程,即使在主进程死后它仍然活着。我找到了这个答案。是开发商的错吗?我可以以某种方式解决这个问题(对于子进程可能是 nohup)?

terminal process
  • 4 4 个回答
  • 209 Views

4 个回答

  • Voted
  1. Best Answer
    Kamil Maciorowski
    2022-04-06T22:56:10+08:002022-04-06T22:56:10+08:00

    初步说明

    我根本没有测试davinci-resolve过。这个答案被设计为通用的。


    分析

    davinci-resolve您的 shell在将自身放回前台并打印提示之前等待退出。davinci-resolve显然,在主进程退出并且外壳做出反应后,主进程的某些子进程(或进一步的后代)会打印出不需要的消息。


    解决方案

    解决方案可能很简单:

    davinci-resolve | cat
    

    诀窍是cat在所有写入管道的进程都关闭它们的管道末端之前不会退出。麻烦的孩子可能从 main 继承了 stdout davinci-resolve,所以cat会等待它。通常,即使不需要的消息被打印到 stderr 或/dev/tty(即它绕过我们的cat),这也会起作用。重要的是孩子保持管道打开,即使它正在打印到其他地方。

    有以下缺点:

    • 整个管道的退出状态将来自于cat,而不是来自于davinci-resolve。在某些 shell 中,您可以对它做一些事情。

    • 来自(及其后代)的 stdout 和 stderrdavinci-resolve将失去同步,因为前者通过cat而后者不通过。

    • 如果你Ctrl+c那么你将杀死cat,可能在其他进程完成打印之前,所以你可能会错过一些你确实想看到的输出。此外,如果麻烦的消息被打印到 stderr,那么无论如何它都会被打印出来,可能是在你看到提示之后。

      但是,您可以对+cat免疫:Ctrlc

      davinci-resolve | sh -c 'trap "" INT; exec cat'
      
    • 麻烦的过程可能会提前关闭或重定向其标准输出,但仍会打印到标准错误。在这种情况下cat不会等待它。

    • 麻烦的进程可能被设计为保留,不需要的消息并不意味着进程退出。如果这个过程仍然存在并保持管道打开,那么我们的cat意志就会存在;你显然不想要这个。似乎不太可能有任何davinci-resolve遗骸的后代(除非有错误),但总的来说它可能会发生。

    由于其中一些原因,您可能希望通过 stdout和stderr传递cat. 免疫+仍然是一个好主意cat:Ctrlc

      davinci-resolve 2>&1 | sh -c 'trap "" INT; exec cat'
    

    现在请注意,您无法将 stderr davinci-resolve(及其后代)与 stdout 区分开来,它们都经过 viacat及其 stdout。这应该不是问题,因为无论如何您都希望它们在终端中混合。如果您想单独重定向或捕获它们,那么您应该放弃我们的装置并从头开始。

    这可能是麻烦的过程提前关闭或重定向其stdout和stderr,并将不需要的消息直接打印到/dev/tty(示例)。在这种情况下,我们cat无能为力。


    外壳函数

    您可以将我们的解决方案实现为 shell 函数:

    davinci-resolve() {
       command davinci-resolve "$@" 2>&1 | sh -c 'trap "" INT; exec cat'
    }
    

    该函数支持将参数传递给davinci-resolve,但其退出状态来自cat,而不是来自davinci-resolve进程(如果有问题,请参阅已经给出的链接以获取想法)。

    • 1
  2. user10489
    2022-04-06T14:21:55+08:002022-04-06T14:21:55+08:00

    后台进程实际上并没有干扰你的 shell,它只是在你的屏幕上乱涂乱画,后台进程和 shell 的输出正在混合。

    有几种方法可以解决这个问题:

    • 您可以使用类似nohup或文件重定向之类的东西从终端中删除消息,可能会将它们保存到文件中。
    • 您可以忽略混乱并继续输入,或者如果您没有输入任何内容,只需按回车即可获得新的提示。
    • 您可以阅读后台进程发送的消息,然后使用命令行编辑击键刷新您键入的内容并使其再次可读。在普通熟终端模式下,Ctrl-R将执行此操作。在 bash 等许多其他应用程序中,Ctrl-L将清除屏幕并重新打印提示和您键入的内容。
    • 您可以在专用窗口中运行该应用程序,并使用图形窗口系统的功能打开另一个不受其输出污染的窗口。:)(我在旁边留了一个小窗口,只是为了运行这些嘈杂的应用程序。)
    • 如果在您结束应用程序之后发生这种情况,并且它留下了您想要停止的工作线程,您可以找到它们ps -t(以显示当前终端上正在运行的内容)并杀死它们。
    • 0
  3. sarac
    2022-04-06T18:35:12+08:002022-04-06T18:35:12+08:00

    您可以键入 control-l 以清除屏幕。这将清除“Socket disconnected”消息,但会保持您的命令提示符和部分写入的命令完好无损。不幸的是,它还会清除 davinci-resolve 的输出,这对于您正在尝试做的事情可能合适,也可能不合适。

    • 0
  4. sarac
    2022-04-06T19:24:32+08:002022-04-06T19:24:32+08:00

    如果在主进程退出后“Socket disconnected”消息很快出现,您可以添加; sleep 2到您的命令并将其放在 shell 别名中。这基本上是一种提醒自己不要立即输入新命令的方法。为此,添加

    alias davinci-resolve="davinci-resolve; sleep 2"
    

    到你的 .bashrc

    • 0

相关问题

  • 寻找终端下载管理器

  • 语法错误:fd 编号错误?

  • traceroute,只打印网关信息

  • 如何在 ssh 上运行一瞥?

  • 备份 Nand Flash 存储区

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve