Cuándo aparece
Lo ves en dos situaciones. No das ningún comando remoto pero alimentas SSH desde una tubería o un heredoc:
echo uname | ssh user@server
ssh user@server <<EOF
uname
EOF
O pides una terminal con -t cuando tu propia entrada no es una, como en cron, CI o un script:
ssh -t user@server tty < /dev/null
Pseudo-terminal will not be allocated because stdin is not a terminal.
not a tty
Los comandos se ejecutan igualmente. El mensaje va a stderr, así que puede parecer alarmante en un log de CI, pero no es un error y no cambia el código de salida.
Qué hace cada opción
Resultados de ejecutar tty en el servidor con entrada desde /dev/null:
| Comando | Terminal en el servidor | Aviso impreso |
|---|---|---|
ssh server tty | No | No |
ssh -T server tty | No | No |
ssh -t server tty | No | Sí |
ssh -tt server tty | Sí | No |
En resumen, un solo -t pide una terminal si tu lado tiene una, mientras que dos la fuerzan en cualquier caso.
Solución: estás ejecutando un script (la mayoría de los casos)
Indica un programa que lea el script. Es la solución más limpia. No imprime aviso y tampoco muestra el texto de bienvenida del servidor:
ssh user@server bash -s <<'EOF'
uname
EOF
-T también quita el aviso, pero la shell de inicio de sesión sigue imprimiendo el mensaje de bienvenida en tu salida:
echo uname | ssh -T user@server
Las comillas alrededor de 'EOF' impiden que tu shell local expanda variables antes de enviarlas.
Para un solo comando, pásalo directamente:
ssh user@server uname
Para comillas, heredocs y códigos de salida, consulta cómo ejecutar un comando por SSH.
Solución: el programa remoto necesita una terminal
Lo sabrás por un error como este, de sudo:
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
Programas como top y vim tienen necesidades parecidas. Fuerza una terminal:
ssh -tt user@server 'sudo systemctl restart nginx'
Ten cuidado con -tt en scripts. Con una terminal, lo que envías se devuelve como eco, los finales de línea pueden cambiar y la salida llega con retornos de carro. Un programa que espera una tecla también puede dejar el trabajo colgado para siempre, porque no hay nadie para pulsarla. Para automatizar, una regla de sudo estrecha, sin contraseña y sin terminal, es mejor que -tt. Mira sudo por SSH.
Fíjalo en tu configuración
Para no escribir la opción en un host usado por scripts, añádela a ~/.ssh/config:
Host backup
HostName 203.0.113.10
RequestTTY no
Los valores aceptados son no, yes, force y auto. Equivalen a -T, -t y -tt, y auto es el valor por defecto.
Preguntas
¿Pseudo-terminal will not be allocated es un error?
No. Es un aviso en stderr. Los comandos se ejecutan igual y el código de salida no cambia.
¿Qué diferencia hay entre ssh -t y ssh -tt?
-t pide un terminal solo si tu propia entrada es uno. -tt lo fuerza incluso desde una tubería o un script.
¿Cómo oculto el mensaje en un script?
Indica el comando, por ejemplo ssh user@server bash -s con un heredoc, o usa -T. RequestTTY no en ~/.ssh/config hace lo mismo para un host.