Двусторонний канал в bash?

Двусторонний канал в bash?

У меня есть двоичный файл, stdout которого перенаправляется на stdin скрипта Python, и мне интересно, есть ли способ отправить stdout скрипта Python на stdin двоичного файла, чтобы получить что-то вроде этого (извините за мою ужасную диаграмму ASCII):


 |->-binary -- python -->-|
/|\                      \|/
 |-<---<---<---<---<---<--|

Мой текущий bash-код — это просто binary | python3 pythonscript.py.

Спасибо!

решение1

Вы должны иметь возможность использовать именованные каналы, чтобы достичь желаемого. Вы бы перенаправили как ввод, так и вывод из каждого процесса в/из другого процесса.

binary < npipe1 > npipe2
python3 pythonscript.py < npipe2 > npipe1

Именованные каналы уже были бы настроены с помощью:

mkfifo /dev/shm/npipe1
mkfifo /dev/shm/npipe2

Именованные каналы помещаются в каталог общей памяти, но это расположение не является обязательным.

Вот простой пример использования скриптов bash и dash:

doug@s19:~/temp$ cat test-fifo-job-control
#! /bin/dash
#
# test-fifo-job-control Smythies 2023.09.03
#       A simple example of using named pipes.
#       See https://askubuntu.com/questions/1484568/two-way-pipe-in-bash
#

# If they do not already exist, then create the named pipes.
# Note: sometimes they might need to be deleted and recreated.
#       i.e. if garbage was left in one, or both.

if [ ! -p /dev/shm/npipe1 ]
then
   mkfifo /dev/shm/npipe1
fi
if [ ! -p /dev/shm/npipe2 ]
then
   mkfifo /dev/shm/npipe2
fi

# Launch the first task
./test-fifo-part-1 < /dev/shm/npipe1 > /dev/shm/npipe2 &
#
# and supply the first input
echo 1000 >> /dev/shm/npipe1
#
# Now launch the second task
#./test-fifo-part-2 < /dev/shm/npipe2 > /dev/shm/npipe1
./test-fifo-part-2 < /dev/shm/npipe2 | tee /dev/shm/npipe1

#
# It'll go until stopped via ^C.

И:

doug@s19:~/temp$ cat test-fifo-part-1
#!/bin/bash

while :
  do
# Note: No error checking
  read next_number
  echo "$next_number"
# Slow things down.
  sleep 1
done

И:

doug@s19:~/temp$ cat test-fifo-part-2
#!/bin/bash

while :
  do
# Note: No error checking
  read next_number
  next_number=$((next_number+1))
  echo "$next_number"
# Slow things down.
  sleep 1
done

Пример сеанса:

doug@s19:~/temp$ ./test-fifo-job-control
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
^C
doug@s19:~/temp$

Для дополнительного вопроса в комментариях:

Если я использую скрипт bash, а не что-то в коде python, есть ли способ вывести данные в stdout без отправки в конвейер?

Не с простым примером, который я привел. Обратите внимание, что я обычно использую это с программами на языке C и записываю вывод напрямую в именованные каналы, таким образом оставляя stdout доступным для другого вывода.

Связанный контент