
Escribí un script para configurar el portapapeles de mi escritorio desde mi teléfono Android.
#!/bin/sh
ssh -Y user@host "export DISPLAY=:0; echo -n $(termux-clipboard-get) | xclip -selection clipboard"
El script funciona como se esperaba pero no finaliza. Tengo que presionar Ctrl+ Cpara volver al mensaje.
He usado la -f
opción y regresa inmediatamente. De man ssh
:
-f
Solicitassh
pasar a segundo plano justo antes de la ejecución del comando. Esto es útil sissh
va a solicitar contraseñas o frases de contraseña, pero el usuario las quiere en segundo plano. […]
No estoy seguro de si es la forma correcta de resolver esto. No es necesario ejecutarlo en segundo plano. Sólo necesita ejecutar un comando y regresar.
¿Por qué no ssh
regresa? ¿Es ssh -f
una buena manera? ¿Existe una mejor manera?
Respuesta1
Las selecciones en X funcionan mediante dos clientes X que cooperan: un cliente X afirma que tiene una selección (primaria, secundaria, portapapeles) y otro cliente X que quiere pegar la selección se comunica con el primer cliente para recibirla.
En su caso el original xclip
muere pero su hijo sobrevive para reclamar que tiene la selección y servir para futuros clientes que quieran pegar. Parece que no se desconecta por completo y el servidor SSH espera a que salga; entonces su ssh
cliente espera a que salga. De ahí la necesidad de Ctrl+ C.
Más tarde, si otro cliente afirma que tiene la selección, el control remoto xclip
saldrá y desbloqueará su local ssh
. Esto significa que su solución -f
no es tan mala: los procesos en segundo plano no se acumularán, habrá como máximo uno detenido ssh
.
La respuesta vinculada intenta resolver un problema que parece algo relacionado.Otra respuestaahí aconseja xsel
. De hecho, en mis pruebas esto no bloquea:
ssh -Y user@host "export DISPLAY=:0; echo -n foobar | xsel -i -b"
Cambiar xclip
a xsel
es crucial. Aún así, tu comando original se puede mejorar más.
Creo que no necesitas
-Y
(o-X
) porque los comandos remotos no interactúan con tu servidor X local. Es suficiente configurarloDISPLAY
a la derecha para que apuntexsel
a la pantalla deseada, que eslocalaxsel
.No hay necesidad de
export
. La variable sólo es relevante paraxsel
, por lo que este fragmento debería ser suficiente:DISPLAY=:0 xsel -i -b
Fallo grave.
$(termux-clipboard-get)
se expande localmente y todo lo que obtengatermux-clipboard-get
se incrustará en la cadena que pase al shell remoto para seriterpretadocomo código.Por ejemplo, si
termux-clipboard-get
regresa; rm -f /very/important/file; true
, se ejecutará el shell remotoexport DISPLAY=:0; echo -n ; rm -f /very/important/file; true | …
¿Ves lo que hace? Lo correcto es conectar a
ssh
:termux-clipboard-get | ssh user@host 'DISPLAY=:0 xsel -i -b'
De esta manera, la salida de
termux-clipboard-get
nunca será tratada como código.Supongo que solías
echo -n
obtener deliberadamente el resultadotermux-clipboard-get
sin ningún carácter de nueva línea al final. Si es así, deberías eliminar las nuevas líneas finales localmente yno confiar enecho
:printf '%s' "$(termux-clipboard-get)" | …
La forma final puede ser:
printf '%s' "$(termux-clipboard-get)" | ssh user@host 'DISPLAY=:0 xsel -i -b'
Tenga en cuenta que el comando eliminará los caracteres de nueva línea finales incluso de los datos que deben interpretarse como binarios y no modificarse. Los caracteres NUL también serán problemáticos. Si necesita pasar algunos datos palabra por palabra, simplemente canalice termux-clipboard-get
directamente desde:
termux-clipboard-get | ssh …