파이핑은 다른 인스턴스가 시작되기 전에 첫 번째 인스턴스가 완료되도록 요구하지 않습니다. 실제로, 실제로하는 일은 첫 번째 인스턴스 의 stdout 을 두 번째 인스턴스의 stdin 으로 리디렉션하는 것이므로 포크 폭탄이 작동하기 위해 동시에 실행될 수 있습니다.
음의 결과는 정확히 무엇입니까 :
? 다른 사람에게 전달되는 것은 무엇 :
입니까?
':'는 다른 ':'인스턴스에 아무것도 쓰지 않고 stdout 을 두 번째 인스턴스 의 stdin 으로 리디렉션합니다 . 경우 그것의 실행 중에 뭔가를 쓰기 (그것은 결코 것이다, 그것은 아무것도하지만 자신을 분기하지 않습니다 이후)가에 갈 것 표준 입력 다른 인스턴스를.
stdin 과 stdout 을 더미로 상상하는 데 도움이됩니다 .
stdin에 기록 된 내용은 프로그램이 읽기를 결정할 때 준비가되며 stdout 은 같은 방식으로 작동합니다.
이렇게하면 통신이없는 파이프 (두 개의 빈 파일) 또는 동기화되지 않은 쓰기 및 읽기와 같은 상황을 쉽게 상상할 수 있습니다.
정확히 두 번 실행됩니까? 제 생각 :
에는 첫 번째 :
실행이 끝날 때까지 두 번째로 전달되는 것이 없으며 실제로는 결코 끝나지 않습니다.
인스턴스의 입력 및 출력을 리디렉션하기 때문에 첫 번째 인스턴스를 시작하기 전에 두 번째 인스턴스를 완료 할 필요가 없습니다. 실제로 두 번째가 동시에 실행되어 두 번째가 첫 번째 데이터에 의해 구문 분석되는 데이터와 함께 작동하는 것이 실제로 바람직합니다. 이것이 여기서 일어나는 일이며, 첫 번째가 끝날 때까지 기다릴 필요없이 둘 다 호출됩니다. 이는 모든 파이프 체인 명령 행에 적용됩니다 .
동일한 논리가 : () {: | : &} ;:에 적용된다고 생각합니다.
:(){ : & };:
같은 작업을 수행
:(){ :|: & };:
첫 번째는 재귀 적으로 실행 되더라도 함수가 백그라운드에서 호출되기 때문에 작동하지 않습니다 ( : &
). 첫 번째 :
는 "자식" :
이 끝나기 전에 기다릴 필요가 없으므로 결국 하나의 인스턴스 만 :
실행하게됩니다. 만약 당신이 :(){ : };:
그것을 가지고 있다면 , 첫 번째 :
는 "자식" :
이 돌아 오기를 기다리기 때문에, "자식" 이 돌아 오기를 기다리는 것 :
입니다.
다음은 실행중인 인스턴스 수에 따라 다른 명령이 어떻게 표시되는지 보여줍니다.
:(){ : & };:
1 개의 인스턴스 (호출 :
및 종료)-> 1 개의 인스턴스 (호출 :
및 종료)-> 1 개의 인스턴스 (호출 :
및 종료)-> 1 개의 인스턴스-> ...
:(){ :|: &};:
1 인스턴스 (2를 호출 :
하고 종료)-> 2 인스턴스 (각 1을 호출하면 2 :
와 종료)-> 4 인스턴스 (각 호출을 2 :
와 종료)-> 8 인스턴스-> ...
:(){ : };:
1 개의 인스턴스 (호출 :
및 리턴 대기)-> 2 개의 인스턴스 (자식이 다른 호출 :
및 리턴 대기)-> 3 개의 인스턴스 (자식이 다른 호출 :
및 리턴 대기)-> 4 개의 인스턴스-> ...
:(){ :|: };:
1 개의 인스턴스 (2를 호출 :
하고 반환 될 때까지 기다립니다)-> 3 개의 인스턴스 (어린이는 :
각각 2 개를 호출 하고 돌아 오기를 기다립니다)-> 인스턴스 7 개 (어린이는 :
각각 2를 호출 하고 돌아 오기를 기다립니다) -> 15 개의 인스턴스-> ...
보시다시피 백그라운드에서 함수를 호출하면 (을 사용하여 &
) 호출 된 함수가 반환되기 전에 수신자가 종료되므로 실제로 포크 폭탄이 느려집니다.
:|:
, 두 번째 명령:
은 첫 번째 명령이 완료 될 때까지 기다릴 필요가 없습니다.