Làm cách nào để tạo tập lệnh shell gửi đầu ra cho một quy trình


11

Tôi hiện đang chạy chương trình bảng điều khiển máy chủ trong một màn hình vì tôi cần đọc cả hai và thỉnh thoảng gửi lệnh.

Tôi muốn chạy ứng dụng như một daemon trong nền (bắt đầu / dừng nó với init).

Tôi có thể tail -fđăng nhập, nhưng điều đó sẽ không cho phép tôi gửi đầu vào cho quá trình.

Có cách nào để thiết lập điều này để tôi có thể vừa đọc và gửi đầu vào, nhưng vẫn để nó chạy ở chế độ nền không?

Tôi cũng muốn có thể gửi đầu vào cho daemon từ các quy trình khác nhau (ví dụ, tập lệnh shell có thể gửi lệnh "Dừng \ n").


Chỉ cần một nhận xét cho bất cứ ai đến để đọc điều này - câu trả lời ở đây là tuyệt vời. Nếu bạn không biết về các đường ống có tên, tôi khuyên bạn ít nhất nên thử chúng. Sử dụng điều này tôi có thể chạy Minecraft như một dịch vụ và tương tác với bảng điều khiển từ các tập lệnh khác bằng cách viết vào đường ống có tên - vì vậy có thể viết tập lệnh để dừng máy chủ, gửi tin nhắn cho người dùng, v.v. trong khi vẫn phân tích nhật ký đầu ra để tìm các dòng chính (chẳng hạn như gửi tin nhắn trò chuyện được gửi đến người dùng cho anh ấy dưới dạng văn bản)
Bill K

Câu trả lời:


9

Đọc từ một đường ống, ghi vào một tập tin

Nếu bạn muốn daemon đọc đầu vào được tạo bởi một số quy trình tùy ý, bạn cần kết nối quy trình đó với một đường ống. Ở đây, quá trình tùy ý là bạn lặp lại các lệnh và nó sẽ chạy trong một bối cảnh khác. Vì vậy, tạo một ống có tên (thường được gọi là fifo trong bối cảnh unix).

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

Và chỉ cần viết lệnh vào đường ống:

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

Tuy nhiên, điều này dường như không hoạt động: có khả năng daemon sẽ thoát khi thấy phần cuối của tệp trên đầu vào tiêu chuẩn của nó, xảy ra ngay khi quá trình đầu tiên ghi vào đường ống kết thúc. Bạn có thể sử dụng tail -fđể tránh vấn đề đó.

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

Với một số tailtriển khai, bạn có thể bị cắn bởi bộ đệm: tailquá trình sẽ đợi cho đến khi nó tích lũy đủ byte để phát ra một số đầu ra. Tôi không nghĩ rằng điều này có thể giải quyết được trong hộp công cụ POSIX; nếu đó là một vấn đề, hãy sử dụng chương trình C hoặc Perl hoặc Python tầm thường. Theo như tôi có thể nói tailtừ GNU coreutils (như được tìm thấy trên Linux và các nơi khác) là an toàn về mặt này.

Khi bạn dừng daemon, echo >/var/run/daemon.fifosẽ giết tailquá trình.


Bắt đầu chương trình bên trong màn hình

Thay vì gọi trình nền trực tiếp từ trình quản lý dịch vụ của bạn (bạn có thực sự chỉ sử dụng SysV init hoặc một cái gì đó bổ sung như tập lệnh bao bọc hoặc Upstart không?), Hãy gọi

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

Vì daemon sẽ không phải là một quy trình con của người quản lý dịch vụ, bạn cần đảm bảo gửi tín hiệu đến đúng quy trình. Làm thế nào để làm điều đó phụ thuộc vào chính xác cách daemon được bắt đầu và bằng gì.

Về mặt kỹ thuật có thể gắn quy trình đang chạy vào thiết bị đầu cuối, nhưng có nguy cơ bạn sẽ làm hỏng chương trình, vì vậy đây chắc chắn là một hệ thống sản xuất.

Các -Ltùy chọn làm cho màn hình ghi tất cả những gì xuất hiện trong cửa sổ của nó vào một tập tin. Tên tập tin được đưa ra daemon.screenrcvới logfilechỉ thị.


Trên thực tế, tôi thực sự muốn có thể gửi tin nhắn đến stdin từ một kịch bản - có lẽ đó là câu hỏi tôi nên hỏi. Hiện tại tôi chỉ đang chạy máy chủ từ một tập lệnh và có thể nhập nó vào một thiết bị đầu cuối, nhưng có vẻ như nó nên được chạy như một dịch vụ ...
Bill K

@Bill: Ok, tôi hiểu rồi. Sau đó, điều đầu tiên tôi nghĩ đến là một đường ống được đặt tên.
Gilles 'SO- ngừng trở nên xấu xa'

Tôi nghĩ rằng đây chính xác là những gì tôi muốn @Gilles! Tôi cần phải hiểu nó tốt hơn mặc dù. Tôi sẽ dành một chút thời gian để phân loại các trang nam để tìm ra nó - Tôi thực sự nhận được rất ít về điều đó (tôi nhận được hầu hết những gì bạn đang làm và hầu như không có cách nào bạn làm điều đó - và tôi nghĩ rằng tôi đã có một đầu mối với công cụ này.) Lý thuyết của tôi không phải là kết nối trực tiếp với quá trình mà là tạo ra một kịch bản khác đã tham gia vào đó là các deamons o / i để làm cho nó giống như giao diện điều khiển gốc đang chạy, nhưng với khả năng để thực hiện tiếng vang 'FORWARD 10' từ một tập lệnh khác cùng một lúc.
Bill K

Tôi nghĩ rằng tôi nhận được nhiều của nó. Nếu tôi phá vỡ nó bây giờ tôi hiểu "mkfifo pipe" và "tail -f pipe | lệnh> output", đã thử nghiệm chúng và chúng hoạt động. Tôi nghĩ rằng hầu hết những thứ khác bạn có là thủ thuật để khiến nó chạy trên một dòng - tôi có thiếu điều gì quan trọng không?
Bill K

@Bill: Bạn có thể ghi vào thiết bị đầu cuối bên trong màn hình từ bên ngoài (sử dụng stufflệnh của màn hình ). Nhưng bạn không cần chi phí chung (xử lý, nhưng quan trọng nhất là nhận thức) của một thiết bị đầu cuối ở đây, một đường ống là gần như đủ (nó là đủ với một quá trình chuyển tiếp bỏ qua cuối tập tin). Bạn có thể muốn thử nghiệm một chút với <fifo cathoặc <fifo tail -f | cattrong một thiết bị đầu cuối và echo >fifo; echo >fifotrong một thiết bị đầu cuối khác; Tôi nghĩ bạn sẽ ổn thôi.
Gilles 'SO- ngừng trở nên xấu xa'
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.