假设我有一个shell脚本,其中有一个如下语句:
a=$(find / -type f)
这表示有一个文件列表,其文件路径将存储在变量“a”中。
它可以存储的最大限制或行数是多少。我怎么找到它?
答案 0 :(得分:9)
IIRC,bash并没有对变量可以存储多少数据施加限制。但是受到bash执行环境的限制。有关更全面的解释,请参阅this answer。
答案 1 :(得分:2)
作为一个数据点,我在OS X 10.10.5中尝试了以下脚本,使用带有2.8 GHz Intel Core i7的Macbook Pro Retina上的内置bash:
#!/bin/bash
humombo="X"
while true; do
humombo="$humombo$humombo"
echo "Time $(date "+%H:%M:%S"), chars $(echo "$humombo" | wc -c)"
done
结果:大小一次又一次快乐地翻倍(注意大小包括单行结尾的额外字节)。当humombo
超过4MB时,事情开始放缓;从256MB加倍到512MB需要48秒,之后脚本爆炸了:
mbpe:~ griscom$ ./delme.sh
Time 16:00:04, chars 3
Time 16:00:04, chars 5
Time 16:00:04, chars 9
Time 16:00:04, chars 17
Time 16:00:04, chars 33
Time 16:00:04, chars 65
Time 16:00:04, chars 129
Time 16:00:04, chars 257
Time 16:00:04, chars 513
Time 16:00:04, chars 1025
Time 16:00:04, chars 2049
Time 16:00:04, chars 4097
Time 16:00:04, chars 8193
Time 16:00:04, chars 16385
Time 16:00:04, chars 32769
Time 16:00:04, chars 65537
Time 16:00:04, chars 131073
Time 16:00:04, chars 262145
Time 16:00:04, chars 524289
Time 16:00:04, chars 1048577
Time 16:00:04, chars 2097153
Time 16:00:05, chars 4194305
Time 16:00:05, chars 8388609
Time 16:00:07, chars 16777217
Time 16:00:09, chars 33554433
Time 16:00:15, chars 67108865
Time 16:00:27, chars 134217729
Time 16:00:51, chars 268435457
Time 16:01:39, chars 536870913
bash(80722,0x7fff77bff300) malloc: *** mach_vm_map(size=18446744071562072064) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
./delme.sh: xrealloc: cannot allocate 18446744071562068096 bytes
mbpe:~ griscom$
两个注释:
我怀疑崩溃更多的是整个过程占用了太多内存,而不是达到单个变量容量的极限。
在玩这个时,我以交互方式运行相同的命令,当循环退出时bash被打破;我不得不打开一个新的终端窗口来做任何事情。因此,过多的内存分配以未知的方式打破了bash;我的猜测是,在脚本中执行此操作会在退出时清除。
编辑:我刚刚在高性能的Ubuntu 18系统上尝试过相同的代码:
Time 18:03:02, chars 3
Time 18:03:02, chars 5
Time 18:03:02, chars 9
Time 18:03:02, chars 17
Time 18:03:02, chars 33
Time 18:03:02, chars 65
Time 18:03:02, chars 129
Time 18:03:02, chars 257
Time 18:03:02, chars 513
Time 18:03:02, chars 1025
Time 18:03:02, chars 2049
Time 18:03:02, chars 4097
Time 18:03:02, chars 8193
Time 18:03:02, chars 16385
Time 18:03:02, chars 32769
Time 18:03:02, chars 65537
Time 18:03:02, chars 131073
Time 18:03:02, chars 262145
Time 18:03:02, chars 524289
Time 18:03:02, chars 1048577
Time 18:03:02, chars 2097153
Time 18:03:02, chars 4194305
Time 18:03:02, chars 8388609
Time 18:03:03, chars 16777217
Time 18:03:04, chars 33554433
Time 18:03:07, chars 67108865
Time 18:03:12, chars 134217729
Time 18:03:23, chars 268435457
Time 18:03:43, chars 536870913
./delme.sh: xrealloc: cannot allocate 18446744071562068096 bytes
花了不到一半的时间,并且死得更干净,但字符大小相同。 (顺便说一句,错误信息中的数字,小数18446744071562068096,是0xffff ffff 8000 0080,所以很明显我们在这里达到了一些数量限制。)
答案 2 :(得分:1)
我认为bash中的变量大小没有限制,但你真的想要你的shell中有一个6GB的变量(当然是ulimit -a
)?
命令行肯定有限制。 grep <pattern> $TEN_MILLION_FILENAMES
不起作用。实际上,使用$TEN_MILLION_FILES
进行任何命令生成都非常困难。您需要其他策略,例如按目录执行,或临时文件&amp; c。
答案 3 :(得分:1)
据我所知,找到限制的唯一方法是通过经验方式。尝试运行以下shell脚本并等待完成:
limit=1
while true
do
limit=`echo 1+$limit|bc`
a=' '$a
echo $limit
done
答案 4 :(得分:1)
Daniel Griscom的脚本略有改进:
注意:当脚本在Cygwin中运行时,“ VmPeak”行将具有空输出,因为cygwin不能完全复制/ proc(基本上缺少“ VmPeak”值,但是您可以使用“ VmSize”在这种情况下?)
$ cat delme.sh
#!/bin/zsh
humombo="X"
pid=$$
while true; do
humombo="$humombo$humombo"
echo "Time $(date "+%H:%M:%S"), chars $(echo "$humombo" | wc -c)"
echo -n "Memory usage: "
grep ^VmPeak /proc/${pid}/status
done
答案 5 :(得分:0)
据我所知,标准没有任何限制。但底层系统可能。我记得曾经在某些AIX上遇到过限制。
您可以检查配置检查最大参数数量 - 尝试直到找到错误。某种具有公式var(i)=concatenation(var(i-1),var(i-1))
的迭代方法。你迟早会达到极限(至少在处理时限制内存)。