이전 명령이 끝날 때까지 bash 스크립트를 일시 중지 –vanilla main.R 10 100

다음과 같은 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명령 을 사용 하여이 작업을 수행 하려고 합니다. 모든 하위 프로세스 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"


답변

몇 가지 사항 :

  • nohup원격 쉘 엑시트가 작업자 프로세스를 종료하지 못하게하는 것이 목표 인 경우 , nohup작성하는 개별 작업자 프로세스가 아니라 스크립트 자체에서 사용해야 합니다.

  • 여기 에 설명 된대로 nohup프로세스가 SIGHUP을 수신하고 터미널과 상호 작용하는 것을 막을뿐 쉘과 자식 프로세스 간의 관계를 끊지는 않습니다.

  • 위의 여부와 상관없이 두 루프 사이의 nohup단순 wait은 두 for번째 루프가 for첫 번째 프로세스에 의해 시작된 모든 하위 프로세스 for가 종료 된 후에 만 ​​실행됩니다 .

  • 간단하게 wait:

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

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

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

답변

fg내장을 사용하십시오 . 백그라운드 프로세스가 완료 될 때까지 기다립니다.

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


답변