“ 인수 목록이 너무 깁니다. ” : 명령을 변경하지 않고 어떻게 처리합니까?

ls */*/*/*/*.jpg와 같은 명령을 실행할 때 오류가 발생합니다.

-bash: /bin/ls: Argument list too long 

이런 일이 발생하는 이유를 알고 있습니다. 이는 명령에 대한 인수 공간의 양에 커널 제한이 있기 때문입니다. 표준 조언은 인수에 너무 많은 공간이 필요하지 않도록 사용하는 명령을 변경하는 것입니다 (예 : findxargs 사용).

명령을 변경하지 않으려면 어떻게합니까? 동일한 명령을 계속 사용하려면 어떻게해야합니까?이 오류가 발생하지 않고 “그냥 작동”하도록하려면 어떻게해야합니까? 어떤 솔루션을 사용할 수 있습니까?

댓글

  • 유용한 자료 : 배쉬 FAQ 95 . 명령을 변경하지 않고 ' 인수 목록의 최대 크기를 늘리기 위해 재 컴파일하는 것 외에는 할 수있는 일이별로 없습니다. 또는 파일 수가 더 적도록 디렉토리 구조를 변경하십시오.
  • @ jw013 Linux 커널 버전에 따라 인수 목록을 늘릴 수 있습니다. 변경 사항에 대한 자세한 내용은 unix.stackexchange.com/a/45161/8979 를 참조하세요. 최근 시스템.
  • @UlrichDangel, 예, 가능합니다! 내 답변을 참조하세요. 내 답변은이를 수행하는 방법을 보여줍니다 (L inux, 최신 커널).

Answer

Linux에서 명령을위한 최대 공간 인수는 사용 가능한 스택 공간 양의 1/4입니다. 따라서 해결책은 스택에 사용할 수있는 공간을 늘리는 것입니다.

짧은 버전 : 다음과 같은 실행

ulimit -s 65536 

긴 버전 : 스택에 사용할 수있는 기본 공간은 8192KB입니다. 다음과 같이 사용 가능한 공간을 확인할 수 있습니다.

$ ulimit -s 8192 

더 큰 숫자를 선택하고 스택에 사용할 수있는 공간을 설정합니다. 예를 들어 스택에 최대 65536KB를 허용하려면 다음을 실행하십시오.

$ ulimit -s 65536 

필요한 크기를 조정해야 할 수 있습니다. 시행 착오를 사용합니다. 대부분의 경우 이것은 명령을 수정하고 find, xargs 등 (그렇게하면 다른 이점이 있다는 것을 알고 있습니다).

저는 이것이 Linux 전용이라고 생각합니다. 다른 Unix 운영 체제 (테스트되지 않음)에서는 도움이되지 않을 것 같습니다.

설명

  • 이렇게 작동하는지 확인할 수 있습니다. : $ getconf ARG_MAX 2097152 $ ulimit -s 65535 $ getconf ARG_MAX 16776960
  • ulimit -s unlimited로 스택 크기를 무제한으로 만들면 명령 줄 크기가 무제한?

답변

ls */*/*/*/*.jpg 대신 시도 :

