Написання до stdin фонового процесу


25

Я в полі Ubuntu 10.04 і запустив сервер у фоновому режимі (myserver &) над ssh. Він працює добре, але мені потрібен спосіб потрапити на жорсткість сервера, оскільки єдиний спосіб контролювати сервер - це за допомогою цього методу.

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

Якісь ідеї?


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

Відповіді:


10

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


Дякую ... Я це виявив одразу після того, як опублікував це (після дня перегляду - типовий). Це, здається, працює (що стосується фактичного надсилання даних у програму). На жаль, програма не приймає команди. Я перевірив його на сервері на моєму локальному комп'ютері, і, звичайно, я бачу, що дані з'являються, але програма не розпізнає команди. Мені потрібно вручну натиснути клавішу enter на серверному терміналі, і тоді це просто говорить нерозпізнана команда. Можливо, якась дива ява? Я застряг…
tajmorton

1
як щодо ехо -е "щось \ n"> / proc / 2000 / fd / 0?
katriel

Насправді, це не завжди хитається, оскільки / proc / <pid> / fd / 0 вказує на / dev / pts <деяке число> принаймні на деяких системах ...
bk138,

Перша відповідь на сервер defaultfault.com/questions/178457/… зазначає, що такий підхід насправді не працює.
barrycarter

2
Це насправді не працює. Ваша оболонка зазвичай (коли не використовуються труби чи переадресації) запускає команду з дескрипторами файлів 0через 2встановлений до того ж файл, який зазвичай є віртуальним терміналом (щось на зразок /dev/pty/...). Потім команда читає з FD 0і записує в FD 1і 2спілкується з віртуальним терміналом (наприклад, через SSH або безпосередньо з емулятором терміналу). Якщо будь-який інший процес отримує доступ до цього файлу (наприклад, через /proc), відбувається саме те саме, тобто запис до нього пише в термінал, а не в команду.
Фейермурмель

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. Принаймні один процес повинен мати письмовий відкритий файл, щоб ваш сервер не отримував 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.


1
це набагато портативніший підхід, ніж той, що від @katriel, оскільки / proc / 2000 / fd / 0 не є жорстким для всіх систем.
Prior99

Трюк з "cat> / tmp / srv-input &" врятував мені кілька головних болів. Дякую!
Prior99

Про що 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.