Mengapa subtitusi proses <() tidak bekerja dengan ssh -F

11

Saya punya beberapa mesin virtual gelandangan. Untuk masuk ke mereka saya mengeluarkan vagrant sshperintah. Saya ingin masuk ke mereka menggunakan sshperintah biasa . The vagrant ssh-configoutput yang sesuai file konfigurasi

$ 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

Saat mengeluarkan konfigurasi ini dalam file dan digunakan dengan ssh -F, semuanya berfungsi dengan baik:

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

Saat menggunakan operator substitusi proses <(cmd)untuk mencegah pembuatan file konfigurasi sementara, gagal:

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

Kesalahan yang sama terjadi saat menggunakan <(cat /tmp/config)

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

Saya menggunakan zsh dan saya mengamati perilaku yang sama dengan bash. Apa yang saya lakukan salah di sini?

cbliard
sumber
2
Sepertinya ssh sedang menutup semua deskriptor file yang tidak terduga.
ctrl-alt-delor

Jawaban:

10

Perintah:

ssh -F <(vagrant ssh-config) default

menjalankan vagrantperintah dalam proses terpisah dengan stdout-nya terhubung ke sebuah pipa. Ujung pipa yang terhubung sebagai file descriptor n(dalam kasus Anda itu 11) ke proses baru yang berjalan sshdan shell berjalan:

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

Sekarang, itu hanya berfungsi jika sshtidak menutup deskriptor file pada saat startup.

Sayangnya, itu terjadi.

Jika menggunakan zsh, alternatifnya adalah menggunakan =(...)bentuk substitusi proses di mana alih-alih menggunakan pipa dan /proc/self/fd, itu menggunakan file temp.

Atau Anda dapat menggunakan deskriptor file yang sshtidak ditutup. Misalnya, jika Anda tidak sshmemasukkan sesuatu ke (jika perintah jarak jauh tidak membaca apa pun dari stdin) Anda dapat menggunakan fd0, misalnya:

vagrant ssh-config | ssh -F /dev/stdin -n default
Stéphane Chazelas
sumber
1
Hebat. Dengan =(...)itu berfungsi seperti pesona dan file sementara secara otomatis dihapus ketika sshsesi berakhir. Varian dengan /dev/stdinkoneksi berhasil tetapi segera keluar.
cbliard
1
@cbliard, ya, jika perintah yang Anda jalankan di ujung yang lain adalah shell interaktif, ia akan membaca dari stdin-nya (yang sekarang digunakan pipa ke gelandangan) melihat eof dan keluar. Itu sebabnya saya katakan jika Anda tidak memberi makan apa punssh .
Stéphane Chazelas
Oke, saya tidak mengerti apa maksud Anda jika Anda tidak memberi makan apa punssh . Sekarang sudah jelas.
cbliard
Apakah ini masih benar? Saya berhasil menggunakan: ssh -F <(cat ~/.ssh/config ~/.ssh/hosts)untuk menggabungkan 2 file konfigurasi bersama ketika menjalankan SSH. Dan pada zsh, aku bisa melakukan ini: ssh -F <(vagrant ssh-config) default.
CMCDragonkai
1

berdasarkan @cbliard

Ini bekerja:

ssh -F =(vagrant ssh-config ) -i =(generate ssh-identity)
Sebastian Wagner
sumber
Terima kasih! Bisakah Anda mengklarifikasi apa =( )? Saya tidak terbiasa dengan itu.
cbliard