별도의 처리를 위해 tee를 사용하여 명령의 표준 출력을 두 개의 "분기"로 리디렉션하려고 합니다. 마지막으로 붙여넣기를 사용하여 두 "분기"의 결과를 병합해야 합니다. 나는 생산자를 위해 다음 코드를 생각해 냈습니다.
mkfifo a.fifo b.fifo
python -c 'print(("0\t"+"1"*100+"\n")*10000)' > sample.txt
cat sample.txt | tee >(cut -f 1 > a.fifo) >(cut -f 2 > b.fifo) | awk '{printf "\r%lu", NR}'
# outputs ~200 lines instantly
# and then ~200 more once I read from pipes
그런 다음 별도의 터미널에서 소비자를 시작합니다.
paste a.fifo b.fifo | awk '{printf "\r%lu", NR}'
# outputs ~200 once producer is stopped with ctrl-C
문제는 그것이 정지된다는 것이다. 이 동작은 입력 길이에 따라 달라지는 것 같습니다.
- 입력 줄이 더 작은 경우(즉, 두 번째 열에 100자가 아닌 30자가 포함된 경우) 이는 잘 작동합니다.
- 동일한(또는 비슷한 길이) 입력이 입력
a.fifo
으로 주어 지면 제대로 작동하는 것 같습니다.b.fifo
a.fifo
문제는 say에서 짧은 청크를 공급하고 b.fifo
. 이 동작은 파이프를 지정하는 순서에 의존하지 않습니다 paste
.
나는 Linux와 그 파이프 논리에 대해 잘 알지 못하지만, 어떻게든 막힌 것 같습니다. 내 질문은 이것이 어떻게든 안정적으로 달성될 수 있는지 여부입니다. 그렇다면 어떻게 해야 할까요? 아마도 tee
and를 사용하지 않고 다른 방법이 있을까요 paste
?
답변1
문제를 자세히 이해하지 못했습니다. 분명히 이것은 일부 버퍼를 채우는 각 라인의 크기 차이와 관련이 있습니다.
이 문제는 버퍼를 확대하여 "해결"할 수 있습니다.
paste a.fifo <(buffer <b.fifo) | awk '{printf "\r%lu", NR}'
재미있는 사실: buffer
빌드 명령에 a를 추가하면 awk
완료가 가능하지만 명령을 사용하면 여전히 차단됩니다(내 경우에는 거의 끝 부분).
$ cat sample.txt | tee >(cut -f 1 > a.fifo) >(cut -f 2 | buffer > b.fifo) | awk '{printf "\r%lu", NR}; END { print; print NR; }'
10001
$ paste a.fifo b.fifo | awk '{printf "\r%lu", NR}'
8152
IMHO, 말도 안 돼요. 버그가 관련되어 있어도 놀라지 않을 것입니다.