xclip 在互動式和非互動式 shell 中的工作方式不同
在調查stackoverflow 的問題中描述的問題時,我將其簡化為一個測試案例,證明在非互動模式下 bash 似乎在退出之前清除了 X 系統剪貼板。該測試打開一個 gnome 終端並在其中執行一個 bash 腳本,該腳本將(通過
xclip
)一些文本放置在 X 系統剪貼板中。當終端打開時,無論 bash 是以互動還是非互動模式執行,查詢剪貼板都會返回放置在其中的文本。但是,在終端關閉後,如果 bash 在互動模式下執行,剪貼板內容仍然存在,但如果 bash 在非互動模式下執行,則剪貼板內容會失去。$ 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 #!!!!!!!!!!!!!
我在 Ubuntu 16.04 上,使用預設的 GNU bash (
version 4.3.46(1)-release (x86_64-pc-linux-gnu)
),沒有對 bash rc 文件進行自定義。我檢查.bash_logout
以防萬一,發現對clear_console
實用程序的呼叫。但是clear_console
似乎沒有處理剪貼板;此外,該範例沒有將 bash 作為登錄 shell 執行。這件事有合理的解釋嗎?
編輯
替換為時問題仍然
gnome-terminal
存在xterm
:
gnome-terminal -x
… –>xterm -e
…&
它也不是獨有的
bash
- 它也被複製dash
。
Stackoverflow上原始問題的作者已確定這是 xclip 中的一個問題。使用
xsel
而不是xclip
操作 X 剪貼板消除了問題(請注意,僅在將數據xclip
放入剪貼板時替換為,而不是從剪貼板讀取時):xsel
$ 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
兩者都
xclip
通過xsel
從終端分離並產生一個負責按需提供選擇的子程序來工作(直到做出新的選擇):$ 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
問題
xclip
似乎是,當從非互動式 shell 啟動時,它不會完全獨立於控制終端並在終端程序退出時死亡。
實際上,沒有 X“系統剪貼板”。X 中的選擇由兩個合作的 X 客戶端工作:一個 X 客戶端聲稱它有一個選擇(主要、次要、剪貼板),另一個想要粘貼選擇的 X 客戶端聯繫第一個客戶端接收它。
因此,當第一個客戶死亡時,就沒有選擇了。但是,我不確定 bash 互動模式如何轉換為“終端/bash 仍然可以響應”。做一個
ps
可能有助於解決問題。這同樣適用於剪貼板選擇,除非您同時執行程序
xclipboard
(或類似程序),它負責提供選擇。(參見例如維基百科文章)。還有一些作為根視窗屬性儲存的剪切緩衝區,您可以使用它來儲存永久內容。