echo */*/*/*/*.jpg | xargs ls 

xargs (1)은 시스템에있는 최대 인수 수를 알고 있습니다. 그 제한보다 더 많은 인수를 사용하지 않고 지정된 명령 줄을 여러 번 호출하도록 표준 입력을 분할합니다 (-n 옵션).

예를 들어 제한이 3 개의 인수이고 5 개의 파일이 있다고 가정합니다. 이 경우 xargsls를 두 번 실행합니다.

  1. ls 1.jpg 2.jpg 3.jpg
  2. ls 4.jpg 5.jpg

종종 이것은 완벽하게 적합하지만 항상 그런 것은 아닙니다. ls (1) 모든 항목을 적절하게 정렬 하십시오. 각각의 개별 ls 호출이 있기 때문입니다. xargs에 의해 주어진 항목의 하위 집합 만 정렬합니다.

다른 사람이 제안한대로 제한을 늘릴 수 있지만 여전히 제한이 있습니다. 언젠가는 JPG 컬렉션이 다시 늘어날 것입니다. 무한한 수를 처리하려면 스크립트를 준비해야합니다 …

댓글

  • 아이디어에 감사드립니다! 이것은 나쁜 해결 방법이 아닙니다. 두 가지주의 사항 : 1. 이름에 공백이있는 디렉토리 및 파일 이름이 중단되므로 ' 완벽한 대체물이 아닙니다. 2. Argument list too long에서 동일한 문제가 발생하지만 ls<대신 echo에서 발생합니까? / div>, echo가 쉘 내장 명령이 아닌 쉘에서? (대부분의 셸에서 ' 문제가되지 않을 수 있으므로 '는 관련이 없습니다.)
  • 예 , 파일 이름의 특수 문자가 문제입니다. 가장 좋은 방법은 -print0 조건 자와 함께 find를 사용하고 출력을 xargs-0 옵션이있는 div>.echo는 셸이 내장되어 있으며 exec (3)의 명령 줄 제한이 없습니다.
  • ls와 같이 마지막 매개 변수로 변수 인수를 예상하는 명령과 함께 작동하지만 mv 여러 파일을 단일 디렉토리에 저장합니다. mv * destdir? *에 " 너무 많은 인수 " 오류가 발생하면 ' xargs에서 경로를 처음으로 mv에 전달하지 마십시오. 아니면 제가 할 수 있습니까?
  • 시스템에서 xargs에 대한 맨 페이지를 확인하십시오. 예를 들어 FreeBSD에서는 -J가 도움이 될 것입니다. 이 작업에 당신. OS에서이 작업을 수행 할 방법이없는 경우 ' 인수를 재정렬하기 위해 사용자 지정 스크립트를 작성해야합니다. 예 : destdir=$1; shift; mv "$@" "$destdir". 그런 다음이 새 스크립트를 xargs에 제공합니다. .... | xargs newscript $destdir

Answer

Linux 저널 기사 는 4 가지 솔루션을 제공합니다. 네 번째 솔루션 만 명령을 변경하지 않습니다.

방법 # 4는 명령 줄을 위해 커널 내에 할당 된 페이지 수를 수동으로 늘리는 것입니다. 인수. include / linux / binfmts.h 파일을 보면 상단 근처에 다음이 있습니다.

/* * MAX_ARG_PAGES defines the number of pages allocated for arguments * and envelope for the new program. 32 should suffice, this gives * a maximum env+arg of 128kB w/4KB pages! */ #define MAX_ARG_PAGES 32 

메모리 양을 늘리기 위해 명령 줄 인수 전용 인 경우 MAX_ARG_PAGES 값을 더 높은 숫자로 제공하면됩니다. 이 편집 내용이 저장되면 평상시처럼 새 커널로 재 컴파일, 설치 및 재부팅하십시오.

내 테스트 시스템에서이 값을 64로 올려 모든 문제를 해결할 수있었습니다. 테스트, 전환 이후 단일 문제가 발생하지 않았습니다. MAX_ARG_PAGES를 64로 설정해도 내가 생성 할 수있는 가장 긴 명령 줄은 256KB의 시스템 메모리만을 차지할 것이기 때문에 이는 전적으로 예상됩니다. 오늘날의 시스템 하드웨어 표준으로는 그리 많지 않습니다. .

방법 # 4의 장점은 분명합니다. 이제 평소처럼 명령을 간단히 실행할 수 있으며 성공적으로 완료됩니다. 단점도 똑같이 분명합니다. 사용 가능한 메모리 양을 늘리면 사용 가능한 시스템 메모리의 양을 넘어서 명령 줄에 연결하면 자신의 시스템에 DOS 공격을 생성하여 충돌을 일으킬 수 있습니다. 특히 다중 사용자 시스템에서는 모든 사용자에게 할당되기 때문에 약간의 증가만으로도 상당한 영향을 미칠 수 있습니다. 추가 메모리. 따라서 항상 자신의 환경에서 광범위하게 테스트하십시오. 이것이 방법 # 4가 실행 가능한 옵션인지 판단하는 가장 안전한 방법이기 때문입니다.

제한이 심각하게 성가시다는 데 동의합니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다