In the first version, you only sleep if the test is truthy and notify-send is called successfully; but not if the test is falsy. In the second version, you only sleep in the branch where the test was falsy, and notify-send was not called. Meaning you'd get the same issue when the battery is low with that latter version.
You should probably have the script sleep in either case, regardless of what the test result is. Minimally, change the && after notify-send to ; in the first version to break the relation between the two commands. I'd go with spelling the if-statement out, though, something like this:
#!/bin/sh
while true; do
pct=$(
upower -i /org/freedesktop/UPower/devices/battery_BAT0 |
grep percentage |
grep -Poe "\d*"
)
if [ "$pct" -lt 5 ]; then
notify-send "Battery below 5%"
fi
sleep 60
done
(Note that the [[ .. ]] conditional isn't a standard feature, and not all shells installed as sh in various systems support it.)