dimanche 18 mars 2018

Buggy home-made code to benchmark memory and time in Bash

The Bash code

I wrote this small code to measure time and peak in memory usage of a process.

# Get arguments
MaxMemory="$1"
MaxTime="$2"
Command="$3"
for (( i=4 ; i<="$#"; i++)); do
    Command="${Command} ${!i}"
done

echo -e "MaxMemory = ${MaxMemory}\nMaxTime = ${MaxTime}\nCommand = ${Command}"


#### run the given Command in the background
${Command} &


#### Get pid
pid=$!
echo "pid = ${pid}"


#### Monitor resources
MemoryPeak=0
timeBefore=$(date +"%s")
while true;do
        # Get memory
        mem=$(ps -o rss,pid | grep ${pid} | awk '{print $1}')

        # Break if the process has stopped running
        if [[ ${mem} == "" ]]; then
                #echo "process has stopped"
                break
        fi

        # Set the MemoryPeak of memory
        if [ "${mem}" -gt "${MemoryPeak}" ]; then
                MemoryPeak=$mem
        fi

        # If it consumed too much memory, then kill
        if [ "${MemoryPeak}" -gt "${MaxMemory}" ];then
                #echo "process consumed too much memory"
                kill ${pid}
                break
        fi

        # If it consumed too much CPU time, then kill
        timeAfter=$(date +"%s")
        timeUsage=$((timeAfter - timeBefore))
        if [ "${timeUsage}" -gt "${MaxTime}" ];then
                #echo "process consumed too much time"
                kill ${pid}
                break
        fi

        # sleep
        sleep 0.1
done

timeAfter=$(date +"%s")
timeUsage=$((timeAfter - timeBefore))

echo "MEM ${MemoryPeak} TIME ${timeUsage}"

The command called memAndTime works as in

memAndTime ${MaxMemory} ${MaxTime} ./myProcess arg1 arg2 arg3

Question

I am not here to discuss reasons why I am not using timeout, gtimeout, memusg or ulimit.

The code sometimes send the following series of error messages

264: integer expression expected
/usr/bin/memAndTime: line 36: [: 473268
644
912
372: integer expression expected
/usr/bin/memAndTime: line 36: [: 705108
652: integer expression expected
/usr/bin/memAndTime: line 36: [: 842760
384: integer expression expected

The line 36 is

if [ "${mem}" -gt "${MemoryPeak}" ]; then

it feels like the object mem built in mem=$(ps -o rss,pid | grep ${pid} | awk '{print $1}') can sometimes start with a column.

I fail to reproduce the error message outside the usage of this command. Also, the error message is rare enough to make it difficult to reproduce. I fail to understand what is causing it. Can you help finding out the source of this error message and how to fix it?

Aucun commentaire:

Enregistrer un commentaire