I want to take screenshots simultaneously from multiple X servers on one desktop PC.

I have multiple users logged in different terminals (tty1, tty2, tty3, tty4) who start multiple Xservers with startx /usr/bin/openbox-session -- :1 (and :2, :3, :4 respectively). So I can access each one of them with Ctrl+Alt+F8, +F9, +F10, +F11.

There is only one monitor on that desktop.

I want to take screenshots for each of these X servers, preferably with scrot, but I currently get a black/blank image whenever I try it. Only when I am active on that X server I get a proper screenshot.

For example, if I am on Ctrl+Alt+F8 and run scrot test.png I get a proper screenshot; if I understand correctly I do not have to set the $DISPLAY, since being on Ctrl+Alt+F8 I get echo $DISPLAY > :1. But if I run sleep 10; scrot test.png and go to Ctrl+Alt+F7, then I get a black image.

How can I get multiple screenshots from each one of those terminals simultaneously?

What worked for me was Xephyr. The only problem with this solution seems to be that when I run extremely fast xdotool commands it is not as responsive as X.

For future reference, what I did for every of the four users and terminals was:

In ~/.profile, I set each user to auto-login after my system boot, like:

if [[ -z $DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
     sleep 30 # for some reason it crashes if I do not let 
              # it sleep for a while, not necessarily so long. 
              # I guess it has to do with my "normal" X at DISPLAY=:0 . 
              # Thus for tty2 I let it sleep 40 seconds, 
              # for tty3 50 seconds and so on.

In ~/.Xsession, I start an Xserver/client (with blackbox) and Xephyr (with openbox) in it like:

Xephyr -fullscreen -screen 1920x1200 :11 &
exec blackbox & 
sleep 3 # Perhaps sleeping is redundant.
DISPLAY=:11 /usr/bin/openbox-session

I want the "final" window manager do be openbox-session. I would like to use openbox for both the Xserver and Xephyr, but exec openbox & DISPLAY=:11 /usr/bin/openbox-session crashes, while exec openbox & DISPLAY=:11 /usr/bin/openbox does not.

This way, the user in :11 can take screenshot, while the monitor shows :0. (or :13, :14, etc.).

I did not try XVnc, but I have the feeling that it might be slower than Xephyr; please correct me if I am wrong.

  • The $DISPLAY variable needs to change for scrot. This will not happen if it remains in the subshell launched from the Xserver you just switched from. – mikeserv Aug 21 '14 at 1:36
  • each one of those VTs is a separate X server. If you are on one of them and switch to another you're looking at a different X server - a different $DISPLAY. So when you run a delayed scrot with one $DISPLAY and switch to a different one before it executes its $DISPLAY goes dark. It would have worked without Xephyr at all - and, in truth, layering the servers that way only complicates the issue further, though it can be made to work. – mikeserv Aug 22 '14 at 0:01
  • @mikeserv I appreciate very much your support and it seems I misunderstand something very basic. How could it work without Xephyr? When on the VT of Ctrl+Alt+F8 I run sleep 3; DISPLAY=$(echo $DISPLAY) scrot test.png (which is the same as sleep 3; DISPLAY=:1 scrot test.png and within 3 seconds I switch to Ctrl+Alt+F7 (where $DISPLAY is :0) I get a blank test.png. – Konstantinos Aug 22 '14 at 7:38
  • This is the reason: the scrot process is a child of VT8 - its $DISPLAY is always :1 - even after you switch. That is the value exported into its environment by its parent shell - which you leave behind when you switch to VT7. Think about it this way - if there were no Xservers running at all and only the console - at boot you'd get a login prompt then a shell. If you switch to another you'll get another login prompt and another shell. Different VTs, different shells. Different VTs, different $DISPLAYs scrot gets left behind. Do DISPLAY=:0 scrot test.png. – mikeserv Aug 22 '14 at 7:47
  • When I am at VT8 and run sleep 3; DISPLAY=:0 scrot test.png and switch within 3 seconds to VT7, I get the screenshot of VT7. Is this what you mean? I want to work on VT7, and get the screenshot of VT8. Is this possible without Xephyr? – Konstantinos Aug 22 '14 at 7:51

I understand the problem in the question as follows:

  • You are on a text console tty,
    so there is no X running on the tty where you are running the screenshot command.

  • You can run command line screenshot commands for the X displays.

  • You have specified the X displays for the screenshot commands, like in
    DISPLAY=:2 scrot out.png.

  • The screen shot command does not give you an error

But you get a black image as output.

The problem could be that the X server is not painting the image into some image buffer, and the screenshot is taken from that empty buffer. But it could also be that it's a compositing window manager, like compiz, that is not painting. At least if you capture single windows, that could be the problem. I think it's worth trying to use a not compositing window manager, like metacity.

If that does not solve it, there is a completely different approach:

Run all your X servers as nested X servers on one display. Each nested X server is showing it's screen output in a window. You can then either make full screen screenshots of the nested display, or window screenshots on the main display.

As implementation of a nested X server, Xephyr seems to be the most current. There are also the older Xnest and Xvfb:

From man Xephyr:

        Xephyr - X server outputting to a window on a pre-existing X display

        Xephyr  is a kdrive server that outputs to a window on a pre-existing "host" X dis‐
        play.  Think Xnest but with support for modern extensions  like  composite,  damage
        and randr.

        Unlike  Xnest  which is an X proxy, i.e.  limited to the capabilities of the host X
        server, Xephyr is a real X server which uses the host X server  window  as  "frame‐
        buffer" via fast SHM XImages.

In a similar way, Xvnc (from package vnc4server) could be used, providing access by VNC protocol additionally:

From Xvnc4:

        Xvnc - the X VNC server

        Xvnc  is the X VNC (Virtual Network Computing) server.  It is based on a standard X
        server, but it has a "virtual" screen rather than a physical one.   X  applications
        display  themselves  on  it  as if it were a normal X display, but they can only be
        accessed via a VNC viewer - see vncviewer(1).

        So Xvnc is really two servers in one. To the applications it is an X server, and to
        the  remote  VNC  users it is a VNC server. By convention we have arranged that the
        VNC server display number will be the same as the X server  display  number,  which
        means  you  can  use eg. snoopy:2 to refer to display 2 on machine "snoopy" in both
        the X world and the VNC world.

(Xvnc is available as package vnc4server in Ubuntu)

|improve this answer|||||
  • the asker has specifically not set the $DISPLAY variable to other than the current VT. - see? if I understand correctly I do not have to set the $DISPLAY, since being on Ctrl+Alt+F8 I get echo $DISPLAY > :1. But if I run sleep 10; scrot test.png and go to Ctrl+Alt+F7, then I get a black image. – mikeserv Aug 21 '14 at 23:57

Method #1 - Using xwd

You could just use the command line tool xwd to grab the X displays like so:

$ xwd -display :1 -root -out 1.xwd

You could loop through 1 to 4 like so:

$ for i in {1..4};do xwd -display :$i -root $i.xwd; done

NOTE: The resulting .xwd files are a special type of X Windows dump file.

$ file 1.xwd 
1.xwd: XWD X Window Dump image data, "xwdump", 4160x1440x24

You can use xwud to display them like so:

$ xwud -in 1.xwd

Or you can use ImageMagick's display command to view them:

$ display 1.xwd

Method #2 - Using import

You can also use ImagMagick's import command to do something similar:

$ import -window root -display :0.0 -screen /tmp/0.png

Method #3 - using scrot

Or as was suggested by @mikeserv in the comments, try setting the $DISPLAY so that scrot can find the active X display correctly:

$ DISPLAY=:1 scrot 1.png

This could be looped like so:

$ for i in {1..4};do DISPLAY=:$i scrot $i.png; done


|improve this answer|||||
  • 1
    @mikeserv - I was able to view the resulting xwd dump file using display out of ImageMagick. I don't even have access to that tool, xwud on F20. Querying the YUM repos to see if it's buried somewhere else 8-) – slm Aug 21 '14 at 14:59
  • @mikeserv - found it, it's buried in this pkg: xorg-x11-apps-0:7.7-7.fc20.x86_64. – slm Aug 21 '14 at 15:02
  • @mikeserv - yeah they do, my mistake. I ran that on F19 last night, and now I'm on F20 and didn't have that pkg installed...yet 8-). Updated the A with your info as well, thanks! – slm Aug 21 '14 at 15:07
  • I may be missing something, but I understood the question as that the OP did try a solution like these, and got a black screen only - so I would expect that these methods do not work too? It the OP just did not set DISPLAY, he would get an error, not a black image, I think. – Volker Siegel Aug 21 '14 at 15:25
  • @VolkerSiegel - he didn't explicitly say that he did set $DISPLAY, also with these methods he does not need to set $DISPLAY since these commands take the display arg. directly. Also I 1/2 suspect that he might need to export $DISPLAY, so that scrot can pick it up. These will just sit here until he confirms all this for us. – slm Aug 21 '14 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.