ls에 대한 인수 목록이 너무 깁니다. long 이 “인수 목록”의 임계 값은

ls *.txt | wc -l많은 파일이 포함 된 디렉토리를 시도 할 때 다음 오류가 발생 합니다.

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

이 “인수 목록”의 임계 값은 배포 또는 컴퓨터 사양에 따라 달라 집니까? 일반적으로 큰 결과의 결과를 다른 명령 ( wc -l예 :)으로 파이프 하므로 터미널의 한계에 관심이 없습니다.



답변

귀하의 오류 메시지 인수 목록이 너무 오래 로부터 오는 *ls *.txt.

이 제한은 바이너리 프로그램과 커널 모두에 안전합니다. 당신은에서 볼 수있는 페이지 가 사용 계산 어떻게 그것에 대한 자세한 내용은합니다.

파이프 크기에는 이러한 제한이 없습니다. 따라서이 명령을 간단히 실행할 수 있습니다.

find -type f -name '*.txt'  | wc -l

주의 : 현대 리눅스에서 (줄 바꿈 등) 파일 이름에 이상한 문자가 같은 도구로 이스케이프됩니다 ls또는 find,하지만 여전히에서 표시 * . 오래된 유닉스에 있다면이 명령이 필요합니다

find -type f -name '*.txt' -exec echo \;  | wc -l

NB2 : 이름에 줄 바꿈이있는 파일을 만드는 방법이 궁금합니다. 트릭을 알고 나면 그렇게 어렵지 않습니다.

touch "hello
world"


답변

주로 Linux 커널 버전에 따라 다릅니다.

다음을 실행하여 시스템의 한계를 볼 수 있어야합니다

getconf ARG_MAX

이것은 쉘에 의해 확장 된 후 명령 행이 가질 수있는 최대 바이트 수를 알려줍니다.

Linux <2.6.23에서 한계는 일반적으로 128KB입니다.

Linux> = 2.6.25에서 제한은 128KB 또는 스택 크기의 1/4 (참조 ulimit -s) 중 더 큰 값입니다.

자세한 내용은 execve (2) 매뉴얼 페이지참조 하십시오.


불행히도, 배관 ls *.txt이 문제를 해결하지 못할 것입니다. 한계는 쉘이 아닌 운영 체제에 있기 때문입니다.

셸이을 확장 한 *.txt다음

exec("ls", "a.txt", "b.txt", ...)

일치 *.txt하는 파일이 너무 많아 128KB 제한을 초과합니다.

당신은 뭔가를해야합니다

find . -maxdepth 1 -name "*.txt" | wc -l

대신에.

(그리고 개행을 포함하는 파일 이름에 대한 아래의 Shawn J. Goff의 의견을 참조하십시오.)


답변

다른 해결 방법 :

ls | grep -c '\.txt$'

생성 (또는 생성 시도) ls보다 더 많은 출력을 생성 하더라도 ls *.txt“인수가 너무 오래”문제가 발생하지 않습니다 . 인수를 전달 하지 않기 때문 ls입니다. 참고 grep파일 일치 패턴보다는 정규 표현식을합니다.

다음을 사용할 수 있습니다.

ls -U | grep -c '\.txt$'

(버전 ls이이 옵션 을 지원 한다고 가정 ). 이렇게 ls하면 출력을 정렬하지 않아도되므로 시간과 메모리를 모두 절약 할 수 있습니다.이 경우 파일을 계산하기 때문에 순서가 중요하지 않습니다. 출력 정렬에 소비 된 리소스는 일반적으로 중요하지 않지만이 경우 이미 많은 *.txt파일 이 있다는 것을 알고 있습니다 .

그리고 단일 디렉토리에 너무 많은 파일이 없도록 파일을 재구성하는 것을 고려해야합니다. 이것은 가능할 수도 있고 아닐 수도 있습니다.


답변

MAX_ARG_PAGES는 커널 매개 변수 인 것으로 보입니다. findand를 사용하면 xargs이 한도를 해결하기위한 일반적인 조합이지만 작동하지 않을 것입니다 wc.

find . -name \*\.txt파일 의 출력을 파이핑하고 해당 파일의 행을 계산하면 해결 방법으로 사용됩니다.


답변

이것은 더러울 수 있지만 내 요구와 역량 내에서 작동합니다. 나는 그것이 매우 빨리 수행한다고 생각하지 않지만 그것은 내 하루를 시작할 수있게했습니다.

ls | grep jpg | <something>

90,000 개의 긴 jpg 목록을 가져 와서 avconv로 파이핑하여 timelapse를 생성했습니다.

이전에 ls * .jpg를 사용했습니다. | 이 문제가 발생하기 전에 avconv.


답변