Bash 명령 줄 및 입력 제한


90

bash (또는 다른 셸)에 입력 할 수있는 시간에 대해 어떤 종류의 문자 제한이 적용됩니까? 그렇다면 글자 수 제한은 얼마입니까?

즉, 명령 줄을 실행하기에 너무 긴 bash에서 명령을 작성할 수 있습니까? 필수 제한이없는 경우 제안 된 제한이 있습니까?


2
입력 제한은 매우 다르다 OS 레벨 인수 제한 (예컨대 환경 변수로 인수 이외의 것들은, 또한 한 방향으로 적용 참고). 운영 체제에 전달 된 생성 된 명령은이를 생성 한 쉘 명령보다 더 많거나 적은 문자를 가질 수 있습니다.
Charles Duffy 2015

답변:


125

명령 줄 길이에 대한 제한은 셸이 아니라 운영 체제에 의해 부과됩니다. 이 제한은 일반적으로 100KB 범위입니다. POSIX는이 제한을 나타내며 ARG_MAXPOSIX 준수 시스템에서 쿼리 할 수 ​​있습니다.

$ getconf ARG_MAX    # Get argument limit in bytes

예를 들어 Cygwin에서 이것은 32000이고 다른 BSD 및 Linux 시스템에서는 131072에서 2621440까지입니다.

이 제한을 초과하는 파일 목록을 처리해야하는 경우 .을 xargs초과하지 않는 인수 하위 집합으로 프로그램을 반복적으로 호출하는 유틸리티 를 살펴볼 수 있습니다 ARG_MAX.

특정 질문에 대답하려면 예, 인수 목록이 너무 긴 명령을 실행할 수 있습니다. 쉘은 "인수 목록이 너무 깁니다"라는 메시지와 함께 오류를 발생시킵니다.

프로그램에 대한 입력 (stdin 또는 기타 파일 설명자에서 읽음)은 제한 되지 않습니다 (사용 가능한 프로그램 리소스에 의해서만). 따라서 쉘 스크립트가 문자열을 변수로 읽는다면 ARG_MAX. 제한은 쉘 내장에도 적용되지 않습니다.


좋은 대답이지만 설명이 필요합니다. 구성이 cmd <<< "$LONG_VAR"있고 LONG_VAR 값이 제한을 초과하면 명령이 날아갈까요?
Krzysztof Jabłoński 2015

1
@ KrzysztofJabłoński의 내용이 LONG_VARstdin으로 전달되고 전적으로 쉘에서 수행 되기 때문입니다 . 에 대한 인수로 확장되지 않으므로 cmdfork () / exec ()에 대한 ARG_MAX 제한이 작동하지 않습니다. 직접 시도해 보는 것은 쉽습니다. ARG_MAX를 초과하는 내용으로 변수를 만들고 명령을 실행하십시오.
Jens

2
기록에 대한 설명은 다음과 같습니다. 8MB m4a 파일의 경우 blah="$(cat /home/schwager/Music/Recordings/20090420\ 131623.m4a)"; cat <<< $blah >/dev/null. 오류가 없습니다.
Mike S

3
약간의주의 사항. 환경 변수도 중요합니다. sysconf 맨 페이지 > ARG_MAX는 사용자의> 환경 변수가 exec (3)에 대한 인수 공간을 얼마나> 소비하는지 지정되지 않았기 때문에 사용하기 어렵습니다.
Gerrit

3
@ user188737 버그 에서 꽤 큰 경고라고 생각합니다 . 예를 들어 xargsmacOS 10.12.6에서는 1 exec()에 넣는 횟수 를 ARG_MAX - 4096. 따라서 xargs누군가가 환경에 너무 많은 것을 넣을 때까지 사용하는 스크립트 는 작동 할 수 있습니다. 지금이 문제를 해결하십시오 (을 사용하여 해결하십시오 xargs -s ???).
neuralmer

44

좋아, 데니 즌. 그래서 저는 명령 줄 길이 제한을 꽤 오랫동안 복음으로 받아 들였습니다. 그렇다면 가정을 어떻게해야할까요? 당연히 확인하십시오.

제 마음대로 Fedora 22 머신을 가지고 있습니다 (의미 : bash4가있는 Linux). 각각 18 자 길이의 500,000 inode (파일)가있는 디렉토리를 만들었습니다. 명령 줄 길이는 9,500,000 자입니다. 이렇게 생성됨 :

seq 1 500000 | while read digit; do
    touch $(printf "abigfilename%06d\n" $digit);
done

그리고 우리는

$ getconf ARG_MAX
2097152

그러나 나는 이것을 할 수 있습니다.

$ echo * > /dev/null

그러나 이것은 실패합니다.

$ /bin/echo * > /dev/null
bash: /bin/echo: Argument list too long

