유틸리티 매개변수 목록 /usr/bin/printf
길이는 쉘의 최대 명령줄 길이(즉 getconf ARG_MAX
, 내 시스템에서는2097152);예:
# try using a list that's way too long
/usr/bin/printf '%s\n' $(seq $(( $(getconf ARG_MAX) * 2 ))) | tail -1
산출:
bash: /usr/bin/printf: Argument list too long
오늘나는 들었다그 껍질내장 printf
s에는 이러한 제한이 없습니다.
printf '%s\n' $(seq $(( $(getconf ARG_MAX) * 2 ))) | tail -1
산출:
4194304
질문:
스키밍은
man bash dash
이러한 이점을 별로 밝혀주지 않는 것 같습니다.내장printf
. 어디예문서화되어 있습니까?하다내장
printf
에스(예를 들어bash
)에는 최대 매개변수 목록 길이(문자)가 있습니다. 그렇다면 그 길이는 얼마입니까?
답변1
특정 유틸리티의 사용을 옹호하는 것은 실제로 매뉴얼의 책임이 아닙니다. 주로 해야한다설명하다내장 유틸리티를 사용할 수 있습니다.
외부 유틸리티에 비해 내장 유틸리티를 사용하는 것의 장점은 주로 속도와 확장 기능의 가용성입니다( printf
예를 들어 bash
변수를 직접 작성할 수 있지만 -v varname
외부 프로그램 printf
으로는 절대 작성할 수 없음 ).
외부 유틸리티 실행은 내장 유틸리티 실행에 비해 느립니다. 특히 루프에서 자주 실행되는 경우에는 더욱 그렇습니다. 또한 알다시피 더 긴 인수 목록도 허용합니다(이는 내장 유틸리티만 printf
허용하는 것이 아닙니다). 그러나 모든 내장 유틸리티는 ).
내장 printf
유틸리티 의 매개변수 목록 길이는 프로세스 자체의 bash
리소스 제한에 의해 제한 됩니다 bash
. 일부 시스템에서는 사용 가능한 RAM의 대부분을 사용하여 명령줄 인수 목록을 작성할 수 있음을 의미할 수도 있습니다.
이런 다양한 정보를 확인할 수 있는 문서는
- 소스
bash
코드, 매개변수 목록이 표시됩니다.printf
동적으로 할당된 연결리스트이며,아니요사용execve()
실행printf
(외부 유틸리티를 실행할 때 매개변수 목록 길이를 제한하는 이유입니다).
쉘의 printf
예아니요내장 유틸리티는 ksh
OpenBSD 쉘입니다. 유틸리티는 괜찮습니다장애가 있는사용 .bash
enable -n printf
답변2
/usr/bin/printf 유틸리티 매개변수 목록의 길이는 쉘의 최대 명령줄 길이로 제한됩니다(예: getconf ARG_MAX, 내 시스템에서는 2097152).
그건 아니야껍데기이러한 제한은 오히려 운영 체제(Linux 커널), 특히 해당 execve(2)
시스템 호출의 제한이며 명령줄 인수와 환경 변수를 시작 프로그램에 전달하는 오래된 방식으로 인해 발생합니다.
(이 제한에는 환경 변수도 포함됩니다!)
Skimming man bash dash는 내장 printf의 이점에 대해 많이 말하지 않는 것 같습니다. 어디에 기록되어 있나요? bash와 같은 printfs 내장 기능에 매개변수 목록 길이가 있습니까? 그렇다면 그 길이는 무엇입니까?
쉘 내장 기능은 통과되지 않으므로 execve(2)
그러한 제한이 필요하지 않습니다. 최신 쉘은 일반적으로 고정 크기 버퍼 등을 사용하지 않으므로 일반적으로 사용 가능한 메모리 양과 가상 주소 공간의 레이아웃에 따라 제한이 부과됩니다. 즉 모든 의도와 목적에 무제한입니다.
답변3
POSIX 표준에서는 셸 구현에 줄 제한이 없어야 합니다.
따라서 이것은 쉘에 의해 문서화되지 않은 자연스러운 현상입니다.
참고: 텍스트 파일은 LINE_MAX 줄 이하의 파일이므로 쉘 스크립트는 텍스트 파일이 아닐 수도 있습니다 ;-)