Проблема с неблокирующим fifo в bash

Я использую несколько серверов Team Fortress 2 и хочу написать небольшой скрипт управления.

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

***@purple:~/tf2$ ./start_server_testing 
Auto detecting CPU
Using AMD Optimised binary.
Server will auto-restart if there is a crash.

Console initialized.
[bla bla bla]
Connection to Steam servers successful.
   VAC secure mode is activated.

status

hostname: Team Fortress
version : 1.0.6.1/15 3883 secure
udp/ip  :  ***.***.133.31:27600
map     : ctf_2fort at: 0 x, 0 y, 0 z
players : 0 (2 max)

# userid name uniqueid connected ping loss state adr

Отлично, теперь я хочу создать скрипт, который отправляет команду sm_reloadadmins на все мои серверы. Лучший способ, который я нашел для этого, - использовать именованный канал fifo. Теперь я хочу, чтобы этот канал был доступен только для чтения и не блокировал серверный процесс, чтобы я мог писать в канал, и сервер выполнял его, но все же я хочу писать через консоль на одном сервере, поэтому, если я переключусь обратно на процесс fg сервера, и я набираю статус, я хочу, чтобы ответ был напечатан.

Я пробовал это (при условии, что serverfifo - это mkfifo serverfifo):

./start_server_testing < serverfifo

Не работает, сервер не запустится, пока что-то не будет записано в канал.

./start_server_testing <> serverfifo

На самом деле это работает довольно хорошо, я вижу консольный вывод сервера и могу писать в fifo, и сервер выполняет команды, но я больше не могу писать через консоль на сервер. Кроме того, если я пишу «выход» в канал (который должен завершить сервер) и запускаю его на экране, экранное окно по какой-то причине уничтожается (wtf почему?).

Мне нужно только, чтобы сервер читал fifo без блокировки, И весь мой ввод с клавиатуры на самом сервере должен быть отправлен на сервер, И весь вывод сервера должен быть записан на консоль.

Возможно ли это? Если да, то как?


person timdel    schedule 29.06.2009    source источник
comment
Я предполагаю, что с помощью ./start_server_testing ‹› serverfifo я переназначаю stdio на serverfifo, поэтому он теряет мою клавиатуру как stdio. Можно ли сопоставить два источника с stdio процесса (в моем случае это клавиатура и serverfifo)   -  person timdel    schedule 29.06.2009
comment
Я удалил ваше недавнее дополнение просто потому, что это не был ответ. Мне жаль, что вы не чувствуете, что сайт вам помог, но (повторите ваш комментарий) я не вижу никаких доказательств того, что кто-то разозлился, кроме вас самих - просто кто-то, кто дал вам свою идею, которая не соответствовала тому, что вы в розыске...   -  person Marc Gravell    schedule 01.07.2009


Ответы (1)


Я понимаю, что это не ответ в том же ключе, что и вы, но вы, вероятно, можете сделать это с помощью экрана Gnu.

Screen — это программа, которая создает псевдо-TTY. Вы можете использовать его возможность, чтобы позволить вам поделиться сеансом экрана. Таким образом, вы можете войти на сервер внутри экрана, и ваш скрипт может поделиться этим сеансом, отправить команду, которую вы видите, а затем прекратить обмен. процесс настройки экрана для разрешения сеансов совместного использования описан здесь< /а>. Для этого требуется root-доступ, но я предполагаю, что он у вас есть, если вы используете сервер TF2.

Как только вы настроите процесс setuid и получите подсказку сервера внутри экрана, вы можете настроить свой скрипт для входа в соответствующее поле, подключиться к экрану, отправить нужную команду на сервер, отправить Ctrl-A,d для отключения от экран, а затем выйдите из системы.

person Conspicuous Compiler    schedule 29.06.2009
comment
На самом деле я использую экран, на котором запускаю все свои серверы (CTRL+A,c создает окна на одном экране). Я еще это написал: [...]and I'm running it in a screen the screen window is getting killed for some reason (wtf why?).[...] А теперь, может быть, я могу написать в экран? Я знаю, если я создаю новый экран, я могу как-то отправить команду, которая выполняется экраном, а затем отсоединиться, но могу ли я отправить команду на существующий экран? - person timdel; 29.06.2009
comment
Нет, подождите, я думаю, что использование конвейера для отправки текста процессу все же лучше, чем отправка его на экран. - person timdel; 29.06.2009
comment
Ах. Я не понял, что вы сказали в этом абзаце. Тот факт, что вы используете экран, уже упрощает задачу. В ответ на ваш вопрос, могу ли я отправить команду на существующий экран?, мой ответ объяснял, как именно вы будете выполнять этот процесс. Где я был непонятен? - person Conspicuous Compiler; 29.06.2009
comment
Это не ответ на мою проблему. Мне нужен автоматизированный сценарий, чтобы я мог ввести ./reloadadmins, и он просто отправляет sm_reloadadmins серверному процессу. Фактически, я использую несколько окон в одном сеансе экрана, и, насколько я знаю, скрипт может передать команду только активному окну в сеансе экрана. В любом случае, я хочу отправить команду sm_reloadadmins не на один сервер, а на ВСЕ мои серверы. Так что я не думаю, что экран — это хорошее/лучшее решение моей проблемы, поэтому я просто останусь на именованных каналах. - person timdel; 29.06.2009
comment
Я понимаю, что это не тот способ, которым вы пытались решить свою проблему. Однако то, что вы пытаетесь сделать, - это иметь несколько входных потоков для одного процесса, для чего в bash нет простого способа. Указанная выше команда перенаправляет как ввод, так и вывод из вашего fifo, что сделает взаимодействие с консолью невозможным. -- Что касается нескольких серверов, вы можете так же легко иметь скрипт для входа на сервер, как и на несколько серверов, закодировав его для повторения процесса. Точно так же вы можете отправить команду (Ctrl A, 1) для переключения окон при входе в систему... - person Conspicuous Compiler; 29.06.2009
comment
...Но не похоже, что вы открыты для изучения альтернатив. Удачи. - person Conspicuous Compiler; 29.06.2009
comment
Я очень открыт для альтернатив, но использование экранного ввода-вывода очень-очень-очень нестабильно, потому что я никогда не знаю, в каком окне моего экрана работает сервер или какой сервер (это не так статично, как именованный канал). Если я использую именованный канал, я могу, например. создайте канал для каждого сервера, чтобы я точно знал, на какой сервер я пишу сейчас. Мне нужно это, чтобы отделить частные серверы от общедоступных серверов. Также я заметил, что ‹› переназначает мой stdio (несколько минут назад я добавил команду в свой пост по этому поводу. Так что мне нужно решение для сопоставления stdout с консолью... - person timdel; 29.06.2009
comment
... и stdin как для моей клавиатуры, так и для именованного канала. - person timdel; 29.06.2009