Вопрос: Могу ли я отправить какой-либо текст в STDIN активного процесса, запущенного на сеансе экрана?


У меня есть длительный серверный процесс внутри сеанса экрана на моем Linux-сервере. Это немного нестабильно (и, к сожалению, не мое программное обеспечение, поэтому я не могу это исправить!), Поэтому я хочу сценарий ночного перезапуска процесса, чтобы помочь стабильности. Единственный способ сделать это - изящное завершение работы - перейти на экранный процесс, переключиться в окно, в котором он запущен, и ввести строку «stop» на своей консоли управления.

Есть ли какие-либо умные перекодировки, которые я могу сделать, чтобы заставить cronjob отправлять эту команду остановки в определенное время каждый день?


58
2017-09-06 11:42


Источник




Ответы:


Этот ответ не решает проблему, но он оставлен здесь, потому что более 30 человек считают это полезным, иначе я бы давно удалил его.

Написать /proc/*pid of the program*/fd/0, fd подкаталог содержит дескрипторы всех открытых файлов и дескриптор файла 0 является стандартным вводом (1 является стандартным, а 2 - stderr).

Вы можете использовать это для вывода сообщений на tty, где работает программа, хотя это не позволяет вам писать в саму программу.

пример

Терминал 1:

[ciupicri@hermes ~]$ cat
shows on the tty but bypasses cat

Терминал 2:

[ciupicri@hermes ~]$ pidof cat
7417
[ciupicri@hermes ~]$ echo "shows on the tty but bypasses cat" > /proc/7417/fd/0

73
2017-09-06 12:06



@James Lawrie: тогда взгляните на Proc (5) а также proc.txt, - Cristian Ciupitu
+2 независимо от того, насколько вы думаете, что знаете, всегда есть чему поучиться :) slick. - troyengel
Имейте в виду, что proc fd только перенаправляет на то, что используется как источник stdin. В вашем примере, если вы введете что-то в терминал 1, он снова распечатает его (он отправит кошкам stdin и cat), что приведет к тому, что вы увидите его дважды. С другой стороны, если вы отправите что-то в fd / 0, оно будет отправлено на консоль, но не на cat, и, таким образом, будет отображаться только один раз. Так как кошка просто распечатывает ввод снова с помощью этого примера, вы не можете действительно увидеть, печатается ли ваш ввод или вывод, таким образом это неправильное представление. / fd / 0 указывает на консоль / pts; видеть ls -l /proc/7417/fd/0, - Kissaki
Пример реального мира: я начал gphoto2 --get-all-files, и он запрашивает подтверждение 100 раз. Когда я повторяю «y»> / proc / PID / fd / 0, gphoto2 не продолжается, однако на терминале печатается «y». - Thorsten Staerk
@ThorstenStaerk, я знаю, поэтому я добавил эту заметку. Вы пишете только файл устройства, соответствующий терминалу, на котором запускается gphoto2 (например, /dev/pts/19), y символ не достигает самого приложения. Это похоже на то, что происходит, когда вы используете написать (1) команда. В любом случае, попробуйте мой другой ответ или графический инструмент автоматизации, например xdotool, - Cristian Ciupitu


Экранное решение

Запустите сервер следующим образом:

# screen -d -m -S ServerFault tr a-z A-Z # replace with your server

экран начнется в отключенном режиме, поэтому, если вы хотите посмотреть, что происходит, запустите:

# screen -r ServerFault

Управляйте сервером следующим образом:

# screen -S ServerFault -p 0 -X stuff "stop^M"
# screen -S ServerFault -p 0 -X stuff "start^M"
# screen -S ServerFault -p 0 -X stuff "^D" # send EOF

(этот ответ основан на отправка текстового ввода на отдельный экран из Unix & Linux родной сайт)

объяснение параметров:

-d -m
   Start screen in "detached" mode. This creates a new session but doesn't
   attach to it.  This is useful for system startup scripts.
-S sessionname
   When creating a new session, this option can be used to specify a meaningful
   name for the session.
-r [pid.tty.host]
-r sessionowner/[pid.tty.host]
   resumes a detached screen session.
-p number_or_name|-|=|+
   Preselect a window. This is useful when you want to reattach to a specific
   window or you want to send a command via the "-X" option to a specific
   window.
-X
   Send the specified command to a running screen session e.g. stuff.

материал [Строка]

   Stuff the string string in the input  buffer of the current window.
   This is like the "paste" command but with much less overhead.  Without
   a parameter, screen will prompt for a string to stuff.

решение на основе tmux

Запустите сервер следующим образом:

# tmux new-session -d -s ServerFault 'tr a-z A-Z' # replace with your server

tmux начнется в отключенном режиме, поэтому, если вы хотите посмотреть, что происходит, запустите:

# tmux attach-session -t ServerFault

Управляйте сервером следующим образом:

# tmux send-keys -t ServerFault -l stop
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault -l start
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault C-d # send EOF

объяснение параметров:

 new-session [-AdDP] [-c start-directory] [-F format] [-n window-name] [-s
         session-name] [-t target-session] [-x width] [-y height]
         [shell-command]
         Create a new session with name session-name.

         The new session is attached to the current terminal unless -d is
         given.  window-name and shell-command are the name of and shell
         command to execute in the initial window.  If -d is used, -x and
         -y specify the size of the initial window (80 by 24 if not
         given).

 send-keys [-lR] [-t target-pane] key ...
               (alias: send)
         Send a key or keys to a window.  Each argument key is the name of
         the key (such as `C-a' or `npage' ) to send; if the string is not
         recognised as a key, it is sent as a series of characters.  The
         -l flag disables key name lookup and sends the keys literally.

31
2017-10-19 01:08





Попробуйте это, чтобы начать:

# screen
# cd /path/to/wd
# mkfifo cmd
# my_cmd <cmd
C-A d

И это, чтобы убить:

# cd /path/to/wd
# echo "stop" > cmd
# rm cmd

4
2017-09-06 12:03



Это хорошо, но, возможно, недостатком является невозможность отправки других команд во время работы программы. Если программа останавливается, когда она нажимает EOF на stdin, тогда на первом echo "xxx" > cmd программа остановится (потому что труба будет закрыта). Хотя некоторые программы достаточно умны для повторного открытия (rewind(3)) их stdin, когда они сталкиваются с EOF. - Cristian Ciupitu


Если это кому-то поможет:
У меня была аналогичная проблема, и поскольку процесс, который я использовал, не был screen или tmux, Мне пришлось придерживаться другого подхода.

Я прикрепил gdb к xterm что мой процесс запущен и используется call write(5, "stop\n", 5) из gdb для записи в дескриптор файла master pty.
Я узнал, какой файловый дескриптор отправить данные, посмотрев на /proc/<pid>/fd для ссылки на /dev/ptmx а затем проб и ошибок между двумя параметрами (отправка моей строки в оба соответствующих дескриптора файла, казалось, не навредила).

РЕДАКТИРОВАТЬ

Оказалось, что xterm процесс, к которому я присоединился, был порожден spawn-new-terminal()  xterm действие от привязки клавиш, а второе ptmx открытый дескриптор файла был просто ptmx родителя xterm процесс, который не был закрыт.
Следовательно, пробные и ошибочные вызовы отправили вывод на этот другой терминал.
Наиболее xterm процессы не имеют двух ptmx файловые дескрипторы.

END EDIT

Это фактически напечатало эту строку в терминале и, следовательно, отправило ее вместе с процессом, запущенным под ним.

нотабене вам может потребоваться разрешить привязку к запущенному процессу с чем-то вроде
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"


1
2017-12-31 09:42