Quando compare
Lo vedi in due situazioni. Non dai alcun comando remoto ma alimenti SSH da una pipe o da un heredoc:
echo uname | ssh user@server
ssh user@server <<EOF
uname
EOF
Oppure chiedi un terminale con -t quando il tuo input non lo è, come in cron, in CI o in uno script:
ssh -t user@server tty < /dev/null
Pseudo-terminal will not be allocated because stdin is not a terminal.
not a tty
I comandi vengono comunque eseguiti. Il messaggio va su stderr, quindi può sembrare allarmante in un log di CI, ma non è un errore e non cambia il codice di uscita.
Cosa fa ogni opzione
Risultati dell'esecuzione di tty sul server con input da /dev/null:
| Comando | Terminale sul server | Avviso stampato |
|---|---|---|
ssh server tty | No | No |
ssh -T server tty | No | No |
ssh -t server tty | No | Sì |
ssh -tt server tty | Sì | No |
In breve, un solo -t chiede un terminale se il tuo lato ne ha uno, mentre due lo forzano comunque.
Soluzione: stai eseguendo uno script (la maggior parte dei casi)
Indica un programma che legga lo script. È la soluzione più pulita. Non stampa alcun avviso e non mostra nemmeno il testo di benvenuto del server:
ssh user@server bash -s <<'EOF'
uname
EOF
Anche -T toglie l'avviso, ma la shell di login stampa comunque il messaggio di benvenuto nel tuo output:
echo uname | ssh -T user@server
Le virgolette intorno a 'EOF' impediscono alla tua shell locale di espandere le variabili prima dell'invio.
Per un singolo comando, passalo direttamente:
ssh user@server uname
Per virgolette, heredoc e codici di uscita, vedi come eseguire un comando via SSH.
Soluzione: il programma remoto ha bisogno di un terminale
Te ne accorgi da un errore come questo, da 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
Programmi come top e vim hanno esigenze simili. Forza un terminale:
ssh -tt user@server 'sudo systemctl restart nginx'
Fai attenzione a -tt negli script. Con un terminale, ciò che invii viene rimandato indietro come eco, i fine riga possono cambiare e l'output arriva con i ritorni a capo. Un programma che aspetta la pressione di un tasto può anche bloccare il job per sempre, perché nessuno è lì a premerlo. Per l'automazione, una regola sudo ristretta senza password e senza terminale è meglio di -tt. Vedi sudo tramite SSH.
Impostarlo nella configurazione
Per non digitare il flag per un host usato dagli script, aggiungilo a ~/.ssh/config:
Host backup
HostName 203.0.113.10
RequestTTY no
I valori accettati sono no, yes, force e auto. Corrispondono a -T, -t e -tt, con auto come valore predefinito.
Domande
Pseudo-terminal will not be allocated è un errore?
No. È un avviso su stderr. I comandi vengono eseguiti lo stesso e lo stato di uscita non cambia.
Che differenza c'è fra ssh -t e ssh -tt?
-t chiede un terminale solo se il tuo input è un terminale. -tt lo forza anche da una pipe o da uno script.
Come nascondo il messaggio in uno script?
Indica il comando, per esempio ssh user@server bash -s con un heredoc, oppure usa -T. RequestTTY no in ~/.ssh/config fa lo stesso per un host.