Предотвратить закрытие/повторное использование FIFO FIFO

Рассмотрим следующий сценарий:

создается FIFO с именем test. В одном окне терминала (A) я запускаю cat <test и в другом (B) cat >test. Теперь можно написать в окне B и получить вывод в окне A. Также можно завершить процесс A и перезапустить его и по-прежнему использовать эту настройку, как предполагалось. Однако, если вы завершаете процесс в окне B, B (насколько мне известно) отправляет EOF через FIFO для обработки A и завершает его также.

Фактически, если вы запустите процесс, который не завершится в EOF, вы все равно не сможете использовать свой FIFO, который вы перенаправили на этот процесс. Я думаю, это потому, что этот FIFO считается закрытым.

Есть ли способ обойти эту проблему?

Причина того, почему я столкнулся с этой проблемой, заключается в том, что я хочу отправлять команды на мой сервер minecraft, работающий на сеансе экрана. Например: echo "command" >FIFO_to_server. Это, вероятно, можно сделать, используя экран сам по себе, но мне не очень нравится экран. Думаю, решение, использующее только трубы, было бы более простым и чистым.

Ответы

Ответ 1

A читается из файла. Когда он достигнет конца файла, он перестает читать. Это нормальное поведение, даже если файл имеет значение fifo. Теперь у вас есть четыре подхода.

  • Измените код считывателя, чтобы он продолжал читать после окончания файла. Это говорит, что входной файл бесконечен, и достижение конца файла - всего лишь иллюзия. Для вас это не подходит, потому что вам придется изменить код сервера minecraft.
  • Применить философию unix. У вас есть писатель и читатель, которые не согласны с протоколом, поэтому вы вставляете инструмент, который их соединяет. Как это бывает, в инструменте unix есть такой инструмент: tail -f. tail -f продолжает чтение из своего входного файла даже после того, как видит конец файла. Попросите всех ваших клиентов поговорить с трубой и подключите tail -f к серверу minecraft:

    tail -n +1 -f client_pipe | minecraft_server &
    
  • Как уже упоминалось в jilles, используйте трюк: каналы поддерживают несколько авторов, и только закрываются, когда последний писатель уходит. Поэтому убедитесь, что есть клиент, который никогда не уходит.

    while true; do sleep 999999999; done >client_pipe &
    
  • Проблема заключается в том, что сервер в основном предназначен для обработки одного клиента. Чтобы обращаться с несколькими клиентами, вы должны перейти на использование сокета. Подумайте о сокетах как "мета-трубах": подключение к сокету создает канал, и как только клиент отключается, этот конкретный канал закрыт, но сервер может принимать больше соединений. Это чистый подход, поскольку он также гарантирует, что вы не будете перепутывать данные, если два клиента будут подключаться в одно и то же время (используя каналы, их команды могут быть перемежены). Однако для этого требуется изменить сервер minecraft.

Ответ 2

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