У меня есть длительный процесс сервера внутри сеанса экрана на моем сервере Linux. Это немного нестабильно (и, к сожалению, не мое программное обеспечение, поэтому я не могу это исправить!), Поэтому я хочу написать сценарий перезапуска процесса каждую ночь, чтобы помочь стабильности. Единственный способ заставить его выполнить корректное завершение работы - перейти к экранному процессу, переключиться в окно, в котором он запущен, и ввести строку «стоп» на его консоли управления.
Есть ли какие-нибудь умные перенаправления, которые я могу сделать, чтобы cronjob отправлял эту команду остановки в определенное время каждый день?
ls -l /proc/7417/fd/0
./dev/pts/19
),y
персонаж не достигает самого приложения. Это похоже на то, что происходит, когда вы используете команду write (1) . В любом случае, попробуйте другой мой ответ или графический инструмент автоматизации, такой как xdotool .Экранное решение
Запустите сервер так:
Экран запустится в отдельном режиме, поэтому, если вы хотите увидеть, что происходит, запустите:
Управляйте сервером так:
(этот ответ основан на отправке текстового ввода на отдельный экран с сайта- партнера Unix & Linux )
Объяснение параметров:
решение на основе tmux
Запустите сервер так:
tmux запустится в автономном режиме, поэтому, если вы хотите увидеть, что происходит, запустите:
Управляйте сервером так:
Объяснение параметров:
источник
Попробуйте это начать:
И это убить
источник
echo "xxx" > cmd
программа останавливается (потому что канал будет закрыт). Хотя некоторые программы достаточно умны, чтобы повторно открывать (rewind(3)
) их стандартный ввод, когда они сталкиваются с EOF.Можно отправить входной текст запущенному процессу без запуска
screen
утилиты или любой другой необычной утилиты. И это можно сделать, отправив этот входной текст в стандартный файл ввода процесса/proc/PID#/fd/0
.Тем не менее, входной текст должен быть отправлен специальным способом для чтения процессом. Отправка введенного текста обычным
write
методом файла не приведет к тому, что процесс получит текст. Это потому, что это добавит только к этому «файлу», но не запустит процесс для чтения байтов.Чтобы запустить процесс для чтения байтов, необходимо выполнить
IOCTL
операцию типаTIOCSTI
для каждого отправляемого байта. Это поместит байт в стандартную очередь ввода процесса.Это обсуждается здесь с некоторыми примерами на C, Perl и Python:
https://unix.stackexchange.com/questions/48103/construct-a-command-by-putting-a-string-into-a-tty/48221
-
Таким образом, чтобы ответить на первоначальный вопрос, заданный почти 9 лет назад, заданию cron нужно было бы запустить небольшой служебный скрипт / программу, аналогичную примерам, которые люди написали для этого другого вопроса, который отправил бы строку «stop \ n» этому серверному процессу. в вопросе, отправив каждый из 5 байтов с помощью
IOCTL
операции типаTIOCSTI
.Конечно, это будет работать только на системах, которые поддерживают
TIOCSTI
IOCTL
тип операции (например, Linux), и только отroot
учетной записи пользователя, так как эти «файлы» в/proc/
«принадлежат»root
.источник
В случае, если это кому-нибудь поможет: у
меня была похожая проблема, и поскольку процесс, который я использовал, не проходил,
screen
илиtmux
мне пришлось использовать другой подход.Я приложил
РЕДАКТИРОВАТЬgdb
кxterm
что мой процесс был запущен в, и используетсяcall write(5, "stop\n", 5)
отgdb
записи в дескрипторе мастер псевдотерминал файла.Я выяснил, в какой файловый дескриптор отправлять данные, посмотрев
/proc/<pid>/fd
ссылку/dev/ptmx
и затем метод проб и ошибок между двумя вариантами (отправка моей строки в оба соответствующих файловых дескриптора, похоже, не принесла вреда).Оказалось, что
КОНЕЦ РЕДАКТИРОВАНИЯxterm
процесс , к которому я присоединился, былspawn-new-terminal()
xterm
вызван действием связывания клавиш, и второйptmx
открытый дескриптор файла был простоptmx
родительскимxterm
процессом, который не был закрыт.Следовательно, вызовы проб и ошибок отправили вывод на этот другой терминал.
Большинство
xterm
процессов не имеют двухptmx
файловых дескрипторов.Это эффективно ввело эту строку в терминал и, следовательно, отправило ее процессу, запущенному под ним.
nb вам может понадобиться разрешить присоединение к запущенному процессу с чем-то вроде
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
источник
Поскольку я не могу прокомментировать наиболее приемлемый ответ Кристиана Чиупиту (2010 г.), я должен поместить это в отдельный ответ:
Этот вопрос уже был решен в этой теме: https://stackoverflow.com/questions/5374255/how-to-write-data-to-existing-processs-stdin-from-external-process
Короче говоря:
Вы должны начать свой процесс с канала для стандартного ввода, который не блокирует и не закрывает, когда текущий ввод был записан. Это может быть реализовано простым бесконечным циклом, который будет передан в рассматриваемый процесс:
Я могу подтвердить, что это не то, как Крисси открыл трубу, которая не работала в моем случае. Показанное решение действительно работает вместо.
Затем вы можете записать в файл ... / fd / 0 процесса и отправить ему инструкции. Единственный недостаток заключается в том, что вам необходимо также завершить процесс bash, который выполняет бесконечный цикл после того, как сервер завершил работу.
источник