`seq` 和 bash 大括号扩展失败

`seq` 和 bash 大括号扩展失败

IINM 我的系统出现故障时bash

for i in {0..10000000}; #   Seven zeroes.
do
    false;
done #   `bash` exited and its `tmux` pane/window was closed.

或者

for i in $(seq 0 10000000); #   Seven zeroes.
do
    false;
done #   `bash` exited and its `tmux` pane/window was closed.

但不是当

for i in {0..1000000}; #   Six zeroes.
do
    false;
done #   Finished correctly.

您能否简要解释一下此行为的内部原理并提示完成任务的解决方法?

答案1

for i in {0..1000000}两者for i in $(seq 1000000)都建立了一个大列表,然后循环遍历它。这效率低下并且占用大量内存。

使用:

for ((i = 0; i<= 1000000; i++))

反而。或者 POSIXly:

i=0; while [ "$i" -le 1000000 ]; do
  ...
  i=$(($i + 1))
done

或者:

seq 1000000 | xargs...

要获取充满 CRLF 的文件:

yes $'\r' | head -n 1000000 >  file

一般来说,在 shell 中应尽可能避免循环。

答案2

@Stéphane Chazelas 在上面给出了很好的答案。

我的不是答案。我只是对不同解决方案的效率感到好奇,所以我想我应该分享我的结果......

~# i=0 ; time while [ "$i" -le 1000000 ]; do ((i++)) ;done
real    0m21.753s

~# time for ((i = 0; i<= 1000000; i++))  ;do : ;done
real    0m15.791s

~# time for i in {0..1000000} ;do : ;done
real    0m8.897s

~# time for i in $(seq 0 1000000) ;do : ;done
real    0m7.760s

:~# time seq 1000000 | xargs true
real    0m0.938s

~# time yes $'\r' | head -n 1000000 >/dev/null
real    0m0.048s

答案yes是明显的赢家。 :-) 此外,它实际上完成了 OP 所需的工作。

相关内容