두 가지 질문이 있습니다. 파이프를 통해 파일을 매개변수로 전달하려고 하고, 해당 파일을 sh
함수 내에서 변수로 사용하려고 합니다.
이것은 내 명령입니다:
find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
여기서 내 라인은 " "처럼 보이는 모든 파일을 찾아서 segment.something
파이프의 오른쪽으로 전달하는 것입니다. 에서는 someFunction.sh
파일 이름이 매개변수로 필요합니다. 파일을 가져오는 중이라고 가정합니다 segment1
.
someFunction.sh
(예를 들어)의 각 줄을 인쇄합니다 .segment1
파이프의 왼쪽에서 오른쪽으로 출력을 전달하는 방법과 내부적으로 호출하는 방법은 무엇입니까 someFunction.sh
?
답변1
주문
$ find . -name 'segment*' | xargs -n1 -P4 sh someFunction.sh
결과적으로 최대 someFunction.sh
4개의 쉘 스크립트 복사본( -P 4
)이 병렬로 시작되고(이전 복사본이 완료되자마자 새 복사본이 생성됨) 각 복사본은 파일 이름을 인수( -n 1
)로 사용합니다.
즉, 스크립트에 대한 모든 호출은 다음과 같습니다.
sh someFunction.sh segmentsomething
스크립트 내부에서 쉘은 다음 값을 입력합니다.위치 매개변수(명령줄의 인수) $1
등을 입력합니다. $2
( $0
일반적으로 스크립트 자체의 이름이 포함되어 있습니다) 귀하의 경우 $1
파일 이름이 포함되고 나머지는 비어 있습니다.
따라서 스크립트에서 다음을 수행합니다.
filename="$1"
echo "$filename"
cat "$filename"
그게 다야. 이제 일반적으로 사람들이 find
파일을 찾고 파일 이름을 전달할 때 xargs
사람들이 서로 상기시키는 불안정한 파일 이름 문제가 있는데 여기서도 그 문제를 다루겠습니다.
유틸리티 find
에는 공백으로 구분된 파일 이름이 전달됩니다. 파일 이름에 공백이 있으면 좋지 않습니다. xargs
올바른 이름으로 스크립트를 호출하는 데 문제가 발생할 수 있기 때문입니다.
따라서 가장 좋은 방법은언제나-print0
with find
및 -0
with를 사용하면 xargs
파일 이름이 공백이 아닌 nul
문자( \0
)로 구분됩니다. 이렇게 하면 더욱 안전해집니다.
그러므로:
$ find . -name 'segment*' -print0 | xargs -0 -n1 -P4 sh someFunction.sh
답변2
someFunction.sh
작업 디렉토리에서 다음과 같은 것을 사용할 수 있다고 가정합니다.
find . -name 'segment*' -print0| xargs -0 -n1 -P4 ./someFunction.sh
이름에 공백이 있는 파일을 허용합니다(FAQ) -print0
. -0
내 안에는 someFunction.sh
내가 있어
#!/bin/bash
echo "Arg: " $1
cat $1
파일 이름을 에코한 다음 전달된 파일의 내용을 씁니다.someFunction.sh