Cómo enviar datos al portapapeles local desde una sesión remota de SSH

161

Pregunta de Borderline ServerFault, pero estoy programando algunos scripts de shell, así que estoy intentando aquí primero :)

La mayoría de los * nixes tienen un comando que le permitirá canalizar / redirigir la salida al portapapeles / cartón local y recuperarla. En OS X estos comandos son

pbcopy, pbpaste 

¿Hay alguna forma de replicar esta funcionalidad mientras SSHed en otro servidor? Es decir,

  1. Estoy usando la computadora A.
  2. Abro una ventana de terminal
  3. I SSH a la computadora B
  4. Ejecuto un comando en la computadora B
  5. La salida de la computadora B se redirige o se copia automáticamente al portapapeles de la computadora A.

Y sí, sé que podría (temblar) usar mi mouse para seleccionar el texto del comando, pero me he acostumbrado tanto al flujo de trabajo de la salida de pipping directamente al portapapeles que quiero lo mismo para mis sesiones remotas.

El código es útil, pero también se aprecian los enfoques generales.

Alan Storm
fuente

Respuestas:

89

Estoy resucitando este hilo porque he estado buscando el mismo tipo de solución y encontré una que funciona para mí. Es una modificación menor a una sugerencia de OSX Daily .

En mi caso, uso Terminal en mi máquina OSX local para conectarme a un servidor Linux a través de SSH. Al igual que el OP, quería poder transferir pequeños fragmentos de texto desde la terminal a mi portapapeles local, usando solo el teclado.

La esencia de la solución:

commandThatMakesOutput | ssh desktop pbcopy

Cuando se ejecuta en una sesión ssh a una computadora remota, este comando toma la salida de commandThatMakesOutput (por ejemplo, ls, pwd) y canaliza la salida al portapapeles de la computadora local (el nombre o IP del "escritorio"). En otras palabras, utiliza ssh anidado: está conectado a la computadora remota a través de una sesión ssh, ejecuta el comando allí, y la computadora remota se conecta a su escritorio a través de una sesión ssh diferente y coloca el texto en su portapapeles.

Requiere que tu escritorio esté configurado como un servidor ssh (que te dejo a ti y a google). Es mucho más fácil si ha configurado claves ssh para facilitar el uso rápido de ssh, preferiblemente usando una frase de contraseña por sesión, o lo que requiera su seguridad.

Otros ejemplos:

ls  | ssh desktopIpAddress pbcopy
pwd |  ssh desktopIpAddress pbcopy

Por conveniencia, he creado un archivo bash para acortar el texto requerido después de la tubería:

#!/bin/bash
ssh desktop pbcopy

En mi caso, estoy usando una clave especialmente nombrada

