วิธีตั้งค่าสคริปต์ให้ทำงานเมื่อพอร์ตได้รับข้อความ


12

ฉันสงสัยว่าจะได้รับเชลล์สคริปต์เพื่อฟังบนพอร์ตบางอย่าง (อาจใช้ netcat?) หวังว่าเมื่อข้อความถูกส่งไปยังพอร์ตนั้นสคริปต์จะบันทึกข้อความและเรียกใช้ฟังก์ชัน

ตัวอย่าง:

  1. คอมพิวเตอร์ 1 มีสคริปต์ที่ทำงานในพื้นหลังสคริปต์เปิดพอร์ต 1234 เพื่อรับส่งข้อมูลขาเข้า

  2. คอมพิวเตอร์ 2 ส่งข้อความ "hello world" ไปยังพอร์ต 1234 ของคอมพิวเตอร์ 1

  3. สคริปต์บนคอมพิวเตอร์ 1 บันทึกข้อความ "hello world" ไปยังตัวแปร $ MESSAGE

  4. สคริปต์เรียกใช้ฟังก์ชันตอนนี้ตัวแปร $ MESSAGE ถูกตั้งค่าแล้ว

ฉันจะบริจาคได้อย่างไร

คำตอบ:


12

socatควรจะเป็นไปได้ด้วย

เขียนสคริปต์ "getmsg.sh" เช่นนี้เพื่อรับข้อความเดียวผ่าน stdin:

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

จากนั้นเรียกใช้socatคำสั่งนี้เพื่อเรียกใช้สคริปต์ของเราสำหรับการเชื่อมต่อ tcp แต่ละพอร์ตที่พอร์ต 7777:

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

ส่งข้อความทดสอบจากเชลล์อื่น:

echo "message 1" | netcat localhost 7777

คุณทดสอบแล้วหรือยัง

เขียนซ้ำและทดสอบตอนนี้;)
rudimeier

1
ฉันได้รับแรงบันดาลใจจากวิธีแก้ปัญหาของคุณและพบวิธีที่ทำงานร่วมกับ netcat: nc -l 7777 | ./getmsg.sh
Daniel

ดีใจที่ได้ยินเช่นนั้น. แต่netcatมีอยู่หลังจากการเชื่อมต่อหนึ่งครั้ง socatจะทำเช่นเดียวกันหากคุณลบ ", fork" จากบรรทัดคำสั่งของฉัน
rudimeier

7

วิธี UCSPI-TCP

มีชุดเครื่องมืออื่นที่ไม่ใช่ netcat นี่คือวิธีการใช้งานไม่กี่คน พวกเขาทั้งหมดเข้าใจว่ามีserviceสคริปต์ที่ทำงานของคุณfuncไม่ว่ามันจะเป็นอะไร:

#! / bin / ดวลจุดโทษ
ในขณะที่อ่าน -r MESSAGE
ทำ
    echo 1> & 2 "$ {TCPREMOTEIP}" "$ {TCPREMOTEPORT}" rx "$ {MESSAGE}"
    func
เสร็จแล้ว

TCPREMOTEIPและTCPREMOTEPORTสภาพแวดล้อมตัวแปรจะถูกกำหนดโดยโปรโตคอล TCP-UCSPI

สคริปต์ถูกวางไข่เป็นกระบวนการเดี่ยวต่อการเชื่อมต่อ TCP โดยใช้ชุดเครื่องมือต่างๆ ในสิ่งต่อไปนี้เครื่องมือจะแสดงตามที่ใช้ในสคริปต์สั้น สคริปต์ชื่อตามอัตภาพrunนั้นเป็นวิธีที่จะรันภายใต้ผู้จัดการบริการ daemontools-family แน่นอนพวกเขาสามารถเรียกใช้โดยตรง

Bernstein ucspi-tcp

กับแดเนียลเจ Bernstein ของ ucspi-TCP, tcpserverspawns serviceสคริปต์:

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

มี Bernstein ucspi-tcp เวอร์ชั่นปรับปรุงที่รองรับ IPv6 ด้วย Erwin Hoffman tcpserverพยายามจัดการทั้ง IPv4 และ IPv6 ในหนึ่งเดียว (หากระบบปฏิบัติการรองรับสิ่งนี้ไม่กี่อย่าง) และวางserviceสคริปต์:

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

