한 줄짜리 bash 루프에서 &(앰퍼샌드) 사용

한 줄짜리 bash 루프에서 &(앰퍼샌드) 사용

구성 파일의 변수를 변경한 다음 루프에서 Python 스크립트를 실행하는 이 명령을 성공적으로 사용했습니다.

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt; python DoMyScript.py; done

DoMyScript.py인스턴스는 종료되기 전에 실행하는 데 약 30초가 걸리므로 다음 인스턴스가 생성될 수 있는 동안 해당 인스턴스를 배경으로 낮추고 싶습니다.

나는 다음과 같은 앰퍼샌드를 추가하여 내가 익숙한 것을 시도했습니다.

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt; python DoMyScript.py &; done

그러나 이로 인해 다음과 같은 오류가 발생합니다.

-bash: syntax error near unexpected token `;'

답변1

;뒷면을 제거합니다 &. 이것은구문 요구 사항

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt;python DoMyScript.py & done

답변2

Stephen의 의견을 고려하면1_CR의 답변, 다음을 수행할 수 있습니다.

for i in {114..255}; do { echo $i > numbers.txt && python DoMyScript.py; } & done

답변3

잃다 ;:

for((i=114;i<=255;i+=1)); do echo $i > numbers.txt;python DoMyScript.py & done

답변4

다른 답변은 다음과 같습니다.

  • 문제는 ;나중에 있습니다 &.
  • ;후자를 제거하면 &명령이 쉘 구문 오류 없이 실행됩니다. 그러나 경쟁 조건이 발생하므로 제대로 작동하지 않을 수 있습니다.

OP는 3초 지연을 추가하여 경쟁 조건을 해결했다고 말했습니다.

아무도 언급하지 않았습니다:

  • 오늘은 3초 지연이 가능할 수 있습니다. 내일은 컴퓨터가 더욱 느려지고 다시 오작동할 수도 있습니다. 내년에는 스크립트를 수정하여 시간이 더 많이 걸리고 다시 실패할 수 있습니다. 지연 시간을 30초씩 늘리면 실패 확률이 낮아집니다. 물론 이는 스크립트 프로세스가 본질적으로 동시(병렬)가 아닌 순차적으로 실행되므로 프로세스를 비동기화하려는 목적이 무산됨을 의미합니다.
  • 스크립트의 여러 인스턴스를 실행해야 하는 경우 명령줄에서 숫자 인수를 허용하도록 스크립트를 수정하는 것이 가장 좋습니다.
    for ((i=114;i<=255;i++)); do python DoMyScript.py --number="$i" & done
    
    그리고 파일을 삭제하세요.
  • 스크립트를 변경할 수 없는 경우 다음 해결 방법이 작동합니다.
    for i in {114..125}; do ( subdir="dir.$i" && mkdir "$subdir" && cd "$subdir" && 
              echo "$i" > numbers.txt && python ../DoMyScript.py; cd .. && rm -r "$subdir" ) & done
    
    이는 numbers.txt별도의 실행 디렉터리를 제공하여 각 스크립트 프로세스에 대해 별도의 파일을 제공합니다. 디렉토리를 생성 및 삭제하고 서브셸에서 스크립트를 실행합니다.
    • DoMyScript.py상대 경로 이름 이외의 파일에 액세스하는 경우 numbers.txt 이를 수용하도록 위 명령을 조정해야 합니다.

    • 위의 영감은 다음에서 비롯됩니다.글렌 잭맨의 답변 (나는 내 ​​것이 작동할 것이고 그 사람은 작동하지 않을 것이라고 믿지만).

    • 명령이B명령이 성공했는지 여부에 따라 다름A, 그렇다면 방어 프로그래밍이 더 좋습니다. 그러나 이는 이 상황을 처리하는 이상적인 방법이 아닐 수도 있습니다. 실패하면 다음 111번의 시도도 실패할 수 있으며 112개의 오류 메시지를 받게 됩니다. 치명적인 오류가 발생하면 루프를 중단하는 것이 가장 좋습니다.A && BABmkdir dir.114

      작업이 비동기식 서브셸에서 발생한다는 사실로 인해 이 작업이 약간 까다로워집니다.

      for i in {114..125}; do
              { subdir="dir.$i" && mkdir "$subdir" && echo "$i" > "$subdir"/numbers.txt; } || break;
              ( cd "$subdir" && python ../DoMyScript.py; cd .. && rm -r "$subdir" ) & done
      

      mkdir 하나 이상의 명령이 실패하면 루프가 중단됩니다.echo value > file

    • 예를 들어 쓰기가 "보장"된 디렉터리에서 작업하는 것이 더 나을 수 있습니다  /tmp. 그러나 이렇게 하면 명령이 다른 프로세스와 충돌(간섭)할 위험이 높아집니다.

      • 예 를  $$들어 디렉터리 이름을 추가하여 이 문제를 완화  할 수 있습니다 .dir.$$.$idir.$BASHPID
      • mkdir 이는 파일 시스템이 가득 차서 파일 생성이 실패할 위험을 제거하지 않습니다.
    • 스크립트가 실패하더라도 위의 코드는 계속 실행되어 임시 디렉터리를 삭제합니다. 이 경우 다른 작업을 수행할 수 있습니다.

      • 이런. 어떤 이유로 mkdir "$subdir"성공했지만 cd "$subdir"실패했다면 계속해서 실행됩니다 cd .. && rm -r "$subdir". 상위 디렉터리 와 유사한 이름을 가진 디렉터리  dir.114(즉, 현재 디렉터리와 평행)가 있는 경우 해당 디렉터리는 삭제됩니다. 마지막 줄을 다음과 같이 변경하면 이 문제를 (적어도 어느 정도) 해결할 수 있다고 생각합니다.
        ( cd "$subdir" && { python ../DoMyScript.py; cd ..; } && rm -r "$subdir" ) & done
        
        또는 절대 경로를 사용하십시오 subdir="$PWD/dir.$i".

관련 정보