
이것:
#!/bin/bash
# Run command ~100Kbytes long
/bin/echo $(perl -e 'print "x"x100000') | wc
# Run command ~54Kbytes long
# This line fails: line 7: /bin/echo: Argument list too long
/bin/echo $(perl -e 'print "x "x27000') | wc
# Same command, but run using xargs
# Run command ~100Kbytes long
perl -e 'print "x"x100000' | xargs -n 100000 /bin/echo | wc
# Run command ~54Kbytes long
# This line fails: xargs: /bin/echo: Argument list too long
perl -e 'print "x "x27000' | xargs -n 100000 /bin/echo | wc
GNU/Linux에서는 잘 작동하지만 MacOS X에서는 2개의 54KB 라인이 실패합니다.
ARG_MAX
100KBytes보다 훨씬 높으며 100Kbytes 라인은~ 아니다실패 - 실패한 것은 54KBytes 라인입니다.
mac$ getconf ARG_MAX
262144
mac$ uname -a
Darwin macosx 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:26:45 PDT 2012; root:xnu-1699.32.7~1/RELEASE_I386 i386
# Kusalananda suggests it may be due to the size of the environment
mac$ env | wc
27 32 956
54Kbytes 명령이 실패하는 이유는 무엇입니까?
MacOS X에서 인수 목록을 실행하지 않고도 인수 목록이 너무 긴지 예측할 수 있는 방법이 있습니까?
연구
이것:
#!/bin/bash
runtest() {
echo environment size:
env | wc
echo Run command ~100Kbytes long
/bin/echo $(perl -e 'print "x"x100000') | wc
echo Run command ~54Kbytes long
# This line fails: line 7: /bin/echo: Argument list too long
/bin/echo $(perl -e 'print "x "x27000') | wc
# Same command, but run using xargs
echo Run command ~100Kbytes long
perl -e 'print "x"x100000' | xargs -n 100000 /bin/echo | wc
echo Run command ~54Kbytes long
# This line fails: xargs: /bin/echo: Argument list too long
perl -e 'print "x "x27000' | xargs -n 100000 /bin/echo | wc
echo
}
# Clean environment
runtest
# Make a huge environment
for a in `seq 5000`; do eval "a$a=1" ; done
for a in `seq 5000`; do eval "a$a() { 1; }" ; done
# This works as before
runtest
# Export environment
for a in `seq 5000`; do eval export a$a ; done
for a in `seq 5000`; do eval export -f a$a ; done
# Now the 100Kbytes commands fail, too
runtest
다음과 같은 출력을 제공합니다.
environment size:
6027 6032 47849
Run command ~100Kbytes long
1 1 100001
Run command ~54Kbytes long
test: line 10: /bin/echo: Argument list too long
0 0 0
Run command ~100Kbytes long
1 1 100001
Run command ~54Kbytes long
xargs: /bin/echo: Argument list too long
0 0 0
environment size:
6027 6032 47849
Run command ~100Kbytes long
1 1 100001
Run command ~54Kbytes long
test: line 10: /bin/echo: Argument list too long
0 0 0
Run command ~100Kbytes long
1 1 100001
Run command ~54Kbytes long
xargs: /bin/echo: Argument list too long
0 0 0
environment size:
16027 26032 126742
Run command ~100Kbytes long
test: line 7: /bin/echo: Argument list too long
0 0 0
Run command ~54Kbytes long
test: line 10: /bin/echo: Argument list too long
0 0 0
Run command ~100Kbytes long
xargs: insufficient space for argument
0 0 0
Run command ~54Kbytes long
xargs: /bin/echo: Argument list too long
0 0 0
그래서 쿠살라난다가 옳았다.수출됨환경이 영향을 미칠 수 있습니다. 이것을 계산하는 공식이 무엇인지는 확실하지 않습니다. 아마도 순전히 크기일 것입니다. 어쩌면 변수의 수도 중요할까요? 어쩌면 이름의 길이일까요? 어쩌면 그것들의 선형 조합일까요?
그것아직주어진 환경에서 100Kbytes 명령은 잘 작동하지만 54Kbytes 명령은 작동하지 않는다는 것을 설명하지 않습니다.
이는 MacOS가 전체 크기에 제한이 있을 뿐만 아니라 인수 개수에도 제한이 있는 것과 같습니다.
MacOS가 인수당 추가로 8바이트를 사용하는 경우에도 이 숫자는 의미가 있습니다.
# One big argument
100K * "x" = 100000+2 < 262144 # Works
# 27K small arguments
27K * "x " = 27K*(8+2) > 262144 # Fails
# 26K small arguments
26K * "x " = 26K*(8+2) < 262144 # Works
그런데 MacOS가 그렇게 합니까?
답변1
추가 연구 결과에 따르면(MacOS 버전은 알 수 없음):
Effective length =
length of arguments +
5 * number of arguments +
length of body/value of exported functions/variables +
length of names of exported functions/variables +
4 * number of exported functions/variables
유효 길이가 256KB 미만인 경우 명령이 실행됩니다. 이것이 모든 MacOS 버전에 해당되는지는 확실하지 않습니다.
MacOS El Capitan 10.11.4의 경우 이는 비관적인 명령줄 길이를 제공합니다(실행하려는 명령이 다음과 같다고 가정 /bin/echo x x x x ...
).
perl -e '
$envc=(keys %ENV);
$envn=length join"",(keys %ENV);
$envv=length join"",(values %ENV);
$maxlen=3+(262144 - $envn - $envv) / 5 - $envc*2;
print("Max len = $maxlen\n");
'
이것이 모든 MacOS 버전에 해당되는지는 확실하지 않습니다.