1

I'm trying to come up with a simple command that reads an image and displays it, while simultaneously writing it to the clipboard. This is what I've tried and how it failed:

cat pic.png | tee >(xclip -selection clipboard -t image/png -i) | display -

This fails because I'm not able to see the image with display until after the xclip process exits

maim -s | tee >(display -) | xclip -selection clipboard -t image/png

This also fails because the picture is not put in the clipboard until after the display process finishes

maim -s | tee >(display -) >(xclip -selection clipboard -t image/png)
maim -s | tee >(xclip -selection clipboard -t image/png) >(display -)

These two also fail with behaviors similar to cases 1 and 2 respectively.

Is it possible to do this without relying on temp files or reading the clipboard right after writing to it?

Update:

Chaining tees yields weird results:

maim -s | tee >(display -) | tee >(xclip -selection clipboard -t image/png)

This partially works, display shows the full image BUT the clipboard only contains a mangled/or incomplete copy of it i.e. if I paste it on GIMP only 10% is pasted and the rest is just the color gray. Example side by side: display and the contents of the clipboard pasted in GIMP.

enter image description here

maim -s | tee >(xclip -selection clipboard -t image/png) | tee >(display -) 

This also works partially, the complete image is put on the clipboard but display fails with an error:

display: no decode delegate for this image format `' @ error/constitute.c/ReadImage/566.

Update 2:

Well, it seems to not be an easy way to do this in an "elegant" way, let alone portable. So the best approach would be to do this in 3 steps:

  1. Create 2 pipes mkfifo /tmp/p1 /tmp/p2
  2. Take the image and write it to said pipes maim | tee /tmp/p1 /tmp/p2
  3. Read from both pipes concurrently display < /tmp/p1 & xclip ... < /tmp/p2

You might even do it in 2 lines but you get the idea...

Another solution is to use the filter flag of xclip, from the man pages:

   -f, -filter
          when xclip is invoked in the in mode with output level set to silent (the defaults), the filter option will cause xclip to print the text piped to standard in back to standard out unmodified

So it looks like this:

maim -s -f png | xclip -i -f -selection clipboard -t image/png | display

This seems to be the best approach and the intended way of using xclip by the way

0

You need to buffer more or less the whole data in memory. I.e. you could write it to a tmp file in /dev/shm, too.

The alternative is a buffering program:

tee <pic.png >(buffer | xclip -selection clipboard -t image/png -i) | display -

You may have to make sure that buffer uses enough memory so you may check the file size in advance and set buffer options accordingly.

| improve this answer | |
  • If I create a tmp file in /dev/shm do I still need buffer? – arielnmz May 12 at 1:36
  • Just tried it and sadly it doesn't work... it has the same problem as the first two examples: one process must end before the other starts to work i.e. I can't see display until xclip exits – arielnmz May 12 at 7:07
  • How large is the file? The memory used by buffer must be large enough (1M by default). With a tmp file you can run the commands in parallel. Then there is no need for buffer. – Hauke Laging May 12 at 12:45

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.