Ho visto le domande e le risposte sulla necessità di eseguire il doppio escape degli argomenti sui comandi ssh remoti. La mia domanda è:esattamente dove e quando viene eseguita la seconda analisi?
Se eseguo quanto segue:
$ ssh otherhost pstree -a -p
Vedo quanto segue nell'output:
|-sshd,3736
| `-sshd,1102
| `-sshd,1109
| `-pstree,1112 -a -p
Il processo padre per il comando remoto (pstree
) è sshd
, non sembra esserci alcuna shell lì che analizzerebbe gli argomenti della riga di comando nel comando remoto, quindi non sembra che siano necessarie virgolette doppie o escape (ma lo è sicuramente). Se invece ssh lì prima e ottengo una shell di accesso, quindi eseguo pstree -a -p
Vedo quanto segue nell'output:
├─sshd,3736
│ └─sshd,3733
│ └─sshd,3735
│ └─bash,3737
│ └─pstree,4130 -a -p
Quindi chiaramente c'è un bash
shell lì che farebbe l'analisi della riga di comando in quel caso. Ma nel caso in cui utilizzo direttamente un comando remoto, non sembra esserci una shell, quindi perché è necessario il doppio apice?
Risposta accettata:
C'è sempre una shell remota. Nel protocollo SSH, il client invia al server una stringa da eseguire. Il client della riga di comando SSH prende i suoi argomenti della riga di comando e li concatena con uno spazio tra gli argomenti. Il server prende quella stringa, esegue la shell di accesso dell'utente e gli passa quella stringa. (Più precisamente:il server esegue il programma che è registrato come shell dell'utente nel database degli utenti, passandogli due argomenti da riga di comando:-c
e la stringa inviata dal client. La shell non viene invocata come shell di login:il server non imposta l'argomento zero su una stringa che inizia con -
.)
È impossibile bypassare la shell remota. Il protocollo non ha nulla come l'invio di un array di stringhe che potrebbe essere analizzato come un array argv sul server. E il server SSH non ignorerà la shell remota perché potrebbe essere una restrizione di sicurezza:l'utilizzo di un programma limitato come shell dell'utente è un modo per fornire un account limitato a cui è consentito eseguire solo determinati comandi (ad esempio un account solo rsync o un account solo git).
Potresti non vedere la shell in pstree
perché potrebbe essere già andato. Molte shell hanno un'ottimizzazione in cui se rilevano che stanno per eseguire "esegui questo comando esterno, attendi che venga completato ed esci con lo stato del comando", la shell esegue "execve
di questo comando esterno”. Questo è ciò che sta accadendo nel tuo primo esempio. Contrasta i seguenti tre comandi:
ssh otherhost pstree -a -p
ssh otherhost 'pstree -a -p'
ssh otherhost 'pstree -a -p; true'
I primi due sono identici:il client invia esattamente gli stessi dati al server. Il terzo invia un comando di shell che annulla l'ottimizzazione exec della shell.
Correlati:qual è la differenza tra spin lock e semafori?