"Pseudo-terminal will not be allocated because stdin is not a terminal": Bedeutung und Lösung

SSH wollte für diese Sitzung ein Terminal auf dem Server, aber Ihre Eingabe ist eine Pipe, eine Datei oder ein Skript statt einer Tastatur, also hat es keines angelegt. Es ist ein Hinweis, und die Sitzung läuft weiter. Um ihn zu unterdrücken, nutzen Sie -T oder nennen Sie den auszuführenden Befehl. Braucht das entfernte Programm wirklich ein Terminal, etwa sudo bei einer Passwortabfrage, erzwingen Sie eines mit -tt.

Sie führen dasselbe Skript auf mehreren Servern aus? Wardterm schickt es an alle und sammelt jedes Ergebnis. Zeigen

Aktualisiert am . Alle Befehle wurden mit OpenSSH 10.3 auf macOS gegen einen OpenSSH-10.0-Server unter Linux ausgeführt, mit Eingabe aus einer Pipe, aus /dev/null und aus einem Heredoc.

Wann sie erscheint

Sie sehen sie in zwei Situationen. Sie geben keinen entfernten Befehl an, speisen SSH aber aus einer Pipe oder einem Heredoc:

echo uname | ssh user@server
ssh user@server <<EOF
uname
EOF

Oder Sie verlangen mit -t ein Terminal, obwohl Ihre eigene Eingabe keines ist, wie in cron, CI oder einem Skript:

ssh -t user@server tty < /dev/null
Pseudo-terminal will not be allocated because stdin is not a terminal.
not a tty

Die Befehle laufen trotzdem. Die Meldung geht an stderr, sie kann in einem CI-Log also alarmierend wirken, ist aber kein Fehler und ändert den Exit-Status nicht.

Was jede Option bewirkt

Ergebnisse beim Ausführen von tty auf dem Server mit Eingabe aus /dev/null:

BefehlTerminal auf dem ServerHinweis ausgegeben
ssh server ttyNeinNein
ssh -T server ttyNeinNein
ssh -t server ttyNeinJa
ssh -tt server ttyJaNein

Kurz: Ein einzelnes -t verlangt ein Terminal, wenn Ihre Seite eines hat, zwei erzwingen es in jedem Fall.

Lösung: Sie führen ein Skript aus (die meisten Fälle)

Nennen Sie ein Programm, das das Skript liest. Das ist die sauberste Lösung. Sie gibt keinen Hinweis aus und zeigt auch den Begrüßungstext des Servers nicht an:

ssh user@server bash -s <<'EOF'
uname
EOF

-T entfernt den Hinweis ebenfalls, aber die Login-Shell gibt die Willkommensmeldung weiterhin in Ihre Ausgabe aus:

echo uname | ssh -T user@server

Die Anführungszeichen um 'EOF' verhindern, dass Ihre lokale Shell Variablen expandiert, bevor sie gesendet werden.

Für einen einzelnen Befehl übergeben Sie ihn direkt:

ssh user@server uname

Zu Anführungszeichen, Heredocs und Exit-Codes siehe Befehle über SSH ausführen.

Lösung: Das entfernte Programm braucht ein Terminal

Sie erkennen es an einem Fehler wie diesem, von 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

Programme wie top und vim haben ähnliche Anforderungen. Erzwingen Sie ein Terminal:

ssh -tt user@server 'sudo systemctl restart nginx'

Seien Sie mit -tt in Skripten vorsichtig. Mit einem Terminal wird zurückgeschickt, was Sie senden, Zeilenenden können sich ändern, und die Ausgabe kommt mit Wagenrückläufen. Ein Programm, das auf eine Taste wartet, kann den Job auch für immer hängen lassen, weil niemand da ist, der sie drückt. Für Automatisierung ist eine eng gefasste sudo-Regel ohne Passwort und ohne Terminal besser als -tt. Siehe sudo über SSH.

In Ihrer Konfiguration festlegen

Um das Flag bei einem von Skripten genutzten Host nicht jedes Mal zu tippen, tragen Sie es in ~/.ssh/config ein:

Host backup
  HostName 203.0.113.10
  RequestTTY no

Die zulässigen Werte sind no, yes, force und auto. Sie entsprechen -T, -t und -tt, wobei auto der Standard ist.

Fragen

Ist Pseudo-terminal will not be allocated ein Fehler?

Nein. Es ist ein Hinweis auf stderr. Die Befehle laufen trotzdem, und der Exit-Status ändert sich nicht.

Was unterscheidet ssh -t von ssh -tt?

-t fordert nur dann ein Terminal an, wenn Ihre eigene Eingabe eines ist. -tt erzwingt es auch aus einer Pipe oder einem Skript.

Wie blende ich die Meldung in einem Skript aus?

Geben Sie den Befehl an, zum Beispiel ssh user@server bash -s mit einem Heredoc, oder verwenden Sie -T. RequestTTY no in ~/.ssh/config bewirkt dasselbe für einen Host.

Quellen

Mehr zu Fehlermeldungen

Alle Anleitungen