ฉันจะสร้างเชลล์สคริปต์ที่ส่งเอาต์พุตไปยังกระบวนการได้อย่างไร


11

ฉันกำลังใช้งานโปรแกรมคอนโซลเซิร์ฟเวอร์ในหน้าจอเพราะฉันจำเป็นต้องอ่านและส่งคำสั่งเป็นครั้งคราว

ฉันต้องการเรียกใช้แอปเป็น daemon ในพื้นหลัง (เริ่ม / หยุดด้วย init)

ฉันสามารถtail -fบันทึกได้ แต่นั่นจะไม่ให้ฉันส่งข้อมูลไปยังกระบวนการ

มีวิธีใดบ้างในการตั้งค่านี้เพื่อให้ฉันสามารถอ่านและส่งอินพุตได้ แต่ยังคงทำงานในพื้นหลังหรือไม่

ฉันต้องการที่จะสามารถส่งอินพุตไปยัง daemon จากกระบวนการที่แตกต่างกันเช่นกัน (เชลล์สคริปต์ที่สามารถส่งคำสั่ง "Stop \ n" เป็นต้น)


เพียงแค่แสดงความคิดเห็นกับทุกคนที่มาอ่านนี้ - คำตอบที่นี่ยอดเยี่ยม หากคุณไม่รู้เกี่ยวกับไพพ์ที่มีชื่อฉันขอแนะนำให้คุณลองใช้ดู เมื่อใช้สิ่งนี้ฉันสามารถเรียกใช้ Minecraft เป็นบริการและโต้ตอบกับคอนโซลจากสคริปต์อื่น ๆ โดยเขียนไปที่ไปป์ที่มีชื่อ - ดังนั้นจึงเป็นไปได้ที่จะเขียนสคริปต์เพื่อหยุดเซิร์ฟเวอร์ส่งข้อความไปยังผู้ใช้ ฯลฯ ขณะที่ยังแยกวิเคราะห์บันทึกผลลัพธ์ เพื่อค้นหาบรรทัดสำคัญ (เช่นการส่งข้อความแชทที่ส่งถึงผู้ใช้ถึงเขาเป็นข้อความ)
Bill K

คำตอบ:


9

อ่านจากไปป์เขียนลงไฟล์

หากคุณต้องการให้ daemon อ่านอินพุตที่สร้างขึ้นโดยกระบวนการบางอย่างคุณต้องเชื่อมต่อกระบวนการนั้นกับไพพ์ ที่นี่กระบวนการโดยพลการคือคุณสะท้อนคำสั่งและมันจะทำงานในบริบทอื่น ดังนั้นสร้างท่อที่มีชื่อ (มักเรียกว่าฟีฟ่าในบริบทยูนิกซ์)

mkfifo /var/run/daemon.fifo
</var/run/daemon.fifo /path/to/daemond --option >daemon.log

และเพียงแค่เขียนคำสั่งไปยังไพพ์:

echo 'FORWARD 10' >/var/run/daemon.fifo
echo 'LEFT 72' >/var/run/daemon.fifo

สิ่งนี้ไม่น่าจะทำงานได้อย่างที่เป็นอยู่: มีโอกาสที่ดีมอนที่จะออกเมื่อเห็นจุดสิ้นสุดของไฟล์ในอินพุตมาตรฐานซึ่งจะเกิดขึ้นทันทีที่กระบวนการแรกที่เขียนไปยังไพพ์สิ้นสุดลง คุณสามารถใช้tail -fเพื่อหลีกเลี่ยงปัญหานั้น

</var/run/daemon.fifo tail -c +1 -f | {
  echo $$ >/var/run/daemon.pid
  exec /path/to/daemond --option >daemon.log
}

ด้วยtailการใช้งานบางอย่างคุณอาจถูกกัดโดยการบัฟเฟอร์: tailกระบวนการจะรอจนกว่าจะมีจำนวนไบต์เพียงพอที่จะส่งออกบางส่วน ฉันไม่คิดว่านี่จะแก้ปัญหาได้ในกล่องเครื่องมือ POSIX; หากเป็นปัญหาให้ใช้โปรแกรม C หรือ Perl หรือ Python เล็กน้อย เท่าที่ฉันสามารถบอกได้tailจาก GNU coreutils (เท่าที่พบใน Linux และที่อื่น ๆ ) มีความปลอดภัยในเรื่องนี้

เมื่อคุณหยุดภูตecho >/var/run/daemon.fifoจะฆ่าtailกระบวนการ