Lo guardé con el nombre de archivo cb (my mnemonic (ClipBoard). Coloque el script en algún lugar de su ruta, hágalo ejecutable y listo:

ls | cb
rhileighalmgren
fuente
3
A menudo a esto en vim. Para hacerlo, seleccione lo que desea copiar en modo visual, luego escriba::'<,'>w !ssh desktop pbcopy
Mike Brennan
@MikeBrennan Cuando tiene el texto seleccionado, ¿por qué no presiona cmd + C (o cualquier tecla de copia que haya configurado)? ...
Petr Peller
36
De esta manera, solo funciona realmente cuando su escritorio tiene una IP estática y es accesible desde la caja en la que ingresó. Ese nunca es el caso para mí.
kqw
66
¿No sería al revés más fácil? ssh user @ remote 'commandThatMakesOutput' | pbcopy
rulio
Necesitaba la -e nonebandera ssh descrita aquí: unix.stackexchange.com/questions/210615/…
Pat Myron
122

Mi forma favorita es ssh [remote-machine] "cat log.txt" | xclip -selection c. Esto es más útil cuando no desea (o no puede) ssh de remoto a local.

Editar: en Cygwin ssh [remote-machine] "cat log.txt" > /dev/clipboard.

Editar: Un comentario útil de nbren12:

Casi siempre es posible configurar una conexión ssh inversa utilizando el reenvío de puertos SSH. Simplemente agregue RemoteForward 127.0.0.1:2222 127.0.0.1:22a la entrada del servidor en su local .ssh/configy luego ejecute ssh -p 2222 127.0.0.1en la máquina remota, lo que redirigirá la conexión a la máquina local. - nbren12

Dominykas Mostauskis
fuente
66
+1: ¡Mucho más fácil que otras soluciones cuando no es posible una conexión SSH inversa!
John Dibling
9
¡Te mereces más Me gusta por esa solución extremadamente simple!
Kamil Dziedzic
31
Para aquellos de nosotros en Mac OSX,ssh [remote-machine] "cat log.txt" | pbcopy
chowey
1
Según este informe aquí , tuve que usar catpara que esto funcionara en cygwin Windows 8: ssh [remote-machine] "cat log.txt" | cat > /dev/clipboard(por supuesto, mi comando remoto no era cat; era algo más dentro de una máquina virtual vagabunda, así que realmente corrí vagrant ssh -c "command" | cat > /dev/clipboard)
tiby
77
Es casi siempre es posible establecer una conexión ssh inversa usando el reenvío de puertos SSH. Simplemente agregue RemoteForward 127.0.0.1:2222 127.0.0.1:22a la entrada del servidor en su local .ssh/configy luego ejecute ssh -p 2222 127.0.0.1en la máquina remota, lo que redirigirá la conexión a la máquina local.
nbren12
30

¡Encontré una gran solución que no requiere una conexión ssh inversa!

Puede usar xclip en el host remoto, junto con el reenvío ssh X11 y XQuartz en el sistema OSX.

Para configurar esto:

  1. Instale XQuartz (hice esto con soloist + pivotal_workstation :: xquartz receta , pero no tiene que hacerlo)
  2. Ejecute XQuartz.app
  3. Abrir las preferencias de XQuartz ( kb_command+ ,)
  4. Asegúrese de que "Habilitar sincronización" y "Actualizar el tablero de cartón cuando los cambios de CLIPBOARD" estén marcados Ejemplo de ventana de preferencias de XQuartz
  5. ssh -X remote-host "echo 'hello from remote-host' | xclip -selection clipboard"
TrinitronX
fuente
1
¿Cómo es esto diferente de ssh remote-host "echo 'hello from remote-host' | pbcopy? Esta sería una excelente respuesta si funcionara así: ssh -X remote-hosten el host remoto:echo 'hello from remote-host' | xclip -selection clipboard
kqw
55
@KasperSouren. Creo que funciona como esperas. El `| xclip` está dentro de las comillas dobles.
gdw2
1
En 2016, esta es obviamente LA mejor solución sin lujos. Olvídate de otras soluciones basadas en ssh inverso.
Shivams
1
¿Hay alguna manera de hacer esto sin ser solo un comando único? Quiero iniciar sesión en mi servidor remoto en una sesión interactiva a través de ssh y luego poder enviar a mi portapapeles local arbitrariamente. ¿Eso requiere ssh inverso?
Kvass
2
@Kvass: siempre que esté utilizando -Xpara el reenvío X11 a través de SSH, los programas X11 podrán actualizar su portapapeles a través de la configuración de XQuartz anterior. El comando único es demostrar que enviar algo a través echodel portapapeles del host remoto xclipfunciona y debe sincronizarse con su host cliente SSH local. Nota como @ gdw2 dice, "El | xclipestá dentro de las comillas dobles". Como tal, se ejecutará como un comando en el servidor remoto para enviar algo a su portapapeles.
TrinitronX
18

Puerto de túnel inverso en el servidor ssh

Todas las soluciones existentes necesitan:

  • X11 en el cliente (si lo tiene, xclipen el servidor funciona muy bien) o
  • que el cliente y el servidor estén en la misma red (que no es el caso si está en el trabajo tratando de acceder a la computadora de su hogar).

Aquí hay otra forma de hacerlo, aunque deberá modificar la forma en que ingresa a su computadora.

He comenzado a usar esto y no es tan intimidante como parece, así que pruébalo.

Cliente (inicio de sesión ssh)

ssh username@server.com -R 2000:localhost:2000

(sugerencia: haga que esta sea una combinación de teclas para que no tenga que escribirla)

Cliente (otra pestaña)

nc -l 2000 | pbcopy

Nota: si no lo tiene pbcopy, solo teelo tiene en un archivo.

Servidor (dentro de la sesión SSH)

cat some_useful_content.txt | nc localhost 2000

Otras notas

En realidad, incluso si estás en medio de una sesión ssh, hay una manera de comenzar un túnel, pero no quiero asustar a la gente de lo que realmente no es tan malo como parece. Pero agregaré los detalles más adelante si veo algún interés

Sridhar Sarnobat
fuente
1
+1: eso es bastante bueno. Sin embargo, el cat some_useful_content.txt | nc localhost 2000comando parece bloquearse cuando hago esto. Necesito ctr-c manualmente para detenerlo, y es solo entonces que el contenido llega al clip / cartón de mi cliente
Alan Storm
1
Esperará hasta que alguien retire los datos en el otro extremo.
Sridhar Sarnobat
En realidad creo que entendí mal tu pregunta. No estoy seguro de por qué sucede eso.
Sridhar Sarnobat
nc -l -pfunciona para mí, pero simplemente nc -lno. Y también tengo el problema de @AlanStorm.
HappyFace
1
Resolví el problema de colgar netcat especificando -c. Yo uso GNU netcat instalado por brew.
HappyFace
7

Existen varias herramientas para acceder a las selecciones X11, incluidas xclip y XSel . Tenga en cuenta que X11 tradicionalmente tiene múltiples selecciones, y la mayoría de los programas tienen cierta comprensión tanto del portapapeles como de la selección primaria (que no son lo mismo). Emacs también puede trabajar con la selección secundaria, pero eso es raro, y nadie sabe realmente qué hacer con los tampones de corte ...

$ xclip -help
Uso: xclip [OPCIÓN] [ARCHIVO] ...
Acceda a una selección de servidor X para leer o escribir.

  -i, -en leer el texto en la selección X de la entrada estándar o archivos
                   (defecto)
  -o, -out imprime la selección al estándar (generalmente para
                   canalización a un archivo o programa)
  -l, -loops número de solicitudes de selección a esperar antes de salir
  -d, -display X display para conectarse (p. ej. localhost: 0 ")
  -h, -ayuda información de uso
      -selección de selección para acceder ("primario", "secundario", "portapapeles" o "corte de búfer")
      -noutf8 no trate el texto como utf-8, use unicode antiguo
      -versión versión información
      -solo errores silenciosos, se ejecuta en segundo plano (predeterminado)
      -secuencia silenciosa en primer plano, muestra lo que está sucediendo
      -verbio comentario corriente

Informe los errores a <[email protected]>
$ xsel -help
Uso: xsel [opciones]
Manipular la selección X.

Por defecto, la selección actual se emite y no se modifica si ambos
La entrada estándar y la salida estándar son terminales (ttys). De otra manera,
la selección actual se emite si la salida estándar no es un terminal
(tty), y la selección se establece desde la entrada estándar si la entrada estándar
No es un terminal (tty). Si se dan opciones de entrada o salida, entonces
el programa se comporta solo en el modo solicitado.

Si se requieren entradas y salidas, entonces la selección previa es
salida antes de ser reemplazado por el contenido de la entrada estándar.

Opciones de entrada
  -a, --append Agregar entrada estándar a la selección
  -f, --siguiente Anexar a la selección a medida que crece la entrada estándar
  -i, --input Lee la entrada estándar en la selección

Opciones de salida
  -o, --output Escribe la selección en la salida estándar

Opciones de acción
  -c, --clear Borrar la selección
  -d, --delete Solicita que se borre la selección y que
                        la aplicación que lo posee borra su contenido

Opciones de selección
  -p, --primary Operate en la selección PRIMARY (predeterminado)
  -s, --secondary Operar en la selección SECUNDARIA
  -b, --clipboard Operar en la selección CLIPBOARD

  -k, --keep No modifique las selecciones, pero haga que PRIMARY
                        y las selecciones SECUNDARIAS persisten incluso después de
                        programas fueron seleccionados en la salida.
  -x, --exchange Intercambia las selecciones PRIMARIA y SECUNDARIA

X opciones
  --display displayname
                        Especifique la conexión al servidor X
  -t ms, --selectionTimeout ms
                        Especifique el tiempo de espera en milisegundos dentro del cual
                        La selección debe ser recuperada. Un valor de 0 (cero)
                        no especifica tiempo de espera (predeterminado)

Opciones varias
  -l, --logfile Especifica el archivo para registrar errores cuando se desconecta.
  -n, --nodetach No se desconecte del terminal de control. Sin
                        esta opción, xsel se bifurcará para convertirse en un fondo
                        proceso en modos de entrada, intercambio y mantenimiento.

  -h, --help Mostrar esta ayuda y salir
  -v, --verbose Imprimir mensajes informativos
  --version Muestra información de la versión y sale

Informe los errores a <[email protected]>.

En resumen, deberías probar xclip -i/ xclip -oo xclip -i -sel clip/ xclip -o -sel clipo xsel -i/ xsel -oo xsel -i -b/ xsel -o -b, dependiendo de lo que quieras.

efímero
fuente
44
Para añadir a @ephemient 's mensaje: Para uso xclip y XSEL con un host remoto, puede utilizar X11 Forwarding, así: ssh -C -X user@remote-host. Si ejecutar xclip en el lado remoto no parece funcionar, asegúrese de que X11Forwarding yesesté configurado en el /etc/ssh/sshd_configarchivo remoto . También asegúrese de que xauthesté instalado en el lado remoto. Para una máquina sin cabeza, puede instalar xauthy xvfb.
TrinitronX
Aquí hay una descripción con detalles adicionales más enlaces de teclas vim.
Tim Bunce
1
@TrinitronX oh wow - golpeando mi cabeza contra la pared, gracias por la xvfbmención. Estaba ejecutando un servidor sin cabeza, ¡así que X11 no debe haber estado ejecutándose!
Cam
5

Esta es mi solución basada en el túnel inverso SSH, netcat y xclip.

Primero cree un script (por ejemplo, clipboard-daemon.sh) en su estación de trabajo:

#!/bin/bash
HOST=127.0.0.1
PORT=3333

NUM=`netstat -tlpn 2>/dev/null | grep -c " ${HOST}:${PORT} "`
if [ $NUM -gt 0 ]; then
    exit
fi

while [ true ]; do
    nc -l ${HOST} ${PORT} | xclip -selection clipboard
done

y comenzarlo en segundo plano.

./clipboard-daemon.sh&

Comenzará la salida de tuberías nc a xclip y el proceso de reaparición después de recibir una porción de datos

Luego, inicie la conexión ssh al host remoto:

ssh user@host -R127.0.0.1:3333:127.0.0.1:3333

Mientras está conectado en la caja remota, intente esto:

echo "this is test" >/dev/tcp/127.0.0.1/3333

luego intente pegar en su estación de trabajo

Por supuesto, puede escribir una secuencia de comandos de contenedor que inicie clipboard-daemon.sh primero y luego la sesión ssh. Así es como funciona para mí. Disfrutar.

Krzysztof Księżyk
fuente
Esta solución es la que mejor funcionó para mí. No es demasiado complicado y funciona correctamente.
Marcel Valdez Orozco
La mejor solución en mi opinión. No tiene que preocuparse por permitir la conexión ssh inversa que tiene implicaciones de seguridad, y el bucle infinito es un buen toque.
R. Taukulis
4

No es una línea, pero no requiere ssh extra .

  • instalar netcatsi es necesario
  • utilizar termbin : cat ~/some_file.txt | nc termbin.com 9999. Esto copiará la salida al termbinsitio web e imprimirá la URL a su salida.
  • visita esa url desde tu computadora, obtienes tu salida

Por supuesto, no lo use para contenido sensible.

maxbellec
fuente
Wow, esa es una solución muy creativa.
Sridhar Sarnobat
3

Esta respuesta se desarrolla tanto sobre la respuesta elegida al agregar más seguridad.

Esa respuesta discutió la forma general

<command that makes output> | \
    ssh <user A>@<host A> <command that maps stdin to clipboard>

Donde la seguridad puede estar ausente en los sshpermisos que permite <user B>el host B>a sshen host Ay ejecutar cualquier comando.

Por supuesto Bque Ael acceso ya pueden estar cerrada por una sshclave, e incluso puede tener una contraseña. Pero otra capa de seguridad puede restringir el alcance de los comandos permitidos que se Bpueden ejecutar A, por ejemplo, para que rm -rf /no se pueda invocar. (Esto es especialmente importante cuando la sshclave no tiene una contraseña).

Afortunadamente, sshtiene una característica incorporada llamada restricción de comando o comando forzado . Consulte ssh.com o esta pregunta de serverfault.com .

La solución a continuación muestra la solución de forma general junto con la ssh restricción de comandos impuesta.

Solución de ejemplo con restricción de comando agregada

Esta solución de seguridad mejorada sigue la forma general: la llamada de la sshsesión en adelante host-Bes simplemente:

cat <file> | ssh <user-A>@<host A> to_clipboard

El resto de esto muestra la configuración para que eso funcione.

Configuración de restricción de comando ssh

Supongamos que la cuenta de usuario en Bes user-B, y B tiene una clave ssh id-clip, que se ha creado de la manera habitual ( ssh-keygen).

Luego, en user-Ael directorio ssh hay un archivo

/home/user-A/.ssh/authorized_keys

que reconoce la clave id-clipy permite la sshconexión.

Por lo general, el contenido de cada línea authorized_keyses exactamente la clave pública que se autoriza, por ejemplo, el contenido de id-clip.pub.

Sin embargo, para imponer la restricción de comandos , el contenido que se ejecutará antepone el contenido de la clave pública (en la misma línea).
En nuestro caso:

command="/home/user-A/.ssh/allowed-commands.sh id-clip",no-agent-forwarding,no-port-forwarding,no-user-rc,no-x11-forwarding,no-pty <content of file id-clip.pub>

El comando designado "/home/user-A/.ssh/allowed-commands.sh id-clip", y solo ese comando designado, se ejecuta cada vez que id-clipse usa la tecla para iniciar una sshconexión host-A, sin importar en qué comando se escriba la sshlínea de comando .

El comando indica un archivo de script allowed-commands.sh, y el contenido de ese archivo de script es

#/bin/bash
#
# You can have only one forced command in ~/.ssh/authorized_keys. Use this
# wrapper to allow several commands.

Id=${1}

case "$SSH_ORIGINAL_COMMAND" in
    "to-clipboard")
          notify-send "ssh to-clipboard, from ${Id}"
        cat | xsel --display :0 -i -b
          ;;
    *)
        echo "Access denied"
        exit 1
        ;;
