Bash 스니펫 설명이 필요합니다.

Bash 스니펫 설명이 필요합니다.
i=0
while read M; do
    ((cd $DEST/cfg/puppet/modules/$M || exit 1
      [ -d .git ] && echo -n "$M: " && git pull) 2>&1 | prep $(printf %04d: $i) puppet/modules/$M) &
    i=$[i+1]
    [ $[ i % 20 ] = 0 ] && wait
done < $(dirname "$0")/modules-puppet.txt

[ $[ i % 20 ] = 0 ] && wait위의 bash 스니펫에서 해당 라인이 무엇을 하는지 설명해줄 수 있는 사람이 있나요 ?

답변1

이 코드는 루프에서 많은 백그라운드 작업을 생성합니다. 이러한 각 작업은 git및 와 관련된 명령을 실행합니다 puppet.

이러한 작업은 매우 빠르게 생성될 수 있으며 시스템에 부담을 주지 않기 위해 코드는 현재 실행 중인 모든 백그라운드 작업이 완료될 때까지 기다리기 전에 해당 작업 중 20개만 실행합니다. wait계속하기 전에 스크립트가 모든 백그라운드 작업이 완료될 때까지 기다리게 하여 또 다른 20개의 작업을 생성하는 것은 올바른 호출입니다 .

호출 전 산술 테스트는 wait20으로 나눌 수 있는 모든 값, 즉 에 대해 true입니다.$i$i = 20$i = 40

산술 확장에 사용되는 구문은 $[ ... ]더 이상 사용되지 않으며 이제 (이식 가능하게) bash작성되었습니다 . $(( ... ))%연산자는 일반적인 모듈로 연산자입니다.


오래된 구문을 사용하는 것 외에도 셸에는 인용 문제가 있을 수도 있습니다. 변수 확장 $DEST$M$i두 명령 대체와 마찬가지로 따옴표가 누락되었습니다. 이들 중 하나라도 $IFS(기본적으로 공백, 탭, 줄 바꿈)에 있는 문자를 포함하거나 생성하는 경우 스크립트가 실패하거나 적어도 오작동할 것으로 예상할 수 있습니다.

wait코드에는 루프에 의해 시작된 마지막 몇 개의 작업을 적절하게 기다리기 위한 루프 이후의 최종 코드도 누락되어 있습니다. 루프가 발생한다는 것을 보장할 수 있다면 이 작업을 수행할 필요가 없습니다.언제나실행 n*20시간(일부 정수의 경우 n)

답변2

$[ i % 20 ]연산 확장으로 인해 감가 상각되어 으로 대체됩니다 $(()).

i % 20산술 연산 "모듈로"입니다.

[ $[ i % 20 ] = 0 ]조건문이며 표준이 아니며 더 읽기 쉬운 또 다른 구문입니다. Posix는 다음과 같습니다.

 if [ "$(( i % 20 ))" -eq 0 ]

&& wait이전 명령의 반환 코드가 0인 경우에만 실행됩니다.

[ $[ i % 20 ] = 0 ] && wait0과 같으면 모듈러스를 테스트합니다 wait.

내 대체 완전한 구문은 다음과 같습니다.

 if [ "$(( i % 20 ))" -eq 0 ] ; then
   wait
 fi

관련 정보