
У меня есть двоичный файл, 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 доступным для другого вывода.