esac

La llamada original a la sshmáquina Bfue

... | ssh <user-A>@<host A> to_clipboard

La cadena to-clipboardpasa a allowed-commands.shla variable de entorno SSH_ORIGINAL_COMMAND. Además, hemos pasado el nombre de la clave id-clip, desde la línea en la authorized_keysque solo se accede por id-clip.

La línea

          notify-send "ssh to-clipboard, from ${Id}"

es solo un cuadro de mensaje emergente para hacerle saber que se está escribiendo el portapapeles; probablemente también sea una buena característica de seguridad. ( notify-sendfunciona en Ubuntu 18.04, tal vez no en otros).

En la linea

cat | xsel --display :0 -i -b

el parámetro --display :0es necesario porque el proceso no tiene su propia pantalla X con un portapapeles, por lo que debe especificarse explícitamente. Este valor :0funciona en Ubuntu 18.04 con el servidor de ventana Wayland. En otras configuraciones, podría no funcionar. Para un servidor X estándar, esta respuesta podría ayudar.

host-A /etc/ssh/sshd_config parámetros

Finalmente, se deben configurar algunos parámetros en /etc/ssh/sshd_configel host Apara garantizar el permiso de conexión y el permiso para usar la sshtecla solo sin contraseña:

PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowUsers user-A

