Cuando se conecta a un host con SSH, por lo general se proporcionan tres "tubos" entre anfitrión y huésped, para stdin
, stdout
, y stderr
.
¿Existe una opción de línea de comandos para crear reenvíos para descriptores de archivo adicionales ( 3
y en adelante)?
Por ejemplo, me gustaría hacer
ssh --forwardfd=10:3 remotehost 'echo test >&3'
que imprimiría 'prueba' al descriptor de archivo abierto localmente 10.
ssh
pipe
file-descriptors
ratones
fuente
fuente
closefrom(STDERR_FILENO + 1)
llamadas bajo el código fuente de OpenSSH. ¿Qué estás tratando de hacer que exige esto?stdin
/out
/err
, pero AFAIK, ningún servidor / cliente proporciona soporte de ninguna manera.infinite-output-cmd | ssh user@host bash /proc/self/fd/3 3< local-script-to-execute-remotely.sh
--forwardfd
ni siquiera debería ser necesario.ssh
podría verificar cuáles son los descriptores de archivos abiertos antes de abrir cualquier otra cosa y reenviarlos automáticamente a los mismos descriptores de archivos en el lado remoto. Podría ser totalmente transparente como mi ejemplo. Me pregunto qué difícil sería arreglarlossh
. Como dijiste, podría ser complicado dependiendo de las razones detrás de esoclosefrom(STDERR_FILENO + 1)
.Respuestas:
Puede hacerlo utilizando el reenvío de socket, que está disponible desde openssh-6.7. Este es algún tipo de tubería. Esta técnica se describe, por ejemplo, aquí: http://www.25thandclement.com/~william/projects/streamlocal.html
Obtendrá una ruta en dos direcciones para sus datos. Hay un ejemplo con mysql:
fuente
Estoy seguro de que debería ser posible. Solo puedo sugerir un truco donde use conexiones ssh adicionales para que cada uno lleve otro par de descriptores de archivo. Por ejemplo, el siguiente script de prueba de concepto realiza un primer ssh para ejecutar un comando ficticio (suspensión) para conectar los fds locales 5 y 6 a stdin y stdout remotos, suponiendo que estos fds son los que desea agregar a los habituales 0,1, 2)
Luego se realiza el ssh real, y en el control remoto conecta los fds remotos 5 y 6 al stdin y stdout del otro ssh.
Solo como ejemplo, este script pasa una página man comprimida al control remoto, que descomprime y ejecuta a través de man. El stdin y el stdout del ssh real todavía están disponibles para otras cosas.
fuente
El problema con la respuesta de @jakuje es: solo funciona con sockets , pero no puede utilizar herramientas UNIX estándar que esperan archivos con ellos:
ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'
También existe el problema de que el archivo de socket local no se elimina en el host remoto; la próxima vez que ejecute el mismo comando, recibirá una advertencia y el socket no se volverá a crear correctamente. Puede dar la opción
-o StreamLocalBindUnlink=yes
dessh
desvincular ese socket antiguo, pero en mis pruebas no fue suficiente; también tiene que editarlosshd_config
para contenerStreamLocalBindUnlink=yes
esa opción para que funcione.Pero puede usar
socat
onetcat
cualquier otra herramienta similar que admita sockets locales UNIX (¡ NOnetcat-traditional
es suficiente!) Para usar el reenvío de sockets locales para la transferencia de archivos:También puede ejecutar comandos interactivos, en cuyo caso debe usar
ssh -t
para asignar TTY.El problema con esta solución es que debe codificar las rutas de los sockets locales de UNIX: localmente, este no es un problema tan grande como puede incluir
$$
en la ruta para que sea único por proceso o usuario, un directorio temporal, pero en el es mejor que no use el directorio de escritura mundial/tmp/
como lo hago en mi ejemplo. El directorio también debe existir cuandossh
se inicia la sesión. Y el inodo del socket permanecerá incluso después de que se cierre la sesión, por lo que usar algo como "$ HOME / .ssh. $$" desordenará su directorio con inodos muertos a lo largo del tiempo.También puede usar los sockets TCP vinculados
localhost
, lo que le ahorrará el desorden de sus sistemas de archivos con inodos muertos, pero incluso con ellos aún tiene problemas para elegir un número de puerto (único) no utilizado. Entonces todavía no es ideal. (ssh
tiene código para asignar puertos dinámicamente, pero no encontré ninguna forma de recuperar esa información en el host remoto).Probablemente, la solución más fácil para copiar archivos es usar la funcionalidad de intercambio de conexiones incorporada de ssh y hacer un comando
scp
osfrp
mientras su sesión interactiva todavía se ejecuta en paralelo. Consulte Copiar un archivo al sistema local con ssh .fuente