GNU Parallel을 사용하여 각 입력 인수에 대한 명령을 실행해 보았습니다. 해당 인수를 명령의 작업 디렉터리로 사용했습니다(명령줄에 추가하지 않고).
기본적으로 내가 해야 할 일은 다음과 같습니다.
/foo -> "cd /foo; mycmd"
/bar -> "cd /bar; mycmd"
/baz -> "cd /baz; mycmd"
Parallel은 대체 문자열을 --workdir
지원하여 {}
내가 원하는 작업을 수행하는 것 같습니다.
--workdir mydir
--wd mydir작업은 mydir 디렉터리에서 실행됩니다. 기본값은 로컬 컴퓨터의 현재 디렉터리와 원격 컴퓨터의 로그인 디렉터리입니다.
<...>
mydir에는 GNU Parallel의 대체 문자열이 포함될 수 있습니다.
-n0
인수가 명령줄에 추가되는 것을 방지하기 위해 또는 다음을 사용해 보았습니다 -N0
.
--max-args 최대 매개변수
-n 최대 매개변수명령줄당 최대 max-args개의 인수를 사용합니다.
<...>
-n 0은 하나의 매개변수를 읽지만 명령줄에 0개의 매개변수를 삽입한다는 의미입니다.
그러나 이것은 작동하지 않는 것 같습니다.
$ mkdir -p $HOME/{foo,bar,baz}
$ printf '%s\n' $HOME/{foo,bar,baz} | parallel --workdir '{}' -n0 'pwd'
parallel: Error: Cannot change into non-executable dir : No such file or directory
앞의 공백에 주목하세요 :
. 이는 GNU 병렬 처리의 오타가 아니지만 workdir이 빈 문자열로 평가된다는 것을 나타냅니다. 앞에 고정 문자열을 추가하면 {}
이 사실이 분명해집니다 . 이 경우 모든 pwd는 해당 고정 문자열을 인쇄합니다.
$ printf '%s\n' $HOME/{foo,bar,baz} | parallel --workdir '/{}' -N0 'pwd'
/
/
/
내가 뭘 잘못했나요?
답변1
나는 가장 간단한 것이 다음과 같다고 믿는다:
printf '%s\n' $HOME/{foo,bar,baz} | parallel 'cd {} && myprg'
너할 수 있는Used --workdir
이지만 이 경우에는 분명히 작동하지 않습니다. GNU Parallel에서는 명령 템플릿에 대체 문자열과 {}
포함하려는 매개변수 가 필요한 경우가 많습니다 --workdir
.
then을 사용하면 then 은 비어 있고 실패할 것이기 -n0
때문에 도움이 되지 않습니다 . 사용되는 곳마다 동일한 문자열로 평가됩니다.{}
--workdir
{}
따라서 해결책은 을 사용하는 것이지만 {}
해가 없는 곳에 사용하는 것입니다.
parallel --workdir {} 'true dummy {}; myprg' ::: $HOME/{foo,bar,baz}
또는 {==}
빌드 명령의 정적 부분을 사용하십시오.
parallel --workdir {} '{= $_="myprg" =}' ::: $HOME/{foo,bar,baz}
개인적으로 저는 이 cd {}
버전을 선호합니다. 무엇을 하려는지 확인하기가 더 쉽다고 생각합니다.
답변2
AFAICT는 인수의 모든 명령을 확장하기 --workdir
위한 것이 아닙니다 . {...}
그럼에도 불구하고 GNU는 parallel
쉘을 실행하여 사용자가 제공한 코드를 해석하므로 언제든지 다음을 수행할 수 있습니다.
... | PARALLEL_SHELL=sh parallel 'CDPATH= cd -P -- {} && mycmd'
(이것은 실행할 쉘을 결정하기 위해 경험적 방법 sh
에 의존하는 대신 쉘을 강제하고 일부 문제를 해결합니다 .)parallel
cd
GNU 기능이 전혀 필요하지 않은 경우 GNU와 함께 parallel
GNU를 사용 하면 GNU 및 쉘 오버헤드와 신뢰할 수 없는 쉘 내장 기능을 피할 수 있습니다.xargs
env
parallel
cd
... | xargs -rd '\n' -P8 -I{} env -C {} mycmd