ken*_*orb 5 command-line osx ssh process-substitution vagrant
我已经通过以下命令配置并启动了默认的 Ubuntu VM 框:
vagrant init ubuntu/trusty64; vagrant up --provider virtualbox
Run Code Online (Sandbox Code Playgroud)
现在,出于教育目的,我想使用以下语法来 ssh 它:
ssh -F /dev/stdin < <(vagrant ssh-config) default
Run Code Online (Sandbox Code Playgroud)
此命令将成功连接到虚拟机,但它会在打印motd后断开连接。
我想了解为什么会发生这种情况以及是否有办法避免它?
我试过强制伪终端分配没有成功。
我知道以下两个命令语法按预期工作:
vagrant ssh-config > ssh_tmp
ssh -F ssh_tmp default
Run Code Online (Sandbox Code Playgroud)
所以我想知道为什么在使用进程替换语法时会失败?
您正在传递命令vagrant ssh-config
的标准输入上的输出ssh
。到ssh
运行远程命令并将远程标准输入连接到本地标准输入时,已到达文件末尾。因此,远程 shell 在其标准输入中看到文件的结尾并立即退出。
通常你应该在不同的文件描述符上传递配置文件:
ssh -F <(vagrant ssh-config) default
Run Code Online (Sandbox Code Playgroud)
但这也不起作用¹因为ssh
在读取其配置文件之前关闭非默认文件描述符。因此,您需要将实际文件名传递给ssh
进程。如果您不想存储以下输出,它可以是命名管道vagrant ssh-config
:
mkfifo fifo
vagrant ssh-config >fifo &
ssh -F fifo …
rm fifo
Run Code Online (Sandbox Code Playgroud)
使用zsh
shell(在 macOS 上默认可用),您可以使用=(...)
命令替换的形式,它使用临时文件而不是通过/dev/fd/x
以下方式访问的管道:
ssh -F =(vagrant ssh-config) …
Run Code Online (Sandbox Code Playgroud)
¹ 除了在不/dev/fd/x
支持的系统上使用命名管道实现进程替换