Saat menghubungkan ke host dengan SSH, biasanya tiga "pipa" yang disediakan antara tuan rumah dan tamu, untuk stdin
, stdout
, dan stderr
.
Apakah ada opsi baris perintah untuk membuat maju untuk deskriptor file tambahan ( 3
dan seterusnya)?
Sebagai contoh, saya ingin melakukannya
ssh --forwardfd=10:3 remotehost 'echo test >&3'
yang akan mencetak 'test' ke deskriptor file yang dibuka secara lokal 10.
ssh
pipe
file-descriptors
mic_e
sumber
sumber
closefrom(STDERR_FILENO + 1)
panggilan di bawah kode sumber OpenSSH. Apa yang Anda coba lakukan yang menuntut ini?stdin
/out
/err
, tetapi AFAIK, tidak ada server / klien yang menyediakan dukungan dengan cara apa pun fitur itu.infinite-output-cmd | ssh user@host bash /proc/self/fd/3 3< local-script-to-execute-remotely.sh
--forwardfd
seharusnya bahkan tidak diperlukan.ssh
dapat memeriksa apa deskriptor file terbuka sebelum membuka hal lain, dan meneruskannya secara otomatis ke deskriptor file yang sama di sisi jarak jauh. Ini bisa sangat transparan seperti contoh saya. Saya bertanya-tanya betapa sulitnya untuk memperbaikissh
itu. Seperti yang Anda katakan, itu bisa rumit tergantung pada alasan di balik ituclosefrom(STDERR_FILENO + 1)
.Jawaban:
Anda dapat melakukan ini menggunakan penerusan soket, yang tersedia sejak openssh-6.7. Ini semacam pipa. Teknik ini dijelaskan misalnya di sini: http://www.25thandclement.com/~william/projects/streamlocal.html
Anda akan mendapatkan rute dua arah untuk data Anda. Ada contoh dengan mysql:
sumber
Saya yakin itu harus mungkin. Saya hanya dapat menyarankan retas di mana Anda menggunakan koneksi ssh ekstra untuk masing-masing membawa sepasang deskriptor file lainnya. Misalnya bukti skrip konsep berikut melakukan ssh pertama untuk menjalankan perintah dummy (sleep) untuk menghubungkan fds lokal 5 dan 6 ke stdin dan stdout jarak jauh, dengan anggapan fds ini adalah yang ingin Anda tambahkan ke 0,1 biasa, 2.
Kemudian ssh asli dilakukan, dan pada remote itu menghubungkan remote fds 5 dan 6 ke stdin dan stdout dari ssh lainnya.
Sama seperti contoh, skrip ini meneruskan halaman manual yang di-gzip ke remote, yang membuka ritsleting dan menjalankannya melalui man. Stdin dan stdout dari ssh asli masih tersedia untuk hal-hal lain.
sumber
Masalah dengan jawaban dari @jakuje adalah: ini hanya berfungsi dengan soket , tetapi Anda tidak dapat menggunakan alat UNIX standar yang mengharapkan file dengannya:
ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'
Juga ada masalah bahwa file soket lokal tidak dihapus pada host jarak jauh; ketika berikutnya Anda menjalankan perintah yang sama, Anda mendapatkan peringatan dan soket tidak dibuat ulang dengan benar. Anda dapat memberikan opsi
-o StreamLocalBindUnlink=yes
untukssh
memutuskan tautan soket lama itu, tetapi dalam pengujian saya itu tidak cukup; Anda juga harus mengeditsshd_config
agar memuatStreamLocalBindUnlink=yes
agar opsi itu berfungsi.Tetapi Anda dapat menggunakan
socat
ataunetcat
atau alat serupa lainnya yang mendukung UNIX soket lokal (netcat-traditional
yang tidak cukup!) Untuk menggunakan forwarding soket lokal untuk transfer file:Anda juga dapat menjalankan perintah interaktif, dalam hal ini Anda harus menggunakan
ssh -t
untuk mengalokasikan TTYs.Masalah dengan solusi ini adalah Anda harus membuat hard-path path dari UNIX local sockets: Secara lokal ini tidak terlalu menjadi masalah karena Anda dapat memasukkannya
$$
di path untuk membuatnya unik per proses atau pengguna direktori sementara, tetapi pada remote-end Anda lebih baik tidak menggunakan direktori yang bisa ditulis dunia/tmp/
seperti yang saya lakukan dalam contoh saya. Direktori juga harus sudah ada saatssh
sesi dimulai. Dan inode soket akan tetap ada bahkan setelah sesi ditutup, jadi menggunakan sesuatu seperti "$ HOME / .ssh. $$" akan mengacaukan direktori Anda dengan inode yang mati seiring waktu.Anda juga dapat menggunakan soket TCP terikat
localhost
, yang akan menyelamatkan Anda dari mengacaukan sistem file Anda dengan inode mati, tetapi bahkan dengan mereka Anda masih harus masalah untuk memilih nomor port (unik) yang tidak digunakan. Jadi masih belum ideal. (ssh
memiliki kode untuk mengalokasikan port secara dinamis, tetapi saya tidak menemukan cara untuk mengambil informasi itu pada host jarak jauh.)Mungkin solusi termudah untuk menyalin file adalah menggunakan fungsi berbagi koneksi built-in ssh dan melakukan
scp
atausfrp
perintah saat sesi interaktif Anda masih berjalan secara paralel. Lihat Menyalin file kembali ke sistem lokal dengan ssh .sumber