เริ่มโปรแกรมภายในหน้าจอ

แทนที่จะเรียกใช้ daemon โดยตรงจากตัวจัดการบริการของคุณ (คุณใช้ SysV init จริง ๆ หรือมีอะไรเพิ่มเติมเช่นสคริปต์ wrapper หรือ Upstart?) เรียกใช้

screen -c daemon.screenrc -L -d -m -S daemon_name /path/to/daemond --option

เนื่องจาก daemon จะไม่ใช่กระบวนการย่อยของตัวจัดการบริการคุณต้องแน่ใจว่าได้ส่งสัญญาณไปยังกระบวนการที่ถูกต้อง วิธีการทำนั้นขึ้นอยู่กับว่า daemon เริ่มต้นอย่างไรและอย่างไร

เป็นไปได้ในทางเทคนิคที่จะแนบกระบวนการทำงานกับเทอร์มินัล แต่มีความเสี่ยงที่คุณจะผิดพลาดของโปรแกรมดังนั้นนี่จึงเป็นระบบการผลิตที่แน่นอน

-Lตัวเลือกที่จะทำให้หน้าจอเขียนทุกอย่างที่ปรากฏในหน้าต่างไปยังแฟ้ม ชื่อไฟล์ที่จะได้รับในdaemon.screenrcกับlogfileคำสั่ง


จริงๆแล้วฉันอยากจะส่งข้อความถึง stdin จากสคริปต์จริงๆ - บางทีนั่นอาจเป็นคำถามที่ฉันควรถาม ขณะนี้ฉันแค่ทำงานเซิร์ฟเวอร์จากสคริปต์และฉันสามารถที่จะพิมพ์ไปใน terminal แต่มันก็ดูเหมือนว่ามันควรจะทำงานเป็นบริการ ...
บิล K

@ บิล: โอเคฉันเข้าใจแล้ว จากนั้นสิ่งแรกที่อยู่ในใจของฉันคือท่อที่มีชื่อ
Gilles 'หยุดชั่วร้าย'

ฉันคิดว่านี่เป็นสิ่งที่ฉันต้องการ @Gilles! ฉันต้องเข้าใจมันให้ดีกว่านี้ ฉันจะใช้เวลาเรียงลำดับหน้าคนเพื่อคิดออก - ฉันได้รับน้อยมาก (ฉันได้สิ่งที่คุณทำและเกือบจะไม่มีวิธีที่คุณทำ - และฉันคิดว่าฉันมี เบาะแสกับสิ่งนี้) ทฤษฎีของฉันไม่ได้เชื่อมต่อโดยตรงกับกระบวนการ แต่เพื่อสร้างสคริปต์อื่นที่เข้าร่วมเป็น i / o ถึง deamons o / i เพื่อให้ดูเหมือนว่าคอนโซลดั้งเดิมกำลังทำงาน แต่มีความสามารถ เพื่อทำ echo 'ไปข้างหน้า 10' จากสคริปต์อื่นในเวลาเดียวกัน
Bill K

ฉันคิดว่าฉันได้รับมาก ถ้าฉันทำลายมันตอนนี้ฉันเข้าใจ "mkfifo pipe" และ "tail -f pipe | command> output" ทดสอบพวกมันและมันใช้งานได้ ฉันคิดว่าสิ่งอื่น ๆ ส่วนใหญ่ที่คุณมีคือกลอุบายเพื่อให้มันวิ่งบนบรรทัดเดียว - ฉันขาดสิ่งสำคัญไปหรือเปล่า?
Bill K

@ บิล: คุณสามารถเขียนถึงเทอร์มินัลภายในหน้าจอจากด้านนอก (โดยใช้stuffคำสั่งของหน้าจอ) แต่คุณไม่จำเป็นต้องมีค่าใช้จ่าย (การประมวลผล แต่ที่สำคัญที่สุดคือความรู้ความเข้าใจ) ของเทอร์มินัลที่นี่ท่อก็เกือบจะพอแล้ว (มันก็เพียงพอแล้วที่มีกระบวนการถ่ายทอดไฟล์ คุณอาจต้องการที่จะทดสอบเล็ก ๆ น้อย ๆ กับ<fifo catหรือ<fifo tail -f | catในหนึ่งขั้วและecho >fifo; echo >fifoใน terminal อื่น ฉันคิดว่าคุณจะสบายดี
Gilles 'หยุดชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.