5

While investigating a problem described in a question at stackoverflow I simplified it down to a test case demonstrating that in non-interactive mode bash seems to clear the X system clipboard before exiting. The test opens a gnome terminal and runs a bash script in it that places (via xclip) some text in the X system clipboard. While the terminal is open, querying the clipboard returns the text that was placed in it regardless of whether bash is run in interactive or non-interactive mode. However, after the terminal is closed, the clipboard contents survives if bash was run in interactive mode, but is lost if bash was run in non-interactive mode.

$ cat xclip_test 
#!/usr/bin/env bash
set -x
gnome-terminal -x bash -i -c "echo abc|xclip -selection clipboard; sleep 3"
sleep 1
xclip -o -selection clipboard
sleep 4
xclip -o -selection clipboard
gnome-terminal -x bash -c "echo 123|xclip -selection clipboard; sleep 3"
sleep 1
xclip -o -selection clipboard
sleep 4
xclip -o -selection clipboard

$ ./xclip_test
+ gnome-terminal -x bash -i -c 'echo abc|xclip -selection clipboard; sleep 3'
+ sleep 1
+ xclip -o -selection clipboard
abc
+ sleep 4
+ xclip -o -selection clipboard
abc
+ gnome-terminal -x bash -c 'echo 123|xclip -selection clipboard; sleep 3'
+ sleep 1
+ xclip -o -selection clipboard
123
+ sleep 4
+ xclip -o -selection clipboard
Error: target STRING not available            #!!!!!!!!!!!!!

I am on Ubuntu 16.04, using default GNU bash (version 4.3.46(1)-release (x86_64-pc-linux-gnu)) with no customizations to bash rc files. I checked .bash_logout just in case and found a call to clear_console utility. However clear_console doesn't seem to deal with the clipboard; besides, the example doesn't run bash as a login shell.

Is this something having a sensible explanation?

EDIT

The problem persists when replacing gnome-terminal with xterm:

gnome-terminal -x ... --> xterm -e ... &

Also it is not unique to bash - it is reproduced with dash, too.

5
  • gnome-terminal has some stuff which senses urls on the screen and makes those specially selectable. It would be nice if gnome-terminal had documentation worth discussing (reading the source code is not always rewarding). Oct 16, 2016 at 16:21
  • It would be interesting to see 1) whether this occurs with a terminal emulator other than gnome-terminal, and 2) whether it occurs with a shell other than bash. Oct 16, 2016 at 19:17
  • @MichaelHomer The problem is reproduced with xterm and dash too. Added that info to the question.
    – Leon
    Oct 17, 2016 at 4:13
  • @ThomasDickey Following Michael's advice I checked that this problem is reproduced with xterm as well. Thus gnome-terminal's URL sensing feature cannot be blamed for it.
    – Leon
    Oct 17, 2016 at 4:16
  • this problem is not limited to non-interactive shells. happens with interactive tcl or python too: stackoverflow.com/questions/46009076/…
    – phil294
    Nov 26, 2017 at 4:58

4 Answers 4

4

The author of the original question on Stackoverflow has identified this to be a problem in xclip. Using xsel instead of xclip for manipulating the X clipboard eliminates the issue (note that xclip was replaced with xsel only when placing data into the clipboard, and not when reading from the clipboard):

$ cat xclip_test 
#!/usr/bin/env bash
set -x
xterm -e bash -c "echo abc|xclip -selection clipboard; sleep 3"&
sleep 1
xclip -o -selection clipboard
sleep 4
xclip -o -selection clipboard

$ cat xsel_test 
#!/usr/bin/env bash
set -x
xterm -e bash -c "echo abc|xsel --input --clipboard; sleep 3"&
sleep 1
xclip -o -selection clipboard
sleep 4
xclip -o -selection clipboard

$ diff xclip_test xsel_test 
3c3
< xterm -e bash -c "echo abc|xclip -selection clipboard; sleep 3"&
---
> xterm -e bash -c "echo abc|xsel --input --clipboard; sleep 3"&


$ ./xclip_test 
+ sleep 1
+ xterm -e bash -c 'echo abc|xclip -selection clipboard; sleep 3'
+ xclip -o -selection clipboard
abc
+ sleep 4
+ xclip -o -selection clipboard
Error: target STRING not available     # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

$ ./xsel_test 
+ sleep 1
+ xterm -e bash -c 'echo abc|xsel --input --clipboard; sleep 3'
+ xclip -o -selection clipboard
abc
+ sleep 4
+ xclip -o -selection clipboard
abc

Both xclip and xsel work by detaching from the terminal and spawning a child process that is responsible for supplying the selection(s) on demand (until a new selection is made):

$ ps -H
  PID TTY          TIME CMD
24307 pts/12   00:00:01 bash
27476 pts/12   00:00:00   ps
$ echo qwerty|xclip -selection clipboard
$ ps -H
  PID TTY          TIME CMD
27481 pts/12   00:00:00 xclip  <-- !!!!!!
24307 pts/12   00:00:01 bash
27482 pts/12   00:00:00   ps

The problem with xclip seems to be that, when launched from a non-interactive shell, it doesn't become fully independent of the controlling terminal and dies when the terminal process exits.

2
  • What happens if you put it in the background, "xclip ... &"? If that works, one could argue that it's the responsibility of the user to keep xclip alive ... And if the problem is that xclip dies to soon, then there's definitely not something running under gnome which takes over the selection like xclipboard, or else it wouldn't matter if xclip is dead or alive.
    – dirkt
    Nov 2, 2016 at 9:51
  • @dirkt Putting xclip in the background doesn't help. Neither helps redirecting its stdout and stderr to /dev/null.
    – Leon
    Nov 2, 2016 at 13:23
3

Actually, there is no X "system clipboard". Selections in X work by two X clients cooperating: One X client claims it has an selection (primary, secondary, clipboard), and another X client that wants to paste the selection contacts the first client to receive it.

So when the first client is dead, there's no selection. I'm not sure how bash interactive mode translates to "the terminal/bash is still available to respond", however. Doing a ps may help to clear things up.

The same applies to the clipboard selection, unless you run the program xclipboard (or a similar program) at the same time, which takes over the responsibility of providing the selection. (See e.g. the wikipedia article).

There are also cut-buffers stored as properties of the root windows, which you can useto store permanent content.

3
  • I'm not sure how bash interactive mode translates to "the terminal/bash is still available to respond" Evidently, xclipboard is running (it would be strange if there was no centralized/global clipboard on a system with a desktop manager). Though ps -A|grep xclipboard shows nothing, an attempt to start xclipboard ends with a "another clipboard is already running" error.
    – Leon
    Oct 17, 2016 at 7:03
  • Then Gnome probably does implement that somehow (and maybe they've screwed this up; they've screwed up other things before, like X authentication per hardlinked cookie). So the next step would be to find out how Gnome is doing these things (have fun ...).
    – dirkt
    Oct 17, 2016 at 12:53
  • 1
    This turned out to a be a problem in xclip. See "my" answer.
    – Leon
    Nov 2, 2016 at 8:07
3

I came across this same problem with pass in eshell. The pass program uses xclip, which was failing in the same way you mentioned.

My solution was to create a wrapper script also named xclip in a location ahead of /usr/bin in my PATH, with the following contents:

#!/bin/sh
exec setsid /usr/bin/xclip "$@"
0

I ran into this, or a similar, problem using xclip -i. A script ending in

echo $totp | xclip -i -r

would run ok at a shell prompt, but when the script was used in a command substitution,

totp=$(get-totp)

xclip would hang. Closing its stdout works around it:

echo $totp | xclip -i -r >&-

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .