티 앤 페이스트(Tee and Paste)를 사용하면 교착 상태가 발생할 수 있습니다.

티 앤 페이스트(Tee and Paste)를 사용하면 교착 상태가 발생할 수 있습니다.

별도의 처리를 위해 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

문제는 그것이 정지된다는 것이다. 이 동작은 입력 길이에 따라 달라지는 것 같습니다.

  1. 입력 줄이 더 작은 경우(즉, 두 번째 열에 100자가 아닌 30자가 포함된 경우) 이는 잘 작동합니다.
  2. 동일한(또는 비슷한 길이) 입력이 입력 a.fifo으로 주어 지면 제대로 작동하는 것 같습니다.b.fifo

a.fifo문제는 say에서 짧은 청크를 공급하고 b.fifo. 이 동작은 파이프를 지정하는 순서에 의존하지 않습니다 paste.

나는 Linux와 그 파이프 논리에 대해 잘 알지 못하지만, 어떻게든 막힌 것 같습니다. 내 질문은 이것이 어떻게든 안정적으로 달성될 수 있는지 여부입니다. 그렇다면 어떻게 해야 할까요? 아마도 teeand를 사용하지 않고 다른 방법이 있을까요 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, 말도 안 돼요. 버그가 관련되어 있어도 놀라지 않을 것입니다.

관련 정보