Настройка приватной области контейнера OpenVZ

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

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

Если вы можете заставить B читать из другого источника, это, конечно, решение.

Если вы контролируете выполнение A, попробуйте stdbuf из GNU coreutils . Он перехватывает вызовы библиотеки, чтобы процесс читал по одному байту за раз. Это работает с большинством программ, но не со всеми: это не работает со статически связанными исполняемыми файлами и не работает, если программа использует метод буферизации, отличный от стандартной библиотеки (stdio).

… | stdbuf -i 1 A

Или попробуйте прочитать из обычного файла. Когда A прочитал ввод из канала или терминала, он не может вернуть его. Но когда он читается из обычного файла, он может перемотать позицию чтения перед вызовом B. Так, например, ведет себя встроенная оболочка read . Нет никакой гарантии, что конкретная программа A сделает это, на самом деле это не очень распространенное поведение, но если да, то это простое решение.

Если это не сработает, или если у вас нет контроля над тем, как выполняется A, вам нужно настроить синхронизацию ввода так, чтобы часть, предназначенная для B, не присутствовала до тех пор, пока B не запустится. Как это сделать, зависит от того, как вы можете определить, что B.Возможное решение, но хрупкое, - установить задержку:

{ echo 123; sleep 1; echo xyzzy; } | A

Это работает, только если A вызывает B в течение 1 секунды, что ненадежно. Более надежным решением является обнаружение вывода, производимого A (или B). Это проблема, для решения которой ожидается . Например, если B отображает какое-то приглашение вроде B> :

#!/usr/bin/expect -f
spawn A
send "123\r"
expect "B>"
send "xyzzy\r"

1
08.07.2015, 22:23
0 ответов

Теги

Похожие вопросы