这个问题可能很微不足道,但是通过这个简单的for
循环
for i in {1..10000000}; do echo "$i" line >> file
done
经过一段时间的精心设计后,我的 shell 崩溃了(终端模拟器中的选项卡自动关闭)并且file
没有创建。
这是GNU bash, version 4.1.11(2)-release
。
这是由于内存限制还是其他什么原因?如果是的话,这个限制应该是多少?
有了{1..1000000}
它就可以正常工作了。
答案1
发生这种情况的原因是因为在调用命令之前括号已展开。因此,您实际上最终会得到如下命令:
for i in 1 2 3 ... 10000000 ; do ...
..因此它会占用大量内存或崩溃。
使用长循环时的解决方案是使用 bash 的 C 风格语法:
for ((i = 1; i <= 10000000; i++))
do
...
done
或者,如果您想与其他 shell 保持兼容,您可以通过管道连接到 while 循环:
seq 1 10000000 | while IFS= read -r line
do
...
done
答案2
是的,我的 bash 进程执行此命令需要大量内存。我的情况是 1.9GB (x86_64)。您可能已经达到了极限,并且内核内存不足杀手已经将其消除。对我来说,它确实有效。大约需要3分钟
$ wc -l file
10000000 file
$ tail -n1 file
10000000 line
$ ls -hl file
-rw-r--r-- 1 seb users 123M Sep 5 13:19 file
确认RAM限制的假设:如果你有交换空间,你可以尝试观察它被填满。htop
为此使用例如。
如果我进一步增加循环超过 100.000.000 个元素,该进程也会消耗十倍以上的 RAM 18GB
:。
@user000001 给出了解释和替代方案。我测试了C 风格语法(他提供的):
for ((i = 1; i <= 10000000; i++))
do
...
done
这个过程不会比常规的 bash 过程占用更多的 RAM。