"매개변수 목록이 너무 깁니다" 오류가 발생하는 방법은 무엇입니까? [복사]

"매개변수 목록이 너무 깁니다" 오류가 발생하는 방법은 무엇입니까? [복사]

문제의 배경:에 따르면POSIX 사양, ARG_MAX는 최대값입니다.길이함수 계열에 대한 명령줄 인수입니다 exec(). 이게 진짜라고 믿게 만드네숫자그러나 이것은 분명히 작동하지 않습니다.

$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$ 

분명히 8192개 이상의 항목이 있음에도 불구하고 잘 작동합니다. ~에 따르면DW의 답변, 8192크기는 kB 단위라고 합니다. 분명히 이전 가정은 잘못되었습니다.

실제 질문은 다음과 같습니다. 실제 항목 수를 어떻게 알 수 있나요?~ 할 것이다8192kB 제한을 초과합니까? 즉, 이러한 *.jpg유형의 glob이 Argument list too long오류를 발생시키려면 어떤 계산을 수행해야 합니까?

중복이 아니니 참고해주세요단일 명령 인수의 최대 크기를 정의하는 것. 나는 그것을 이해 getconf ARG_MAX하고 ulimit -s소중히 여깁니다. 그것은 내 문제가 아닙니다. 난 방법을 알아야 해크기가 제한을 초과하는 충분한 매개변수를 생성합니다.. 즉, 오류를 피하는 것이 아니라 오류를 얻는 방법을 찾아야 합니다.

답변1

getconf ARG_MAX긴 목록 생성을 사용 x하고 이를 인수로 사용하여 외부 유틸리티를 호출하면 "매개변수 목록이 너무 김" 오류가 생성됩니다.

$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long

오류가 발생하는 원인에는 환경과 문자열 길이가 /bin/echo포함되므로 다음을 빼서 가능한 가장 큰 숫자를 찾을 수 있습니다.

$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin

(이 쉘을 로 시작했기 때문에 env -i sh환경에는 변수만 있습니다)PATH

$ /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long

아직 너무 깁니다. 얼마나?

i=0
while ! /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
    i=$(( i + 1 ))
done

루프는 for 를 종료합니다 i=8.

그래서 즉시 해석할 수 없는 4바이트가 있습니다(8바이트 중 4바이트는이름환경 PATH변수). 이는 4개의 문자열, PATH값 및 긴 문자열의 null 종결자입니다.PATH/bin/echox

알아채다매개변수는 null로 끝나므로 명령에 매개변수가 많을수록 결합된 길이는 짧아집니다.


또한 일반 환경의 효과를 보여주기 위해 다음을 수행합니다.

$ export BIG=$( perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )

$ /bin/echo hello
sh: /bin/echo: Argument list too long

$ /bin/echo
sh: /bin/echo: Argument list too long

답변2

많은 Linux 배포판에서 다음 명령을 실행하여 ARG_MAX의 현재 값을 확인할 수 있습니다.

getconf ARG_MAX

"매개변수 목록이 너무 깁니다"라는 메시지를 생성하는 쉬운 방법은 예를 들어 내 시스템에서 실제로 긴 매개변수 목록을 제공하는 것입니다.

/bin/echo "$(find / -xdev 2> /dev/null)"

유효하지만

/bin/echo "$(find / -xdev 2> /dev/null)" "$(find / -xdev 2> /dev/null)"

생산하다

bash: /bin/echo: Argument list too long

자세한 논의는 "rm, cp, mv 명령 매개변수 목록이 너무 깁니다. 오류" 스택 오버플로에 있습니다.

PS 문제의 길이는 매개변수와 환경을 저장하는 데 필요한 실제 메모리 양입니다. 그것은 아무 관련이 없습니다숫자논쟁.

답변3

새 셸을 더 쉽게 시작하고( exit완료된 후) 제한을 더 낮은 값(100KB)으로 설정하려면 다음을 수행하세요.

$ bash
$ ulimit -s 100

사용한 예에서는 오류가 발생할 수 있습니다.

$ touch {1..100000}.jpg
bash: /usr/bin/touch: Argument list too long

하지만 이와 같은 것을 사용하는 것이 더 좋습니다 echo. 내장 명령이 오류를 유발하지 않을 수 있다는 점을 이해하면 다음 명령이 제대로 작동합니다.

$ echo {000001..100000}6789

또한 바이트 수가 위에 설정된 제한(1.1Mbyte)을 훨씬 초과합니다.

$ echo {000001..100000}6789 | wc -c
1100000

하지만 이 명령은 작동하지 않습니다.

$ /bin/echo {000001..100000}6789
bash: /bin/echo: Argument list too long

제한은 쉘 환경 크기에 추가된 매개변수 목록의 크기(바이트)로 설정됩니다.

답변4

이 명령은 시스템의 모든 파일을 나열하지 않으므로 시간이 오래 걸리고 스파스 시스템에서는 작동하지 않습니다.

/bin/echo {1..200000}

오류를 생성하는 더 빠른(163ms) 방법입니다. 제 경우에는 (2,097,152, 약 200만개) ARG_MAX인데 2097152명령이 여전히 잘못되었습니다.

쉘에 가 없으면 {start..end}약간 느린 것을 사용할 수 있습니다(그러나 파일 나열보다 여전히 빠릅니다).

/bin/echo $(seq 1 200000)

두 명령 중 하나가 작동하지 않으면 작동할 때까지, bash메모리가 부족할 때까지 또는 seq계산할 수 없을 때까지 최종 값을 늘리십시오.

관련 정보