"매개변수 목록이 너무 깁니다": 명령을 변경하지 않고 이를 처리하는 방법은 무엇입니까?

"매개변수 목록이 너무 깁니다": 명령을 변경하지 않고 이를 처리하는 방법은 무엇입니까?

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

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

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

명령을 변경하고 싶지 않으면 어떻게 하나요? 동일한 명령을 계속 사용하려면 어떻게 해야 합니까? 이 오류가 발생하지 않고 "제대로 작동"하도록 하려면 어떻게 해야 합니까? 어떤 솔루션을 사용할 수 있나요?

답변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.

  1. ls 1.jpg 2.jpg 3.jpg
  2. 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

관련 정보