Cách đặt tập lệnh thực thi khi cổng nhận được thông báo


12

Tôi đang tự hỏi làm thế nào để có được một kịch bản shell để lắng nghe trên một cổng nhất định (có thể sử dụng netcat?). Hy vọng rằng khi một tin nhắn được gửi đến cổng đó, tập lệnh sẽ ghi lại tin nhắn và sau đó chạy một chức năng.

Thí dụ:

  1. Máy tính 1 có tập lệnh chạy ở chế độ nền, tập lệnh đã mở cổng 1234 cho lưu lượng đến

  2. Máy tính 2 gửi tin nhắn "hello world" tới cổng 1234 của máy tính 1

  3. Tập lệnh trên Máy tính 1 ghi thông báo "hello world" vào một biến $ MESSAGE

  4. Tập lệnh chạy chức năng bây giờ biến $ MESSAGE đã được đặt

Làm thế nào để tôi đi quyên góp này?

Câu trả lời:


12

Nên có thể với socat.

Viết một đoạn script "getmsg.sh" để nhận một tin nhắn qua stdin:

#!/bin/bash
read MESSAGE
echo "PID: $$"
echo "$MESSAGE"

Sau đó chạy socatlệnh này để gọi tập lệnh của chúng tôi cho mỗi kết nối tcp trên cổng 7777:

socat -u tcp-l:7777,fork system:./getmsg.sh

Gửi tin nhắn thử nghiệm từ shell khác:

echo "message 1" | netcat localhost 7777

Bạn đã thử nó chưa?

Viết lại và thử nghiệm ngay bây giờ;)
rudimeier

1
Tôi đã được truyền cảm hứng từ giải pháp của bạn và tìm ra cách làm việc với netcat: nc -l 7777 | ./getmsg.sh
Daniel

Vui mừng khi nghe điều đó. Nhưng netcattồn tại sau một kết nối. socatsẽ làm tương tự nếu bạn loại bỏ ", fork" khỏi dòng lệnh của tôi.
rudimeier

7

Cách UCSPI-TCP

Có bộ công cụ khác ngoài netcat. Dưới đây là cách sử dụng một vài trong số chúng. Tất cả đều cho rằng sự tồn tại của một servicetập lệnh chạy của bạn func, bất cứ điều gì có thể là:

#! / thùng / sh
trong khi đọc -r TIN NHẮN
làm
    echo 1> & 2 "$ {TCPREMOTEIP}" "$ {TCPREMOTEPORT}" rx "$ {TIN NHẮN}"
    func
làm xong

Các biến TCPREMOTEIPTCPREMOTEPORTmôi trường được xác định bởi giao thức UCSPI-TCP.

Tập lệnh được sinh ra dưới dạng một quy trình riêng lẻ trên mỗi kết nối TCP bằng các bộ công cụ khác nhau. Trong phần tiếp theo, các công cụ được hiển thị như được sử dụng trong một tập lệnh ngắn. Một kịch bản như vậy, được đặt tên theo quy ước run, là cách người ta điều hành chúng dưới một người quản lý dịch vụ gia đình daemontools. Họ tất nhiên có thể được gọi trực tiếp.

Bernstein ucspi-tcp

Với ucspi-tcp của Daniel J. Bernstein, tcpserversinh ra servicekịch bản:

#! / bin / sh -e
exec tcpserver -v -P -R -H -l 0 0.0.0.0 7777 ./service

Có các phiên bản nâng cao có khả năng IPv6 của Bernstein ucspi-tcp. Với Erwin Hoffman, các tcpservernỗ lực xử lý cả IPv4 và IPv6 trong một (nếu hệ điều hành hỗ trợ điều này, một số thì không) và sinh ra servicetập lệnh:

#! / bin / sh -e
exec tcpserver -v -P -R -H -l 0 :: 0 7777 ./service

Bercot s6-mạng, s6 và thực thi

Với kết nối mạng s6 của Laurent Bercot s6-tcpserver4s6-tcpserver6xử lý riêng IPv4 và IPv6 và tạo ra servicetập lệnh:

#! / lệnh / execlineb
s6-tcpserver4 -v 0.0.0.0 7777 
./dịch vụ
#! / lệnh / execlineb
s6-tcpserver6 -v :: 0 7777 
./dịch vụ

Người ta có thể xây dựng các máy chủ phức tạp hơn bằng cách thay thế các công cụ như s6-tcpserver-accesss6-applyuidgidtrong chuỗi ngay trước đó ./service.

công cụ UCSPI

Với bộ công cụ nosh, tcp-socket-listenlắng nghe trên ổ cắm TCP, một lần nữa xử lý IPv4 và IPv6 một cách tự động nếu hệ điều hành hỗ trợ làm như vậy và các chuỗi sẽ tcp-socket-acceptlần lượt tạo ra servicetập lệnh:

#! / bin / nosh
tcp-socket-lắng nghe --combine4and6 :: 7777
tcp-socket-accept --verbose --localname 0
./dịch vụ

Hoặc một chạy hai quy trình riêng biệt, trên các hệ điều hành như OpenBSD:

#! / bin / nosh
tcp-socket-lắng nghe 0.0.0.0 7777
tcp-socket-accept --verbose --localname 0
./dịch vụ
#! / bin / nosh
tcp-socket-lắng nghe: 7777
tcp-socket-accept --verbose --localname ::
./dịch vụ

Người ta có thể xây dựng các máy chủ phức tạp hơn bằng cách thay thế các công cụ như ucspi-socket-rules-checksetuidgidtrong chuỗi.

#! / bin / nosh
tcp-socket-lắng nghe --combine4and6 :: 7777
setuidgid không được ưu tiên người dùng
tcp-socket-accept --verbose --localname 0
ucspi-socket-quy tắc-kiểm tra --verbose
./dịch vụ

Pape ipsvd

Với ipsvd của Gerrit Pape, tcpsvdsinh ra servicekịch bản:

#! / bin / sh -e
thực hiện tcpsvd -v 0.0.0.0 7777 ./service

UCSPI-UDP

serviceKịch bản chung có thể xử lý khi đầu vào tiêu chuẩn là một ổ cắm luồng . Nhưng bạn đã không chỉ định rõ ràng TCP.

Mặc dù một số bộ công cụ đã nói ở trên có thể được sử dụng để xây dựng các máy chủ UDP theo cách tương tự như cách người ta có thể sử dụng chúng để xây dựng các máy chủ TCP (cf udp-socket-listenin nosh), thật khó để xây dựng chương trình dịch vụ thực tế với tập lệnh shell, vì các hàm dựng của shell không nhất thiết phải đối phó tốt khi đầu vào tiêu chuẩn là một ổ cắm datagram .

đọc thêm


0

Điều này cũng có thể được thực hiện với udpsvdUbuntu / Debian ( xem manpage ) cũng như tích hợp sẵn trên busybox. Thí dụ:

# simple UDP "echo" on port 9998
udpsvd 0.0.0.0 9998 cat

Thay thế catbằng kịch bản shell của bạn để thực thi, stdin là gói.

Với netcat, bạn có thể chạy trong một vòng lặp để tiếp tục lắng nghe và truyền từng gói cho myscript:

 while true; do nc -ul 9998 | myscript.sh; done

Nếu bạn muốn chuyển tất cả các gói đã nhận dưới dạng luồng sang một lệnh gọi duy nhất cho tập lệnh của mình:

# this will keep listening instead of terminating the process:
nc -kul 9998 |myscript.sh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.