1

I am trying to create a command that imposes a hard limit on memory usage and CPU time usage to a given process by killing it if it overpasses these limits. The command must also outputs the memory usage and CPU time usage at the end of the process (whether the process was killed or not).

Here is my code.

# 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 (( MemoryPeak < mem )); then
        MemoryPeak=mem
    fi

    # If it consumed too much memory, then kill
    if (( MemoryPeak > 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 > 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 code exaclty as shown here is placed in the file in /usr/bin/memAndTime and I gave it access authorization with chmod. When I set the arguments in the terminal and copy paste the rest of the code directly on the terminal it seems to work fine but somehow when I do

memAndTime 50000 5000 sleep 3s

the process stops almost instantaneously with the output

MaxMemory = 50000
MaxTime = 5000
Command = sleep 3s
pid = 31430
process has stopped
MEM 0 TIME 0

What is going wrong?

Remi.b
  • 17,389
  • 28
  • 87
  • 168

1 Answers1

1

Here's ShellCheck's output:

Line 13:
${command} &
^-- SC2154: command is referenced but not assigned (for output from commands, use "$(command ...)" ).

The variable you defined uses a capital C.

However, you should really be using ulimit instead

that other guy
  • 116,971
  • 11
  • 170
  • 194
  • Wow ShellCheck sounds quite handy. I am a little ashamed that the error was so simple. I am afraid `ulimit` is not working for MAC OS recent versions (see [here](https://stackoverflow.com/questions/3274385/how-to-limit-memory-of-a-os-x-program-ulimit-v-neither-m-are-working)). At least it is not working for me (I am on MAC OSX). – Remi.b Mar 05 '18 at 04:25