Подтвердить что ты не робот

Напишите оболочку bash script, которая потребляет постоянное количество ОЗУ за определенное пользователем время

Я пытаюсь написать оболочку bash script, которая потребляет большое количество ОЗУ на встроенном устройстве за определенное пользователем время. Как мне это сделать без использования массивов?

4b9b3361

Ответ 1

Даже если традиционные Bash массивы не поддерживаются, все же возможно создать массивные переменные с помощью команды eval встроенный в конкретную оболочку.

Следующий пример script основан на некоторых сценариях, которые я использовал при использовании BusyBox во встроенном проекте Linux. BusyBox использует оболочку Almquist (также известную как 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

Будьте осторожны при цитировании при использовании eval!

Вывод:

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

В зависимости от вашего конкретного сценария может быть достаточно script, аналогичного приведенному ниже.

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

В моем кратком тестировании этот script потреблял от 570M до 575M физической памяти * за указанный период времени 5 минут.

* Мониторинг с использованием программ top и memprof в отдельных тестах

Ответ 2

Лично я бы пошел с Ником, потому что делать это на C будет намного проще.

Но... если вы действительно хотите избежать написания суперпростой C-программы, чтобы сделать это, тогда (если в системе работает Linux с правильным встроенным материалом), вы должны иметь возможность сделать это, установив tmpfs с ограничением по размеру любой памяти, которую вы хотите использовать, а затем извлечения данных в файл в этом tmpfs для его заполнения (например, путем копирования данных из бесконечного источника (например, /dev/zero).

Программа C действительно проще, хотя, если вы можете скомпилировать ее для платформы.

Ответ 3

Вам нужно различать выделенное и рабочее ОЗУ. Легко есть память в bash:

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

но если script часто перебирает данные, тогда эти страницы памяти являются хорошими кандидатами для замены.

Ответ 4

@JohnBartholomew

Ваша идея о монтировании tmpfs также не так сложна, и вы можете быть уверены, что она фактически потребляет ОЗУ, верно? (см. комментарий Криса Додда в ответ Ник)

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

Вероятно, dd будет жаловаться, что на устройстве нет места. Кроме того, я не знаю, сколько оперативной памяти будет использоваться точно, но если вы говорите о MB, это должно быть хорошо.

Ответ 5

Если у вас есть устройство /dev/shm, вы можете записать в файл, расположенный там, поскольку по умолчанию он имеет tmpfs.

Ответ 6

Я придумал это. /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