GNU/Linux >> Tutoriels Linux >  >> Linux

`ssh <host>` est un shell de connexion, mais `ssh <host> <command>` ne l'est pas ?

OpenSSH (probablement ce que vous exécutez) décide de créer ou non un shell de connexion, et il ne le fait que si vous n'exécutez pas une commande spécifique. De man ssh :

 If command is specified, it is executed on the remote host instead of a
 login shell.

C'est donc un choix d'implémentation pour le serveur ssh qu'il veuille ou non créer un shell de connexion, et si vous donnez une commande à exécuter, ce n'est pas le cas.

Alors que ssh effectue une connexion, si vous lui demandez d'exécuter une commande et de quitter, cela ressemble beaucoup plus à la création d'un shell juste pour exécuter cette commande qu'à l'obtention d'un environnement de connexion. Il semble, étant donné cela, que les personnes qui écrivent OpenSSH aient décidé de le traiter comme ce genre de tâche.

Ils créent un shell non interactif et sans connexion pour exécuter la commande, car c'est l'esprit d'exécuter une commande dans un autre contexte/shell. Normalement, cependant, les shells non interactifs ne sourceraient pas automatiquement ~/.bashrc ce qui se passe clairement ici. bash essaie en fait de nous aider ici. À partir de la documentation

Appelé par le démon shell distant

Bash tente de déterminer quand il est exécuté avec son entrée standard connectée à une connexion réseau, comme lorsqu'il est exécuté par le démon shell distant, généralement rshd, ou le démon shell sécurisé sshd. Si Bash détermine qu'il est exécuté de cette manière, il lit et exécute les commandes de ~/.bashrc, si ce fichier existe et est lisible. Il ne le fera pas s'il est invoqué en tant que sh. L'option --norc peut être utilisée pour inhiber ce comportement, et l'option --rcfile peut être utilisée pour forcer la lecture d'un autre fichier, mais ni rshd ni sshd n'invoquent généralement le shell avec ces options ou ne permettent pas de les spécifier.


Le pourquoi de ce comportement se situe à un niveau inférieur à celui des shells :ssh host (le cas "shell de connexion") utilise un pseudoterminal sur l'hôte distant, pour communiquer entre le sshd processus serveur et shell ; ssh host command utilise des pipes entre sshd et command , Au lieu. Les pseudoterminaux sont nécessaires pour utiliser de manière interactive un interpréteur de commandes, tel qu'un shell, ou le mode "lecture-évaluation-impression" d'un langage de script ; ils implémentent un tas de fonctionnalités conviviales comme la possibilité de revenir en arrière sur les fautes de frappe. Mais ils ont plus de surcharge et (selon la configuration) ne permettent pas aux données arbitraires de passer sans modification, donc SSH évite de les utiliser lorsqu'il n'y aura pas d'interaction.

Parfois, l'heuristique commande/pas de commande de SSH se trompe; il peut être remplacé par le -t et -T commutateurs. Par exemple, pour se connecter à une machine distante et rattacher immédiatement un screen suspendu session, vous devez faire ssh -t host screen -R; ssh host screen -R causera screen se plaindre de ne pas être connecté à une borne. Je ne peux pas penser à une situation où vous voudriez réellement vouloir utiliser -T , mais il est là si jamais vous en trouvez un.


Linux
  1. Commande introuvable dans Zsh, mais trouvée dans Bash ?

  2. ln :commande introuvable

  3. Changer le shell par défaut sous Linux

  4. Commande Linux pour vérifier si un script shell est en cours d'exécution ou non

  5. Commande Conda fonctionnant dans l'invite de commande mais pas dans le script bash

Tutoriel de commande Linux chsh pour les débutants (5 exemples)

Commande source sous Linux

Interface de commandes

rm :commande introuvable

mv :commande introuvable

Autoriser SCP mais pas la connexion réelle à l'aide de SSH