xclip funciona de forma diferente em shells interativos e não interativos

5

Ao investigar um problema descrito em uma pergunta em stackoverflow Eu simplifiquei isso em um caso de teste demonstrando que no modo não interativo o bash parece limpar a área de transferência do sistema X antes de sair. O teste abre um terminal do gnome e executa um script bash que coloca (via xclip ) algum texto na área de transferência do sistema X. Enquanto o terminal está aberto, a consulta da área de transferência retorna o texto que foi colocado nele, independentemente de o bash ser executado no modo interativo ou não interativo. No entanto, depois que o terminal é fechado, o conteúdo da área de transferência sobrevive se o bash foi executado no modo interativo, mas é perdido se o bash foi executado no modo não interativo.

$ 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            #!!!!!!!!!!!!!

Eu estou no Ubuntu 16.04, usando bash padrão do GNU ( version 4.3.46(1)-release (x86_64-pc-linux-gnu) ) sem customizações para bash arquivos rc. Eu verifiquei .bash_logout apenas no caso e encontrei uma chamada para clear_console utility. No entanto clear_console não parece lidar com a área de transferência; Além disso, o exemplo não executa o bash como um shell de login.

Isso é algo que tem uma explicação sensata?

EDITAR

O problema persiste ao substituir gnome-terminal por xterm :

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

Também não é exclusivo de bash - também é reproduzido com dash .

    
por Leon 16.10.2016 / 12:34

2 respostas

3

O autor da pergunta original no Stackoverflow < um href="https://stackoverflow.com/a/40137805/6394138"> identificou isso como um problema no xclip . Usando xsel em vez de xclip para manipular a área de transferência X elimina o problema (observe que xclip foi substituído por xsel somente quando coloca dados na área de transferência, e não quando < em> lendo de a área de transferência):

$ 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

Ambos xclip e xsel funcionam desanexando do terminal e gerando um processo filho que é responsável pelo fornecimento da (s) seleção (ões) sob demanda (até que uma nova seleção seja feita):

$ 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

O problema com xclip parece ser que, quando lançado de um shell não interativo, ele não se torna totalmente independente do terminal de controle e morre quando o processo do terminal termina.

    
por 02.11.2016 / 09:01
3

Na verdade, não existe X "área de transferência do sistema". Seleções no X funcionam por dois clientes X cooperando: Um cliente X afirma que possui uma seleção (primária, secundária, área de transferência) e outro cliente X que deseja colar a seleção contata o primeiro cliente para recebê-lo.

Então, quando o primeiro cliente está morto, não há seleção. Eu não tenho certeza de como o modo interativo do bash se traduz em "o terminal / bash ainda está disponível para responder", no entanto. Fazer um ps pode ajudar a esclarecer as coisas.

O mesmo se aplica à seleção da área de transferência, a menos que você execute o programa xclipboard (ou um programa semelhante) ao mesmo tempo, que assume a responsabilidade de fornecer a seleção. (Veja, por exemplo, o artigo wikipedia ).

Há também buffers de corte armazenados como propriedades das janelas raiz, que você pode usar para armazenar conteúdo permanente.

    
por 17.10.2016 / 08:43