Pourquoi la substitution de processus <() ne fonctionne-t-elle pas avec ssh -F

11

J'ai quelques machines virtuelles vagabondes. Pour me connecter, j'émets la vagrant sshcommande. Je veux me connecter en utilisant la sshcommande régulière . Les vagrant ssh-configsorties le fichier de configuration approprié

$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2201
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/cbliard/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

Lors de la sortie de cette configuration dans un fichier et de l'utilisation avec ssh -F, tout fonctionne correctement:

$ vagrant ssh-config > /tmp/config
$ ssh -F /tmp/config default
=> logged successfully

Lorsque vous utilisez l'opérateur de substitution de processus <(cmd)pour empêcher la création du fichier de configuration temporaire, il échoue:

$ ssh -F <(vagrant ssh-config) default
Can't open user config file /proc/self/fd/11: No such file or directory

La même erreur se produit lors de l'utilisation <(cat /tmp/config)

$ ssh -F <(cat /tmp/config) default
Can't open user config file /proc/self/fd/11: No such file or directory

J'utilise zsh et j'observe le même comportement avec bash. Qu'est-ce que je fais mal ici?

cbliard
la source
2
Il semble que ssh ferme tous les descripteurs de fichiers inattendus.
ctrl-alt-delor

Réponses:

10

La commande:

ssh -F <(vagrant ssh-config) default

exécute la vagrantcommande dans un processus distinct avec sa sortie standard connectée à un tuyau. L'autre extrémité du canal est connectée en tant que descripteur de fichier n(dans votre cas, c'est 11) à un nouveau processus qui s'exécute sshet le shell s'exécute:

ssh -F /proc/self/fd/n default

Maintenant, cela ne fonctionne que si sshne ferme pas ses descripteurs de fichiers au démarrage.

Malheureusement, c'est le cas.

Si vous utilisez zsh, une alternative consiste à utiliser la =(...)forme de substitution de processus où au lieu d'utiliser un canal et /proc/self/fd, il utilise un fichier temporaire.

Ou vous pouvez utiliser un descripteur de fichier qui sshne se ferme pas. Par exemple, si vous n'alimentez rien ssh(si la commande à distance ne lit rien depuis stdin), vous pouvez utiliser fd0, par exemple:

vagrant ssh-config | ssh -F /dev/stdin -n default
Stéphane Chazelas
la source
1
Formidable. Avec =(...)cela fonctionne comme un charme et le fichier temporaire est automatiquement supprimé à la sshfin de la session. La variante avec se /dev/stdinconnecte avec succès mais se ferme immédiatement.
cbliard
1
@cbliard, oui, si la commande que vous exécutez à l'autre bout est un shell interactif, il lira sur son stdin (qui est le tube maintenant utilisé pour vagabonder) voir le eof et quitter. C'est pourquoi je disais que si tu ne donnais rien à mangerssh .
Stéphane Chazelas
D'accord, je n'ai pas compris ce que tu voulais dire si tu ne donnais rien à mangerssh . C'est maintenant clair.
cbliard
Est-ce toujours vrai? J'utilise avec succès: ssh -F <(cat ~/.ssh/config ~/.ssh/hosts)pour joindre 2 fichiers de configuration ensemble lors de l'exécution de SSH. Et ZSH, je peux le faire: ssh -F <(vagrant ssh-config) default.
CMCDragonkai
1

basé sur @cbliard

Cela marche:

ssh -F =(vagrant ssh-config ) -i =(generate ssh-identity)
Sebastian Wagner
la source
Merci! Pouvez-vous préciser ce que =( )fait? Je ne le connais pas.
cbliard