Tubo bidirecional no bash?

Tubo bidirecional no bash?

Eu tenho um binário cujo stdout está sendo redirecionado para o stdin de um script python, e queria saber se existe alguma maneira de enviar o stdout do script python para o stdin do binário, para obter um efeito parecido com este, (desculpe meu terrível diagrama ascii):


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

Meu código bash atual é apenas binary | python3 pythonscript.py.

Obrigado!

Responder1

Você deve ser capaz de usar pipes nomeados para conseguir o que deseja. Você redirecionaria a entrada e a saída de cada processo para/do outro processo.

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

Os pipes nomeados já teriam sido configurados com:

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

Onde os pipes nomeados estão sendo colocados no diretório de memória compartilhada, mas esse local não é obrigatório.

Aqui está um exemplo simples usando scripts bash e 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.

E:

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

E:

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

Sessão de exemplo:

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

Para a pergunta adicional nos comentários:

Se estou canalizando usando o script bash, e não algo no código python, ainda existe uma maneira de imprimir no stdout sem que ele vá para o canal?

Não com o exemplo simples que dei. Observe que eu normalmente uso esse material com programas c e escrevo a saída diretamente nos pipes nomeados, deixando assim o stdout disponível para outras saídas.

informação relacionada