Bagaimana cara membuat skrip shell yang mengirimkan output ke suatu proses

11

Saat ini saya sedang menjalankan program konsol server di layar karena saya harus membacanya dan sesekali mengirim perintah.

Saya ingin menjalankan aplikasi sebagai daemon di latar belakang (mulai / hentikan dengan init).

Saya dapat tail -flog, tetapi itu tidak akan membiarkan saya mengirim input ke proses.

Apakah ada cara untuk mengatur ini sehingga saya bisa membaca dan mengirim input, tetapi masih menjalankannya di latar belakang?

Saya juga ingin dapat mengirim input ke daemon dari proses yang berbeda juga (skrip shell yang dapat mengirim perintah "Stop \ n", misalnya).

Bill K.
sumber
Hanya komentar kepada siapa pun yang datang untuk membaca ini - jawabannya di sini luar biasa. Jika Anda tidak tahu tentang pipa bernama, saya sangat menyarankan Anda setidaknya mencobanya. Menggunakan ini saya bisa menjalankan Minecraft sebagai layanan dan berinteraksi dengan konsol dari skrip lain dengan menulis ke pipa bernama - sehingga menjadi mungkin untuk menulis skrip untuk menghentikan server, mengirim pesan ke pengguna, dll sambil masih mengurai log keluaran untuk mencari jalur utama (seperti mengirim pesan obrolan yang ditujukan kepada pengguna sebagai teks)
Bill K

Jawaban:

9

Baca dari pipa, tulis ke file

Jika Anda ingin daemon membaca input yang dihasilkan oleh beberapa proses sewenang-wenang, Anda perlu menghubungkan proses itu ke sebuah pipa. Di sini proses sewenang-wenang adalah Anda mengulangi perintah, dan itu akan berjalan dalam konteks yang berbeda. Jadi buatlah pipa bernama (sering disebut fifo dalam konteks unix).

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

Dan cukup tulis perintah ke pipa:

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

Ini tidak mungkin berfungsi sebagaimana adanya: ada kemungkinan besar bahwa daemon akan keluar ketika melihat akhir file pada input standarnya, yang terjadi segera setelah proses pertama yang menulis ke pipa berakhir. Anda dapat menggunakan tail -funtuk menghindari masalah itu.

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

Dengan beberapa tailimplementasi, Anda dapat digigit dengan buffering: tailproses akan menunggu sampai ia telah mengumpulkan cukup byte untuk memancarkan beberapa output. Saya tidak berpikir ini bisa dipecahkan dalam kotak alat POSIX; jika itu masalah, gunakan program C atau Perl atau Python yang sepele. Sejauh yang saya tahu taildari GNU coreutils (seperti yang ditemukan di Linux dan di tempat lain) aman dalam hal ini.

Ketika Anda menghentikan daemon, echo >/var/run/daemon.fifoakan mematikan tailprosesnya.


Mulai program di dalam layar

Alih-alih memanggil daemon langsung dari manajer layanan Anda (apakah Anda benar-benar hanya menggunakan SysV init, atau sesuatu tambahan seperti skrip pembungkus atau Pemula?), Panggil

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

Karena daemon tidak akan menjadi proses anak dari manajer layanan, Anda perlu memastikan untuk mengirim sinyal ke proses yang benar. Cara melakukannya tergantung pada bagaimana tepatnya daemon dimulai dan oleh apa.

Secara teknis dimungkinkan untuk melampirkan proses yang sedang berjalan ke terminal, tetapi ada risiko Anda akan crash program, jadi ini jelas untuk sistem produksi.

The -Lpilihan membuat layar menulis segala sesuatu yang muncul di jendela untuk file. Nama file diberikan daemon.screenrcdengan logfilearahan.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Sebenarnya, saya benar-benar ingin dapat mengirim pesan ke stdin dari skrip - mungkin itu pertanyaan yang seharusnya saya tanyakan. Saat ini saya hanya menjalankan server dari sebuah skrip dan saya bisa mengetikkannya di terminal, tetapi sepertinya itu harus dijalankan sebagai layanan ...
Bill K
@ Bill: Ok, saya mengerti. Maka hal pertama yang muncul di benak saya adalah pipa bernama.
Gilles 'SO- stop being evil'
Saya pikir inilah yang saya inginkan @Gilles! Saya perlu memahaminya dengan lebih baik. Saya akan menghabiskan waktu memilah-milah halaman manual untuk mencari tahu - saya jujur ​​mendapatkan sangat sedikit dari itu (saya mendapatkan sebagian besar dari apa yang Anda lakukan dan hampir tidak ada bagaimana Anda melakukannya - dan saya pikir saya agak punya petunjuk dengan hal ini.) Teori saya bukan untuk terhubung langsung ke proses tetapi untuk membuat skrip lain yang bergabung itu i / o ke deamons o / i untuk membuatnya tampak seperti konsol asli sedang berjalan, tetapi dengan kemampuan untuk melakukan gema 'MAJU 10' dari skrip lain secara bersamaan.
Bill K
Saya pikir saya mendapatkan banyak dari itu. Jika saya memecahnya, saya sekarang mengerti "mkfifo pipe" dan "tail -f pipe | command> output", menguji mereka dan mereka bekerja. Saya pikir sebagian besar hal lain yang Anda miliki adalah trik untuk menjalankannya pada satu baris - apakah saya kehilangan sesuatu yang penting?
Bill K
@ Bill: Anda bisa menulis ke terminal di dalam layar dari luar (menggunakan stuffperintah layar ). Tetapi Anda tidak perlu overhead (pemrosesan, tetapi yang paling penting kognitif) dari terminal di sini, pipa hampir cukup (cukup dengan sedikit proses relay pengabaian file-end). Anda mungkin ingin bereksperimen sedikit dengan <fifo catatau <fifo tail -f | catdi satu terminal dan echo >fifo; echo >fifodi terminal lain; Saya pikir kamu akan baik-baik saja.
Gilles 'SO- stop being evil'