Quand il apparaît
Vous le voyez dans deux situations. Vous ne donnez aucune commande distante mais vous alimentez SSH depuis un tube ou un heredoc :
echo uname | ssh user@server
ssh user@server <<EOF
uname
EOF
Ou bien vous demandez un terminal avec -t alors que votre propre entrée n'en est pas un, comme dans cron, la CI ou un script :
ssh -t user@server tty < /dev/null
Pseudo-terminal will not be allocated because stdin is not a terminal.
not a tty
Les commandes s'exécutent quand même. Le message va sur stderr : il peut paraître alarmant dans un journal de CI, mais ce n'est pas une erreur et il ne change pas le code de sortie.
Ce que fait chaque option
Résultats obtenus en lançant tty sur le serveur avec une entrée venant de /dev/null :
| Commande | Terminal sur le serveur | Avis affiché |
|---|---|---|
ssh server tty | Non | Non |
ssh -T server tty | Non | Non |
ssh -t server tty | Non | Oui |
ssh -tt server tty | Oui | Non |
En résumé, un seul -t demande un terminal si votre côté en a un, tandis que deux le forcent malgré tout.
Solution : vous lancez un script (la plupart des cas)
Indiquez un programme pour lire le script. C'est la solution la plus propre. Elle n'affiche aucun avis, et n'affiche pas non plus le texte de bienvenue du serveur :
ssh user@server bash -s <<'EOF'
uname
EOF
-T supprime aussi l'avis, mais le shell de connexion affiche quand même le message de bienvenue dans votre sortie :
echo uname | ssh -T user@server
Les guillemets autour de 'EOF' empêchent votre shell local de développer les variables avant l'envoi.
Pour une seule commande, passez-la directement :
ssh user@server uname
Pour les guillemets, les heredocs et les codes de retour, voir comment exécuter une commande en SSH.
Solution : le programme distant a besoin d'un terminal
Vous le reconnaîtrez à une erreur comme celle-ci, venant 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
Des programmes comme top et vim ont des besoins similaires. Forcez un terminal :
ssh -tt user@server 'sudo systemctl restart nginx'
Soyez prudent avec -tt dans les scripts. Avec un terminal, ce que vous envoyez est renvoyé en écho, les fins de ligne peuvent changer, et la sortie comporte des retours chariot. Un programme qui attend une touche peut aussi bloquer la tâche indéfiniment, car personne n'est là pour appuyer. Pour l'automatisation, une règle sudo étroite, sans mot de passe et sans terminal, vaut mieux que -tt. Voir sudo sur SSH.
Le définir dans votre configuration
Pour éviter de taper l'option pour un hôte utilisé par des scripts, ajoutez-la à ~/.ssh/config :
Host backup
HostName 203.0.113.10
RequestTTY no
Les valeurs acceptées sont no, yes, force et auto. Elles correspondent à -T, -t et -tt, auto étant la valeur par défaut.
Questions
Pseudo-terminal will not be allocated est-il une erreur ?
Non. C'est un avis sur stderr. Les commandes s'exécutent quand même et le code de sortie ne change pas.
Quelle différence entre ssh -t et ssh -tt ?
-t demande un terminal seulement si votre propre entrée en est un. -tt l'impose même depuis un pipe ou un script.
Comment masquer le message dans un script ?
Indiquez la commande, par exemple ssh user@server bash -s avec un heredoc, ou utilisez -T. RequestTTY no dans ~/.ssh/config fait de même pour un hôte.