나는 MacBook을 가지고 있습니다 (기본 쉘은 zsh입니다)
실행 가능한 Python 스크립트가 있습니다(script1.py).
나는 다음과 같은 다른 실행 가능한 스크립트를 사용합니다.기동기)달리다script1.py 내 컴퓨터가 부팅되면 실행되는 터미널 창이기동기자동으로 열리고 닫히며,script1.py프로세스는 여전히 별도의 프로세스로 실행됩니다. (기동기내 컴퓨터가 켜지면 szh 쉘 인스턴스를 통해 자동으로 실행됩니다. 원래의기동기스크립트 파일은 다음과 같습니다.
#!/bin/bash
cd /script1; nohup ./script1.py &
이 스크립트는 잘 실행되고 모든 것이 잘 됩니다.
하지만 스크립트에서 (;) 대신 (&&)를 사용하면 어떤 일이 발생하는지 이해하려고 노력 중입니다. 즉
#!/bin/bash
cd /scritp1 && nohup ./script1.py &
내 문제는 이것도 작동하지만 Python 스크립트의 프로세스를 종료하려고 할 때마다 szh 또는 다른 것(아마도 bash 프로세스)의 터미널 인스턴스가 프로세스로 실행되고 있다는 것입니다. 즉, 내가 전화하면메모터미널에서 나는 얻는다
ps -ef | grep "script1"
123 14679 1 0 2:12PM ?? 0:00.00 /bin/bash /script1 starter
123 14680 14679 0 2:12PM ?? 0:03.46 /PythonFolder/python ./script1.py
123 14690 14683 0 2:12PM ttys000 0:00.00 grep scrip1
스크립트용기동기사용&&
그리고
ps -ef | grep "script1"
123 14644 1 0 2:08PM ?? 0:03.46 /PythonFolder/python ./script1.py
123 14652 14647 0 2:08PM ttys000 0:00.00 grep scrip1
~을 위한기동기스크립트 사용법;
한 버전에는 두 개의 프로세스가 있고 다른 버전에는 하나만 있는 이유는 무엇입니까? szh가 실행되는 이유를 이해하려고 노력 중입니다.기동기사용할 때 Python 스크립트를 실행하는 하위 프로세스를 만듭니다.&&내 시작 스크립트가 다음을 사용할 때 종료되는 이유는 무엇입니까?;Python 스크립트를 단일 프로세스로 실행하도록 만듭니다.
내가 달릴 때기동기사용된 스크립트로&&터미널 애플리케이션이 나타났다가 닫히지만 두 개의 실행 중인 프로세스(14679그리고14680이 경우).
내가 사용한다면기동기스크립트 사용법;python.py 프로세스를 종료하고 싶습니다. 그냥 호출합니다.
kill 14644
하지만 내가 사용한다면기동기사용된 스크립트&&두 개의 프로세스를 종료하고 싶습니다. 하위 프로세스를 종료하거나 상위 프로세스를 종료하면 하위 프로세스가 작동한다는 것을 알았습니다.
kill 14680
또는
kill 14679; kill 14680
나는 또한 부모 프로세스를 죽일 수 있다는 것을 알았습니다.
kill 14679
내 Python 스크립트는 평소대로 계속 실행됩니다.
답변1
핵심은 어떻게명령 목록#!/bin/bash
작동합니다( shebang 라인을 사용하고 있으므로 여기에서 Bash 매뉴얼을 인용합니다 ):
목록은 연산자 ';', '&', '&&' 또는 '||' 중 하나로 구분되고 선택적으로 ';', '&' 또는 새 줄이 앞에 오는 하나 이상의 파이프 시퀀스입니다.
이러한 목록 연산자 중에서 &&와 ||는 동일한 우선순위를 가지며 그 다음에는 동일한 우선순위를 갖는 ;
(아직 하나 남았는데관로|
또는 )로 구분된 하나 이상의 명령 시퀀스입니다 |&
.
이는 다음을 의미합니다.
cd /script1; nohup ./script1.py &
연산자 간의 우선 순위 규칙으로 인해 셸은 cd /script1
에 의해 종료된 목록을 확인한 ;
다음 "기본" 셸에서 동기적으로 실행되고 nohup ./script1.py
목록은 에 의해 종료된 &
다음 생성된 별도의 프로세스에서 비동기적으로 실행됩니다.
반면에,
cd /scritp1 && nohup ./script1.py &
쉘은 AND 목록을 확인 cd /scritp1 && nohup ./script1.py
하고 종료하며 &
전체 목록을 비동기적으로 실행합니다. 이를 bash
위해서는 목록 자체를 (백그라운드에서) 실행하기 위한 새로운 프로세스를 생성해야 하며 , 이는 차례로 Python 스크립트에 대한 별도의 프로세스를 생성합니다.
정보 kill
: 상위 프로세스 종료하위 프로세스를 자동으로 종료하지 않습니다.. 이는 표준 쉘 동작입니다. list 의 경우 &&
하위 프로세스를 종료하면 상위 프로세스가 종료될 수 있습니다. 상위 프로세스가 수행하는 모든 작업은 하위 프로세스가 반환될 때까지 기다리는 것이기 때문입니다.
nohup ./script1.py
성공에 따라 조건부로 실행 하려는 경우cd /script1
그리고AND 목록에 대한 셸 생성을 방지하려면 두 번째 요소를큰 괄호:
cd /scritp1 && { nohup ./script1.py & }
또는 조건부 블록을 사용하십시오.
if
cd /scritp1
then
nohup ./script1.py &
fi
답변2
상위 프로세스에 의존하지 않는 프로세스를 만드는 간단한 방법을 찾았습니다.
(<command here> &)
그러면 명령을 실행하는 또 다른 배경 셸을 생성하는 새 셸이 생성됩니다. 위 명령이 실행되는 기본 셸을 닫아도 프로세스는 중지되지 않습니다. 이 명령을 실행하는 프로세스의 PPID(init)는 1입니다.
이는 두 번째 셸이 세 번째 셸의 상위 프로세스이고 하위 프로세스가 완료될 때까지 기다리지 않고 실행을 완료하기 때문에 발생합니다(유일한 작업은 세 번째 셸을 생성하는 것임). 그러면 아이는 고아가 되어 init에 의해 처리됩니다.
상술 한 바와 같이여기
프로세스는 재할당에 사용한 리소스를 해제하는 _exit 시스템 호출을 사용하여 종료할 수 있습니다. 따라서 프로세스가 종료될 준비가 되면 종료 상태라는 정보를 통해 프로세스가 종료된 이유를 커널에 알립니다. 가장 일반적으로 상태 0은 프로세스가 성공했음을 나타냅니다. 그러나 이는 프로세스를 완전히 종료하는 데 충분하지 않습니다. 상위 프로세스는 하위 프로세스의 종료를 확인하기 위해 wait 시스템 호출을 사용해야 합니다. 그 기능은 하위 프로세스의 종료 상태를 확인하는 것입니다. 생각하기가 무서운 건 알지만, 전화를 기다리는 것은 필수입니다. 결국 자녀가 어떻게 죽었는지 알고 싶지 않은 부모가 어디 있겠습니까?
고아 프로세스
상위 프로세스가 하위 프로세스보다 먼저 종료되면 커널은 대기 호출을 받지 않을 것임을 알고 있으므로 해당 프로세스를 "고아"로 만들고 init의 관리하에 둡니다(모든 프로세스의 어머니를 기억하십시오). Init는 결국 이러한 고아가 죽을 수 있도록 대기 시스템 호출을 수행합니다.
좀비 프로세스
하위 프로세스가 종료되고 상위 프로세스가 아직 wait를 호출하지 않은 경우 어떻게 되나요? 우리는 여전히 하위 프로세스가 어떻게 종료되는지 확인할 수 있기를 원하므로 하위 프로세스가 완료되더라도 커널은 하위 프로세스를 좀비 프로세스로 전환합니다. 하위 프로세스에서 사용하는 리소스는 여전히 다른 프로세스로 해제될 수 있지만 프로세스 테이블에는 여전히 좀비 프로세스에 대한 항목이 있습니다. 좀비 프로세스도 기술적으로 "죽었기" 때문에 종료할 수 없으므로 신호를 사용하여 종료할 수 없습니다. 결국 상위 프로세스가 wait 시스템 호출을 호출하면 좀비 프로세스가 사라지게 됩니다. 이를 "수확"이라고 합니다. 상위 프로세스가 대기 호출을 수행하지 않으면 init는 좀비를 채택하고 자동으로 대기를 수행하고 좀비를 삭제합니다. 좀비 프로세스가 너무 많으면 프로세스 테이블의 공간을 차지하고 프로세스 테이블이 꽉 차면 다른 프로세스가 실행되지 못하게 되므로 문제가 될 수 있습니다.