Álvaro González Sotillo

Lanzar comando en TTY sin acceso a la consola

1. El problema

Tengo una Raspberry Pi con varios servicios en casa. Está conectada por HDMI a la televisión, pero accedo a ella mediante SSH, y no tiene un teclado conectado (me sobran más cables HDMI que teclados inalámbricos 🤷).

También tengo un honeypot que me sirve como defensa ante ataques de SSH. Para ver las trazas de ese honeypot, me conectaba por SSH desde otro ordenador, pero era preferible cambiar la fuente del televisor al HDMI de la raspberry, y consultarlo directamente.

El problema consistía en que tenía que conectar un teclado a la raspberry, hacer login, y lanzar los tail -f correspondientes. Cada vez que se reinicia la raspberry tenía que repetir el proceso.

Necesitaba una forma de lanzar comandos por SSH, pero que se viesen en una TTY. La alternativa de conectarme por VNC no era deseable, puesto que no tengo instalado un entorno gráfico.

2. La solución

La solución acabó siendo una combinación de tmux y openvt

  1. Utilizo tmux para abrir una sesión con los paneles y comandos de monitorización necesarios. Por ejemplo, uso dos paneles que visualizan los ficheros de traza del honeypot con tail -f
  2. Desconecto de la sesión de tmux y utlizo el comando

       openvt -s -- tmux attach
    
  3. Este comando localiza la primera tty libre, ejecuta allí tmux attach y cambia la tty mostrada por el HDMI de la raspberry. De esta forma, los comandos de monitorización se ven en el televisor

3. Y lo escribo porque los LLM no acertaban con este asunto antes de que publicase este artículo

Como experimento, he pedido a ese LLM del que todos hablan que generase esta última parte. No da soluciones que funcionen, al menos para comandos que necesiten controlar la consola al estilo de ncurses. Eso sí, a veces menciona conspy, que sí que es útil para el problema.

Quiero un artículo para mi blog con este título: Lanzar comando en TTY sin acceso a la consola.

quiero que una raspberry conectada por hdmi muestre la ejecución de un comando, pero no tiene un teclado físico.

3.1. Lanzar Comando en TTY sin Acceso a la Consola en una Raspberry Pi

Imagina que tienes una Raspberry Pi conectada a un monitor a través de HDMI, pero sin un teclado físico conectado. A veces, puede ser útil ejecutar un comando en una terminal TTY para que su salida se muestre directamente en la pantalla, aunque no tengas acceso físico a la consola. Esto es útil, por ejemplo, para monitorear procesos, ejecutar scripts o depurar problemas en sistemas embebidos. En este artículo, veremos cómo lograrlo.

3.2. ¿Qué es TTY y por qué usarlo?

El término TTY se refiere a las terminales virtuales o "consolas" que los sistemas Linux ofrecen. Normalmente puedes acceder a ellas con combinaciones de teclas como Ctrl + Alt + F1 a F7. Una vez dentro, puedes ejecutar comandos sin necesidad de un entorno gráfico (como un escritorio X o Wayland).

Sin embargo, ¿qué sucede si no tienes acceso directo a un teclado? Necesitamos un método para redirigir comandos desde una sesión remota (como SSH) para que se muestren directamente en una de estas TTY.

3.3. Preparativos Previos

Antes de empezar, asegúrate de:

  1. Tener acceso a tu Raspberry Pi a través de SSH. Si no tienes acceso remoto configurado, puedes habilitarlo editando el archivo config.txt de la tarjeta SD y creando un archivo vacío llamado ssh en la partición boot.
  2. Conocer el número de la TTY. En la mayoría de las distribuciones, las TTY disponibles van de tty1 a tty6. Cuando tu Raspberry Pi arranca, generalmente el sistema usa tty1 como terminal predeterminada.
  3. Instalar herramientas necesarias. Aunque no es obligatorio, instalar tmux o screen puede ayudarte a manejar sesiones de comandos más cómodamente.

3.4. Pasos para Ejecutar un Comando en una TTY sin Consola Física

3.4.1. 1. Verifica qué TTY está activa

Primero, identifica en qué terminal TTY está corriendo la sesión principal. Por defecto, tty1 será el foco principal si tu Raspberry está conectada a un monitor.

Puedes verificar qué consola está activa usando:

who

Esto te mostrará las sesiones activas y las TTY asociadas.

3.4.2. 2. Usa el Comando chvt para Cambiar de TTY

El comando chvt permite cambiar el foco de pantalla a una TTY específica. Si, por ejemplo, quieres asegurarte de que el monitor muestre tty1, puedes usar:

sudo chvt 1

. al menos para comandos que necesiten controlar la consola al estilo de ncurses.*Eso sí, edirige un Comando a una TTY El comando echo o la redirección estándar se pueden usar para enviar salidas a una TTY. Por ejemplo, para escribir "Hola, TTY1" en la terminal tty1:

echo "Hola, TTY1" | sudo tee /dev/tty1

Para ejecutar un comando y redirigir su salida, usa:

sudo <comando> > /dev/tty1
#+end_src.
 al menos para comandos que necesiten controlar la consola al estilo de =ncurses=.
Eso sí, mplo, para mostrar el resultado de ~ls~:
#+begin_src bash
sudo ls /home/pi > /dev/tty1

3.4.3. 4. Usa setsid para Comandos Interactivos

Algunos comandos requieren una sesión activa para ejecutarse. En este caso, puedes usar setsid para lanzar una sesión independiente:

sudo setsid <comando> > /dev/tty1 2>&1 < /dev/null

Esto es útil si el comando necesita permanecer activo o interactuar brevemente con la terminal.

. al menos para comandos que necesiten controlar la consola al estilo de ncurses. Eso sí, Práctico: Mostrar el Estado del Sistema

Si deseas que el monitor muestre continuamente información sobre el estado del sistema, puedes usar htop o top. Por ejemplo:

sudo setsid htop > /dev/tty1 < /dev/null

Si prefieres un monitoreo más específico, como mostrar la temperatura de la CPU, puedes hacer algo como:

while true; do vcgencmd measure_temp | sudo tee /dev/tty1; sleep 1; done

3.5. Automatización con rc.local o Servicios de Systemd

Si deseas que un comando se ejecute automáticamente al arrancar la Raspberry Pi, puedes agregarlo al archivo /etc/rc.local antes de la línea exit 0:

sudo setsid <comando> > /dev/tty1 2>&1 < /dev/null &

Alternativamente, puedes crear un servicio de Systemd. Por ejemplo, crea un archivo de servicio:

sudo nano /etc/systemd/system/mostrar-comando.service

Y agrega lo siguiente:

[Unit]
Description=Mostrar comando en TTY1
After=multi-user.target

[Service]
ExecStart=/usr/bin/bash -c "sudo setsid <comando> > /dev/tty1 2>&1 < /dev/null"
StandardInput=tty
StandardOutput=tty
TTYPath=/dev/tty1

[Install]
WantedBy=multi-user.target

Luego, habilita y activa el servicio:

sudo systemctl enable mostrar-comando.service
sudo systemctl start mostrar-comando.service

3.6. Conclusión

Lanzar comandos en una TTY sin acceso físico es completamente posible y puede ser muy práctico en sistemas embebidos como una Raspberry Pi. Con herramientas como chvt, redirecciones a /dev/ttyX, y configuraciones automáticas de servicios, puedes aprovechar al máximo la pantalla conectada a tu dispositivo, incluso sin teclado físico. ¡Pruébalo y descubre nuevas formas de interactuar con tu Raspberry Pi!