Запись в стандартный фоновый процесс

Я на Ubuntu 10.04 box и запустил сервер в фоновом режиме (myserver &) поверх ssh. Он работает нормально, но мне нужен способ получить доступ к стандартному серверу, так как единственный способ управлять сервером - это использовать этот метод.

Есть ли какой-нибудь способ добраться до stdin уже запущенного процесса, чтобы я мог написать ему (и, надеюсь, прочитать его stdout)? Очевидно, что если бы я собирался делать это сейчас, я бы начал с FIFO, перенаправляющего на stdin, но, к сожалению, сейчас уже немного поздно.

Есть идеи?

4 ответа

Вы можете запустить свой сервер с именованным каналом (fifo) в качестве ввода:

mkfifo /tmp/srv-input
cat > /tmp/srv-input &
echo $! > /tmp/srv-input-cat-pid
cat /tmp/srv-input | myserver &

cat > /tmp/srv-input & Важно, чтобы ваш сервер не получал EOF. По крайней мере один процесс должен иметь открытую записку fifo, чтобы ваш сервер не получал EOF. PID этой команды сохраняется в /tmp/srv-input-cat-pid файл для последнего убийства.

В вашем случае, когда вы уже запустили свой сервер, вы должны использовать отладчик, такой как gdb прикрепить к вашему процессу, чтобы перенаправить его stdin до пятерки:

gdb -p PID
call close(0)
call open(0, "/tmp/srv-input", 0600)

А затем сделайте что-то вроде ниже, чтобы отправить входные данные на ваш сервер (в другом окне терминала, если необходимо):

echo "command" > /tmp/srv-input

Чтобы отправить EOF на ваш сервер, вам нужно убить cat > /tmp/srv-input процесс, который PID был сохранен в /tmp/srv-input-cat-pid file,

В случае GDB просто выйдите из GDB, и EOF будет отправлен.

Вы можете попробовать записать в каталог /proc pid. Скажите, что pid вашего демона 2000, попробуйте написать в /proc/2000/fd/0

То же, что и выше, но "кошка" не работает для меня. Файл получил EOF и закончился после отправки одной команды.

Это сработало для меня:

#!/bin/bash

mkfifo /tmp/srv-input
tail -f /tmp/srv-input | myserver &

Существует более элегантное решение, которое решает проблемы сtail -fи

  • Создайте именованный канал для маршрутизации STDIN:mkfifo /data/in.

  • Заблокируйте его для записи, чтобы он не закрывался, когда ваш процесс прочитает все текущее содержимое:sleep infinity > /data/in &.

Спать вечно лучше, чемtailf -f /dev/nullпотому что Tailf использует ресурсы inotify и будет запускаться каждый раз, когда какое-либо приложение отправляет данные в /dev/null. Вы можете увидеть это, запустивstraceв теме. Это также лучше, чемcat > /dev/null &потому чтоcatсам будет отключен от STDIN, который, в свою очередь, закроется.

  • Запустите свой процесс в фоновом режиме с помощью/data/inпредоставление STDIN:application < /data/in &.

Это работает лучше, чем использование трубопровода из хвоста.tail -f /data/in | application &потому что канал будет завершен только в том случае, если хвост остановится, но если ваше приложение выйдет из строя, канал продолжит работать.

  • Остановите ожидание завершения работы приложения.wait $(pidof application).

При этом не используются ресурсы, и если приложение приводит к сбою вашего сценария послеwaitбудет казнен. При желании вы можете добавить вокруг него цикл перезапуска приложения.

  • Чтобы завершить работу приложения, корректно перехватывать и передавать ему системные сигналы с помощьюtrap 'kill -SIGTERM $(pidof app)' SIGTERM
Другие вопросы по тегам