У меня есть программа, P
которая ожидает получить «Hello» и вывод «Почему?» перед предоставлением функции. Эта функция используется другими программами, которые не знают, что общение с «Hello» является обычной вежливостью. Таким образом, я хочу написать оболочку для P
этого работает так (синтаксис zsh):
coproc P
print -p Hello # Send Hello to P
read -pr line # Read what P has to say
[[ "$line" = "Why?" ]] && Replace current process with the coprocess.
echo Could not get P's attention.
Использование cat
или dd
в Replace...
части (что-то вроде cat <&p &; exec cat >&p
) приводит к ненужной буферизации. Какие у меня варианты?
zsh
решение илиbash
решение приемлемо?bash
решением, которое не применимоzsh
, но, безусловно, примет его »ssh
и его вариантомProxyCommand
.cat
как правило, не буферизуется. Если это происходит в вашей системе, попробуйтеcat -u
.Ответы:
Проблема, которую вы указали, заключается не в замене процесса , а в замене потоков существующего процесса . Цель состоит в том, чтобы немного поработать с процессом, а затем передать его ввод / вывод другой паре связанных потоков.
Нет никакого способа сделать это напрямую (по крайней мере, в оболочке; внутри процесса
dup2
вызов может работать). Вам нужно будет склеить потоки. То есть:Использование
coproc
как в вашем примере тоже нормально. Обратите внимание, что команда сохраняет файловые дескрипторы в массив, и вы можете позже использовать их для перенаправлений.Это не должно вызывать дополнительную буферизацию (по крайней мере, для GNU cat), если P не проверяет входные / выходные потоки, к которым он подключен, и не принимает решение о буферизации на основе этого. Например, стандартная библиотека C включит буферизацию на
stdout
/,stderr
если они подключены к файлу, но выполнит буферизацию строки, только если они подключены к терминалу.источник
Можно протестировать с приведенным ниже кодом, используя Perl, чтобы избежать буферизации, попробуйте, если это работает для вас
источник
dd ibs=1
, например. Я не в порядке с этим. В некотором смысле, у coproc есть своя собственная буферизация, и именно эту я хочу использовать.