Как записать живой вывод запущенного процесса - PullRequest
1 голос
/ 23 июня 2019

Я хочу запустить игровой сервер на моей машине с Ubuntu. Я хочу запустить его в фоновом режиме и записать результаты этого процесса в файл журнала. Я попытался использовать nohup и запустить игровой сервер, используя "&" в конце, но я не мог заставить его работать так, как я хотел.

Тогда я начал читать о именованных каналах и действительно попробовал. Я сделал простой скрипт, который по идее должен работать. Но, конечно, я что-то упускаю.

Сначала я создал канал с помощью команды mkfifo.

mkfifo testpipe

Затем я создал небольшой скрипт:

#!/bin/bash
./mta-server64 > pipe &

pid=$!

echo $pid // so I know the pid of the process

cat < pipe > log.txt &

(Примечание: я написал этот код из памяти.)

Код работает только в случае ошибки и остановки процесса. Это фактически записывает ошибку игровой консоли. Но когда игровой сервер работает, я не получаю вывод в лог-файл.

Я хочу прочитать вывод (stdout и stderr, если я не ошибаюсь) процесса, работающего в фоновом режиме, и записать его в файл журнала.

Я также думал об использовании экрана, поскольку он регистрирует все внутри файла, но я бы предпочел не использовать его, если есть лучшее решение.

EDIT:

Прежде всего: спасибо за интерес, который вы проявили к моей помощи. Точно так же я должен извиниться за то, что дал только скудные подробности о том, что я собираюсь сделать с этим небольшим проектом, и за мое ограниченное понимание stdout и stderr.

Пойдем на первую базу.

Я хочу запустить игровой сервер с именем Multi Theft Auto (https://multitheftauto.com/). Это GTA San Andreas, но мультиплеер.

Я легко могу запустить этот игровой сервер на своем сервере Ubuntu, вызвав исполняемый файл ./mta-server-64. После его вызова появляется консоль игрового сервера:

[|] MTA: San Andreas :: 0/32 players :: 196 resources :: 125 fps (25)
MTA:BLUE Server for MTA:SA
==================================================================
= Multi Theft Auto: San Andreas v1.5.6 [64 bit]
==================================================================
= Server name      : Default MTA Server
= Server IP address: auto
= Server port      : 22884
=
= Log file         : /root/mta/mods/deathmatch/logs/server.log
= Maximum players  : 32
= HTTP port        : 22564
= Voice Chat       : Disabled
= Bandwidth saving : Medium
==================================================================
[09:49:07] Resource 'mapmanager' requests some acl rights. Use the command 'aclrequest list mapmanager'
[09:49:07] Resources: 196 loaded, 0 failed
[09:49:07] Starting resources...
[09:49:07] Server minclientversion is now 1.5.6-9.16588.0
[09:49:07] INFO: MAPMANAGER: Some important ACL permissions are missing. To ensure the correct functioning of Mapmanager, please write: aclrequest allow mapmanager all
[09:49:07] Gamemode 'play' started.
[09:49:07] Authorized serial account protection is enabled for the ACL group(s): `Admin`  See http://mtasa.com/authserial
[09:49:07] WARNING: <owner_email_address> not set
[09:49:07] Server started and is ready to accept connections!
[09:49:07] To stop the server, type 'shutdown' or press Ctrl-C
[09:49:07] Type 'help' for a list of commands.
[09:49:07] Querying MTA master server... success! (Auto detected IP:xxx.xxx.xxx.xxx)

Я использую следующий скрипт для запуска процесса в фоновом режиме и (пытаюсь) получить вывод в реальном времени:

#!/bin/bash

newport=$(shuf -i 22003-22900 -n 1)
newip=$(shuf -i 22003-22900 -n 1)

rm -rf ~/server/*

cp -r /home/user*/ftp/server/mtaserver/serverfiles/* ~/server

sed -i "s/<httpport>[0-9][0-9][0-9][0-9][0-9]<\/httpport>/<httpport>$newport<\/httpport>/g" ~/server/mods/deathmatch/mtaserver.conf
sed -i "s/<serverport>[0-9][0-9][0-9][0-9][0-9]<\/serverport>/<serverport>$newip<\/serverport>/g" ~/server/mods/deathmatch/mtaserver.conf

~/server/mta-server64 2>&1 | tee -a outfile &

mta_pid=$!

echo $mta_pid

sleep 6

pkill $mta_pid

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

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

ВЫПУСК:

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

Ответы [ 3 ]

2 голосов
/ 23 июня 2019

Полагаю, вы хотите использовать команду tee, чтобы разделить вывод канала в файл журнала.

Я предлагаю вам прочитать эту статью и эти ответы 1 2 .

1 голос
/ 23 июня 2019

Обычно этого достаточно nohup somecommand > somecommand.log 2>&1 &, затем tail -F somecommand.log, чтобы следить за журналами.

0 голосов
/ 25 июня 2019

Через 2 дня я наконец-то нашел способ заставить его работать (так, как я намеревался работать, без учета каких-либо серьезных рисков безопасности / производительности).

Чтение комментариев заставило меня понять, что я атакую ​​не ту точку. Stdout игрового сервера буферизуется, что делает невозможным запись его в файл журнала, используя методы, которые я попробовал, когда отправил свой вопрос. По крайней мере, это то, что я понял).

Я провел некоторое исследование о том, как запустить приложение без буферизации стандартного вывода: https://serverfault.com/questions/294218/is-there-a-way-to-redirect-output-to-a-file-without-buffering-on-unix-linux

Мой код сейчас:

    stdbuf -o0 ~/server/mta-server64 >> pipe &

    cat < pipe | tee -a outfile &

После создания именованного канала он запускает игровой сервер внутри этого канала и затем добавляет стандартный вывод в файл журнала.

Команда stdbug -o0 отключает буферизацию стандартного вывода (как отмечено в ссылке выше).

Это работает для меня, и я не могу гарантировать, что это будет работать для всех остальных. Я до сих пор не знаю, является ли отключение буферизации безопасным подходом к моей проблеме, но сейчас это то, что мне нужно.

...