OpenSSH (molto probabilmente quello che stai eseguendo) decide se creare o meno una shell di login, e lo fa solo se non stai eseguendo un comando specifico. Da man ssh
:
If command is specified, it is executed on the remote host instead of a login shell.
Quindi è una scelta di implementazione per il server ssh se vuole creare o meno una shell di login, e se dai un comando da eseguire, non lo fa.
Mentre ssh
esegue un accesso, se gli stai facendo eseguire un comando ed esci, è davvero molto più simile alla creazione di una shell solo per eseguire quel comando piuttosto che per ottenere un ambiente di accesso. Sembra, dato questo, che le persone che scrivono OpenSSH abbiano deciso di trattarlo come quel tipo di compito.
Creano una shell non interattiva e non di accesso per eseguire il comando, perché questo è lo spirito di eseguire un comando in un altro contesto/shell. Normalmente, però, le shell non interattive non generano automaticamente ~/.bashrc
che sta chiaramente accadendo qui. bash
in realtà sta cercando di aiutarci qui. Dai documenti
Invocato dal demone della shell remota
Bash tenta di determinare quando viene eseguito con il suo input standard connesso a una connessione di rete, come quando viene eseguito dal demone della shell remota, solitamente rshd, o dal demone della shell sicura sshd. Se Bash determina che viene eseguito in questo modo, legge ed esegue i comandi da ~/.bashrc, se quel file esiste ed è leggibile. Non lo farà se invocato come sh. L'opzione --norc può essere usata per inibire questo comportamento, e l'opzione --rcfile può essere usata per forzare la lettura di un altro file, ma né rshd né sshd generalmente invocano la shell con quelle opzioni o permettono che vengano specificate.
Il perché di questo comportamento si trova a un livello inferiore rispetto alle shell:ssh host
(il caso "login shell") utilizza uno pseudoterminale sull'host remoto, per comunicare tra i sshd
processo server e shell; ssh host command
utilizza pipe tra sshd
e command
, invece. Gli pseudoterminali sono necessari per fare un uso interattivo di un interprete di comandi, come una shell, o la modalità "lettura-valutazione-stampa" di un linguaggio di scripting; implementano una serie di funzionalità a misura d'uomo come la possibilità di tornare indietro rispetto agli errori di battitura. Ma hanno un sovraccarico maggiore e (a seconda della configurazione) non consentono il passaggio di dati arbitrari senza modifiche, quindi SSH evita di utilizzarli quando l'interazione non avverrà.
A volte l'euristica comando/nessun comando di SSH sbaglia; può essere sovrascritto con -t
e -T
interruttori. Ad esempio, per accedere a una macchina remota e ricollegare immediatamente un screen
sospeso sessione, devi eseguire ssh -t host screen -R
; ssh host screen -R
causerà screen
lamentarsi di non essere connesso a un terminale. Non riesco a pensare a una situazione in cui vorresti davvero volere per usare -T
, ma è lì se mai ne trovi uno.