둘다
<file.txt tee >(grep LITERAL) >(wc -l) >/dev/null
과:
{ { <file.txt tee /dev/fd/3 | grep LITERAL >&4; } 3>&1 | wc -l ;} 4>&1
모든 tee
, grep
그리고 wc
동시에 시작됩니다. 중요한 것은 마지막에 일어나는 일입니다.
wc
표준 입력에서 파일 끝을 볼 때만 결과를 인쇄합니다. 첫 번째 경우, tee
출구 가 될 때입니다. 그러면 읽고 있는 파이프의 다른 쪽 끝을 tee
닫습니다 (프로세스 대체로 시작). 보장이 없어 그때까지의 모든 입력을 읽은 것입니다 혼자 (파이프 데이터의 꽤 많은 양을 저장할 수와 그 주어진 출력을 작성 내버려 것보다 더 빨리 될 것입니다 )fd
wc
grep
wc
grep
두 번째 경우, wc
파이프에서 읽고있는 모든 작성자가 파이프의 끝을 닫으면 파일 끝이 표시됩니다. 이 경우 여러 작가가 있습니다. tee
(에 미치는 FD 개방을 통해 /dev/fd/3
그리고 그 전략 중 3를 통해) grep
또한이 fd
에 파이프 개방 3 wc
(그것의 사용을 아니지만, 그것에 혼자 쓰기를하자). 내부는 {
가능성도있을 것이다 별도의 서브 쉘 프로세스가 발생합니다 fd
3 개방을하고 모두 대기 tee
와 grep
.
즉, 종료 wc
후에 만 줄 번호를 씁니다 grep
.
올바른 방법으로 작성 했습니까? 즉, 열 필요가없는 fd를 닫는 것입니다.
{ { <file.txt tee /dev/fd/3 4>&- |
grep LITERAL >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1
그러면 서브 쉘 프로세스를 최적화하는 쉘에서 순서가 보장되지 않았을 것입니다. 그러나, 단지 내가 즉 않습니다 알고 쉘 ksh93
하지만 ksh93
용도는 그래서 파이프 쌍 소켓 /dev/fd/3
적어도 리눅스가 작동하지 않습니다.
실행중인 프로세스를 확인하려면 다음 grep
과 ps
같이 바꾸십시오 .
$ { { <file.txt tee /dev/fd/3 4>&- | ps -H >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1
PID TTY TIME CMD
8727 pts/5 00:00:00 bash
8815 pts/5 00:00:00 bash
8817 pts/5 00:00:00 tee
8818 pts/5 00:00:00 ps
8816 pts/5 00:00:00 wc
을 사용하면 bash
추가 쉘 프로세스를 볼 수 있으며 fd 3에서 파이프가 다음과 같이 열려 있음을 알 수 있습니다.
$ (p=$BASHPID; { { <file.txt tee /dev/fd/3 4>&- | lsof -ag "$p" -d3 >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1)
COMMAND PID PGID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 9843 9842 chazelas 3w FIFO 0,8 0t0 153304 pipe
tee 9845 9842 chazelas 3w FIFO 0,8 0t0 153304 pipe
lsof 9846 9842 chazelas 3r DIR 0,3 0 1 /proc
grep LITERAL >&4 3>&- 4>&-
에서 fd 4가 사용되고 닫혀있는 것처럼 보이는 것은 무엇입니까?