为什么进程替换 <() 不适用于 ssh -F

cbl*_*ard 12 bash ssh zsh file-descriptors process-substitution

我有一些流浪的虚拟机。要登录它们,我发出vagrant ssh命令。我想使用常规ssh命令登录它们。的vagrant ssh-config输出合适的配置文件

$ 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
Run Code Online (Sandbox Code Playgroud)

在文件中输出此配置并使用 with 时ssh -F,一切正常:

$ vagrant ssh-config > /tmp/config
$ ssh -F /tmp/config default
=> logged successfully
Run Code Online (Sandbox Code Playgroud)

使用进程替换操作符<(cmd)阻止创建临时配置文件时,失败:

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

使用时发生同样的错误 <(cat /tmp/config)

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

我正在使用 zsh 并且我观察到与 bash 相同的行为。我在这里做错了什么?

Sté*_*las 11

命令:

ssh -F <(vagrant ssh-config) default
Run Code Online (Sandbox Code Playgroud)

vagrant在一个单独的进程中运行命令,其标准输出连接到管道。管道的另一端作为文件描述符n(在您的情况下是 11)连接到一个运行ssh并且 shell 运行的新进程:

ssh -F /proc/self/fd/n default
Run Code Online (Sandbox Code Playgroud)

现在,只有ssh在启动时不关闭其文件描述符才有效。

不幸的是,确实如此。

如果使用zsh,另一种方法是使用=(...)进程替换的形式,而不是使用管道和/proc/self/fd,而是使用临时文件。

或者您可以使用ssh不关闭的文件描述符。例如,如果您没有提供任何内容ssh(如果远程命令没有从标准输入读取任何内容),您可以使用fd0,例如:

vagrant ssh-config | ssh -F /dev/stdin -n default
Run Code Online (Sandbox Code Playgroud)