명령줄 길이 제한: 기본 제공 및 실행 가능

명령줄 길이 제한: 기본 제공 및 실행 가능

그래서 따르면POSIX 사양우리는 다음과 같은 정의를 가지고 있습니다 *:

1부터 시작하여 위치 매개변수로 확장되며 처음에는 각 위치 매개변수 세트에 대한 필드를 생성합니다. 필드 분할이 수행되는 컨텍스트에서 확장이 발생하는 경우 빈 필드는 삭제될 수 있으며 비어 있지 않은 각 필드는 필드 분할에 설명된 대로 추가로 분할되어야 합니다. 필드 분할을 수행하지 않는 컨텍스트에서 확장이 발생하는 경우 IFS에 하나 이상의 문자가 포함되어 있으면 초기 필드를 연결하여 단일 필드를 형성해야 하며 각 인수의 값은 IFS 변수의 첫 번째 문자로 구분됩니다. IFS가 설정되지 않은 경우 a로 구분됩니다. IFS가 빈 문자열로 설정된 경우 구분 기호가 사용되지 않습니다.

우리 대부분은 다음과 같은 잘 알려진 ARG_MAX제한 사항을 알고 있습니다.

$ getconf ARG_MAX
2621440

이로 인해 다음이 발생할 수 있습니다.

$ cat * | sort -u > /tmp/bla.txt
-bash: /bin/cat: Argument list too long

고맙게도 그 뒤에 있는 좋은 사람들 ([POSIX와 같은 다른 모든 사람들 포함])이 우리에게 내장된 기능을 bash제공하여 간단히 다음을 수행할 수 있습니다.printf

printf '%s\0' * | sort -u --files0-from=- > /tmp/bla.txt

모든 것이 사용자에게 투명합니다.

명령을 ARG_MAX사용하여 제한 사항을 우회하는 것이 왜 그렇게 쉬운지, 독립 실행형 실행 파일의 특수 매개 변수를 우아하게 처리하는 일관된 POSIX 셸 해석기를 제공하는 것이 왜 그렇게 어려운지 누군가 말해 줄 수 있습니까 ?built-in*

$ cat *

그게 문제가 될까요? 사람들에게 내장 명령을 bash제공하라고 요청하는 것이 아닙니다 . 작업 순서 와 명령이 내장 명령인지 독립 실행형 실행 파일인지에 따라 크기 조정이 다르게 동작하는 이유에만 관심이 있습니다.cat*

답변1

제한은 셸에 있는 것이 아니라 exec()기능 계열에 있습니다.

POSIX 표준이와 관련된 발언:

새 프로세스의 결합된 인수와 환경 목록에 사용할 수 있는 바이트 수는 입니다 {ARG_MAX}. 널 종결자, 포인터 및/또는 정렬 바이트가 이 합계에 포함되는지 여부는 구현에 따라 정의됩니다.

셸에 내장된 유틸리티를 실행하기 위해 셸을 호출할 필요가 없으므로 exec()이 제한 사항의 영향을 받지 않습니다.

또한 제한되는 것은 명령줄 길이뿐만 아니라 명령 길이, 인수, 현재 환경 변수 및 해당 값의 조합이기도 합니다.

또한printf아니요pdkshsh예를 들어 ( OpenBSD에서 내장 유틸리티 로 작동하는 경우 ) ksh. 이를 내장 기능으로 사용하려면 사용되는 특정 셸을 고려해야 합니다.

답변2

선행은 이루기가 어렵다~의답변ARG_MAX쉘 내장에 문제가 없는 이유를 설명합니다 .

cat *영향을 받지 않는 방식으로 구현한다는 점에서 그렇게 ARG_MAX하는 것은 간단합니다. cat구현에서 해야 할 일은 모두 다음과 같습니다.glob(3)자체 와일드카드를 구현하려면 쉘이 자체 와일드카드를 실행하지 않도록 이를 사용 cat \*하거나 실행할 수 있습니다. cat '*'Linux 또는 Unix 스타일 시스템에는 자체적으로 와일드카드를 처리할 수 있는 몇 가지 명령이 있습니다. 적어도 어떤 경우에는 기본 DOS 버전의 많은 명령에 적어도 와일드카드를 처리하는 코드가 포함되어 있습니다. 외부 명령에 대한 와일드카드 find인수 가 아닙니다 tar.zip

POSIX 셸에 대한 기대를 고려하면 이 기능은 상당히 놀랍고 발견하기 어려울 것입니다! 이전 버전의 Unix에서는 와일드카드가 별도의 프로그램에서 사용되었습니다 /etc/glob.

관련 정보