Command to measure CPU time and RAM usage of process while making sure it does not go over certain ressource limitation
Command=&quot;$3&quot;
for (( i=4 ; i&lt;=&quot;$#&quot;; i++)); do
    Command=&quot;${Command} ${!i}&quot;
done
# …
${Command} &amp;


Much cleaner to just reference the end of the $@ array directly.  Since you're running the commands later, and would like to keep quoting intact, use an array:
declare -a Command=( &quot;${@:3}&quot; )

&quot;${Command[@]}&quot; &amp;



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


The idiomatic way to test for process existence is with kill -0, as in:
 kill -0 $pid || break

Since $mem is a number, or empty, an arithmetic test is good too:
(( mem )) || break



if [ &quot;${mem}&quot; -gt &quot;${MemoryPeak}&quot; ]; then
    MemoryPeak=$mem
fi

if [ &quot;${MemoryPeak}&quot; -gt &quot;${MaxMemory}&quot; ];then
    #echo &quot;process consumed too much memory&quot;
    kill ${pid}
    break
fi


Prefer parentheses over single brackets (or double brackets) for arithmetic operations:
 (( MemoryPeak = ( mem &gt; MemoryPeak ? mem : MemoryPeak ) ))
 
 if (( MemoryPeak &gt; MaxMemory )); then # etc.
 



 # If it consumed too much CPU time, then kill


You're measuring wallclock time, not CPU time.  There's also some slop:  timeBefore is recorded when the script collects it, which might not be close to the binary invocation time.  Better to read the times and cputimes values from ps, and calculate with those:
 MaxElapsed= # …
 MaxCPU= # …
 # …
 read mem dt ct &lt;&lt;&lt; $( ps --no-headers -o rss,etimes,cputimes -p$pid )
 # …
 if (( dt &gt; MaxElapsed || ct &gt; MaxCPU )); then # …
 



timeAfter=$(date +&quot;%s&quot;)
timeUsage=$((timeAfter - timeBefore))


See timing comments above.  If you make the outer loop condition kill -0 $pid, you can simply reference $dt here.

Putting it all together:
 MaxMemory=$1 MaxElapsed=$2 MaxCPU=$3 Command=( &quot;${@:4}&quot; ) MemoryPeak=0
 &quot;${Command[@]}&quot; &amp; pid=$!
 while kill -0 $pid; do
    read mem dt ct &lt;&lt;&lt; $( ps --no-headers -o rss,etimes,cputimes -p$pid )
    (( mem )) || break
    (( MemoryPeak = ( mem &gt; MemoryPeak ? mem : MemoryPeak ) ))
    (( MemoryPeak &gt; MaxMemory || dt &gt; MaxElapsed || ct &gt; MaxCPU )) &amp;&amp; kill $pid &amp;&amp; wait $pid  # loop conditional will break for us
done
echo &quot;MEM $MemoryPeak ELAPSED $dt CPU $ct&quot;