"Pseudo-terminal will not be allocated because stdin is not a terminal": qué significa y cómo solucionarlo

SSH quería una terminal en el servidor para esta sesión, pero tu entrada es una tubería, un archivo o un script y no un teclado, así que no la creó. Es un aviso y la sesión continúa. Para silenciarlo, usa -T o indica el comando que ejecutar. Si el programa remoto realmente necesita una terminal, como sudo pidiendo una contraseña, fuérzala con -tt.

Actualizada el . Todos los comandos se ejecutaron con OpenSSH 10.3 en macOS contra un servidor OpenSSH 10.0 en Linux, con entrada desde una tubería, desde /dev/null y desde un heredoc.

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:

ComandoTerminal en el servidorAviso impreso
ssh server ttyNoNo
ssh -T server ttyNoNo
ssh -t server ttyNoSí
ssh -tt server ttySí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.

Fuentes

Más en Mensajes de error

Todas las guías