Por que a substituição do processo <() não funciona com ssh -F

11

Eu tenho algumas máquinas virtuais vagantes. Para entrar neles, emito o vagrant sshcomando. Eu quero entrar neles usando o sshcomando regular . O vagrant ssh-configgera o arquivo de configuração adequada

$ 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

Ao enviar esta configuração em um arquivo e usar com ssh -F, tudo funciona bem:

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

Ao usar o operador de substituição de processo <(cmd)para impedir a criação do arquivo de configuração temporário, ele falha:

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

O mesmo erro ocorre ao usar <(cat /tmp/config)

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

Estou usando o zsh e observo o mesmo comportamento com o bash. O que eu estou fazendo errado aqui?

cbliard
fonte
2
Parece que o ssh está fechando todos os descritores de arquivos inesperados.
ctrl-alt-Delor

Respostas:

10

O comando:

ssh -F <(vagrant ssh-config) default

executa o vagrantcomando em um processo separado com seu stdout conectado a um pipe. A outra extremidade do canal é conectada como descritor de arquivo n(no seu caso, é 11) a um novo processo que é executado sshe o shell é executado:

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

Agora, isso só funciona se sshnão fechar seus descritores de arquivo na inicialização.

Infelizmente sim.

Se estiver usando zsh, uma alternativa é usar a =(...)forma de substituição de processo em que, em vez de usar um pipe /proc/self/fd, ele usa um arquivo temporário.

Ou você pode usar um descritor de arquivo que sshnão fecha. Por exemplo, se você não estiver alimentando nada ssh(se o comando remoto não estiver lendo nada do stdin), poderá usar fd0, por exemplo:

vagrant ssh-config | ssh -F /dev/stdin -n default
Stéphane Chazelas
fonte
Maravilhoso. Com =(...)isso funciona como um encanto e o arquivo temporário é removido automaticamente quando a sshsessão termina. A variante com se /dev/stdinconecta com êxito, mas sai imediatamente.
Cbliard
1
@cbliard, sim, se o comando que você executa do outro lado for um shell interativo, ele lerá em seu stdin (que agora é o pipe usado para vagar) ver o eof e sair. É por isso que eu estava dizendo se você não está alimentando nadassh .
Stéphane Chazelas
Ok, eu não entendi o que você quis dizer com se não está alimentando nadassh . Agora está claro.
Cbliard
Isso ainda é verdade? Estou usando com sucesso: ssh -F <(cat ~/.ssh/config ~/.ssh/hosts)para unir 2 arquivos de configuração ao executar o SSH. E no ZSH, eu posso fazer isso: ssh -F <(vagrant ssh-config) default.
CMCDragonkai #