9

I would like to, every 30 seconds or so, copy all text of a certain terminal or terminal emulator to a file, and display it in conky. I'm not talking about simple redirection (command > file), which doesn't work for ncurses programs or games such as NetHack.

How could I go about doing this?

IBPX
  • 581
  • 1
    if it's a console terminal, you can get the contents from /dev/vcs* – Jasen Nov 09 '15 at 08:57
  • That'll work! Is it possible to open more than the default 6 (or whatever your distro uses)? – IBPX Nov 09 '15 at 17:53
  • You want text, so the accepted screen answer is indeed right. But for others who land here looking for a graphic screenshot of a Linux console running without X or any GUI, there is fbgrab as suggested in https://askubuntu.com/a/558588/8822 – mivk Jan 09 '18 at 12:25

2 Answers2

7

There is no portable way to ask a terminal emulator to do screen dumps. You can work around this by running your application in GNU screen or tmux and using them to carry out the screen-dumps.

GNU screen can do this:

Likewise, there is a plugin for tmux to do screen captures.

Thomas Dickey
  • 76,765
0

capture the *visible* output of a process (text screenshot)

this will render special characters like carriage return (\r) and other terminal control codes as they would be visible to a human

for example, a live progress bar should produce

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

and not

[==>                               ]  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

milahu
  • 208