많은 파일을 처리하고 싶습니다. 여러 코어가 있으므로 병렬로 처리하고 싶습니다.
for i in *.myfiles; do do_something $i `derived_params $i` other_params; done
나는 Makefile 솔루션을 알고 있지만 명령에는 쉘 globbing 목록에서 인수가 필요합니다. 내가 찾은 것은 :
> function pwait() {
> while [ $(jobs -p | wc -l) -ge $1 ]; do
> sleep 1
> done
> }
>
이를 사용하기 위해서는 작업과 pwait 호출을 모두 한 후 수행해야합니다. 매개 변수는 병렬 프로세스 수를 제공합니다.
> for i in *; do
> do_something $i &
> pwait 10
> done
그러나 이것은 잘 작동하지 않습니다. 예를 들어 많은 파일을 변환하는 for 루프로 시도했지만 오류가 발생하여 작업이 취소되었습니다.
zsh 메일 링리스트에 대한 토론이 너무 오래되어서 아직 완료되지 않았다는 것을 믿을 수 없습니다. 그래서 당신은 더 잘 알고 있습니까?
답변
makefile 은 문제에 대한 좋은 해결책입니다. 이 병렬 실행을 쉘에서 프로그래밍 할 수는 있지만 알다시피 어렵습니다. make의 병렬 구현은 작업 시작 및 종료 감지뿐만 아니라로드 밸런싱도 처리하므로 까다로울 수 있습니다.
globbing의 요구 사항은 장애물이 아닙니다.이를 지원하는 구현이 있습니다. GNU make (와 같은 와일드 카드 확장 $(wildcard *.c)
및 쉘 액세스 (예 : $(shell mycommand)
자세한 내용은 GNU make 설명서 기능 참조)) make
Linux 의 기본값 이며 대부분의 다른 시스템에서 사용 가능합니다. 다음은 필요에 따라 조정할 수있는 Makefile 스켈레톤입니다.
출처 = $ (와일드 카드 * .src) 모두 : $ (sources : .src = .tgt) % .tgt : $ .src do_something $ <$$ (파생 _ 매개 변수 $ <)> $ @
make -j4
4 개의 작업을 병렬로 실행하거나 make -j -l3
로드를 약 3으로 유지하는 것과 같은 것을 실행 하십시오 .
답변
나는 당신의 파생 주장이 무엇인지 잘 모르겠습니다. 그러나 GNU Parallel http : // www.gnu.org/software/parallel/을 사용하면 CPU 코어 당 하나의 작업을 수행 할 수 있습니다.
find . | parallel -j+0 'a={}; name=${a##*/}; upper=$(echo "$name" | tr "[:lower:]" "[:upper:]");
echo "$name - $upper"'
파생하고자하는 것이 단순히 .extension을 변경하는 것이라면 {.}가 유용 할 수 있습니다
parallel -j+0 lame {} -o {.}.mp3 ::: *.wav
http://www.youtube.com/watch?v=OpaiGYxkSuQ 에서 GNU Parallel에 대한 소개 비디오를 보십시오.
답변
쉘 wait
명령을 사용하지 않습니까?
for i in *
do
do_something $i &
done
wait
루프는 작업을 실행 한 다음 기다렸다가 다음 작업을 수행합니다. 위의 방법으로 문제가 해결되지 않으면 pwait
이후에 이동하면 더 잘 작동 할 수 있습니다 done
.
답변
왜 아무도 xargs를 언급하지 않았습니까?
정확히 세 개의 주장이 있다고 가정하면,
for i in *.myfiles; do echo -n $i `derived_params $i` other_params; done | xargs -n 3 -P $PROCS do_something
그렇지 않으면 구분 기호를 사용하십시오 (null이 유용합니다).
for i in *.myfiles; do echo -n $i `derived_params $i` other_params; echo -ne "\0"; done | xargs -0 -n 1 -P $PROCS do_something
편집 : 위의 경우 각 매개 변수는 null 문자로 구분되어야하며 xargs -n으로 매개 변수 수를 지정해야합니다.
답변
나는 몇 가지 대답을 시도했다. 스크립트가 필요한 것보다 조금 더 복잡해집니다. 이상적으로 사용 parallel
또는 xargs
for 루프가 복잡 내부의 작업이 병렬 공급 크고 긴 줄 파일을 만들 문제가 될 수 있다면 그러나 바람직 할 것이다. 대신 다음과 같이 소스를 사용할 수 있습니다
# Create a test file
$ cat test.txt
task_test 1
task_test 2
# Create a shell source file
$ cat task.sh
task_test()
{
echo $1
}
# use the source under bash -c
$ cat test.txt | xargs -n1 -I{} bash -c 'source task.sh; {}'
1
2
따라서 문제 해결 방법은 다음과 같습니다.
for i in *.myfiles; echo " do_something $i `derived_params $i` other_params
" >> commands.txt ; done
무언가를 정의하다 do_something.sh
do_something(){
process $1
echo $2
whatever $3
}
xarg
또는로 실행gnu parallel
cat commands.txt | xargs -n1 -I{} -P8 bash -c 'source do_something.sh; {}'
for 반복의 기능적 독립성이 내포되어 있다고 가정합니다.