for 루프를 실행할 수 있습니다.

$ for f in *; do :; done

이것은 또 다른 쉘 내장입니다.

exec 함수에 대한 인수의 최대 길이 상태 에 대한 문서를ARG_MAX 주의 깊게 읽으십시오 . 즉 ,를 호출 하지 않으면 제한 이 없습니다 . 따라서 쉘 내장 기능이 .execARG_MAXARG_MAX

그리고 실제로 ls내 인수 목록이 109948 파일 길이이거나 약 2,089,000 문자 (주거나 가져 가기)이면 디렉토리를 사용할 수 있습니다 . 18 자 파일 이름 파일을 하나 더 추가하면 Argument list too long 오류가 발생합니다. 따라서 ARG_MAX광고 된대로 작동합니다. exec는 ARG_MAX인수 목록에있는 문자 (환경 데이터 포함) 이상으로 실패 합니다.


흠. 나는 빌트인이 문제의 제약의 대상임을 암시하는 기존 답변을 읽지 않았지만 누군가가 어떻게 할 수 있는지 확실히 알 수 있습니다.
Charles Duffy 2015

6
예, 특히 새로운 명령 줄 애호가의 경우 bash 내장을 호출하는 상황과 명령을 포크 / 실행하는 상황이 명확하지 않은 방식으로 다르다는 것을 기억하기가 어렵습니다. 나는 그것을 분명히하고 싶었다. 내가 (리눅스 시스템 관리자로서) 면접에서 변함없이받는 한 가지 질문은 "그래서 나는 디렉토리에 많은 파일을 얻었습니다. 어떻게 모든 파일을 반복합니까 ..."질문자는 항상 라인을 향해 운전하고 있습니다. 길이 제한이며 find / while 또는 xargs 솔루션을 원합니다. 앞으로는 "아 지옥-그냥 for 루프를 사용하세요. 처리 할 수 ​​있어요!"라고 말할 것입니다. :-)
Mike S

@MikeS for 루프를 수행 할 수 있지만 find-xargs 콤보를 사용할 수 있다면 포크가 훨씬 줄어들고 더 빨라질 것입니다. ;-)
Lester Cheung

4
@LesterCheung for f in *; do echo $f; done은 전혀 포크하지 않습니다 (모든 내장 기능). 그래서 나는 find-xargs 콤보가 더 빠를 것이라는 것을 모릅니다. 테스트되지 않았습니다. 사실, 나는 OP의 문제 세트가 무엇인지 모릅니다. 어쩌면 find /path/to/directory이 파일의 경로 이름을 반환하기 때문에 그에게 도움이되지 않습니다. 아마도 그는 for f in *루프 의 단순함을 좋아할 것 입니다. 그럼에도 불구하고 대화는 효율성이 아닌 라인 입력 제한에 관한 것입니다. 이제 명령 줄 길이와 관련된 주제를 계속 살펴 보겠습니다.
Mike S

내가 회상 하듯이 FWIW, 문제는 C로 쉘을 작성하고 입력을 허용해야하는 시간을 결정하는 것입니다.
Derek Halden

-3

1024와 같은 버퍼 제한이 있습니다. 읽기는 단순히 중간 붙여 넣기 또는 입력을 중단합니다. 이를 해결하려면 -e 옵션을 사용하십시오.

http://linuxcommand.org/lc3_man_pages/readh.html

-e Readline을 사용하여 대화 형 쉘에서 행을 얻습니다.

읽기를 -e로 변경하면 성가신 줄 입력 중단이 사라집니다.


1
이것은 read"명령 줄을 실행하기에 너무 긴 명령을 bash에서 작성할 수 있습니까?" 에 관한 것이 아닙니다 .
Chai T. Rex

@ ChaiT.Rex 당신은 일종의 정확하지만 여기에 문제가 있습니다 : Readline없이 대화식으로 Bash를 실행하십시오. 즉 bash --noediting, 새 프롬프트에서 명령을 실행하십시오 echo somereallylongword. Ubuntu 18.04에서 시도한 결과 단어가 잘 리므로 Readline이 활성화되지 않은 것과 관련이 있습니다.
Amir

@Amir 흥미로운! 당신이 올바른지! 대답을 편집하려고 시도했지만 -e 옵션 이이 컨텍스트에서 bash에 적용되지 않는다는 것을 깨달았습니다 (bash에서는 오류가 발생하면 즉시 쉘을 종료합니다). 그리고 나는 Paul이 왜 읽기를 선택했는지 잘 모르겠습니다. 어쨌든 bash가 --noreadline으로 시작될 때 4 ~ 5000 자의 버퍼 제한이 있습니다. 그것은 내가 알지 못했거나 예상하지 못한 부작용입니다.
Mike S
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.