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


25

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

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

Любые идеи?


Не могли бы вы просто вернуть его на передний план? («jobs» отобразит ваш текущий фоновый процесс, «fg $ X» вернет работу на передний план, ctrl + b приостановит работу и вернет вас в вашу оболочку, а «bg» продолжит приостановленный процесс в фон)
symcbean

Ответы:


10

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


Спасибо ... Я нашел это сразу после того, как я отправил это (после дня поиска - типичный). Это, кажется, работает (насколько реально отправка данных в программу). К сожалению, программа не принимает команды. Я проверил его, запустив сервер на своем локальном компьютере, и, конечно же, я вижу, что данные появляются, но программа не распознает команды. Я должен вручную нажать Enter на серверном терминале, а затем он просто говорит нераспознанную команду. Может быть, какая-то странная ява? Я застрял ...
Таймортон

1
как насчет echo -e "что-то \ n"> / proc / 2000 / fd / 0?
Катриэль

На самом деле, это не всегда работает, так как / proc / <pid> / fd / 0 указывает на / dev / pts <некоторое число> хотя бы в некоторых системах ...
bk138

Первый ответ на serverfault.com/questions/178457/… отмечает, что этот подход на самом деле не работает.
Баррикартер

2
Это на самом деле не работает. Ваша оболочка обычно (когда не используются каналы или перенаправления) запускает команду с файловыми дескрипторами 0через 2набор в тот же файл, который обычно является виртуальным терминалом (что-то вроде /dev/pty/...). Затем команда читает из FD 0и записывает в FD 1и 2связывается с виртуальным терминалом (например, через SSH или напрямую с вашим эмулятором терминала). Если какой-либо другой процесс обращается к этому файлу (например, через /proc), происходит точно то же самое, то есть запись в него записывает в терминал, а не в команду.
Feuermurmel

29

Вы можете запустить свой сервер с именованным каналом (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 на fifo:

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 будет отправлен.


1
это гораздо более переносимый подход, чем у @katriel, поскольку / proc / 2000 / fd / 0 подходит не для всех систем.
99

Трюк с "cat> / tmp / srv-input &" избавил меня от некоторых головных болей. Спасибо!
99

Как насчет mkfifo /tmp/srv-input; tail -f /tmp/srv-input | myserver &? Это также будет держать трубу открытой ...
bk138

@ bk138: мне кажется, что хвост должен работать, но есть только один способ узнать наверняка: тест.
jfg956

tailне работает, но добавил это, чтобы закончить работу: cat /tmp/srv-input | myserver; kill -9 cat / tmp / srv-input-cat-pid` && rm / tmp / srv-input-cat * `
Тиаго Маседо

4

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

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

#!/bin/bash

mkfifo /tmp/srv-input
tail -f /tmp/srv-input | myserver &
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.