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
- 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 contail -f
Desconecto de la sesión de
tmux
y utlizo el comandoopenvt -s -- tmux attach
- Este comando localiza la primera
tty
libre, ejecuta allítmux attach
y cambia latty
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:
- 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 llamadossh
en la particiónboot
. - Conocer el número de la TTY. En la mayoría de las distribuciones, las TTY disponibles van de
tty1
atty6
. Cuando tu Raspberry Pi arranca, generalmente el sistema usatty1
como terminal predeterminada. - Instalar herramientas necesarias. Aunque no es obligatorio, instalar
tmux
oscreen
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!