Probably, you can't.
cpulimit's logic is pretty simple, it takes pid of process and simply sending its signal
kill -STOP $PID, thereafter
kill -CONT $PID, and again, and again, and again, and again......
And measuring the cpu-usage to calculate delay between STOP and CONT.
In your case,
pstree of complex bash-script would take N*x screens of console.
I can suggest to you another one method to downgrade cpu-usage of any bash-script or even binary executable.
nice - its taking process and increasing or decreasing its priority from -20(Highest priority) to 20(Lowest priority). Probably in too low diapason, that is why, there are appears another two utils and kernel hooks:
ionice - may be it is second generation of
nice. You could separate processes by priority from 0(Lowest priority) to 7 (Highest priority). Plus, you could separate processes by classes, real-time( Highest ),
best-efforts ( Middle ), Idle ( Lowest ) and None ( Default ).
chrt - the highest thing that I have ever met, it is similar to
cpulimit by its power and dominion on process. Here you could too meet classes of priority,
batch, etc... And diapason of priorities very large, from 1 to 99.
For example, you could launch one huge process with
chrt -r -p 99 process - and it will eats all of your resources.
The same way, any huge daemon could soft works in "background" with
chrt -r -p 0 process - it will wait for everyone other while resources of a system is busy.
Anyway, I'm highly suggest you to read
man chrt and
man ionice before you start.
For example, I'm using
rtorrent for p2p. It is lowest priority task for my system, then I'm launching it in such way:
nice -n 20 chrt -i 0 ionice -c3 /usr/bin/rtorrent
Or, you can take the hooks&haks way. And write your own cpulimit_wrapper script. For example:
# cat bash_script.sh
while sleep 0; do
dd if=/dev/random of=/tmp/random.bin bs=1M count=1000
# cat cpulimit.sh
[ -z "$TARGET" ] && echo "Usage bash cpulimit.sh command" && exit 1
cpulimit -l 1 bash $TARGET
while sleep 0;do
lsof -n -t $TARGET | xargs pstree -p | sed -e 's/(/(\n/g' | sed -e 's/)/\n)/g' | egrep -v '\(|\)' | while read i; do
cpulimit -l 1 -b -p $i;