Zweiwege-Pipe in Bash?

Zweiwege-Pipe in Bash?

Ich habe eine Binärdatei, deren Standardausgabe auf die Standardeingabe eines Python-Skripts umgeleitet wird, und ich frage mich, ob es eine Möglichkeit gibt, die Standardausgabe des Python-Skripts an die Standardeingabe der Binärdatei zu senden, um einen Effekt wie diesen zu erzielen (entschuldigen Sie mein fürchterliches ASCII-Diagramm):


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

Mein aktueller Bash-Code ist einfach binary | python3 pythonscript.py.

Danke!

Antwort1

Sie sollten in der Lage sein, benannte Pipes zu verwenden, um das zu erreichen, was Sie möchten. Sie würden sowohl die Eingabe als auch die Ausgabe von jedem Prozess zum/vom anderen Prozess umleiten.

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

Die benannten Pipes wären bereits mit Folgendem eingerichtet worden:

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

Wobei die benannten Pipes in das gemeinsam genutzte Speicherverzeichnis gestellt werden, dieser Speicherort ist jedoch nicht obligatorisch.

Hier ist ein einfaches Beispiel mit Bash- und Dash-Skripting:

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.

Und:

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

Und:

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

Beispielsitzung:

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

Für die Zusatzfrage in den Kommentaren:

Wenn ich die Pipe mithilfe des Bash-Skripts und nicht mithilfe von etwas im Python-Code verwende, gibt es dann trotzdem eine Möglichkeit, auf stdout zu drucken, ohne dass es an die Pipe geht?

Nicht mit dem einfachen Beispiel, das ich gegeben habe. Beachten Sie, dass ich dieses Zeug normalerweise mit C-Programmen verwende und die Ausgabe direkt in die benannten Pipes schreibe, sodass stdout für andere Ausgaben verfügbar bleibt.

verwandte Informationen