파이프를 통해 입력 파일을 인수로 전달하시겠습니까?

파이프를 통해 입력 파일을 인수로 전달하시겠습니까?

두 가지 질문이 있습니다. 파이프를 통해 파일을 매개변수로 전달하려고 하고, 해당 파일을 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.sh4개의 쉘 스크립트 복사본( -P 4)이 병렬로 시작되고(이전 복사본이 완료되자마자 새 복사본이 생성됨) 각 복사본은 파일 이름을 인수( -n 1)로 사용합니다.

즉, 스크립트에 대한 모든 호출은 다음과 같습니다.

sh someFunction.sh segmentsomething

스크립트 내부에서 쉘은 다음 값을 입력합니다.위치 매개변수(명령줄의 인수) $1등을 입력합니다. $2( $0일반적으로 스크립트 자체의 이름이 포함되어 있습니다) 귀하의 경우 $1파일 이름이 포함되고 나머지는 비어 있습니다.

따라서 스크립트에서 다음을 수행합니다.

filename="$1"

echo "$filename"
cat "$filename"

그게 다야. 이제 일반적으로 사람들이 find파일을 찾고 파일 이름을 전달할 때 xargs사람들이 서로 상기시키는 불안정한 파일 이름 문제가 있는데 여기서도 그 문제를 다루겠습니다.

유틸리티 find에는 공백으로 구분된 파일 이름이 전달됩니다. 파일 이름에 공백이 있으면 좋지 않습니다. xargs올바른 이름으로 스크립트를 호출하는 데 문제가 발생할 수 있기 때문입니다.

따라서 가장 좋은 방법은언제나-print0with find-0with를 사용하면 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

관련 정보