Write a bash shell script that consumes a constant amount of RAM for a user defined time [closed]

穿精又带淫゛_ 提交于 2019-11-27 14:36:50

Even if traditional Bash arrays are not supported, it may still be possible to create array-like variables using the eval command built into the particular shell.

The following example script is based on some scripting I did when using BusyBox in an embedded Linux project. BusyBox uses the Almquist shell (also known as A Shell, ash, and sh), which does not support arrays.

#!/bin/ash

for index in 1 2 3 4 5; do
    value=$(($index * 1024))
    eval array$index=\"array[$index]: $value\"
done

for i in 1 3 5; do
    eval echo \$array$i
done

Be careful with quoting when using eval!

Output:

array[1]: 1024
array[3]: 3072
array[5]: 5120

Depending on your particular scenario, a script similar to the following may suffice.

#!/bin/ash

echo "Provide sleep time in the form of NUMBER[SUFFIX]"
echo "   SUFFIX may be 's' for seconds (default), 'm' for minutes,"
echo "   'h' for hours, or 'd' for days."
read -p "> " delay

echo "begin allocating memory..."
for index in $(seq 1000); do
    value=$(seq -w -s '' $index $(($index + 100000)))
    eval array$index=$value
done
echo "...end allocating memory"

echo "sleeping for $delay"
sleep $delay

In my brief testing, this script consumed ~570M to ~575M physical memory* for the specified time period of 5 minutes.

* Monitored using top and memprof programs in separate tests

Personally I would go with Nick's answer, since doing it in C is going to be much easier really.

But... if you really want to avoid writing a super-simple C program to do it, then (if the system is running Linux with the right stuff built in) you should be able to do it by mounting a tmpfs with a size limit of however much memory you want to use, then spewing data into a file in that tmpfs to fill it up (by, e.g., copying data from an infinite source (e.g., /dev/zero).

The C program is really easier though, as long as you can compile for the platform.

If you have a /dev/shm device, you can write to file located there, since it's a tmpfs by default.

You need to distinguish between allocated and working-set RAM. It's easy to eat up memory in bash:

A="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
for power in $(seq 8); do
  A="${A}${A}"
done

but unless the script churns through the data frequently then those pages of memory are good candidates to be swapped out.

@JohnBartholomew

Your idea about a tmpfs mount is also not that hard and you can be more sure that it's actually consuming RAM, right? (see Chris Dodd's comment at Nick's answer)

mount -t tmpfs none /new/path/for/temp -o size=32m
dd if=/dev/zero of=/new/path/for/temp/zero.txt bs=32m count=1

Probably dd will complain that there is no space left on the device. Also, I don't know how much RAM will be used exactly, but if you're talking about MB's than this should be fine.

I came up with this. /dev is a tmpfs

 #!/bin/sh

 mntroot rw
 cd /dev
 while : 
 do 
        dd > /dev/null 2>&1 if=/dev/zero of=myfile1 count=25000 bs=1024 # eat up 25 MB of RAM 
        usleep 1 
        rm myfile1

 done
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!