ls에 대한 매개변수 목록이 너무 깁니다.

ls에 대한 매개변수 목록이 너무 깁니다.

ls *.txt | wc -l많은 파일이 포함된 디렉터리에 액세스하려고 하면 다음 오류가 발생합니다.

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

이 "매개변수 목록"의 임계값은 시스템의 배포 또는 사양에 따라 달라지나요? 일반적으로 이렇게 큰 결과를 다른 명령(예:)으로 파이프하므로 wc -l터미널의 제한 사항은 신경 쓰지 않습니다.

답변1

오류 메시지매개변수 목록이 너무 깁니다.~에서*ls *.txt.

이 제한은 바이너리와 커널 모두에 안전합니다. 바라보다ARG_MAX, 새 프로세스의 최대 매개변수 길이이에 대한 자세한 정보와 사용 및 계산 방법.

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

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

ls참고: 최신 Linux에서는 파일 이름의 이상한 문자(예: 개행 문자)가 또는 같은 도구를 사용하여 이스케이프되지만 find여전히 나타납니다.*. 이전 Unix를 사용하는 경우 이 명령이 필요합니다.

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

NB2: 이름에 개행 문자가 포함된 파일을 만드는 방법을 알고 싶습니다. 요령을 알고 나면 어렵지 않습니다.

touch "hello
world"

답변2

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

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

getconf ARG_MAX

이는 쉘에 의한 확장 후 명령줄이 가질 수 있는 최대 바이트 수를 알려줍니다.

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

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

보다execve(2) 매뉴얼 페이지모든 세부정보를 확인하세요.


불행하게도 파이핑은 ls *.txt문제를 해결하지 못합니다. 왜냐하면 그 한계는 셸이 아니라 운영 체제에 있기 때문입니다.

쉘이 확장된 *.txt후 호출을 시도합니다.

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

그리고 일치하는 파일이 너무 많아서 *.txt128KB 제한을 초과했습니다.

당신은 다음과 같은 일을해야합니다

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

대신에.

(개행 문자가 포함된 파일 이름에 대해서는 아래 Shawn J. Goff의 설명을 참조하세요.)

답변3

또 다른 해결 방법:

ls | grep -c '\.txt$'

ls생산하는 것 보다 더 많은 출력을 생산 하더라도 ls *.txt(또는 생산하려고 시도하는 경우) 통과하지 못했기 때문에 "인수가 너무 길다"는 문제가 발생하지 않습니다.어느인수 ls. grep파일 일치 패턴이 아닌 정규식을 사용한다는 점에 유의하세요 .

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

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

(귀하의 버전이 ls이 옵션을 지원한다고 가정). 이는 ls출력을 정렬하지 않도록 지시하므로 시간과 메모리가 절약됩니다. 이 경우 파일 수를 세는 것이므로 순서는 중요하지 않습니다. 일반적으로 출력을 정렬하는 데 소요되는 리소스는 중요하지 않지만 이 경우에는 이미 많은 수의 *.txt파일이 있다는 것을 알고 있습니다.

그리고 단일 디렉터리에 너무 많은 파일이 포함되지 않도록 파일을 재구성하는 것을 고려해야 합니다. 이는 실현 가능하거나 불가능할 수 있습니다.

답변4

MAX_ARG_PAGES는 커널 매개변수인 것 같습니다. findand 를 사용하는 것은 xargs이 제한 사항을 해결하기 위한 일반적인 조합이지만 에서 작동하는지 확실하지 않습니다 wc.

출력을 find . -name \*\.txt파일로 파이프하고 해당 파일의 줄 수를 계산하면 문제를 해결할 수 있습니다.

관련 정보