11

I like to use the xclip utility to capture the output of commands on the clipboard. However, when I try to use it with shell-command it seems to hang.

In a "normal" shell I can run a command such as echo "hello world" | xclip -selection clipboard and it will return almost immediately and copy hello world to the clipboard. When I try to run the same command from shell-command the command seems to "hang": the focus stays in the minibuffer and I can't do anything until I cancel the command with C-g. After cancelling the command the text has been copied to the clipboard though.

I'm running emacs 24.4.1 on Debian 8.6

Any idea why the xclip command hangs?

1
  • use xsel instead
    – chen bin
    Feb 23, 2018 at 5:32

2 Answers 2

4

xclip has to "hang" around to own the clipboard, as X uses asynchronous clipboards which belong to a process. You should be able to get away with just using async-shell-command, which is bound to M-& by default. Another solution would be to use some clipboard manager instead.

4
  • 7
    Doing some research on xsel led me to some other information that helped clarify things for me. The way xclip is implemented is that it forks a child to manage the copied data and stdout is kept open. It seems that stdout being kept open is the immediate cause for shell-command not returning. Redirecting stdout to /dev/null (e.g. hello world" | xclip -selection clipboard &> /dev/null) causes shell-command to return immediately as expected.
    – shay
    Feb 23, 2018 at 15:40
  • 2
    This above comment is actually exactly what I needed to find out. Not emacs-specific and a very useful piece of information. Thanks!
    – rosuav
    Sep 25, 2019 at 6:42
  • And, if you xclip call is within a shell script that you call from Emacs, the &> /dev/null must be appended to the shell script call instead of the xclip. May 7, 2021 at 10:43
  • 1
    This first comment should be the accepted answer!
    – margolari
    Feb 7, 2023 at 23:09
0

Right, Commands such as (shell-command "xclip -selection clipboard -o") hang unless the clipboard has the "right" content either text or image.

As a workaround, you can terminate it by using timeout TIMEOUT.

An example:

When only plain text exists in the clipboard and you use

(shell-command (format "xclip -selection clipboard -t image/png -o > %s" image-file))

to get the plain text saved as an image-file, emacs will hang until you Ctrl-g to terminate it by force.

Adding Timeout 0.05 as

(shell-command (format "timeout 0.05 xclip -selection clipboard -t image/png -o > %s" image-file))

will end the xclip process after 0.05.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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