Shell 外壳可变容量

Shell 外壳可变容量,shell,unix,scripting,Shell,Unix,Scripting,假设我有一个shell脚本,其中有如下语句: a=$(find / -type f) 这表示有一个特定的文件列表及其文件路径,将存储在变量“a”中 它可以存储的最大行数限制是多少。如何找到它?IIRC,bash对变量可以存储的数据量没有限制。但是,它受到bash执行环境的限制。请参阅以获得更全面的解释。据我所知,标准没有任何限制。但潜在的系统可能会。我记得我曾经在某些AIX上遇到过限制 您可以像“配置检查”一样检查最大参数数-请尝试,直到找到错误为止。某种迭代方法,使用公式var(i)=串联(

假设我有一个shell脚本,其中有如下语句:

a=$(find / -type f)
这表示有一个特定的文件列表及其文件路径,将存储在变量“a”中


它可以存储的最大行数限制是多少。如何找到它?

IIRC,bash对变量可以存储的数据量没有限制。但是,它受到bash执行环境的限制。请参阅以获得更全面的解释。

据我所知,标准没有任何限制。但潜在的系统可能会。我记得我曾经在某些AIX上遇到过限制


您可以像“配置检查”一样检查最大参数数-请尝试,直到找到错误为止。某种迭代方法,使用公式
var(i)=串联(var(i-1),var(i-1))
。迟早您会达到限制(至少在处理时内存限制)。

我认为bash中的变量大小没有限制,但您真的希望shell中有6GB的变量吗(当然要服从
ulimit-a


命令行当然有限制<代码>grep$1000万文件名不起作用。事实上,用一千万美元的文件来生成任何命令都是非常困难的。您需要其他策略,如按目录或临时文件执行。据我所知,找到限制的唯一方法是通过经验方法。尝试运行以下shell脚本并等待完成:

limit=1
while true
do
  limit=`echo 1+$limit|bc`
  a=' '$a
  echo $limit
done

作为一个数据点,我在OS X 10.10.5中尝试了以下脚本,使用Macbook Pro Retina上的内置bash和2.8 GHz Intel Core i7:

#!/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,所以很明显我们在这里遇到了一些数字容量限制。)

对Daniel Griscom的脚本有一点改进:

  • 您可以添加显示脚本正在使用的内存量(请参阅循环中添加的最后一个命令)
  • 您可以尝试不同的shell环境(我的测试表明,对于与zsh大小相同的变量,bash使用的内存大约是zsh的5倍——您可以自己进行以下测试)
  • 注意:当脚本在Cygwin中运行时,“VmPeak”行将有空输出,因为Cygwin没有完全复制/proc(基本上缺少“VmPeak”值,但在这种情况下,您可以选择“VmSize”)


    x=x;n=1;虽然真实;执行回显“$(日期+%H:%M:%S)长度$n”;x=“$x$x”;n=$((n*2));完成
    $ 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