What you seem to be looking for is something like this:
while true
do
time=$(date '+%H')
echo $time
sleep 0.1
done
Notes
As you found, one invocation of date will produce only one date. Connecting it to a while loop will not convince it to produce any more.
This is not a reliable way to extract something from date:
date|cut -d' ' -f4|cut -d':' -f1|read time
It gives me different results depending on whether the day of the month is one or two digits. I think that you are looking to get the hour and that is simply done with:
date '+%H'
If you want to capture that into a shell variable, use:
time=$(date '+%H')
The while loop in the question, if it has no delay, will chew up a lot of CPU time. I added a sleep 0.1 to slow it down.
Why it only works with the while loop
This has to do with environment variables and subshells. Compare and contrast the following two version. In the first version below the output is blank:
$ date | cut -d' ' -f4 | cut -d':' -f1 | read time
$ echo $time
$
In this version the output is non-blank (and the day of the month is printed):
$ date | cut -d' ' -f4 | cut -d':' -f1 | { read time; echo $time; }
2
The issue here is that read time is run in a subshell. This means that any settings to environment variables are lost the moment that the subshell ends. In the latter version there is output because the echo $time statement is run inside the same subshell as read time.
Alternative using redirection adn process substitution
CharlesDuffy points to an alternative approach:
$ read time < <(date '+%H')
$ echo $time
21
This approach uses two steps. First, we use process substitution to create a file-like object: <(date '+%H'). The construct <(...) denotes process substution. It takes a the output of a command, in this case date '+%H' and makes it readable as if it were a file.
The second step is to use read time with its stdin redirected from our newly created file-like object. The result is that the output of date is read into time in the current shell so that the time variable survives.
Note that the space between the angle brackets in < <(date '+%H') is significant. If it is removed, the shell will report a syntax error.
Pipelines and subshells: an advanced feature
In bash, there is a way around this if one sets lastpipe on. This makes the last command in a pipeline run in the current shell. Consequently, any environment variables it assigns will survive. In interactive mode, to turn lastpipe on, one has to turn off job control. Observe:
$ set +m; shopt -s lastpipe
$ date | cut -d' ' -f4 | cut -d':' -f1 | read time
$ echo $time
2
time=$(date|cut -d' ' -f4|cut -d':' -f1)read time < <(date | cut -d' ' -f4 | cut -d: -f1)if you wanted to.dateto give you only what you wanted, instead of using other programs to extract content:time=$(date '+%H')for just the hourprintf -v time '%(%H)T'-- no subshell, thus even less overhead.