2011-09-30 5 views
9

GNU parallel을 사용하여 많은 파일을 웹 서버에 게시하려고합니다. 내 디렉토리에서, 나는 일부 파일이 있습니다"find"와 "ls"with GNU parallel

file1.xml 
file2.xml 

및 I는 다음과 같습니다 쉘 스크립트가 있습니다

#! /usr/bin/env bash 

CMD="curl -X POST [email protected]$1 http://server/path" 

eval $CMD 

스크립트에서 다른 물건이있다, 그러나이 간단한 예이다. 나는 다음과 같은 명령을 실행하려고 :

GNU parallel 페이지 디렉토리에 파일을 작동 할 수있는 "일반적인"방법으로 보여줄 것입니다
ls | parallel -j2 script.sh {} 

. 이것은 내 스크립트에 파일의 이름을 전달하는 것 같지만 컬은 전달 된 데이터 파일을로드 할 수 없습니다 불평하지만, 내가 할 경우 :. 잘 작동

find . -name '*.xml' | parallel -j2 script.sh {} 

. lsfind이 스크립트에 인수를 전달하는 방법과 차이가 있습니까? 아니면 해당 스크립트에서 추가 작업을 수행해야합니까?

+1

#으로 실행 해 보았습니다./ bin/bash -x. 당신의 주장이 당신이 생각하는 것과 다르다면 그것을 보여 줄 것입니다. –

+0

이런 일이 생길 때마다 나는 당혹 스럽지만, 다음날이 문제를 재현하려고 시도했을 때 (제안 된대로 -x를 사용) 재현 할 수 없었고 모든 것이 잘 작동했습니다. 나는 매번 ls를 사용하거나 성공할 수있었습니다. 내가 어떻게 든 내 환경을 정리하고 로그 아웃/아웃을하면 뭔가를 정리 궁금하네요. – Dave

답변

2

나는 parallel을 사용하지 않았지만 ls & find . -name '*.xml' 사이에 다른 것이 있습니다. ls을 모두으로 표시하고 find . -name '*.xml'.xml으로 끝나는 파일 (및 디렉토리) 만 나열합니다.
폴 루벨 (Paul Rubel)의 제안에 따라 스크립트에서 $ 1 값을 인쇄하여 확인하십시오. 또한 -type f 옵션이있는 find의 파일에만 입력을 필터링하는 것이 좋습니다.
희망이 도움이됩니다.

1

청초한.

필자는 전에 평행을 사용하지 못했습니다. 그것은 두 가지가 있지만, 나타납니다. 하나는 Gnu Parrallel이고, 내 시스템에 설치된 것은 Tollef Fog Heen 이 man 페이지에 저자로 나열되어 있습니다.

: 바울이 언급 한 바와 같이

, 당신은 당신이 위에서 언급 한 패러다임은 다음을 수행하기보다는, 내가 을 가지고, 내 병렬 작동하지 않는 것, 는 또한

-x를 설정 사용해야합니다

$ cat ../script.sh 
+ cat ../script.sh 
#!/bin/bash 
echo [email protected] 
$ parallel -ij2 ../script.sh {} -- $(find -name '*.xml') 
++ find -name '*.xml' 
+ parallel -ij2 ../script.sh '{}' -- ./b.xml ./c.xml ./a.xml ./d.xml ./e.xml 
./c.xml 
./b.xml 
./d.xml 
./a.xml 
./e.xml 
$ parallel -ij2 ../script.sh {} -- $(ls *.xml) 
++ ls --color=auto a.xml b.xml c.xml d.xml e.xml 
+ parallel -ij2 ../script.sh '{}' -- a.xml b.xml c.xml d.xml e.xml 
b.xml 
a.xml 
d.xml 
c.xml 
e.xml 

find는 다른 입력을 제공하지만, 이름에 상대 경로를 앞에 붙입니다. 어쩌면 그것은 당신의 대본을 엉망으로 만드는 것입니까?

5

GNU parallelxargs의 변형입니다. 두 인터페이스 모두 매우 유사한 인터페이스를 가지고 있으며 parallel에 대한 도움을 얻으 려한다면 xargs에 대한 정보를 더 많이 찾을 수 있습니다.

