如何从使用 tput 的命令“渲染”输出,以便仅保留最终的终端后处理结果?

如何从使用 tput 的命令“渲染”输出,以便仅保留最终的终端后处理结果?

我捕获了使用 tput 在屏幕上绘制某些内容的脚本的输出。当我执行 cat myoutput 时,一切都很清楚(看起来终端从头开始重新解释它),但是当我编辑或管道输出时,我看到大量的 ansi 序列以及破坏性打印之前的所有内容,例如 tput clear 等。

我怎样才能对其进行后处理,以便我只得到最终的“渲染”?

更好的是,其根源是我目前正在编写我的脚本,因此它将除了终端之外的所有内容都打印到文件中

exec > >(tee /dev/tty)

有没有办法告诉标准输出通道在保存之前“渲染”所有内容?

答案1

你想要的是一个程序明白这些终端控制序列,并且能够渲染最终视图。那么,这样的程序称为终端仿真器。其中一些是图形化的——比如您启动使用 shell 的程序,例如 gnome-terminal 或 alacritty,其他的主要是无头的。

较古老的screen或更现代的tmux都是这里的相关内容。

  1. 写一个“外部”脚本:
    1. 创建命名管道
    2. tmux在后台启动您的“内部”脚本(即输出内容的脚本)
    3. 在你的外部脚本中,从 fifo 读取(这会阻塞,因为没有写入任何内容),
    4. 读取完成后,指示tmux输出屏幕截图
  2. 在您的内部脚本中,向命名管道写入一些内容以表明您处于要截取屏幕截图的状态

把它放在一起,就像

#!/usr/bin/zsh
# outer script
# SPDX-License-Identifier: WTFPL

# Make a temporary directory
tmpdir="$(mktemp -d)"

# Prepare the FIFO
fifo="${tmpdir}/fifo"
mkfifo "${fifo}"

# Start the inner script in tmux
tmux new-session -d -s "${tmpdir}" -e "FIFO=${fifo}" ./inner-script.sh …
#^   ^           ^  ^------+-----^ ^------+--------^ ^                 ^
#|   |           |         |              |          |                 |
#\------run tmux, the terminal emulator
#    |           |         |              |          |                 |
#    \---in tmux, run the "new-session" command to, well, get a new session
#                |         |              |          |                 |
#                \---detach that session, i.e. *don't* connect it to the current terminal
#                          |              |          |                 |
#                          \--specify the session name. Conveniently, we abuse the name
#                             of our temporary directory, as it's inherently unique
#                                         |          |                 |
#                                         \-- for the started command, set the environment
#                                             variable FIFO to the name of our FIFO
#                                                    |                 |
#                                                    \-- launch your script
#                                                …with its arguments--/

# Wait for something to be written to our FIFO
cat "${fifo}" > /dev/null

# instruct tmux to take a "pane shot"
tmux capture-pane -t "${tmpdir}" -p > "/path/to/capture"
#                 ^------+-----^  ^ ^---------+--------^
#                        |        |           |
#                        \-------------------------------- target (session name as above)
#                                 |           |
#                                 \----------------------- print to stdout
#                                             |
#                                             \----------- redirect stdout to file

# Finally, clean up session and temporary directory
tmux kill-session -t "${tmpdir}"
rm -rf "${tmpdir}"

您只需要将写入的内容添加到 fifo 中inner-script.sh,例如echo done > "${FIFO}"; sleep 100.

如果您已经有“记录”输出,您inner-script.sh可能只是cat recording.txt; echo done > "${FIFO}"; sleep 100

相关内容