$ seq 1 12773 | tee /dev/null >(wc -l > tmp.txt) | head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
--> 8473 (임의로 1~12773 사이)
$ cat tmp.txt
--> 8473
$ seq 1 12774 | tee /dev/null >(wc -l > tmp.txt) | head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
-->(비어 있음)
$ cat tmp.txt
--> 8844 (임의로 1~12773 사이)
$ seq 1 25011 | tee /dev/null >(wc -l > tmp.txt) | cat | head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
--> 13778 (임의로 1~25011 사이)
$ cat tmp.txt
--> 13778
$ seq 1 25012 | tee /dev/null >(wc -l > tmp.txt) | cat |head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
-->(비어 있음)
$ cat tmp.txt
--> 24939 (1~25012 사이에서 임의로)
$ seq 1 46014 | tee /dev/null >(wc -l > tmp.txt) | cat | cat |head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
--> 34111 (임의로 1~46014 사이)
$ cat tmp.txt
--> 34111 (임의로 1~46014 사이)
$ seq 1 46015 | tee /dev/null >(wc -l > tmp.txt) | cat | cat |head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
-->(비어 있음)
$ cat tmp.txt
--> 343 (임의로 1~46014 사이)
cat 뒤의 '|'(wc -l > tmp.txt)' 개수가 늘어날수록 위 명령이 처리하는 라인 수를 늘릴 수 있습니다.
어떻게 되어가나요?
답변1
~처럼알렉스 P이미 댓글에서 설명했지만,파이프라인의 명령은 병렬로 실행됩니다.. 당신은 이것이 사실이 아니라고 확신하는 것 같습니다. 마음을 열지 않는 한 무슨 일이 일어나고 있는지 이해할 수 없다는 오해를 잊어버리십시오.
프로세스가 병렬로 실행되기 때문에 작업 순서는 정확한 시간에 따라 달라지며 한 실행에서 다음 실행으로 복제되지 않을 수 있습니다.
첫 번째 예에서는 다음 명령이 병렬로 실행됩니다.
seq 1 12773
tee /dev/null
wc -l > tmp.txt
(프로세스 교체도 파이프를 생성하고 명령을 병렬로 실행합니다)head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))
— 여기에는 세 가지 다른 명령이 포함되며 두head
명령이openssl
모두 종료된cat
후에 시작됩니다 .tail -1
병렬로 실행되므로 wc -l > tmp.txt
다음 출력 과 관련된 런타임은 예측할 수 없습니다 .cat tmp.txt
cat tmp.txt
wc
- 리디렉션을 수행하기 전에 실행될 수
tmp.txt
있으며 이전 실행에서 파일을 가져오거나(있는 경우) 파일이 존재하지 않는다고 불평할 수 있습니다. - 리디렉션이 수행된 후 실행할 수 있지만
wc
이 경우 리디렉션으로 인해 파일이 잘리기 때문에 출력이 생성되기 전에 파일이 비어 있습니다. - 출력이 생성되는 동안 실행될 수
wc
있으며 출력의 시작 부분만 선택합니다. 대부분의 시스템에서는wc
출력이 자동으로 생성되므로(짧기 때문에) 이런 일이 발생하지 않습니다. wc
출력이 완료된 후 실행할 수 있습니다.
실험을 통해 나는 당신과 동일한 결과를 얻었습니다(대부분 유휴 상태였던 커널 3.16을 실행하는 Linux 시스템에서). , 의 출력을 seq 1 12773
얻으려면 ; , 를 사용하여 빈 파일을 선택하세요. 그렇다면 12773과 12774 사이에 차이가 있는 이유는 무엇입니까? 그런데 그 아래 결과는 상당히 신뢰할 수 있습니까?cat tmp.txt
wc
seq 1 12774
cat tmp.txt
$ seq 1 12774 | wc -c
65538
임계값은 65536바이트이고 값은 다음과 같습니다.파이프 버퍼 용량. 이 명령은 먼저 실행 하고 완료 head …
해야 하므로 시작 속도가 느립니다 . 시작되면 파이프의 이전 명령이 파이프 버퍼에 기록됩니다. 파이프 버퍼가 가득 차면 이전 명령을 중지해야 합니다. 숫자가 12773에 도달하면 파이프 버퍼가 절대 채워지지 않으므로 실행이 이전에 완료되어 (해야 할 작업이 훨씬 적었음) 출력을 작성할 시간이 있었을 가능성이 높습니다. 그러나 숫자가 12774보다 크면 파이프 버퍼가 가득 차서 에 출력 쓰기가 중단되고 아직 출력 쓰기가 완료되지 않았습니다 . 또한 빈 파일로 실행하십시오.openssl
cat
seq
openssl
wc
tee
head …
wc
cat
tee
더 많은 파이프를 추가하면 각 파이프에는 자체 버퍼가 있으므로 지연되기 전에 더 많은 공간이 있습니다.