5

I've configured and booted default Ubuntu VM box by the following commands:

vagrant init ubuntu/trusty64; vagrant up --provider virtualbox

Now, for education purposes, I'd like to use the following syntax to ssh it:

ssh -F /dev/stdin < <(vagrant ssh-config) default

This command will successfully connect to the VM, however it disconnects just after printing motd.

I'd like to understand why this is happening and if there any way to avoid it?

I've tried forcing the pseudo-terminal allocation with no success.

I'm aware the following two-command syntax works as expected:

vagrant ssh-config > ssh_tmp
ssh -F ssh_tmp default

so I'd like to know why it fails when using with a process substitution syntax?

kenorb
  • 20,250
  • 14
  • 140
  • 164

1 Answers1

5

You're passing the output of vagrant ssh-config on the standard input of the ssh command. By the time ssh runs the remote command and connects the remote stdin to the local stdin, the end of file has been reached. So the remote shell sees the end of the file on its standard input and exits immediately.

Normally you should pass the configuration file on a different file descriptor:

ssh -F <(vagrant ssh-config) default

but this doesn't work either¹ because ssh closes non-default file descriptors before it reads its configuration file. So you'll need to pass an actual file name to the ssh process. It can be a named pipe if you don't want to store the output of vagrant ssh-config:

mkfifo fifo
vagrant ssh-config >fifo &
ssh -F fifo …
rm fifo

With the zsh shell (available by default on macOS), you can use the =(...) form of command substitution which uses a temporary file instead of a pipe accessed via /dev/fd/x:

ssh -F =(vagrant ssh-config) …

¹ except on systems without /dev/fd/x support where process substitution is implemented with named pipes instead

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175