xargs
-n
각 명령 실행에 대한 최대 인수 수를 지정하는 옵션이 있습니다 .
xargs
제공된 모든 인수가 포함된 명령이 항상 즉시 실행되도록 지정하는 방법이 있습니까 ? (모든 인수를 사용하지 않고 명령을 직접 실행하는 것과 마찬가지로 xargs
명령줄 길이에 대한 시스템 제한으로 인한 실패를 피하려는 것은 아닙니다)
다음은 내 문제가 아닙니다. 주의가 산만해지면 무시하세요.
나는 개행 문자를 제거하고 후행하는 명령 대체를 사용하고 싶지 않으므로 대안으로 NUL
사용하는 것을 고려하고 있습니다 . xargs
그러나 여러 실행의 매개변수를 그룹화하고 싶지 않습니다. xargs
왜냐하면 xargs가 실행하는 명령에 따라 다양한 매개변수 하위 집합을 사용하는 여러 실행의 결과가 모든 매개변수를 사용하는 단일 실행의 결과와 다를 수 있기 때문입니다. 그래서 xargs
항상 모든 매개변수를 동시에 실행하라고 말씀드리고 싶습니다 .
답변1
나는 아직도 당신이 하고 있는 일을 이해하지 못하지만 -x
옵션("명령줄이 맞지 않으면 종료")과 큰 값(시스템 제한보다 큰)으로 설정된 옵션을 -n
결합하면 다음을 수행해야 합니다.
a) xargs
인수 수에 관계없이 한 번만 실행하십시오.
b) 운영 체제 또는 xargs 내부 제한으로 인해 단일 명령에 인수를 넣을 수 없는 경우 오류가 발생합니다.
예:
$ seq 1 10000 | xargs -n 100000000 -x sh -c 'echo "$#"' sh
10000
$ seq 1 100000 | xargs -n 100000000 -x sh -c 'echo "$#"' sh
xargs: argument list too long
불행하게도 이것은 BSD나 Solaris xargs에서는 작동하지 않습니다. *BSD에서 이 -x
옵션을 사용하면 xargs
해당 명령이 종료되지 않고 단일 인수로 실행됩니다.
fz11_2$ jot 10000 1 | xargs -n 10000 -x sh -c 'echo $#' sh | head -3
1
1
1
xargs: sh: terminated with signal 13; aborting
터무니없이 작은 일부 매개변수만 -s
트리거됩니다 -x
.
fz11_2$ jot 10000 1 | xargs -s 19 -n 10000 -x sh -c 'echo $#' sh | head -3
xargs: insufficient space for arguments
이것기준GNU xargs 동작과 일치하는 것 같습니다.
-n number Invoke utility using as many standard input arguments as possible, up to number (a positive decimal integer) arguments maximum. Fewer arguments shall be used if: + The command line length accumulated exceeds the size specified by the -s option (or {LINE_MAX} if there is no -s option). + The last iteration has fewer than number, but not zero, operands remaining. -x Terminate if a constructed command line will not fit in the implied or specified size (see the -s option above).
답변2
귀하가 설명하는 내용은 이미 기본값입니다. xargs -n
사용할 최대 인수 수를 제공하지만 지정하지 않으면 xargs
가능한 많은 인수가 사용됩니다.
귀하의 질문에 시스템 제한 사항을 언급하셨는데 이를 회피하고 싶지 않거나 피할 필요가 없습니다. xargs
이 시스템 제한이 고려되지만 --max-chars
( ) 옵션 -s
사용법에 설명된 대로 더 낮은 값을 사용할 수도 있습니다.
--max-chars=max-chars -s max-chars
가장 많이 사용 최대 문자 수명령 및 초기 인수와 인수 문자열 끝의 종료 null 값을 포함하여 명령줄당 문자 수입니다. 허용되는 최대 값은 시스템에 따라 다르며 exec에 대한 매개변수 길이 제한에서 환경 크기, 2048바이트 여백을 뺀 값으로 계산됩니다. 값이 128KiB보다 크면 128KiB가 기본값으로 사용됩니다. 그렇지 않으면 기본값이 최대값입니다. 1KiB는 1024바이트입니다.
(강조는 내 것)
무엇인지 확인하실 수 있습니다 echo | xargs --show-limits
. 출력 예:
Your environment variables take up 3712 bytes
POSIX upper limit on argument length (this system): 2091392
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2087680
Size of command buffer we are actually using: 131072
Maximum parallelism (--max-procs must be no greater): 2147483647
이는 내 하드 제한이 2087680(2MiB 바로 아래)임을 보여줍니다. 시스템에서 128K 이상을 허용하는 경우 xargs -s 2087680
(자신의 한계에 맞게 조정)을 사용하여 분할을 방지할 수 있습니다.
이전 버전에서는 xargs
운영 체제에서 허용하는 것보다 더 높은 제한을 제공할 수도 있습니다. 4.4.2에서는 경고가 표시되지만 지정된 값은 관계없이 허용되며 명령을 직접 실행할 때 표시되는 것과 동일한 오류가 발생합니다.
$ seq 1 2000000 | xargs -s 2100000 echo | wc -l
xargs: value for -s option should be < 2092927
xargs: echo: Argument list too long
0
그러나 버전 4.6에서는 하드 제한이 준수됩니다.
$ seq 1 2000000 | xargs -s 2100000 echo | wc -l
xargs: value for -s option should be <= 2091392
23
답변3
몇 가지 설명:
존재하다
cmd1 $(cmd2)
출력 결과는 다음과 같습니다 cmd2
.
- 에서는
bash
NUL이 삭제됩니다. 다른 쉘과의 YMMV(zsh
일부 쉘은 보존된 경우 첫 번째 NUL 이후의 모든 것을 무시합니다). - 후행 줄 바꿈이 제거됩니다.
- 결과는
$IFS
대부분의 쉘의 기본값을 기준으로 SPC, TAB, NL 입니다zsh
. - 모든 작업은 와일드카드의 영향을 받습니다( 제외
zsh
). 예를 들어,*
현재 디렉터리에 숨겨져 있지 않은 파일 목록이 됩니다. - 결과 목록은 환경과 결합된 목록이 너무 큰 경우(Linux의
cmd1
경우execve()
단일 인수가 128KiB보다 큰 경우) 이 작업을 수행하는 시스템 호출이 실패합니다.
존재하다
cmd2 | xargs cmd1
출력 결과는 다음과 같습니다 cmd2
.
- 일부 구현에서는 이 출력의 바이트가 문자로 해석됩니다. 예를 들어, UTF-8 문자 세트를 사용하는 로케일에서 e2 80 86 바이트 시퀀스는 U+2006 문자를 구성합니다.1인당 6명이 이용할 수 있는 공간문자, 일반적으로 공백 문자로 처리됩니다. 일부 바이트가 유효한 문자를 형성하지 않으면 구현에 따라 제거되거나 오류가 발생할 수 있습니다. 입력이 텍스트가 아닌 경우 POSIX는 이 동작을 지정하지 않습니다.
- NUL 바이트가 있는 경우 이는 텍스트가 아니므로 구현에 따라 동작이 달라집니다.
- LINE_MAX(일부 시스템에서는 1024개까지 낮을 수 있음)보다 행이 더 많은 경우에도 동작이 지정되지 않습니다.
xargs
예상되는 형식에 따라 입력을 구문 분석합니다. 이 형식에서 공백과 줄 바꿈은 구분 기호로 이해됩니다(따라서 후행 줄 바꿈은 동일하게 분할됩니다). 그 목록은 구현(경우에 따라 U+2006 포함)에 따라 다르며 를 사용하고 백슬래시는 이를 방지하기 위한 인용 연산자'...'
역할을 합니다 ."..."
해당 구분 기호 및 기타 인용 연산자는 특별하게 처리됩니다.- 결과는 목록 또는성격.
- 일부 구현에서는 이러한 단어 중 하나라도 이면
_
파일 끝 논리적 표시기로 처리되고 그 뒤의 모든 내용은 무시됩니다. - 이러한 단어 중 하나라도 특정 제한(많은 시스템에서 255바이트 정도)보다 큰 경우 동작은 지정되지 않습니다.
- 나머지 단어는 인수로 전달되지만
cmd1
목록이 너무 큰 경우 명령 대체 사례에서와 같이 실패하는 대신 성공xargs
하기 위해 가능한 한 많은 단어(구현에 따라 약간의 여유가 있음)를 맞추고 실행합니다.execve()
모든 매개변수를 사용하기 위해 필요한 만큼 명령을 실행합니다.
지금:
cmd2
전체 출력을 매개변수로 전달하려는 경우cmd1
:- 해당 출력에 NUL 문자가 포함되어 있으면
execve()
명령 대체나xargs
. - 해당 출력이 ARG_MAX 제한보다 큰 경우에는 그렇게 할 수 없습니다(일부 시스템에서는 해당 제한을 늘릴 수 있는 방법이 있음)
exexve()
. 예를 들어cmd1
쉘의 내장 기능이나 기능을 사용할 수 있습니다(그때execve()
에는 관련되지 않으므로). , 그러나 그럼에도 불구하고 실제로zsh
이 경우에도 NUL이 포함된 매개변수만 지원됩니다. - Linux에서는 128KiB보다 크면 불가능합니다. 이 한도는 늘릴 수 없습니다.
- 그렇지 않은 경우(NUL이 없고 충분히 작은 경우) 언제든지 다음을 수행
out=$(cmd2; echo .); cmd1 "${out%.}"
하거나 GNU를 사용할 수 있습니다xargs
.cmd2 | xargs -0 cmd1
- 해당 출력에 NUL 문자가 포함되어 있으면