Capturing Screenshot of terminal application via shell script?

9,717

Solution 1

I don't think you'll be able to do this with screen unless the output is actually rendered in a window, which probably defeats the point of using screen. However, the window does not have to be in the foreground.

The ImageMagick suite contains a utility called import you can use for this. If import --help gives you "command not found", install the imagemagick package, it will be available in any linux distro.

import needs the name of the window. iftop is a terminal interface, so to make sure you use the right name, you'll have to set the title of the GUI terminal it runs in. How you do that depends on which GUI terminal you use. For example, I prefer the XFCE Terminal, which would be:

Terminal -T Iftop -e iftop

Opens a new terminal running iftop with the title "Iftop". A screenshot of that can be taken:

import -window Iftop ss.jpg

If you are going to do this every five seconds, you probably want to instead open the window running a script so you can reuse the same terminal:

count=0;
while ((1)); do
    iftop &
    pid=$!
    sleep 1  # make sure iftop is up
    count=$(($count+1))
    import -window Iftop iftop_sshot$count.jpg
    kill $pid
    sleep 5
done

If the script is "iftopSShot.sh" then you'd start this Terminal -T Iftop -e iftopSShot.sh -- except you're probably not using Terminal. Most of the linux GUI terminals are associated with specific DE's, although they are stand-alone applications which can be used independently. I believe the name of the default terminal on KDE is Konsole and it follows the -T and -e conventions; for GNOME it is probably gnome-terminal (this may have changed) and it appears to use -t and not -T.

Beware import by default rings the bell, which will get irritating, but there is a -silent option.

Solution 2

screen can log to a file :

-L tells screen to turn on automatic output logging for the windows.

or make a copy of the current screen to a file :

hardcopy [-h] [file]

   Writes out the currently displayed image to the file file, or,
   if no filename is specified, to hardcopy.n in the  default directory,
   where  n  is the number of the current window.  This either appends
   or overwrites the file if it exists. See below.  If the option -h
   is specified, dump also the contents of the scrollback buffer.

If you have one screen session running, you can save it's current content with this command:

screen -X hardcopy

For saving to 100 separate files, 1 every 10 seconds:

for c in {1..100}; do screen -X hardcopy /my/dir/screen-$c; sleep 10; done

Solution 3

In a X environment:


Set dynamically the terminal title:

From our script, a way to change the terminal title using ansi sequences:

echo -e "\033]0;Term | myApp\007";

Capture a png by window title:

Now we can search for the window id by the exact title using wmctrl and pass the id to the import utility:

import -window $(wmctrl -l | grep -i 'Term | myApp' | awk '{print $1}') ~/Pictures/capture.png

Build a gif:

Example to tweak, take 5 captures every second then convert them in order to a gif using convert, in an infinite 2 seconds loop.

rm -f /tmp/*png && for i in {1..5}; do import -window $(wmctrl -l | grep -i 'Term | myApp' | awk '{print $1}') /tmp/$i.png && sleep 1; done && convert -delay 200 -loop 0 /tmp/*.png animation.gif
Share:
9,717

Related videos on Youtube

Satish
Author by

Satish

Updated on September 18, 2022

Comments

  • Satish
    Satish over 1 year

    Problem

    Run iftop for 5 seconds, capture the screenshot and save it to a file.

    iftop is a beautiful program for visualizing network traffic, but it doesn't have a batch mode where I can run it for few seconds and capture the output to a file.

    So my idea is

    • use commands like screen to create a virtual display and run iftop in it.
    • look for any tools (screendump) to take a screen shot of the screen.

    Any idea on how do I go with this?

    • slm
      slm over 10 years
    • Satish
      Satish over 10 years
      Appreciate the responses. Ended up using shellinaboxd and to pipe the program output as is to browser.
    • slm
      slm over 10 years
      Glad you resolved your Q. You can always show your appreciation by upvoting the answers that others have provided. Additionally if you wouldn't mind could you provide an answer to your own question and accept it (green checkmark under the answers) so that others may benefit from all these answers in the future? Thanks!
  • Timo
    Timo over 3 years
    How can I find the Terminal cmd? I use Lubuntu 20_04, there is no such cmd. I want to take browser snapshots every some seconds, should I start the browser with chromium - T test - e script?.
  • Timo
    Timo over 3 years
    I get with the import: import-im6.q16: missing an image filename capture.png' @ error/import.c/ImportImageCommand/1289.`
  • goldilocks
    goldilocks over 3 years
    GUI terminal apps are usually part of a DE (eg. Terminal is from XFCE). Pretty sure Lubuntu uses LXDE by default, their terminal is wiki.lxde.org/en/LXTerminal I think the command line invocation is lxterminal.
  • Timo
    Timo over 3 years
    thanks, I use lxqt.
  • NVRM
    NVRM over 3 years
    Make sure the window name match exactly. Just do wmctrl -l to verify. Check this other answer from me stackoverflow.com/a/61659109/2494754 I tested it just now it works for me, so not sure. Able to reproduce your error, when wmctrl -l | grep -i 'Term | myApp' | awk '{print $1}' return nothing. It must return a window id in this format 0x05c00113
  • Timo
    Timo over 3 years
    Now it works, but the term | my app stays only for one return, then switches back to the previous terminal name. I want to take a browser shot, however there is a partially black screen resulting from the terminal I call the import. A workaround would be to make the terminal minimal.
  • NVRM
    NVRM over 3 years
    Yes the program must be running, or the origin title comes back. Originally this was made to run from the same script..
  • Timo
    Timo over 3 years
    In the gif script, what is delay 200? Is it the 2 seconds loop? I would say 200*5=1000 ms, which means 5 shots every sec? But my logic does not make sense as delay is arg for gif-convert
  • Timo
    Timo over 3 years
    The delay arg in convert is here in case anyone's brain is as curious driven as mine, basis is 1/100 sec, so 200 are two secs. Thank NVRM for the script.
  • Mila Nautikus
    Mila Nautikus about 2 years