
이와 같은 명령을 실행하면 ls */*/*/*/*.jpg
오류가 발생합니다.
-bash: /bin/ls: Argument list too long
나는 왜 이런 일이 일어나는지 알고 있습니다. 명령 인수를 위한 공간 크기에 커널 제한이 있기 때문입니다. 표준 조언은 너무 많은 인수 공간이 필요하지 않도록 사용하는 명령을 변경하는 것입니다(예: use find
및 xargs
).
명령을 변경하고 싶지 않으면 어떻게 하나요? 동일한 명령을 계속 사용하려면 어떻게 해야 합니까? 이 오류가 발생하지 않고 "제대로 작동"하도록 하려면 어떻게 해야 합니까? 어떤 솔루션을 사용할 수 있나요?
답변1
Linux에서 명령 매개변수의 최대 공간은 사용 가능한 스택 공간의 1/4입니다. 따라서 해결책은 스택의 여유 공간을 늘리는 것입니다.
짧은 버전: 다음과 같은 것을 실행합니다.
ulimit -s 65536
더 긴 버전: 스택의 기본 여유 공간은 약 8192KB입니다. 다음과 같이 여유 공간을 확인할 수 있습니다.
$ ulimit -s
8192
더 큰 숫자를 선택하고 스택의 여유 공간을 설정하십시오. 예를 들어 스택을 최대 65536KB까지 허용하려면 다음 명령을 실행합니다.
$ ulimit -s 65536
필요한 크기를 결정하려면 시행착오를 거쳐야 할 수도 있습니다. 대부분의 경우 이는 명령 및 계산 구문 등을 수정할 필요가 없는 빠르고 더러운 솔루션입니다. find
( xargs
이렇게 하면 다른 이점이 있다는 것을 알고 있지만)
나는 이것이 Linux에만 국한된 것이라고 생각합니다. 다른 Unix 운영 체제(테스트되지 않음)에서는 도움이 되지 않을 수도 있습니다.
답변2
대신 ls */*/*/*/*.jpg
다음을 시도해 보세요.
echo */*/*/*/*.jpg | xargs ls
xargs
(1) 시스템에 있는 최대 인수 수를 파악하면 표준 입력이 폭발하여 해당 제한을 초과하지 않는 인수로 지정된 명령줄을 여러 번 호출합니다(최대값보다 낮게 설정할 수도 있음). 이 옵션을 사용하는 운영 체제 -n
).
예를 들어 매개변수 제한이 3개이고 파일이 5개 있다고 가정합니다. 이 경우 두 번 xargs
실행됩니다 ls
.
ls 1.jpg 2.jpg 3.jpg
ls 4.jpg 5.jpg
종종 이것은 완벽하게 적절하지만 항상 그런 것은 아닙니다. 예를 들어 ls
(1) 에 의존할 수는 없습니다.종류각 개별 ls
호출은 지정된 항목 하위 집합만 정렬하므로 모든 항목을 올바르게 정렬합니다 xargs
.
다른 사람들이 제안한 대로 제한을 늘릴 수 있지만 제한은 여전히 존재합니다. 언젠가는 JPG 컬렉션이 다시 한도를 초과하게 됩니다. 무제한으로 처리할 수 있는 스크립트를 준비해야 합니다.
답변3
이것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로 높여 모든 문제를 성공적으로 해결했습니다. 광범위한 테스트를 거친 후 전환 이후에는 아무런 문제가 발생하지 않았습니다. 이는 64로 설정 하더라도
MAX_ARG_PAGES
생성할 수 있는 가장 긴 명령줄이 256KB의 시스템 메모리만 차지하므로 이는 전적으로 예상된 일입니다. 이는 오늘날의 시스템 하드웨어 표준에 비해 그리 많지 않은 수치입니다.접근 방식 #4의 장점은 분명합니다. 이제 정상적으로 명령을 실행하면 성공적으로 완료됩니다. 단점도 똑같이 분명합니다. 사용 가능한 시스템 메모리 양 이상으로 명령줄에서 사용할 수 있는 메모리 양을 늘리면 시스템에 DOS 공격이 시작되어 시스템이 충돌할 수 있습니다. 특히 다중 사용자 시스템에서는 각 사용자에게 추가 메모리가 할당되기 때문에 작은 증가라도 상당한 영향을 미칠 수 있습니다. 따라서 항상 자신의 환경에서 광범위한 테스트를 수행하십시오. 이것이 방법 #4가 귀하에게 적합한지 여부를 결정하는 가장 안전한 방법입니다.
나는 이 제한이 매우 짜증난다는 데 동의합니다.
답변4
풀 공간 제한에 도달하면 Bash 시스템 호출과 직접적인 변형(인수 및 환경 변수)은 "인수 목록이 너무 깁니다"를 생성합니다.
내가 찾은이 제한을 피하는 방법, 처리특수 문자파일 이름(예: 공백)에 다음을 사용합니다.인쇄 기능그리고매개변수:
printf '%s\0' */*/*/*/*.jpg | xargs -0 ls