Почему подстановка процесса <() не работает с 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. Что я здесь не так делаю?

cbliard
источник
2
Похоже, ssh закрывает все неожиданные файловые дескрипторы.
Ctrl-Alt-Delor

Ответы:

10

Команда:

ssh -F <(vagrant ssh-config) default

запускает vagrantкоманду в отдельном процессе с его stdout, подключенным к каналу. Другой конец канала связан как файловый дескриптор n(в вашем случае это 11) с новым процессом, который запускается sshи оболочка запускается:

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, да, если команда, которую вы запускаете на другом конце, представляет собой интерактивную оболочку, она будет читать из своего стандартного ввода (теперь это использованный канал для vagrant), увидеть eof и выйти. Вот почему я говорил, что ты ничего не кормишьssh .
Стефан Шазелас
Хорошо, я не поняла, что вы имели в виду, если вы ничего не кормитеssh . Теперь понятно.
cbliard
Это все еще правда? Я успешно использую: ssh -F <(cat ~/.ssh/config ~/.ssh/hosts)объединить 2 файла конфигурации при запуске SSH. А на ZSH, я могу сделать это: ssh -F <(vagrant ssh-config) default.
CMCDragonkai
1

основанный на @cbliard

Это работает:

ssh -F =(vagrant ssh-config ) -i =(generate ssh-identity)
Себастьян Вагнер
источник
Благодарность! Можете ли вы уточнить, что =( )делает? Я не знаком с этим.
вечером