Bercot s6-networking, s6 และดำเนินการ

ด้วยเครือข่าย s6 ของ Laurent Bercot s6-tcpserver4และs6-tcpserver6จัดการ IPv4 และ IPv6 แยกกันและวางserviceสคริปต์:

#! / คำสั่ง / execlineb
s6-tcpserver4 -v 0.0.0.0 7777 
./บริการ
#! / คำสั่ง / execlineb
s6-tcpserver6 -v :: 0 7777 
./บริการ

หนึ่งสามารถสร้างขึ้นเซิร์ฟเวอร์ที่ซับซ้อนมากขึ้นโดย interposing เครื่องมือเช่นs6-tcpserver-accessและในห่วงโซ่ทันทีก่อนs6-applyuidgid./service

เครื่องมือ nosh UCSPI

ด้วยชุดเครื่องมือ nosh tcp-socket-listenฟังบนซ็อกเก็ต TCP จัดการ IPv4 และ IPv6 อีกครั้งโดยบังเอิญหากระบบปฏิบัติการรองรับการทำเช่นนั้นและเชื่อมโยงtcp-socket-acceptกับserviceสคริปต์ที่วางไข่:

#! / bin / Nosh
tcp-socket-Listen --combine4and6 :: 7777
tcp-socket-accept --verbose - local ชื่อ 0
./บริการ

หรือกระบวนการหนึ่งทำงานแยกกันสองกระบวนการบนระบบปฏิบัติการเช่น OpenBSD:

#! / bin / Nosh
tcp-socket-Listen 0.0.0.0 7777
tcp-socket-accept --verbose - local ชื่อ 0
./บริการ
#! / bin / Nosh
tcp-socket-Listen :: 7777
tcp-socket-accept --verbose - local ชื่อ ::
./บริการ

หนึ่งสามารถสร้างเซิร์ฟเวอร์ที่ซับซ้อนมากขึ้นโดยการแทรกเครื่องมือเช่นucspi-socket-rules-checkและsetuidgidในห่วงโซ่

#! / bin / Nosh
tcp-socket-Listen --combine4and6 :: 7777
setuidgid ผู้ใช้ที่ไม่มีสิทธิ์
tcp-socket-accept --verbose - local ชื่อ 0
ucspi-socket-rules-check --verbose
./บริการ

Pips ipsvd

ด้วย ipsvd ของ Gerrit Pape tcpsvdวางไข่serviceสคริปต์:

#! / bin / sh -e
exec tcpsvd -v 0.0.0.0 7777 ./service

UCSPI-UDP

serviceสคริปต์ทั่วไปสามารถจัดการได้เมื่ออินพุตมาตรฐานคือซ็อกเก็ตสตรีม แต่คุณไม่ได้ระบุ TCP อย่างชัดเจน

แม้ว่าบางชุดของเครื่องมือดังกล่าวสามารถใช้เพื่อสร้างเซิร์ฟเวอร์ UDP ในลักษณะเดียวกันกับวิธีที่พวกเขาสามารถใช้เพื่อสร้างเซิร์ฟเวอร์ TCP (cf udp-socket-listenใน nosh) แต่มันก็ยากที่จะสร้างโปรแกรมบริการจริงด้วยสคริปต์เชลล์เนื่องจากบิวด์อินของเชลล์ไม่ได้ จำเป็นต้องรับมือได้ดีเมื่ออินพุตมาตรฐานคือซ็อกเก็ตดาตาแกรม

อ่านเพิ่มเติม


0

สิ่งนี้สามารถทำได้ด้วยudpsvdซึ่งมีอยู่ใน Ubuntu / Debian ( ดู manpage ) เช่นเดียวกับในตัวไปยัง busybox ตัวอย่าง:

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

แทนที่catด้วยเชลล์สคริปต์ของคุณเพื่อดำเนินการ stdin เป็นแพ็กเก็ต

ด้วยnetcatคุณสามารถทำงานเป็นวงเพื่อฟังต่อและส่งแต่ละแพ็คเก็ตไปที่myscript:

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

หากคุณต้องการส่งแพ็กเก็ตที่ได้รับทั้งหมดเป็นสตรีมไปยังการเรียกใช้สคริปต์ของคุณ:

# this will keep listening instead of terminating the process:
nc -kul 9998 |myscript.sh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.