10

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?

shay
  • 203
  • 1
  • 7

2 Answers2

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.

  • 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 '18 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 '19 at 06: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`. – Torsten Bronger May 07 '21 at 10:43
  • 1
    This first comment should be the accepted answer! – margolari Feb 07 '23 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.

Leu_Grady
  • 2,420
  • 1
  • 17
  • 27