2017-11-22 4 views
4

argument list too long 주제와 관련된 몇 가지 관련 커뮤니티뿐만 아니라 StackOverflow에서 많은 posts을 탐색했으며 길이 제한이 쉘 내장 함수에 적용되는지 여부를 명확하게 파악하지 못했습니다.셸 내장 함수에 "인수 목록이 너무 길다"제한이 적용됩니까?

string="a very long list of words ..." 

내가 말할 수 :

# not using double quotes around $string is deliberate 
printf '%s\n' $string | cmd ... 

또는

cmd <<< $string 

심지어 파이프

의 내가 표준 입력을 통해 명령에 매우 긴 문자열을 전달하고 싶은 말은하자 그것을 xargs :

printf '%s\n' $string | xargs cmd ... 

누군가가이를 명확히 할 수 있습니까?

답변

8

bash에서 오류가 발생하는 명령 줄 길이에 대한 OS 적용 제한은이 쉘 내장 명령에 적용되지 않습니다.

이 오류는 execve() 시스템 호출이 오류 코드 E2BIG을 리턴 할 때 트리거됩니다. 내장을 호출 할 때 execve() 호출이 포함되어 있지 않으므로 오류가 발생할 수 없습니다.

따라서 제안 된 작업은 모두 안전합니다. 은 임시 파일에 $string을 작성합니다.이 파일은 argv 요소 (또는 동일한 예약 공간 풀에 저장된 환경 변수)로 전달 될 필요가 없습니다); 외장 printf 구현을 사용하려면 enable -n printf처럼 쉘의 구성을 수정하지 않으면 printf '%s\n' "$cmd"이 쉘 내부에서 실행됩니다.

3

길이 제한이 쉘 내장 명령에 적용되는지 여부는 알 수 없습니다.

아마 그렇지는 않지만 특정 버전의 소스 코드 (무료 소프트웨어이기 때문에)를 확인해야합니다. 그러나 분명히 어떤 경우에는 더 큰 제한이 있습니다. 특히 내부에서 수행 된 일부 malloc이 실패 할 수 있기 때문입니다. 그러나 다른 오류 메시지 나 동작이 발생합니다.

AFAIK는 인수 목록이 너무 긴 오류가 E2BIG에 실패 execve(2)에 의해 주어지며, 배쉬의 내장 기능 (외부 프로그램이 할 호출 명령 등) execve하지 fork 다음을 수행합니다.

실제적으로 E2BIG은 수십만 바이트로 나타날 수 있지만 정확한 제한은 커널과 시스템에 달려 있습니다.하지만 내장 데스크톱은 수십 메가 바이트 (오늘의 데스크톱)에서 사용될 수 있습니다. 하지만 YMMV (이후 ...)를 수행하기 위해 ulimit을 사용할 수 있기 때문에. 셸 내장 데이터를 통해 기가 바이트의 데이터를 처리하는 것을 권장하지 않습니다.

BTW, xargs(1)이 유용 할 수 있으며 커널을 다시 컴파일하여 (최근 커널에서 다른 방법으로도) 한도를 높일 수도 있습니다 (E2BIG). 몇 년 전 커널을 다시 컴파일해야한다는 강력한 동기였습니다.

+1

모든 것은 사실입니다. 그러나 malloc이 실패한 경우 (f/e), 이는 '인수 목록이 너무 길다'이외의 오류입니다. –

+0

물론. 내가 너를 그렇게 생각하게하는 어떤 것을 썼는가? –

+1

이 질문은 명시 적으로 "인수 목록이 너무 길다"라는 질문을하기 때문에 문맥에서 가져 왔습니다. –

관련 문제