Así que estoy escribiendo una utilidad de línea de comandos y me encontré con un problema que me intriga.
La utilidad se puede llamar con argumentos de archivo o se puede leer desde sys.stdin . Originalmente estaba usando sys.stdin.isatty() para averiguar si los datos se están canalizando, sin embargo, descubrí que si llamo a la utilidad de forma remota a través ssh server utility , sys.stdin.isatty() devolverá falso, a pesar de la hecho de que no se están canalizando datos reales.
Como solución alternativa, estoy usando - como argumento de archivo para forzar la lectura desde stdin (por ejemplo: echo "data_here" | utility -f - ), pero tengo curiosidad por saber si hay una manera confiable de diferenciar entre una tubería obtener datos de un proceso y una tubería que solo está abierta porque la llamada es a través de ssh.
La programación de sistemas no es mi fuerte, así que estoy agradecido por cualquier ayuda que pueda obtener de ustedes.
Puede saber si lo están invocando a través de SSH al verificar su entorno. Si lo invocan a través de una conexión SSH, se establecerán las variables de entorno SSH_CONNECTION y SSH_CLIENT . Puede probar si están configurados con, digamos:
if "SSH_CONNECTION" in os.environ: # do something Otra opción, si quisiera seguir con su enfoque original de sys.stdin.isatty() , sería asignar un pseudo-tty para la conexión SSH. Normalmente, SSH hace esto de forma predeterminada si solo ingresa a SSH para una sesión interactiva, pero no si proporciona un comando. Sin embargo, puede forzarlo a que lo haga cuando proporcione un comando pasando el indicador -t :
ssh -t server utilitySin embargo, le advierto que no haga ninguno de estos. Como puede ver, tratar de detectar si debe aceptar la entrada de stdin en función de si es un TTY puede causar un comportamiento sorprendente. También podría causar frustración en los usuarios si quisieran una forma de proporcionar información interactiva a su programa al depurar algo.
El enfoque - agregar un argumento explícito hace que sea mucho más explícito y menos sorprendente qué comportamiento obtienes. Algunas utilidades también usan la falta de argumentos de archivo para leer desde stdin, por lo que también sería una alternativa menos sorprendente.
De acuerdo con esta respuesta , se debe declarar la variable de entorno SSH_CLIENT o SSH_TTY . A partir de eso, el siguiente código debería funcionar:
import os def running_ssh(): return 'SSH_CLIENT' in os.environ or 'SSH_TTY' in os.environ Un ejemplo más completo examinaría los procesos principales para verificar si alguno de ellos es sshd , lo que probablemente requiera el módulo psutil .