그래서 따르면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
아니요pdksh
sh
예를 들어 ( OpenBSD에서 내장 유틸리티 로 작동하는 경우 ) ksh
. 이를 내장 기능으로 사용하려면 사용되는 특정 셸을 고려해야 합니다.
답변2
선행은 이루기가 어렵다~의답변ARG_MAX
쉘 내장에 문제가 없는 이유를 설명합니다 .
cat *
영향을 받지 않는 방식으로 구현한다는 점에서 그렇게 ARG_MAX
하는 것은 간단합니다. cat
구현에서 해야 할 일은 모두 다음과 같습니다.glob(3)
자체 와일드카드를 구현하려면 쉘이 자체 와일드카드를 실행하지 않도록 이를 사용 cat \*
하거나 실행할 수 있습니다. cat '*'
Linux 또는 Unix 스타일 시스템에는 자체적으로 와일드카드를 처리할 수 있는 몇 가지 명령이 있습니다. 적어도 어떤 경우에는 기본 DOS 버전의 많은 명령에 적어도 와일드카드를 처리하는 코드가 포함되어 있습니다. 외부 명령에 대한 와일드카드 find
인수 가 아닙니다 tar
.zip
POSIX 셸에 대한 기대를 고려하면 이 기능은 상당히 놀랍고 발견하기 어려울 것입니다! 이전 버전의 Unix에서는 와일드카드가 별도의 프로그램에서 사용되었습니다 /etc/glob
.