ProGrammer
ProGrammer

Reputation: 1021

Update Bash commands every 2 seconds (without re-running code everytime)

for my first bash project I am developing a simple bash script that shows basic information about my system:

#!/bash/sh
UPTIME=$(w)  
MHZ=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq)   
TEMP=$(cat /sys/class/thermal/thermal_zone0/temp)    

#UPTIME shows the uptime of the device   
#MHZ shows the overclocked specs   
#TEMP shows the current CPU Temperature

echo "$UPTIME" #displays uptime
echo "$MHZ" #displays overclocked specs
echo "$TEMP" #displays CPU Temperature

MY QUESTION: How can I code this so that the uptime and CPU temperature refresh every 2seconds without re-generating the code new every time (I just want these two variables to update without having to enter the file path again and re-running the whole script).

This code is already working fine on my system but after it executes in the command line, the information isn't updating because it executed the command and is standing by for the next command instead of updating the variables such as UPTIME in real time.

I hope someone understands what I am trying to achieve, sorry about my bad wordings of this idea.

Thank you in advance...

Upvotes: 1

Views: 3155

Answers (5)

TrueY
TrueY

Reputation: 7610

I may suggest some modifications.

For such simple job I may recommend no to use external utilities. So instead of $(cat file) you could use $(<file). This is a cheaper method as does not have to launch cat.

On the other hand if reading those devices returns only one line, you can use the bash built-in read like: read ENV_VAR <single_line_file. It is even cheaper. If there are more lines and for example you want to read the 2nd line, you could use sg like this: { read line_1; read line2;} <file.

As I see w provides much more information and as I assume you need only the header line. This is exactly what uptime prints. The external utility uptime reads the /proc/uptime pseudo file. So to avoid to call externals, you can read this pseudo file directly.

The looping part also uses the external sleep(1) utility. For this the timeout feature of the read internal could be used.

So in short the script would look like this:

while :; do
  # /proc/uptime has two fields, uptime and idle time
  read UPTIME IDLE </proc/uptime
  # Not having these pseudo files on my system, the whole line is read
  # Maybe some formatting is needed. For MHZ /proc/cpuinfo may be used
  read MHZ </sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
  read TEMP </sys/class/thermal/thermal_zone0/temp

  # Bash supports only integer arithmetic, so chomp off float
  UPTIME_SEC=${UPTIME%.*}
  UPTIME_HOURS=$((UPTIME_SEC/3600))
  echo "Uptime: $UPTIME_HOURS hours"
  echo $MHZ
  echo $TEMP

  # It reads stdin, so pressing an ENTER it returns immediately
  read -t 2
done

This does not call any external utility and does not make any fork. So instead of executing 3 external utilities (using the expensive fork and execve system calls) in every 2 seconds this executes none. Much less system resources are used.

Upvotes: 0

Karthikeyan.R.S
Karthikeyan.R.S

Reputation: 4041

I think it will help you. You can use the watch command for updating that for every two seconds without the loop.

watch ./filename.sh

It will give you the update of that command for every two second.

watch - execute a program periodically, showing output fullscreen

Upvotes: 6

paxdiablo
paxdiablo

Reputation: 881323

You need the awesome power of loops! Something like this should be a good starting point:

while true ; do
    echo 'Uptime:'
    w 2>&1 | sed 's/^/   /'

    echo 'Clocking:'
    sed 's/^/   /' /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

    echo 'Temperature:'
    sed 's/^/   /' /sys/class/thermal/thermal_zone0/temp

    echo '=========='
    sleep 2
done

That should give you your three sections, with the data of each nicely indented.

Upvotes: 1

orestiss
orestiss

Reputation: 2283

you could use while [ : ] and sleep 2

Upvotes: 0

Benjamin MALYNOVYTCH
Benjamin MALYNOVYTCH

Reputation: 51

Not sure to really understand the main goal, but here's an answer to the basic question "How can I code this so that the uptime and CPU temperature refresh every two seconds ?" :

#!/bash/sh

while :; do
  UPTIME=$(w)  
  MHZ=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq)   
  TEMP=$(cat /sys/class/thermal/thermal_zone0/temp)

  #UPTIME shows the uptime of the device   
  #MHZ shows the overclocked specs   
  #TEMP shows the current CPU Temperature

  echo "$UPTIME" #displays uptime
  echo "$MHZ" #displays overclocked specs
  echo "$TEMP" #displays CPU Temperature

  sleep 2
done

Upvotes: 2

Related Questions