Dlaczego podstawienie procesu <() nie działa z ssh -F

11

Mam jakieś wirtualne maszyny wirtualne. Aby się do nich zalogować, wydaje vagrant sshpolecenie. Chcę się do nich zalogować za pomocą zwykłego sshpolecenia. vagrant ssh-configWysyła odpowiedni plik konfiguracyjny

$ 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

Kiedy wypisujesz tę konfigurację do pliku i używasz z ssh -F, wszystko działa dobrze:

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

Podczas korzystania z operatora podstawiania procesów w <(cmd)celu uniemożliwienia utworzenia tymczasowego pliku konfiguracyjnego nie powiedzie się:

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

Ten sam błąd występuje podczas używania <(cat /tmp/config)

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

Używam zsh i obserwuję to samo zachowanie z bash. Co robię tutaj źle?

Cbliard
źródło
2
Wygląda na to, że ssh zamyka wszystkie nieoczekiwane deskryptory plików.
ctrl-alt-delor

Odpowiedzi:

10

Komenda:

ssh -F <(vagrant ssh-config) default

uruchamia vagrantpolecenie w osobnym procesie, a jego standardowe wyjście jest podłączone do potoku. Drugi koniec potoku jest podłączony jako deskryptor pliku n(w twoim przypadku jest to 11) do nowego procesu, który działa, ssha powłoka działa:

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

Teraz działa to tylko wtedy, sshgdy nie zamyka deskryptorów plików podczas uruchamiania.

Niestety tak jest.

Jeśli używasz zsh, alternatywą jest użycie =(...)formy podstawienia procesu, w której zamiast rury /proc/self/fdużywa pliku tymczasowego.

Lub możesz użyć deskryptora pliku, sshktóry się nie zamyka. Na przykład, jeśli nic nie podajesz ssh(jeśli zdalne polecenie nie odczytuje niczego ze standardowego wejścia), możesz użyć fd0, np .:

vagrant ssh-config | ssh -F /dev/stdin -n default
Stéphane Chazelas
źródło
1
Wspaniale. Dzięki =(...)temu działa jak urok, a plik tymczasowy jest automatycznie usuwany po zakończeniu sshsesji. Wariant z /dev/stdinłączy się pomyślnie, ale wychodzi natychmiast.
cbliard
1
@cbliard, tak, jeśli polecenie, które uruchomisz na drugim końcu, jest interaktywną powłoką, odczyta ze swojego standardowego wejścia (które jest teraz zużytą rurką do włóczęgowania) zobaczy eof i wyjdzie. Właśnie dlatego mówiłem, że nic nie karmiszssh .
Stéphane Chazelas,
Ok, nie rozumiem o co ci chodzi, jeśli niczego nie karmiszssh . Teraz jest jasne.
cbliard
Czy to nadal prawda? Z powodzeniem używam: ssh -F <(cat ~/.ssh/config ~/.ssh/hosts)do łączenia 2 plików konfiguracyjnych razem podczas uruchamiania SSH. I zsh, mogę to zrobić: ssh -F <(vagrant ssh-config) default.
CMCDragonkai
1

na podstawie @cbliard

To działa:

ssh -F =(vagrant ssh-config ) -i =(generate ssh-identity)
Sebastian Wagner
źródło
Dzięki! Czy możesz wyjaśnić, co =( )robi? Nie znam tego.
cbliard