Он ведет себя так, как должен. То, что вы ожидаете, может быть достигнуто следующим образом:
while [ true ]; do
NOW=$(date +"%H")
echo $NOW
done
Теперь переменная обновляется на каждой итерации цикла.
Сравните оба с этим:
NOW=date
while [ true ]; do
$NOW
done
Здесь дата пересчитывается на каждой итерации, поскольку в переменной сохраняется сама команда, а не ее результат.