为什么进程替换<()与ssh -F不兼容


11

我有一些无所事事的虚拟机。要登录他们,我发出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

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

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

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

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

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

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

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


2
看起来ssh正在关闭所有意外的文件描述符。
ctrl-alt-delor

Answers:


10

命令:

ssh -F <(vagrant ssh-config) default

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

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

现在,这仅ssh在启动时不关闭其文件描述符的情况下有效。

不幸的是,确实如此。

如果使用zsh,则替代方法是使用=(...)过程替换的形式,其中/proc/self/fd使用临时文件代替管道和。

或者,您可以使用ssh无法关闭的文件描述符。例如,如果您不给任何东西ssh(如果远程命令没有从stdin读取任何东西),则可以使用fd0,例如:

vagrant ssh-config | ssh -F /dev/stdin -n default

1
精彩。有了=(...)它就像一个魅力和临时文件的时候自动删除ssh会话结束。与的变体/dev/stdin连接成功,但立即退出。
cbliard

1
@cbliard,是的,如果在另一端运行的命令是交互式shell,它将从其stdin(这是现在已经用尽的流浪者管道)中读取内容,并看到eof并退出。这就是为什么我要说的是您是否不给任何食物ssh
斯特凡Chazelas

好的,如果您不向喂食ssh,我不明白您的意思。现在很清楚。
cbliard 2013年

这仍然是真的吗?我成功使用:ssh -F <(cat ~/.ssh/config ~/.ssh/hosts)运行SSH时将2个配置文件连接在一起。在ZSH上,我可以这样做:ssh -F <(vagrant ssh-config) default
CMCDragonkai '16

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.