![이 무한 루프로 인해 시스템 리소스가 소모되지 않는 이유는 무엇입니까?](https://linux55.com/image/111397/%EC%9D%B4%20%EB%AC%B4%ED%95%9C%20%EB%A3%A8%ED%94%84%EB%A1%9C%20%EC%9D%B8%ED%95%B4%20%EC%8B%9C%EC%8A%A4%ED%85%9C%20%EB%A6%AC%EC%86%8C%EC%8A%A4%EA%B0%80%20%EC%86%8C%EB%AA%A8%EB%90%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
BASH에서 다음을 수행했습니다.
while true;do bash;done
나는 이 줄을 썼지만 처음에는 그것이 맞는지 확신할 수 없었습니다:
- 메모리가 부족할 때 메인 셸에 머물면서 가능한 한 많은 하위 셸을 만드세요.
- 메인 셸은 하위 셸을 생성한 다음 계보에 메모리가 부족할 때까지 하위 셸을 생성합니다.
그러나 일단 라이너를 실행하면 종료 및 또 다른 종료 및 또 다른 종료 및 종료, 종료, 종료를 입력하기 시작하기 때문에 이것이 두 번째 경우인 것 같습니다. 그러나 프롬프트 직후에 여전히 메인 쉘로 돌아오지 않습니다. 돌아오다 .
이제 너무 많은 서브쉘이 열려 있고 각 서브쉘이 프로그램이기 때문에 각 서브쉘에는 고유한 PID가 있어야 한다고 생각했습니다.
그래서 나는 이렇게 했습니다:
ps aux | grep bash
이름에 bash가 포함된 프로세스가 많이 있을 것으로 예상됩니다.
그러나 그러한 것은 없으며 두 개의 bash 쉘만 있습니다.
어떻게 가능합니까? 프로세스, 쉘, 서브 쉘 및 PID에 대해 매우 잘못된 생각을 가지고 있지만 어디에 있는지 모르겠습니다.
답변1
루프는 각 반복에서 대화형 셸 세션을 시작합니다.
대화형 세션은 힌트를 제공합니다(대화형이기 때문). 종료하면 루프에 대한 제어가 반환되어 다른 대화형 셸이 시작됩니다.
그렇기 때문에 한 번에 많은 프로세스를 얻지 않고 bash
두 개의 프로세스, 즉 루프를 실행하는 상위 프로세스와 새 프롬프트를 제공하는 하위 프로세스만 얻는 것입니다.
루프는 다음과 같이 작성할 수도 있습니다.
while true; do bash; done
이 true
유틸리티는 인수를 사용하지 않으며 단순히 0 종료 값을 반환하며 이는 쉘에서 "true"로 해석됩니다.
bash
폭발하는 프로세스(소위 "포크 폭탄")를 원했다면 다음과 같이 작성했을 것입니다.
while true; do { bash & }; done
bash
그러면 루프가 반복될 때마다 대화형 세션이 시작되지만백스테이지 과정. 세션이 백그라운드 프로세스로 시작되므로 루프는 bash
다음 프로세스를 시작하기 전에 최신 프로세스가 완료될 때까지 기다리지 않습니다 .
복구하려면 시스템을 다시 시작해야 할 수도 있습니다.
이 포크 폭탄은 이제 막 시작했기 때문에 생각보다 가볍습니다.하나각 반복마다 새로운 프로세스. 다른 사람들은 기하급수적으로 프로세스를 시작할 가능성이 높습니다.
답변2
귀하의 루프는 수많은 쉘을 실행하지만 병렬이 아닌 하나씩 실행됩니다. 루프가 처음 실행되면 실행되어 bash
새 셸이 시작되고 프롬프트가 표시됩니다. 상위 쉘은 쉘이 종료될 때까지 기다립니다. exit
이는 입력하고 하위 쉘을 종료한 다음 상위 쉘로 돌아갈 때 발생하며, 상위 쉘은 루프를 반복하고 다시 실행되어 bash
새 쉘을 시작하고 프롬프트를 표시합니다.
다음을 실행하여 쉘 레벨을 표시할 수 있습니다.
echo $SHLVL
명령을 계속 입력해도 이 숫자는 변경되지 않습니다 exit
.