I tried using DISPLAY=:0 import -window root "$HOME/Pictures/screenshot.png" (import is part of the ImageMagick suite), but that just displays a black screen.

I want to do this as I wanted to automate opening an app and taking screenshots of it in different languages, and to change languages, I need to restart lightdm. therefore, run on a tty so your script continues running...


In addition to the existing answers, to display the screenshot in ASCII in the terminal:

xwd -root -display :0 | convert - jpg:- | jp2a - --colors

(Requires x11-apps for xwd, imagemagick for convert and jp2a.)

  • Not exactly relevant, but cool addition. – Yatharth Agarwal Jul 25 '14 at 5:39
  • 1
    xwd -root -display :0 | convert - jpg:- > screenshot.jpg – gregn3 Jun 19 '16 at 20:48
  • 2
    Modern ImageMagick versions often can't infer the xwd format from magic numbers, so it's better to specify the input format explicitly: xwd -root -display :0 | convert xwd:- jpg:- | jp2a - --colors – Bass Mar 16 '18 at 9:51
  • For me: xwd -name "$win_name" | convert xwd:- /tmp/"$win_name".png, where win_name=$(xwininfo -tree -root | grep 'The Window Name Im Looking For' | awk -F\" '{print $2}') – Avio Dec 13 '18 at 13:30

Here is solution using xwd, which is is available in almost all Xorg installations:

 xwd -root -out screenshot.xwd

The screenshot.xwd file can be opened with GIMP:

For more info see http://www.x.org/wiki/UserDocumentation/GettingStarted/.


Here's what worked for me.

chvt 7
DISPLAY=:0 import -window root "$HOME/Pictures/screenshot.png
chvt 1

Try using shutter

DISPLAY=:0 shutter -f -e -n -o "$HOME/Pictures/screenshot.png"

Import won't work, because the root window is not in use. Compositing "bypasses" it (each window is rendered in its own buffer then multiplexed to the display, instead of the old way, where they were all rendered on the "root" window).

In addition you need to make sure the VTY is active before you take the screenshot. So for example,

X :1 &  
export DISPLAY=:1  
sleep 10 # give time for X to start  
gedit &  
sleep 10 # give time for app to do something  
chvt 8  # ensure the X display is active  
shutter -f -e -n -o "$HOME/Pictures/screenshot.png" # screenshot  
killall xorg # terminate X
  • Nope, still giving a black screen :( – Yatharth Agarwal Dec 8 '12 at 16:35
  • Are you in the X session (on a monitor) when you do this. I just tried and it worked quite well. You will need to be logged in, and have the X session in the active VTY. – coteyr Dec 9 '12 at 0:38
  • I want a script launched in the tty to be able to do this. – Yatharth Agarwal Dec 9 '12 at 14:34
  • Yes, but do you switch to the X session before taking the screen shot. X :0 & sleep 50 && sudo chvt 6 && program & sleep 5 && screenshot (notice totally fake script). – coteyr Dec 9 '12 at 16:14
  • Also just to make sure were talking the same thing you want VT0 (or something) not a screen shot of a text console. So your running the script from a TTY trying to screen shot X (VTY). Is that correct? – coteyr Dec 9 '12 at 16:16

Sitting on the same computer and doing it from a different virtual terminal than the X server is running does not work.

It is explained there: http://www.karlrunge.com/x11vnc/faq.html#faq-linuxvc. Quote:

Q-108: I use Linux Virtual Terminals (VT's) to implement 'Fast User Switching' between users' sessions (e.g. Betty is on Ctrl-Alt-F7, Bobby is on Ctrl-Alt-F8, and Sid is on Ctrl-Alt-F1: they use those keystrokes to switch between their sessions.) How come the view in a VNC viewer connecting to x11vnc is either completely black, doesn't update, or pixels messed up unless the X session x11vnc is attached to is in the active VT?

This seems to have to do with how applications (the X server processes in this case) must "play nicely" if they are not on the active VT (sometimes called VC for virtual console.) That is, they should not read from the keyboard or mouse or manage the video display unless they have the active VT. Given that it appears the XGetImage() call must ultimately retrieve the framebuffer data from the video hardware itself, it would make sense x11vnc's polling wouldn't work unless the X session had active control of the VT.

There does not seem to be an easy way to work around this. Even xwd(1) doesn't work in this case (try it.) Something would need to be done at a lower level, say in the XFree86/Xorg X server. Also, using the Shadow Framebuffer (a copy of the video framebuffer is kept in main memory) does not appear to fix the problem (last checked 2007.)

If no one is sitting at the workstation and you just want to remotely switch the VT over to the one associated with your X session (so x11vnc can poll it correctly), one can use the chvt(1) command, e.g. "chvt 7" for VT #7.

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.