여러 폴더에 대해 연속적으로 명령 실행

여러 폴더에 대해 연속적으로 명령 실행

상위 폴더 "parent"가 있습니다. 이 폴더에는 하위 폴더와 "names.txt"라는 파일이 있습니다. 파일에는 다음과 같은 하위 폴더의 이름이 포함되어 있습니다.

Parent_folder
folder1
folder2
folder3
folder4
.
.
.
.
names.txt

"names.txt" 파일의 내용은 다음과 같습니다.

folder1
folder2
folder3
folder4
.
.
.

각 폴더에는 이미지가 있고 각 이미지에 10개의 스크립트를 연속해서 적용하려고 합니다. 각 스크립트는 각 폴더에서 해당 작업을 수행한 다음 두 번째 스크립트를 실행해야 합니다. These scripts have different names and they are exist in one folder. I set an environment by sourcing a file then I can call these scripts by its name from terminal.또한 이 과정을 모든 폴더에 한번에 적용하고 싶습니다. 즉, 스크립트 #1이 실행될 때 모든 폴더에서 동시에 실행되기를 원합니다. 완료되면 스크립트 #2가 시작됩니다. 모든 폴더 등에서 즉시 시작되기를 원합니다. 이를 달성하기 위해 다음 코드를 작성했습니다.

#!/bin/bash
path=PATH/TO/THE/PARENT/FOLDER
for i in $(cat $path/names.txt); do
{
script#1
} &
{
script#2
} &
.
.
.

done

이 코드는 모든 명령이 동시에 실행되기 때문에 효율적으로 실행되지 않습니다. 명령이 모든 폴더에서 동시에 지속적으로 실행되기를 원합니다. 내가 뭘 잘못했나요?

답변1

먼저 첫 번째(유일한) 명령줄 인수에 지정된 디렉터리로 변경하고 필요한 모든 설정/변수 초기화 등을 수행한 다음 필요한 인수를 사용하여 10개의 스크립트를 실행하는 래퍼 스크립트를 만듭니다.

예를 들어 각 스크립트가 디렉터리의 모든 .jpg, .png 및 .gif 파일을 처리하는 경우:

#! /bin/bash
# example-wrapper.sh

cd "$1"

script1 *.{jpg,png,gif}
script2 *.{jpg,png,gif}
script3 *.{jpg,png,gif}
script4 *.{jpg,png,gif}
script5 *.{jpg,png,gif}
script6 *.{jpg,png,gif}
script7 *.{jpg,png,gif}
script8 *.{jpg,png,gif}
script9 *.{jpg,png,gif}
script10 *.{jpg,png,gif}

다음 find으로 디렉터리 목록을 parallel.

find /path/to/parent/ -mindepth 1 -type -d -print0 | 
  parallel -0 -n 1 ./example-wrapper.sh

( -mindepth 1의 옵션에는 find최상위 디렉터리, 즉 상위 디렉터리 자체가 포함되지 않습니다.)

./example-wrapper.sh기본적으로 병렬 처리는 보유한 각 CPU 코어에 대해 하나의 인스턴스(하나의 "작업")를 실행합니다. 각 인스턴스는 ( ) 디렉터리 이름을 갖게 됩니다 -n 1. 한 작업이 완료되면 다른 작업이 시작됩니다(실행할 작업이 남아 있는 경우).

이는 작업이 CPU 시간을 두고 서로 경쟁하지 않고 사용 가능한 CPU 성능의 사용을 최대화합니다.

한 번에 실행되는 작업 수를 조정 parallel하는 데 사용할 수 있는 옵션입니다. -jCPU 집약적 작업의 경우 시스템 코어당 하나의 작업이라는 기본 설정이 원하는 것일 수 있습니다.

작업이 CPU 집약적이지는 않지만 I/O 바인딩이 더 많은 경향이 있는 경우 입력 파일의 크기와 저장 속도에 따라 각 코어에 대해 2~3개의 작업을 실행해야 할 수도 있습니다. 해당 스토리지를 구성하는 장치 유형 - 예를 들어 SSD는 검색 대기 시간의 영향을 받지 않으므로 디스크 전체에서 데이터를 찾는 여러 프로세스로 인해 하드 드라이브 속도가 느려지지 않으며 검색 시간으로 인해 속도가 느려집니다. 무작위 - Linux의 디스크 버퍼링/캐싱이 도움이 되지만 문제가 제거되지는 않습니다.

이러한 작업이 실행되는 동안 다른 작업을 수행하려면(예: 일반적인 데스크톱 사용) 시스템보다 1~2개 적은 코어를 사용하도록 -j지시하는 작업(예: 8코어 시스템)을 사용하세요.parallel-j 6

참고: 병렬 프로세스를 조정하는 것은 예술이며 최상의 결과를 얻으려면 몇 가지 실험이 필요합니다.

어쨌든, 출처 man parallel:

--jobs N, -j N, --max-procs N, -P N

직위 수. 최대 N개의 작업을 병렬로 실행합니다. 0은 가능한 한 많은 것을 의미합니다. 기본값은 100%이며, 이는 CPU 코어당 하나의 작업을 의미합니다.

--semaphore기본값이 1로 설정 되면 뮤텍스가 생성됩니다.

이것은 실제로 기본적이고 원래의 사용법입니다 parallel. 더 많은 일을 할 수 있습니다. 자세한 내용은 매뉴얼 페이지를 참조하십시오.

그런데 작업을 병렬로 실행하는 옵션 xargs도 있습니다 . -P이처럼 간단한 사용법에서는 xargs -Por 를 사용해도 별 차이가 없습니다 parallel. 그러나 요구 사항이 더 복잡하다면 parallel.

parallel대부분의 Linux 배포판용으로 패키지되어 있어야 하며 그렇지 않은 경우 다음에서 사용할 수 있습니다.https://www.gnu.org/software/parallel/

답변2

"&"는 첨자를 백그라운드에 두므로 동시에 실행됩니다.

아마도 당신이 원하는 것은 루프를 바꾸는 것입니다:

for script in script1 script2 script3 …; do
    for folder in $(cat $path/names.txt); do
        ( cd $path/$folder; $script; ) &
    done
    wait
done

관련 정보