Linux 编写一个 bash shell 脚本,在用户定义的时间内消耗恒定数量的 RAM

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4964799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:48:17  来源:igfitidea点击:

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

linuxbashshellembedded-linux

提问by Ankur Agarwal

I am trying to write a bash shell script that consumes a high amount of RAM on an embedded device for a user defined time. How do I do it without using arrays ?

我正在尝试编写一个 bash shell 脚本,该脚本在用户定义的时间内在嵌入式设备上消耗大量 RAM。如何在不使用数组的情况下做到这一点?

采纳答案by jschmier

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

即使不支持传统的Bash 数组,仍然可以使用eval内置在特定 shell 中的命令创建类似数组的变量。

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

以下示例脚本基于我在嵌入式 Linux 项目中使用BusyBox时所做的一些脚本。 BusyBox使用不支持数组的Almquist shell(也称为 A Shell、ash 和 sh)。

#!/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!

使用时要小心引用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.

在我的简短测试中,此脚本在 5 分钟的指定时间段内消耗了 ~570M 到 ~575M 的物理内存*

* Monitored using top and memprof programs in separate tests

* 在单独的测试中使用 top 和 memprof 程序进行监控

回答by John Bartholomew

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

就我个人而言,我会同意尼克的回答,因为在 C 中这样做真的会容易得多。

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).

但是......如果你真的想避免编写一个超级简单的 C 程序来做到这一点,那么(如果系统运行的 Linux 内置了正确的东西)你应该能够通过挂载一个大小的 tmpfs 来做到这一点您想使用多少内存的限制,然后将数据喷入该 tmpfs 中的文件以填充它(例如,通过从无限源(例如,/dev/zero)复制数据)。

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

不过,C 程序确实更容易,只要您可以为平台编译。

回答by jbvo

@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)

您关于 tmpfs 挂载的想法也不是那么难,您可以更确定它实际上正在消耗 RAM,对吗?(请参阅 Chris Dodd 在 Nick 的回答中的评论)

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

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 ddwill 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.

可能dd会抱怨设备上没有剩余空间。另外,我不知道确切会使用多少 RAM,但是如果您谈论的是 MB,那么这应该没问题。

回答by ?aphink

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

如果您有/dev/shm设备,则可以写入位于那里的文件,因为默认情况下它是 tmpfs。

回答by Phil

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

您需要区分分配的 RAM 和工作集 RAM。在 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.

但除非脚本频繁地翻阅数据,否则这些内存页面是被换出的好候选。

回答by Ankur Agarwal

I came up with this. /dev is a tmpfs

我想出了这个。/dev 是一个 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