在终端的特定位置显示后台进程的标准输出

在终端的特定位置显示后台进程的标准输出

我有一个命令,每次打开新终端或进行新登录时都会运行该命令。

该程序产生输出(彩色),该输出应位于命令提示符之前。运行可能需要几秒钟,这将阻止我在此之前使用终端(除非在后台运行)。

鉴于 zsh 有一些高级方法可以重绘终端而不破坏现有文本,我想知道如何以一种无需等待它完成才能使用终端的方式运行此命令,但是一旦完成,它就会打印输出,就好像它一开始就没有后台一样。

在实践中我想要一些可以做的事情:

Command output:
... (running on background)
me@computer: somecommand
me@computer: someothercommand

命令完成后我会得到:

Command output:
 * Output foo
 * Multiple lines bar
 * and some yada
me@computer: somecommand
me@computer: someothercommand

我尝试在启动时将进程置于后台,但随后它无法清晰地显示输出。我得到类似的东西:

Command output:
[2] 32207
me@computer: somecommand
me@computer: someother * Output foo
 * Multiple lines bar
 * and some yada
[2]  + done       command
me@computer: someothercommand

那么,这可能吗?如果不使用 zsh 是否有任何解决方案可以做到这一点?

欢迎任何指示或信息。

答案1

如果您愿意接受当前提示行上方的输出,这是一个简单的解决方案。

bufferout () {
    local buffer
    while IFS= read -r line; do              # buffer stdin
        buffer="$buffer$line\n"
    done
    print -rn -- $terminfo[dl1]              # delete current line
    printf "$buffer"                         # print buffer
    kill -USR1 $$                            # send USR1 when done
}

TRAPUSR1 () {                                # USR1 signal handler
    zle -I                                   # invalidate prompt
    unhash -f TRAPUSR1 bufferout             # remove ourselves
}

./testout 2>&1 | bufferout &!                # run in background, disowned

作业完成后,当前的提示和输入缓冲区将被删除,并打印整个命令的stdout和。stderr

请注意,这假设它将只运行一次并在之后自行删除。如果您想在同一 shell 中继续重用此功能,请删除unhash -f中的行TRAPUSR1


这个答案包括Clint Priest 在评论中建议的改进。谢谢!

相关内容