J'ai vu les questions et réponses sur la nécessité de double-échapper aux arguments des commandes ssh distantes. Ma question est: exactement où et quand la deuxième analyse est-elle effectuée?
Si je lance ce qui suit:
$ ssh otherhost pstree -a -p
Je vois ce qui suit dans la sortie:
|-sshd,3736
| `-sshd,1102
| `-sshd,1109
| `-pstree,1112 -a -p
Le processus parent de la commande distante ( pstree
) est sshd
, il ne semble pas y avoir de shell qui analyserait les arguments de la ligne de commande à la commande distante, il ne semble donc pas que des guillemets doubles ou des échappements soient nécessaires ( mais c'est certainement). Si au lieu de cela, je ssh d'abord et obtenez un shell de connexion, puis exécutez, pstree -a -p
je vois ce qui suit dans la sortie:
├─sshd,3736
│ └─sshd,3733
│ └─sshd,3735
│ └─bash,3737
│ └─pstree,4130 -a -p
Il est donc clair qu'il y a un bash
shell qui ferait une analyse de ligne de commande dans ce cas. Mais dans le cas où j'utilise directement une commande à distance, il ne semble pas y avoir de shell, alors pourquoi la citation double est-elle nécessaire?
Je pense que je l'ai compris:
Les arguments à
pstree
sont les suivants: afficher les arguments de la ligne de commande, afficher les pids et afficher uniquement les processus parents du pid donné. Il'$$'
s'agit d'une variable shell spéciale que bash remplacera par son propre pid lorsque bash évalue les arguments de la ligne de commande. Il est cité une fois pour l'empêcher d'être interprété par mon shell local. Mais il n'est pas doublement cité ou échappé pour qu'il puisse être interprété par le shell distant.Comme nous pouvons le voir, il est remplacé par
12001
donc c'est le pid de la coque. Nous pouvons également voir à la sortie:pstree,12001
que le processus avec un pid de 12001 est pstree lui-même. Lapstree
coquille aussi?Ce que je comprends, c'est qu'il
bash
est invoqué et qu'il analyse les arguments de la ligne de commande, mais il invoque ensuiteexec
pour se remplacer par la commande en cours d'exécution.Il semble qu'il ne le fasse que dans le cas d'une seule commande à distance:
Dans ce cas, je demande l'exécution de deux commandes:
pstree
suivi deecho
. Et nous pouvons voir ici quebash
cela apparaît en fait dans l'arbre de processus en tant que parent depstree
.la source
Soutenant ce que les autres réponses ont dit, j'ai recherché le code qui appelle des commandes sur la télécommande, https://github.com/openssh/openssh-portable/blob/4f29309c4cb19bcb1774931db84cacc414f17d29/session.c#L1660 ...
... qui, comme vous pouvez le voir, invoque inconditionnellement
shell
avec le premier argument-c
et le deuxième argumentcommand
. Auparavant, lashell
variable a été définie sur le shell de connexion de l'utilisateur comme enregistré dans/etc/passwd
.command
est un argument de cette fonction, et est finalement défini sur une chaîne lue textuellement sur le fil (voirsession_exec_req
dans le même fichier ). Ainsi, le serveur n'interprète pas du tout la commande, mais un shell est toujours appelé sur la télécommande.Cependant, la partie pertinente de la spécification du protocole SSH ne pas semble exiger ce comportement; ça dit seulement
C'est probablement parce que tous les systèmes d'exploitation n'ont pas le concept d'un shell de ligne de commande. Par exemple, il n'aurait pas été fou qu'un serveur ssh MacOS classique fournisse à la place des chaînes de commande "exec" à l' interpréteur AppleScript .
la source