8

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?

3
  • Take a look at this script: arch-ed.dk/screenshot-tool-for-repetitive-screenshotting
    – slm
    Sep 26, 2013 at 13:16
  • Appreciate the responses. Ended up using shellinaboxd and to pipe the program output as is to browser.
    – Satish
    Sep 30, 2013 at 22:36
  • 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!
    – slm
    Sep 30, 2013 at 23:43

4 Answers 4

4

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.

3
  • 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
    Jan 8, 2021 at 20:15
  • 1
    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.
    – goldilocks
    Jan 8, 2021 at 20:27
  • thanks, I use lxqt.
    – Timo
    Jan 8, 2021 at 20:34
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
1
2

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
6
  • 1
    I get with the import: import-im6.q16: missing an image filename capture.png' @ error/import.c/ImportImageCommand/1289.`
    – Timo
    Jan 8, 2021 at 20:24
  • 1
    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
    – NVRM
    Jan 9, 2021 at 7:17
  • 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.
    – Timo
    Jan 9, 2021 at 19:51
  • 1
    Yes the program must be running, or the origin title comes back. Originally this was made to run from the same script..
    – NVRM
    Jan 9, 2021 at 20:00
  • 1
    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.
    – Timo
    Jan 9, 2021 at 20:30
0

Couple of ideas:

  1. You could use this script from this articled titled: Screenshot tool for repetitive screenshotting.

    #!/bin/bash
    # Screenshot tool for TIMS.
    #
    # -------------------------
    #
    # By regj 2012.05
    #
    # -------------------------
    #
    # Check for config file create if needed with sane defaults then exit.
    if [ ! -f $HOME/.scrotter ]; then
        echo "Creating scrotter config file ${HOME}/.scrotter"
        echo "scrotfldrbase=${HOME}/Desktop/scrots" > $HOME/.scrotter
        echo "fontsize=14" >> $HOME/.scrotter 
        echo "fillcolor=white" >> $HOME/.scrotter 
        echo "whiteterm=yes" >> $HOME/.scrotter
        echo "subw=130" >> $HOME/.scrotter
        echo "subh=5" >> $HOME/.scrotter
        echo "fontpath=/usr/share/fonts/dejavu/DejaVuSansMono.ttf" >> $HOME/.scrotter
        if [ $? = 0 ] ; then
            echo -e "Config file succesfully created. Adjust values if needed in ~/.scrotter.\nIf you use a black term background set whiteterm to no."
            echo "Current values:"
            cat $HOME/.scrotter
            echo "Rerun scrotter with --server-id if initial run"
            exit 0
        else
            echo "Something went wrong"
            exit 1
        fi
    fi
    
    # Source config file
    source $HOME/.scrotter
    
    # convert functions for white or black terminal
    conv_black () {
    convert -pointsize $fontsize \
        -font $fontpath \
        -fill $fillcolor \
        -draw "text ${xyplace} \"$(date "+%Y.%m.%d %H:%M"|sed -e ' s/\"/\\\"/g' )\"" \
        $scrotfldr/$srvid-$count.png $scrotfldr/$srvid-$count.png 
    }
    
    conv_white () {
    convert -pointsize $fontsize \
            -font $fontpath \
            -fill $fillcolor \
        -stroke black \
        -strokewidth 1 \
            -draw "text ${xyplace} \"$(date "+%Y.%m.%d %H:%M"|sed -e ' s/\"/\\\"/g' )\"" \
            $scrotfldr/$srvid-$count.png $scrotfldr/$srvid-$count.png
    }
    
    
    # Options
    case $1 in
    
    --server-id) echo "Setting srvid" ; echo $2 > /tmp/${USER}-scrot-srvid ; exit 0;;
    --reset-count) echo "0" > /tmp/$USER-scrot-count ; exit 0;;
    --clean-up) rm -f $scrotfldr/*.png ; rm -f /tmp/${USER}-scrot-* ; exit 0 ;;
    --help) echo "Options are:
            --server-id: Set servername used in test.
            --reset-count: Reset counter for enumerating png's.
            --clean-up: Delete png's in current serverfolder and reset counters and serverid.
            --help: This info." 
            exit 0;;
    
    # Uncomment below if you want to remove everything in your scrot folder with this script
    #--clean-all) if [ -z $scrotfldrbase ]; then 
    #       echo "Exiting .." ; exit 1
    #        fi 
    #       echo "NB: $scrotfldrbase will be removed recursively!"  
    #       rm -rI $scrotfldrbase/*  
    #       rm -f /tmp/${USER}-scrot-*
    #       exit 0 ;;
    
    esac
    
    # Check if serverid is defined, use if yes
    if [ -s /tmp/${USER}-scrot-srvid ]; then
        srvid=$(cat /tmp/${USER}-scrot-srvid)
        scrotfldr=$HOME/Desktop/scrots/$srvid
    else
        echo "Please set server id with --server-id option. # scrotter --server-id <servername>"
        exit 1
    fi
    
    # Check if root, exit if yes.
    if [ $(id -u) = 0 ]; then
        echo "Do not run as root!"
        exit 1
    fi
    
    # Create count file
    if [ ! -f /tmp/${USER}-scrot-count ]; then
        echo "0" > /tmp/$USER-scrot-count
    fi
    
    # Create Screenshot folder if not present
    if [ ! -d $scrotfldr ];  then
        mkdir -p $scrotfldr
    fi
    
    # Get active window ID
    activewin=$(xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)" | grep "window id" )
    activewinid=${activewin:40}
    
    # Get geometry of window
    geowinw=$(xwininfo -id ${activewinid} | awk '/Width/ {print $2}')
    geowinh=$(xwininfo -id ${activewinid} | awk '/Height/ {print $2}')
    
    # Define X,Y placment of date text
    xyplace="$(($geowinw - $subw)),$(($geowinh - $subh))"
    
    # Get current count
    count=$(cat /tmp/${USER}-scrot-count)
    
    # Take screenshot
    import -window "$activewinid" $scrotfldr/$srvid-$count.png
    
    # Insert date stamp into screenshot use xyplace variable to adjust placement
    if [ $whiteterm = yes ] ; then
        conv_white
    else
        conv_black
    fi
    
    # Increment counter
    echo $(($count+1)) > /tmp/$USER-scrot-count
    

    Put the above in a file called scrotter and make it executable. When you run it the first time:

    $ ./scotter
    Creating scrotter config file /home/saml/.scrotter
    Config file succesfully created. Adjust values if needed in ~/.scrotter.
    If you use a black term background set whiteterm to no.
    Current values:
    scrotfldrbase=/home/saml/Desktop/scrots
    fontsize=14
    fillcolor=white
    whiteterm=yes
    subw=130
    subh=5
    fontpath=/usr/share/fonts/dejavu/DejaVuSansMono.ttf
    Rerun scrotter with --server-id if initial run
    

    Running it a 2nd time you'll get the usage:

    $ ./scrotter 
    Please set server id with --server-id option. # scrotter --server-id <servername>
    

    Now run it with a --server-id blah, and start taking screenshots:

    $ ./scrotter --server-id blah
    $ ./scrotter
    

    It will take screenshots of the active window. This would be modified into a looping structure or modified directly!

  2. You could use the import command to take a screenshot and wrap that in whatever type of loop you like (for, whilte, etc.) depending on your needs. This aritcle, Timelapse Screenshots, has everything you need, I don't think you want to make the script run from a cron but everything else seems applicable.

    For example:

    # takes screenshot
    $ import -window root -display :0 -crop 958x490+20+128 "savedfiles/screenshot_$(date +%d%m%y-%H.%M).png"
    
    # makes a video out of a bunch of them
    $ mencoder "mf://screamshots/*.png" -mf fps=10 -o test.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800
    

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .