xargs가 일부 명령에서는 작동하지만 다른 명령에서는 작동하지 않는 이유는 무엇입니까?

xargs가 일부 명령에서는 작동하지만 다른 명령에서는 작동하지 않는 이유는 무엇입니까?

이 명령을 실행하면 작동합니다.

find . -type f -print0 | xargs md5sum

그러면 각 파일의 md5sum이 인쇄됩니다.

그러나 다른 명령의 경우 모든 파일을 단일 명령 호출로 전달하는 것 같습니다. 예를 들어, 이 문제가 있는 것 같습니다 printf. 다음과 같은 경고가 표시 echo됩니다 printf.

printf: warning: ignoring excess arguments, starting with ...

echo를 사용하면 예를 들어 다음 명령이 있는 경우 한 줄만 인쇄됩니다.

find . -type f -print0 | xargs -r0 echo GOT

발견된 모든 파일과 같은 줄에 "GOT"가 한 번만 인쇄된 것을 볼 수 있습니다.

echo도 내장되어 있기 때문일 것이라고 생각했지만 /bin/echo를 명시적으로 실행하면 동일한 동작이 발생합니다.

참고로 make 명령에서도 다음과 같은 문제가 발생했습니다.

$ echo "a b c" | xargs echo GOT
GOT a b c

바꾸다:

GOT a
GOT b
GOT c

내가 뭘 잘못했나요? 먼저 명령에 접두사를 붙여 디버깅하는 것이 많은 도움이 되었지만 echo그렇게 할 수도 없습니다.

편집: 댓글에서 언급했듯이 실제로 해당 -exec옵션을 사용할 수 없습니다 find. 실제로 정렬을 포함하는 다소 긴 파이프라인이 있지만 이는 관련 없는 세부 사항인 것 같고 내가 얻을 수 없다는 사실과는 아무런 관련이 없습니다. 더욱 간단한 파이프라인 작업.

답변1

표준 입력에서 가져온 모든 내용이 추가되고 일부 구분 기호로 구분된 xargs command-arg명령의 단일 인스턴스를 실행하는 것으로 생각할 수 있습니다 (기본값은 예제에서 사용한 공백 또는 NUL 바이트입니다). command-arg예를 들어:

echo 1 2 3 | xargs something

실행할 수 있습니다 something 1 2 3. 또는 질문에 게시한 예를 사용하여:

echo "a b c" | xargs echo GOT

달리다 echo GOT a b c.

표준 입력에서 얻은 각 인수 xargs를 사용하여 새 command-arg 인스턴스를 생성하려면 -n1 옵션을 사용할 수 있습니다.

$ echo "a b c" | xargs -n1 echo GOT
GOT a
GOT b
GOT c

물론 일부 명령은 여러 인수를 허용하지 않으므로 항상 사용해야 합니다 -n1.

xargs 사용의 장점은 새 프로세스를 생성하는 것이 비용이 많이 드는 작업이므로 여러 인수를 사용하여 단일 프로세스를 실행하는 것이 더 빠르다는 것입니다. 이 답변에서 수행한 일부 벤치마크를 확인하십시오. https://unix.stackexchange.com/a/536023/72304

답변2

첫 번째 답변에서 언급한 "사용" 외에도 -n1쉘에는 특정 명령의 내장 버전이 있을 수 있습니다. 명령이 다른 프로그램(예: )에서 호출되면 xargs셸의 내장 버전이 아닌 외부 프로그램을 호출합니다.

특히 printfBash와 다른 여러 셸에 내장되어 있으며 Bash의 내장 버전은 모든 인수를 소진하는 데 필요한 만큼 형식을 반복합니다.

예를 들어 Bash의 내장 버전을 사용하면

printf '%s and %s\n' How now brown cow

2 줄을 출력하는 반면

/usr/bin/printf '%s and %s\n' How now brown cow

설치한 버전에 따라 매개변수가 너무 많다는 불만이 있을 수 있습니다.

답변3

일반적으로 나는 그것을 피할 것입니다 xargs.

웹에서 찾은 대부분의 예제는 취약합니다. 환경이 코드를 작성하는 사람의 가정과 일치하지 않으면 예상치 못한 방식으로 중단될 것입니다.

이 질문에 제공된 예제에도 버그가 있습니다. find...를 사용 -print0하지만 다음을 사용합니다.xargs 아니요 -0.

게다가 대부분의 용도는 xargs불필요합니다. 특히 와 함께 사용할 경우 find의 표현식을 사용하는 것이 더 안정적이고 오류가 발생할 가능성이 적습니다.-execfind

주어진 예는 다음으로 대체될 수 있습니다.

find . -type f -exec md5sum {} +

관련 정보