프로세스가 완료되면 bash 명령 실행

프로세스가 완료되면 bash 명령 실행

GPU를 사용하고 ML 모델을 학습하는 두 개의 스크립트가 있습니다. 잠들기 전에 시작해서 밤에 작동하고 아침에 결과를 볼 수 있을 것으로 기대합니다.

하지만 GPU 메모리가 제한되어 있기 때문에 병렬 대신 직렬로 실행하고 싶습니다.

나는 그것을 할 수 있습니다 python train_v1.py && python train_v2.py; 하지만 내가 train_v1. 그동안 훈련 시간이 오래 걸리기 때문에 두 번째 스크립트 구현을 시작하고 완료했으며 완료 train_v2.py되면 자동으로 실행하고 싶습니다 python train_v1.py.

어떻게 이를 달성할 수 있나요? 감사합니다.

답변1

다음은 다른 프로세스가 아직 살아 있는지 반복하고 확인하거나 train_v1.py일반적으로 수행하는 것과 다른 방식으로 호출하는 작업을 포함하지 않는 접근 방식입니다.

$ python train_v1.py
^Z
[1]+  Stopped                 python train_v1.py
$ % && python train_v2.py

프로세스가 실행되는 동안 신호 를 보내 절전 모드 로 전환하는 동안 +를 ^Z누르는 것 입니다 . 그런 다음 끝에 를 추가할 수 있는 명령으로 사용하여 셸을 깨우도록 지시합니다 . 이렇게 하면 마치 처음부터 했던 것처럼 동작하게 됩니다 .CtrlZtrain_v1.pySIGTSTP%&& python train_v2.pypython train_v1.py && python train_v2.py

대신에 %를 사용할 수도 있습니다 fg. 그건 같은거야. 이러한 유형의 셸 기능에 대해 자세히 알아보려면 해당 내용을 읽어보세요.Bash 맨페이지의 "JOB Control" 섹션.

편집: 대기열에 계속 추가하는 방법

의견에서 jamesdlin이 지적한 것처럼, 예를 들어 v2가 시작되기 전에 패턴을 계속 추가하려고 하면 train_v3.py다음을 수행할 수 없다는 것을 알게 될 것입니다.

$ % && python train_v2.py
^Z
[1]+  Stopped                 python train_v1.py

train_v1.py아직 시작되지 않았기 때문에 중지될 뿐이며 train_v2.py, 아직 시작되지 않은 항목은 중지/일시 중지/잠자기할 수 없습니다.

$ % && python train_v3.py

결과는 다음과 같습니다.

python train_v1.py && python train_v3.py

%마지막으로 일시 중단된 프로세스에 해당하기 때문입니다 . v3그런 식으로 추가하는 대신 기록을 사용해야 합니다.

$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py

위와 같이 히스토리 확장을 수행하거나 키 바인딩(예: up)으로 마지막 명령을 호출하고 끝에 v3를 추가할 수 있습니다.

$ % && python train_v2.py && python train_v3.py

이는 파이프라인에 더 많은 것을 추가하기 위해 반복될 수 있는 것입니다.

$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py
^Z
[1]+  Stopped                 python train_v1.py
$ !! && python train_v4.py
% && python train_v2.py && python train_v3.py && python train_v4.py

답변2

이미 시작한 경우 프로세스가 사라질 때까지 해당 프로세스를 폴링한 다음 두 번째 Python 스크립트를 실행할 python train_v1.py수 있습니다 .pgrep

while pgrep -u "$USER" -fx 'python train_v1.py' >/dev/null
do
    # sleep for a minute
    sleep 60
done
python train_v2.py

-f및를 사용하면 -x첫 번째 Python 스크립트를 실행하는 데 사용된 정확한 명령줄과 일치합니다. 일부 시스템에서는 과 같이 조용하게 만드는 옵션을 pgrep구현합니다. 이는 리디렉션이 필요하지 않음을 의미합니다.-qgrep -q/dev/null

-u옵션은 실행 중인 명령으로 일치를 제한합니다(같은 시스템에 있는 친구나 다른 사람이 아님).

아직 첫 번째 스크립트를 시작하지 않은 경우:

설명에서 언급했듯이 첫 번째 스크립트 바로 다음에 두 번째 스크립트를 시작할 수 있습니다. 두 번째 스크립트가 존재하지 않거나 아직 실행할 준비가 되지 않았다는 사실은 중요하지 않습니다(첫 번째 스크립트가 완료될 때 실행할 준비가 되어 있는 한).

python train_v1.py; python train_v2.py

이렇게 하면 첫 번째 스크립트의 종료 상태에 관계없이 두 번째 스크립트가 시작됩니다. 질문에 표시된 것처럼 대신 사용하면 작동하지만 두 번째 스크립트를 시작하려면 첫 번째 스크립트가 성공적으로 완료되어야 &&합니다 .;

답변3

다음을 사용하여 첫 번째 스크립트를 시작할 수 있습니다.

python train_v1.py; touch finished

그런 다음 정기적으로 finished존재하는지 확인하는 루프를 만드십시오.

while [ ! -f finished ] ; do     
    sleep 5
done
python train_v2.py
rm finished

답변4

첫 번째 스크립트의 종료 상태를 알 필요가 없다면 다음과 같은 것을 권장합니다.쿠살라난다가 쓴 것.

종료 상태를 알아야 하는 경우(이 경우에는 알 수 없지만 다른 사람이 이를 수행하는 솔루션을 찾을 수 있음) 더 복잡합니다. 나는 다음을 썼다.작은 리눅스 유틸리티pwait이를 통해 프로세스가 완료될 때까지 기다리고 종료 상태를 확인할 수 있습니다.

관련 정보