Para hacer que el sshdservidor vuelva a leer la configuración

sudo systemctl restart sshd.service

o

sudo service sshd.service restart

conclusión

Es un esfuerzo configurarlo, pero otras funciones además to-clipboardse pueden construir en paralelo en el mismo marco.

Craig Hicks
fuente
1
El Xsel con envío remoto fue la única respuesta que me funcionó en Ubuntu 18.04 ejecutando i3 localmente. No se necesita reenvío X11.
Jay Stanley
2

La solución más simple de todas, si está en OS X usando Terminal y ha estado trabajando en un servidor remoto y desea obtener los resultados de un archivo de texto o un registro o un csv, simplemente:

1) Cmd-Kpara borrar la salida del terminal

2) cat <filename>para mostrar el contenido del archivo

3) Cmd-Spara guardar la salida del terminal

Deberá eliminar manualmente la primera línea y la última línea del archivo, pero este método es un poco más simple que confiar en la instalación de otros paquetes, "túneles inversos" e intentar tener una IP estática, etc.

tw0000
fuente
+1 para una técnica útil que he utilizado yo mismo, pero te obliga a perder tu historial de terminal y (como se mencionó) el problema de la primera / última línea es un poco complicado.
Alan Storm
De acuerdo @AlanStorm
tw0000
El problema más importante con este enfoque es que solo guardará el número de líneas que retiene el búfer de su terminal. A menudo, eso no es un problema, pero si está tratando de tomar el contenido de un archivo de registro, entonces puede quedarse sin capacidad,
Sridhar Sarnobat
Eso es cierto @ Sridhar-Sarnobat, no es una muy buena solución en general. Yo solo uso scp!
tw0000