이전 명령이 완료 될 때까지 bash 스크립트 일시 중지

다음과 같은 bash 스크립트가 있습니다.

##script #!/bin/bash rm data* rm logfile* for i in {1..30} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & done 

첫 번째 루프 다음에 또 다른 for 루프를 만들어서 30 개 더 계속하고 싶습니다. 예를 들어

##script #!/bin/bash rm data* rm logfile* for i in {1..30} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & for i in {31..60} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & done 

새 세트를 시작하기 전에 완료 할 첫 번째 작업 세트. 그러나 nohup 때문에 모두 동시에 실행되는 것 같습니다.

nohup가 있습니다. 원격으로 서버에 로그인하여 작업을 시작한 다음 bash를 닫았 기 때문입니다. 대체 솔루션이 있습니까?

댓글

  • 매뉴얼에서 wait 내장 기능을 검색하십시오.

li>

답변

wait 명령을 사용하여 모든 하위 프로세스 ID를 캡처하고 구체적으로 기다릴 수 있습니다. 또는 스크립트가 생성하는 유일한 백그라운드 프로세스 인 경우 wait를 호출 할 수 있습니다. 인수없이. 예 :

#!/bin/bash # run two processes in the background and wait for them to finish nohup sleep 3 & nohup sleep 10 & echo "This will wait until both are done" date wait date echo "Done" 

Answer

몇 가지 요점 :

  • nohup의 목표가 원격 셸 종료로 인해 작업자 프로세스가 종료되는 것을 방지하는 것이라면 스크립트 자체가 아니라 스크립트 자체에서 생성합니다.

  • 여기에 설명 된대로 , nohup는 프로세스가 SIGHUP를 수신하지 못하도록 차단합니다. 터미널과의 상호 작용에서 벗어나지 만 셸과 하위 프로세스 간의 관계를 끊지는 않습니다.

  • 위의 점 때문에 , 두 개의 for 루프 사이의 간단한 wait로 인해 두 번째 for는 첫 번째 for에 의해 시작된 모든 하위 프로세스가 종료 된 후에 만 실행됩니다.

  • 간단한 wait :

    현재 활성화 된 모든 하위 프로세스가 대기하고 반환 상태는 0입니다.

  • 첫 번째 오류가없는 경우에만 두 번째 for를 실행해야하는 경우 이면 각 작업자 PID를 $!로 저장하고 모두 wait에 전달해야합니다.

    pids= for ... worker ... & pids+=" $!" done wait $pids || { echo "there were errors" >&2; exit 1; } 

댓글

  • ld는 서버에서 실행되는 다른 작업입니다. 그래서 저는 ' 배치를 기다리기만합니다. 그들은 R 스크립트이므로 R 또는 iv id =에서 실행됩니다. top 명령의 “4700a8d421″>
  • 또한 내부에서 nohup을 사용하고 싶습니다 ' 모든 명령을 " 병렬 "에서 실행합니다. 기본적으로 이것은 과학 프로그램을위한 시뮬레이션입니다. 총 180 개의 시뮬레이션을 60 개 일괄 실행하고 싶습니다. 카운터도 1에서 180까지 이동해야합니다. 한 번에 하나씩 수행하면 시간이 너무 오래 걸립니다.
  • waitbash가 자체 생성 한 백그라운드 작업을 기다리게합니다. 여기에 약간의 혼동이있을 수 있습니다. 이러한 for 루프, 파일에 저장하고 스크립트로 호출 했습니까 ( 줄) 또는 터미널에 직접 입력하고 있습니까?
  • cat file.txt | while를 수행하고 있었고 PID가 루프 외부에 설정되지 않았습니다. 그래서 wait 명령은 빈 $pids 문자열을 발견했습니다. 이 문제가 발생하는 이유는 serverfault.com/q/259339 에서 설명합니다. serverfault.com/a/259346
  • 에서 답변 한대로 while ... < files.txt로 쉽게 고정됩니다.

  • 그냥 궁금합니다. pids 변수로 + 기호의 목적은 무엇입니까?
  • 답변

    내장. 백그라운드 프로세스가 완료 될 때까지 대기합니다.

    자세한 내용은 help fg를 참조하세요.

    댓글

    • 스크립트는 작업 제어없이 실행됩니다.

    답변

    다음 코드 세그먼트와 같은 것을 삽입하는 경우 두 개의 for 루프 사이에 있으면 도움이 될 수 있습니다.

    flag=0 while [ flag -eq 0 ] do ps -ef | grep "Rscript --vanilla" | grep -v grep > /dev/null flag=${?} sleep 10 done 

    물론 애플리케이션이 Rscript가 성공적으로 완료되지 않고 계속 남아있을 수 있으며 두 번째 for 루프가 실행되지 않을 수 있습니다. 위의 코드 세그먼트는 식별자가 Rscript --vanilla 인 모든 프로세스가 제대로 완료되고 사라진다고 가정합니다. 애플리케이션이 무엇을하고 어떻게 실행되는지 알지 못한 채이 가정에 의존해야합니다.

    편집

    댓글에 비추어 볼 때 이것이 더 적합합니다. 너의 요구. (원본 코드와 완료 확인 논리 포함)

    for i in {1..30} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & pids[$i]=${!} done flag=0 while [ flag -eq 0 ] do for PID in $(echo ${pids[@]}) do flag=1 ps -ef | grep ${PID} | grep -v grep >/dev/null; r=${?} if [ ${r} -eq 0 ] then flag=0 fi done done for i in {31..60} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & done 

    댓글

    • 프로세스 top의 이름은 R 또는 cc1plus를 표시합니다.
    • 이 경우 ps -ef 목록에 표시되는 공통 분모를 찾아야합니다. 또는 각 nohup 명령 후에 echo ${!}를 사용하여 PID를 변수 (바람직하게는 배열)에 기록하고이 PID 그룹을 확인합니다. 모두 사라지면 두 번째 for 루프

    로 진행할 수 있습니다.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다