Saya membuat layanan jaringan sederhana dengan xinetd yang membaca string dari soket tcp dan menampilkan tampilan yang disandikan. Biner asli (qrencode) baru saja membaca stdin.
Ini berfungsi dengan baik ketika saya menggunakannya dengan netcat
sebagai echo string | nc <ip> <port>
Tapi itu tidak menjawab ketika saya mencoba menggunakannya melalui pengalihan bash tcp.
exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7
Itu menunggu selamanya. Saya mencoba mengulang \004, cat /dev/null ke fd ini dan tidak berhasil.
Bagaimana saya bisa membuatnya bekerja?
Jawaban yang Diterima:
inetd
. itu layanan atau milik Anda mungkin menunggu EOF sebelum keluar (lalu menutup koneksi).
Untuk melakukan itu, Anda memerlukan klien untuk mematikan sisi pengirim soket sambil tetap menjaga sisi penerima tetap terbuka. Itu yang nc
lakukan saat mendeteksi EOF pada stdinnya.
/dev/tcp/host/port
antarmuka virtual bash
(disalin dari ksh) tidak mengizinkan itu. Bahkan zsh
ztcp
alternatif yang lebih fleksibel tidak memiliki kemampuan untuk mematikan koneksi secara asimetris.
Anda bisa mengandalkan batas waktu sebagai gantinya, tapi itu tidak bisa diandalkan. Jadi sebaiknya tetap mengandalkan utilitas khusus seperti nc
atau socat
(mungkin dengan coproc untuk memiliki antarmuka yang serupa), atau menggunakan bahasa pemrograman dengan API jaringan yang tepat (dengan antarmuka ke shutdown()
).
Karakter 0x04 (^D
) hanya berarti EOF untuk perangkat terminal ketika disiplin baris ada di icanon
mode (menerapkan editor garis kasar). Jadi agar itu berfungsi, Anda harus memasukkan terminal semu di antara soket yang dibuat oleh xinetd
dan layanan Anda. Misalnya, dengan memulainya dengan:
socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3
bukannya
your-service
Maka Anda perlu mengirim:
printf 'text\n\4' >&7
Atau:
printf 'text\4\4' >&7
untuk layanan Anda untuk melihat akhir input.
Karena editor baris itu, your-service
hanya akan melihat input saat Anda mengirim baris baru atau ^D
karakter (kami telah menonaktifkan semua karakter pengeditan lainnya seperti werase
, erase
, kill
di atas dan ^C
, ^Z
… penanganan juga dinonaktifkan sebagai bagian dari raw
).
Jadi, Anda sebaiknya memasukkan pra-prosesor input yang berhenti pada karakter 0x4 seperti:
awk -v RS='\4' -v ORS= '{print; exit}' | your-service
(perhatikan bahwa awk
tidak boleh mawk
sebagai mawk
bersikeras untuk tidak memproses inputnya selama tidak menerima buffer atau eof penuh).