그들이 말하는 두 가지 방식은 모두 매우 간단합니다. 기본 동작을 사용하면 두 프로그램 모두 STDIN에서 입력을 읽은 다음 입력을 공백을 기반으로하는 토큰으로 분리합니다. 각 토큰은 제공된 프로그램에 인수로 전달됩니다. xargs의 기본값은 가능한 한 많은 토큰을 프로그램에 전달한 다음 제한에 도달하면 새 프로세스를 시작하는 것입니다. 병렬 작업의 기본값이 어떻게 작동하는지 잘 모르겠습니다.기본 동작 몇 가지 문제가 있습니다

> echo "foo bar \ 
    baz" | xargs echo 
foo bar baz 

, 그래서 몇 가지 변화를 볼 것이 일반적이다 : 여기

은 예입니다.

첫 번째 문제는 공백을 사용하여 토큰 화하기 때문에 공백이있는 파일은 평행선과 xargs가 깨지는 원인이된다는 점입니다. 한 가지 해결책은 대신 NULL 문자를 토큰 화하는 것입니다. find도이 쉽게 할 수 있도록하는 옵션을 제공합니다 :

> echo "Success!" > bad\ filename 
> find . "bad\ filename" -print0 | xargs -0 cat 
Success! 

-print0 옵션은 NULL 문자 대신 공백을 가진 파일을 분리해서하는 find을 알려줍니다.
-0 옵션은 xargs에 NULL 문자를 사용하여 각 인수를 토큰 화합니다.

parallel은 기본 동작이 줄 바꿈 만 토큰 화 된 점에서 xargs보다 약간 낫다는 점에 유의하십시오. 따라서 기본 동작을 변경할 필요가 적습니다.

다른 일반적인 문제는 인수를 xargs 또는 parallel으로 전달하는 방법을 제어하려는 경우 일 수 있습니다. 프로그램에 전달 된 인수의 특정 위치를 가져야하는 경우 {}을 사용하여 인수를 배치 할 위치를 지정할 수 있습니다.

> mkdir new_dir 
> find -name *.xml | xargs mv {} new_dir 

이렇게하면 현재 디렉토리와 하위 디렉토리의 모든 파일을 new_dir 디렉토리로 이동합니다. 실제로 다음으로 분해 :

> find -name *.xml | xargs echo mv {} new_dir 
> mv foo.xml new_dir 
> mv bar.xml new_dir 
> mv baz.xml new_dir 

그래서 xargsparallel 일, 당신이 희망 명령으로 문제를 볼 수있는 방법을 고려. find . -name '*.xml'script.sh 프로그램에 전달할 XML 파일 목록을 생성합니다.

> find . -name '*.xml' | parallel -j2 echo script.sh {} 
> script.sh foo.xml 
> script.sh bar.xml 
> script.sh baz.xml 

그러나 ls | parallel -j2 script.sh {}는 script.sh 프로그램에 전달되는 현재 디렉토리에있는 모든 파일의 목록을 생성합니다. 다음과 같이 ls 버전

> ls | parallel -j2 echo script.sh {} 
> script.sh some_directory 
> script.sh some_file 
> script.sh foo.xml 
> ... 

더 정확한 변형은 다음과 같습니다

> ls *.xml | parallel -j2 script.sh {} 

을하지만,이 및 찾기 버전 사이의 중요한 차이는 있지만, 그 파일에 대한 모든 하위 디렉토리를 검색한다 찾을 수있다 ls는 현재 디렉토리 만 검색합니다. 이 내용은 현재 디렉토리를 검색합니다

> find -maxdepth 1 -name '*.xml' 

다음과 같이 위의 ls 명령의 해당 find 버전이 될 것입니다.

3

find과 작동하기 때문에 GNU Parallel이 (-v 또는 --dryrun을 사용하여) 어떤 명령을 실행하는지 확인한 다음 실패한 명령을 수동으로 실행하려고합니다.

ls *.xml | parallel --dryrun -j2 script.sh 
find -maxdepth 1 -name '*.xml' | parallel --dryrun -j2 script.sh 
관련 문제