경고: 대부분의 셸에서 이 명령을 실행하면 시스템이 손상되어 복구를 위해 강제 종료가 필요합니다.
나는 재귀 함수 :(){ :|: & };:
와 그 기능을 이해합니다. 하지만 포크 시스템 호출이 어디에 있는지 모르겠습니다. 확실하진 않지만 파이프 안에 있는 것 같아요 |
.
답변1
의 파이프로 인해 x | y
파이프를 포그라운드 프로세스 그룹의 일부로 포함하는 하위 쉘이 생성됩니다. 이렇게 하면 계속해서 서브쉘(패스)이 생성되어 fork()
포크 폭탄이 생성됩니다.
$ for (( i=0; i<3; i++ )); do
> echo "$BASHPID"
> done
16907
16907
16907
$ for (( i=0; i<3; i++ )); do
> echo "$BASHPID" | cat
> done
17195
17197
17199
:
그러나 분기는 코드의 마지막 호출 인 코드가 실행될 때까지 실제로 발생하지 않습니다 .
포크 폭탄 해체 작동 방식:
:()
-라는 새로운 함수를 정의합니다.:
{ :|: & }
- 호출 함수를 백그라운드 호출 함수의 다른 인스턴스로 재귀적으로 전송하는 함수 정의:
- 포크 폭탄 기능 호출
이는 많은 메모리를 차지하지 않는 경향이 있지만 PID를 차지하고 CPU 사이클을 소모합니다.
답변2
코드의 마지막 비트 ;:
는 함수를 실행하는 것입니다 :(){ ... }
. 여기서 포크가 발생합니다.
세미콜론은 첫 번째 명령을 종료하고 함수를 호출하는 또 다른 명령을 시작합니다 :
. 함수 정의에는 :
자체 호출( )이 포함되며 해당 호출의 출력은 백그라운드 버전으로 파이프됩니다 :
. 이는 프로세스를 무기한으로 지원합니다.
이 함수를 호출할 때마다 :()
C 함수를 호출하는 것입니다 fork()
. 결국 이로 인해 시스템의 모든 프로세스 ID(PID)가 소진됩니다.
예
|:&
무슨 일이 일어나고 있는지 이해할 수 있도록 다른 것으로 바꿀 수 있습니다 .
관찰자 설정
터미널 창에서 다음을 수행합니다.
$ watch "ps -eaf|grep \"[s]leep 61\""
"퓨즈 지연" 포크 폭탄 설정
다른 창에서는 약간 수정된 Fork Bomb 버전을 실행하겠습니다. 이 버전은 자체적으로 제한을 시도하여 해당 버전이 수행하는 작업을 연구할 수 있습니다. 우리 버전은 이 함수를 호출하기 전에 61초 동안 절전 모드로 전환됩니다 :()
.
또한 초기 호출이 이루어진 후 백그라운드에 배치할 수도 있습니다. Ctrl+ z를 입력하고 bg
.
$ :(){ sleep 61; : | : & };:
# control + z
[1]+ Stopped sleep 61
[2] 5845
$ bg
[1]+ sleep 61 &
이제 초기 창에서 명령을 실행하면 다음이 jobs
표시됩니다.
$ jobs
[1]- Running sleep 61 &
[2]+ Running : | : &
몇 분 후:
$ jobs
[1]- Done sleep 61
[2]+ Done : | :
관찰자에게 확인
한편 다른 창에서는 다음을 실행하고 있습니다 watch
.
Every 2.0s: ps -eaf|grep "[s]leep 61" Sat Aug 31 12:48:14 2013
saml 6112 6108 0 12:47 pts/2 00:00:00 sleep 61
saml 6115 6110 0 12:47 pts/2 00:00:00 sleep 61
saml 6116 6111 0 12:47 pts/2 00:00:00 sleep 61
saml 6117 6109 0 12:47 pts/2 00:00:00 sleep 61
saml 6119 6114 0 12:47 pts/2 00:00:00 sleep 61
saml 6120 6113 0 12:47 pts/2 00:00:00 sleep 61
saml 6122 6118 0 12:47 pts/2 00:00:00 sleep 61
saml 6123 6121 0 12:47 pts/2 00:00:00 sleep 61
프로세스 계층
a는 ps -auxf
다음 프로세스 계층 구조를 보여줍니다.
$ ps -auxf
saml 6245 0.0 0.0 115184 5316 pts/2 S 12:48 0:00 bash
saml 6247 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
....
....
saml 6250 0.0 0.0 115184 5328 pts/2 S 12:48 0:00 bash
saml 6268 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6251 0.0 0.0 115184 5320 pts/2 S 12:48 0:00 bash
saml 6272 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6252 0.0 0.0 115184 5324 pts/2 S 12:48 0:00 bash
saml 6269 0.0 0.0 100988 464 pts/2 S 12:48 0:00 \_ sleep 61
...
...
청소 시간
A는 killall bash
일이 통제 불가능해지기 전에 일이 일어나는 것을 막을 것입니다. 이 방법으로 청소하는 것은 약간 가혹할 수 있지만 모든 bash
껍질을 벗기지 않을 수 있는 더 부드럽고 온화한 방법은 다음을 수행하는 것입니다.
포크 폭탄이 실행될 의사 터미널을 결정합니다.
$ tty /dev/pts/4
의사 터미널 종료
$ pkill -t pts/4
무슨 일이야?
및 에 대한 각 호출 은 bash
명령을 실행하는 셸에서 호출되는 sleep
C 함수 입니다.fork()
bash