Olá, estou tentando usar um FIFO Unix para comunicar entre um script Python e um script shell. A intenção é que o script shell capture toda a saída do script python. Até agora, tenho o seguinte:
#!/bin/bash
# Test IPC using FIFOs.
## Create a named pipe (FIFO).
mkfifo ./myfifo
## Launch the Python script asynchronously and re-direct its output to the FIFO.
python3 helloworld.py > ./myfifo &
PID_PY=$!
echo "Python script (PID=$PID_PY) launched."
## Read from the FIFO using cat asynchronously.
## Note that running asynchronously using & runs it the program (in this case `cat`)
## in a child shell "subshell", so I will collect the output in a file.
echo "Reading FIFO."
>output.log cat ./myfifo &
PID_CAT=$!
## Sleep for 10 seconds.
sleep 10
## Kill the Python script.
kill -15 $PID_PY && echo "Python script (PID=$PID_PY) killed."
## Kill the cat!
kill -15 $PID_CAT
## Remove the pipe when done.
rm -fv ./myfifo
## Check for the existence of the output log file and print it.
[[ -f output.log ]] && cat output.log || echo "No logfile found!." 1>&2
No entanto, quando abro o arquivo de log output.log
, ele está vazio, e é por isso que o último comando retorna vazio. Há algo que estou fazendo errado? Entendo que o acima pode ser facilmente realizado usando um pipe anônimo como este: python3 helloworld.py | cat >output.log
(ou mesmo python3 helloworld.py > output.log
para esse assunto), mas minha intenção é entender o uso de pipes nomeados no Unix/Linux.
O script python apenas imprime algo a stdout
cada 1 segundo:
if __name__ == "__main__":
import time
try:
while True:
print("Hello, World")
time.sleep(1)
except KeyboardInterrupt:
print('Exiting.')
finally:
pass
Seu entendimento de como o fifos funciona está bom, o problema está no script python. Como em qualquer coisa assim, a melhor maneira de depurar é executar os comandos no terminal manualmente para que você possa ver o que cada um está fazendo. Se você executar
helloworld.py > outfile
, e entãocat outfile
, verá que ele não tem conteúdo. Se, no entanto, você não redirecionar a saída e apenas executarhelloworld.py
, obterá uma saída normal. Isso ocorre porque o Python armazena sua saída em buffer e não teve tempo de preencher o buffer e imprimir seu conteúdo no momento em que você mata o script.Se você substituir seu
helloworld.py
por um script de shell simples, ele funcionará como esperado:Como alternativa, faça seu python produzir uma saída sem buffer , e ele também funcionará como esperado: