对当前终端内容进行文本“截图”

对当前终端内容进行文本“截图”

我想每隔 30 秒左右将某个终端或终端模拟器的所有文本复制到一个文件中,并将其显示在conky.我不是在谈论简单的重定向 ( command > file),它不适用于 ncurses 程序或 NetHack 等游戏。

我该怎么做呢?

答案1

没有可移植的方法来要求终端仿真器进行屏幕转储。您可以通过在 GNU screen 或 tmux 中运行应用程序并使用它们来执行屏幕转储来解决此问题。

GNU 屏幕可以做到这一点:

同样,有一个tmux 插件进行屏幕截图。

答案2

捕获流程的*可见​​输出(文本屏幕截图)

这将呈现特殊字符,如回车符 ( \r) 和其他终端控制代码因为它们对人类来说是可见的

例如,实时进度条应该产生

[================================>] 100%          

并不是

[==>                               ]  9%
[========>                         ] 28%
[==============>                   ] 47%
[=====================>            ] 65%
[===========================>      ] 84%
[================================>] 100%
#! /usr/bin/env bash

# text screenshot
# capture the visible output of a process
# https://unix.stackexchange.com/a/697804/295986

captureCommand="$(cat <<'EOF'
  # example: progress bar
  # https://stackoverflow.com/a/23630781/10440128
  for ((i=0; i<100; i++)); do
    sleep 0.1
    printf .
  done | pv -p -c -s 100 -w 40 > /dev/null
EOF
)"
# note: to stop the captureCommand after some time
# you can wrap it in `timeout -k 60 60`
# to stop after 60 seconds
# or use `for waiterStep in $(seq 0 60)`
# in the waiter loop

# create a new screen session. dont attach
screenName=$(mktemp -u screen-session-XXXXXXXX)
screen -S "$screenName" -d -m

# create lockfile
screenLock=$(mktemp /tmp/screen-lock-XXXXXXXX)
# remove lockfile after captureCommand
screenCommand="$captureCommand; rm $screenLock;"

echo "start captureCommand"
# send text to detached screen session
# ^M = enter
screen -S "$screenName" -X stuff "$screenCommand^M"
hardcopyFile=$(mktemp /tmp/hardcopy-XXXXXXXX)

enableWatcher=true
if $enableWatcher; then
  echo "start watcher"
  (
    # watcher: show live output while waiting
    while true
    #for watcherStep in $(seq 0 100) # debug
    do
      sleep 2
      # take screenshot. -h = include history
      screen -S "$screenName" -X hardcopy -h "$hardcopyFile"
      cat "$hardcopyFile"
    done
  ) &
  watcherPid=$!
fi

echo "wait for captureCommand ..."
while true
#for waiterStep in $(seq 0 60) # debug
do
  sleep 1
  [ -e "$screenLock" ] || break
done
echo "done captureCommand"

if $enableWatcher; then
  kill $watcherPid
fi

# take a last screenshot
screen -S "$screenName" -X hardcopy -h "$hardcopyFile"
echo "done hardcopy $hardcopyFile"

# kill the detached screen session
screen -S "$screenName" -X quit

相关内容