이 무한 루프가 왜 내 시스템 리소스를 사용하지 않습니까?


4

BASH에서 다음을 수행했습니다.

while true;do bash;done

나는이 라이너를 썼지 만 처음에는 확실하지 않았다.

  • 메모리 나 다른 것들이 마르면 메인 쉘과 아버지에게 많은 서브 쉘을 유지합니다.
  • 이 셸이 메모리 나 다른 것들이 없어 질 때까지 서브 쉘을 낳습니다.

그러나 두 번째 경우라고 생각합니다. 한 라이너를 실행하면 프롬프트가 나온 직후에 출구와 다른 출구와 출구, 출구, 출구, 출구를 입력하기 시작했지만 여전히 돌아 오지 않았기 때문에 주요 껍질.

이제는 너무 많은 서브 쉘이 열렸고 각각의 프로그램은 하나의 프로그램이기 때문에 각각의 고유 한 PID를 가져야한다고 생각했습니다.

그래서 나는했다 :

ps aux | grep bash

이름에 bash가있는 많은 프로세스를 기대합니다.

그러나 이것과 같은 것은 없으며, bash 쉘은 두 개뿐입니다.

어떻게 가능한지, 프로세스, 셸, 서브 셸 및 PID에 대한 잘못된 아이디어가 있지만 어디에 있는지 모릅니다.


쉘이 많은 쉘을 병렬 또는 순서로 생성하는 방법을 알고 있습니까?
상어

2
찾고있는 용어는 " 포크 폭탄 "입니다. 포크 폭격은 그다지 재미 있지 않으므로 조심해서 다루십시오.
amalloy

내가 그런 극적인 이름이 인식되지 않았습니다, 감사합니다
sharkant

@sharkant f () {f () & f () &;}; f
Joshua

답변:


6

루프는 각 반복마다 하나의 대화식 쉘 세션을 시작합니다.

대화식 세션은 대화식이므로 프롬프트를 제공합니다. 종료하면 루프로 제어권이 다시 주어지고 다른 대화식 쉘이 시작됩니다.

이것이 바로 bash한 번에 방대한 양의 프로세스를 얻지 못하는 이유입니다 . 단 두 개만, 루프를 실행하는 부모와 새 프롬프트를 제공하는 자식입니다.


루프도 작성 될 수 있습니다

while true; do bash; done

true유틸리티는 인수를 사용하지 않고 쉘에서 "true"로 해석되는 종료 값 0 만 리턴합니다.


bash프로세스 폭발 ( "포크 폭탄")을 원한다면 다음과 같이 작성했을 수 있습니다.

while true; do { bash & }; done

이것은 bash루프의 각 반복에서 대화식 세션을 시작 하지만 백그라운드 프로세스로 시작 합니다. 세션은 백그라운드 프로세스로 시작되므로 루프는 bash다음 프로세스를 시작하기 전에 최신 프로세스가 완료 될 때까지 기다리지 않습니다 .

이를 복구하기 위해 시스템을 재부팅해야 할 수도 있습니다.

이 포크 폭탄은 반복 할 때마다 하나의 새로운 프로세스 만 시작하므로 가능한 것보다 더 양성 입니다. 다른 사람들은 기하 급수적으로 프로세스를 시작할 수 있습니다.


이것은 적어도 시각적으로 각 반복이 루프에서 나를 쫓아 내고 출구를 입력하면 다시 시작하기 위해 루프로 돌아갑니다. 나는 그 용어를 들었지만 실제로 "대화식 쉘"이 무엇인지 모르지만 그것이 "비 대화식 쉘"이라면 많은 서브 쉘을 생성하는 것이 효과가 있을까요?
상어

2
@sharkant 대화식 쉘은 명령을 입력하는 쉘입니다. 비 대화식 쉘은 쉘 스크립트 실행과 같이 사용자에게 입력을 요구하지 않고 작업을 수행하는 쉘입니다. 교체 시도 bashbash -c 'echo hello'(실행되는 bash차이를 볼 수있는 대화 형이 아닌 셸). Ctrl+C이것을 테스트하면 루프를 중단하려면 (몇 번 정도) 누르십시오 .
Kusalananda

2
@sharkant 그래도 한 번에 총 2 개의 껍질 만 얻습니다. 비 대화식 쉘은 루프가 다음 쉘을 시작하기 전에해야 할 일을하고 종료합니다.
Kusalananda

6

당신의 루프는 끝없는 수의 쉘을 시작하고 있습니다. 루프가 처음 실행될 bash때 새 쉘을 시작하고 프롬프트를 표시하는 루프가 실행 됩니다. 상위 쉘은 해당 쉘이 종료 될 때까지 기다립니다. 이것은 입력 할 때 exit자식 쉘을 종료하고 부모 쉘로 돌아갈 때 발생합니다 . 이는 루프를 다시 돌고 실행 bash되어 새 쉘을 시작하고 프롬프트를 표시합니다 ...

다음을 실행하여 쉘 레벨을 표시 할 수 있습니다

echo $SHLVL

연속 exit명령 을 입력 할 때이 숫자가 변경되지 않는 것을 볼 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.