xargs에 목록/배열을 에코합니다.

xargs에 목록/배열을 에코합니다.

목록/배열이 있다고 가정해 보겠습니다.

list=(a b c)

각 요소를 xargs에 에코하는 방법은 무엇입니까? 그것은 다음과 같습니다:

for v in list; do echo v; done; | xargs

더 간단한 방법이 있나요?

답변1

printf '%s\n' "${list[@]}" | xargs

그러면 list각 요소가 한 줄에 인쇄되고 개행으로 구분된 목록이 에 전달됩니다 xargs.

"${list[@]}"로 확장될 개별 큰따옴표 요소입니다 list. printf형식 문자열의 자리 표시자보다 더 많은 인수가 제공되면 해당 형식 문자열이 재사용됩니다.

그러나 이는 요소에 공백, 작은따옴표, 큰따옴표 또는 백슬래시 문자가 포함되어 있지 않고 빈 문자열이 아닌 경우에만 작동합니다(일부 xargs구현은 텍스트로만 구성되어 있고 텍스트가 아니며 _상대적으로 짧습니다).

임의의(너무 길지 않은 1) 요소(NUL 문자를 포함하지 않지만 현재 버전의 bash는 어쨌든 변수에 NUL을 저장할 수 없음)의 경우 xargs대부분의 구현에서 지원하는 NUL로 구분된 레코드 옵션 으로 목록을 전달할 수 있습니다 -0(Appearing POSIX 표준의 다음 버전에서):

{
  [ "${#list[@]}" -eq 0 ] || printf '%s\0' "${list[@]}"
} | xargs

print0도우미 기능을 사용하면 도움이 될 수 있습니다.

print0() {
  [ "$#" -eq 0 ] || printf '%s\0' "$@"
}
print0 "${list[@]}" | xargs -0

NetBSD를 제외한 빈 목록의 경우 명령은 echo(기본적으로) 인수 없이 한 번만 호출됩니다. 이 옵션을 사용하면 이러한 -r상황을 피할 수 있습니다(POSIX 표준의 다음 버전에서도 마찬가지).


¹ 시스템 호출 제한을 xargs해결하도록 설계되었지만 execve()중간에 개별 인수를 제거하지 않으므로 단일 인수가 제한보다 크면 execve()명령이 실행되지 않습니다. 또한 Linux에는 대부분의 시스템에 공통된 모든 매개변수 및 환경 변수의 누적 크기에 대한 전체 제한과 달리 개별 매개변수의 크기에 대한 제한이 있습니다.

답변2

특별히 긴 목록이 아니면 xargs완전히 포기 해도 됩니다.

list=(a b c)

# With xargs
printf "%s\n" "${list[@]}" | xargs foo    # Results in « foo a b c »

# Without xargs
foo "${list[@]}"                          # Also results in « foo a b c »

물론, 이를 귀하의 사례에 적용할 수 있는 여부는 xargs실제 명령에 전달하려는 추가 플래그가 무엇인지에 따라 달라집니다.

이를 테스트 하려면 foo이 스크립트를 실행하고 위의 모든 인스턴스를 foo다음으로 바꾸십시오 ./foo.

cat <<'EOF' > foo
#!/bin/bash
echo "Got $# arg(s): $*"
for ARG in "$@"; do echo "> $ARG <"; done
EOF
chmod a+x foo

또한 기본적으로(여기에 표시된 대로) xargs해당 인수는 공백으로 분할되므로 다음과 같습니다.

list=('a b' c d)                          # Three arguments; the first contains a space
printf "%s\n" "${list[@]}" | xargs foo    # Gives foo four arguments « a b c d »
foo "${list[@]}"                          # Gives foo three arguments, with the first containing a space, « 'a b' c d »

관련 정보