Як зробити скрипт оболонки, який надсилає вихідний процес


11

Наразі я запускаю програму консолі сервера на екрані, тому що мені потрібно як її читати, так і періодично надсилати команди.

Я хотів би запустити додаток як демон у фоновому режимі (запустити / зупинити його з init).

Я міг би tail -fжурнал, але це не дозволить мені надсилати вхід у процес.

Чи є спосіб налаштувати це так, щоб я міг читати та надсилати дані, але все-таки він працює у фоновому режимі?

Я також хотів би мати можливість надсилати дані до демона з різних процесів (наприклад, сценарій оболонки, який може надіслати команду "Зупинити \ n").


Просто коментар до кожного, хто приходить прочитати це - відповідь тут фантастична. Якщо ви не знаєте про названі труби, я настійно рекомендую вам хоча б спробувати. Використовуючи це, я міг би запустити Minecraft як послугу та взаємодіяти з консоллю з інших сценаріїв, написавши на названу трубку - так стає можливим писати сценарії для зупинки сервера, надсилання повідомлень користувачам тощо, поки ще розбирає вихідний журнал шукати ключові рядки (наприклад, надсилати повідомлення в чаті, адресовані користувачеві йому як тексти)
Bill K

Відповіді:


9

Прочитайте з труби, запишіть у файл

Якщо ви хочете, щоб демон зчитував вхід, отриманий деяким довільним процесом, вам потрібно підключити цей процес до труби. Тут довільний процес - це відголос команд, і він запускається в іншому контексті. Тому створіть названу трубу (її часто називають фіфою в контекстах Unix).

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. Наскільки я можу сказати, що tailGNU coreutils (як це можна знайти в Linux та інших місцях) є безпечним у цьому відношенні.

Коли ви зупините демон, echo >/var/run/daemon.fifoвб'є tailпроцес.


Запуск програми всередині екрану

Замість того, щоб викликати демона безпосередньо у вашого менеджера сервісів (ви справді використовуєте тільки SysV init чи щось додаткове, наприклад, скрипти для обгортки чи Upstart?), Викликайте

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

Оскільки демон не буде дочірнім процесом менеджера сервісів, вам потрібно переконатися, що надіслати сигнал правильному процесу. Як це зробити, залежить від того, як саме починається демон і чим.

Це технічно можливо прикріпити процес , що протікає до терміналу, але є ризик , ви будете врізатися програмою, так що це безперечно поза для виробничої системи.

Цей -Lпараметр змушує екран записувати у файл усе, що з’являється у його вікні. Ім'я файлу задається в daemon.screenrcс logfileдирективою.


Насправді, мені дуже хотілося б, щоб я могла надсилати повідомлення на це stdin із сценарію - можливо, це питання, яке я мав би задати. Наразі я просто запускаю сервер зі сценарію і можу набрати його в терміналі, але мені здається, що він повинен працювати як послуга ...
Білл К

@Bill: Гаразд, бачу. Тоді перше, що мені спадає на думку - це названа труба.
Жил "ТАК - перестань бути злим"

Я думаю, що саме цього я хочу @Gilles! Мені потрібно це краще зрозуміти. Я проведу деякий час, перебираючи сторінки чоловіків, щоб зрозуміти це - я, чесно кажучи, отримую дуже мало цього (я отримую більшість того, що ти робиш, і майже нічого, як ти це робив, - і я думав, що у мене був "Моя теорія полягала не в тому, щоб підключитись безпосередньо до процесу, а створити ще один сценарій, який приєднав це i / o до deamons o / i, щоб зробити це схожим на те, що оригінальна консоль працює, але з можливістю одночасно робити відлуння "Вперед 10" з іншого сценарію.
Білл К

Я думаю, що я багато чого отримую. Якщо я розбиваю його, я тепер розумію "mkfifo pipe" і "tail -f pipe | команда> вихід", протестував їх і вони працюють. Я думаю, що більшість речей, які ви мали, були хитрощами, щоб змусити його працювати на одній лінії - я пропускаю щось критичне?
Білл К

@Bill: Ви можете записувати на внутрішній екран терміналу ззовні (використовуючи stuffкоманду екрана ). Але тут вам не потрібні накладні (обробка, але найголовніше пізнавальна) терміналу, труби майже достатньо (достатньо з невеликим процесом ретрансляції кінця файлу). Ви можете трохи поекспериментувати з <fifo catабо <fifo tail -f | catв одному терміналі і echo >fifo; echo >fifoв іншому терміналі; Я думаю, ти будеш добре.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.