1

I need to create a script that will execute daily (cron job), calculate the uptime of the system, and if that number is greater than 72 hours, reboot the system.

I am getting lost in converting the value of hours to something I can compare to 72. It returns me 6499.04: command not found

#!/bin/bash if $(awk '{print $1}' /proc/uptime) / 3600 > 72 ; then echo "yes" fi 

Thank you in advance for any help!

3
  • Relating unix.stackexchange.com/questions/27276/… with using pid 1. Commented Sep 14, 2021 at 12:03
  • Is the host running on Amazon Web Services by chance? Commented Sep 15, 2021 at 14:46
  • @MarkStosberg, no. It's a computer running on Ubuntu Linux. Commented Sep 16, 2021 at 15:05

5 Answers 5

7

I would do the whole test in AWK:

awk '$1 > (72 * 3600) { print "yes" }' /proc/uptime 

If you want to use that as a test, use the exit code:

if awk '{ exit ($1 < (72 * 3600)) }' /proc/uptime; then echo Need to reboot fi 

AWK evaluates ($1 < (72 * 3600)) as 0 if the comparison fails, 1 otherwise; 0 indicates success as an exit code, so we invert the condition.

If you’re using systemd, another approach would be to use a systemd timer, with OnBootSec=72h (see FelixJN’s answer for details).

6

A systemd timer would work, too:

[Unit] Description=reboot after 72h [Timer] Unit=systemd-reboot.service OnBootSec=72h [Install] WantedBy=multi-user.target 

Note that this is not a service, but a timer, i.e. the file name must end in .timer. Put it in e.g. /etc/systemd/system/reboot27h.timer, then enable and start it it for the current session as usual:

systemctl enable reboot72h.timer systemctl start reboot72h.timer 

To check if the timer works properly and how much time is left until the next run, use

systemctl list-timers 
1
  • Because my question was more about correcting my bash script, I felt that the correct answer was @Stephen Kitt. But this solution is way more clean and elegant. Commented Sep 15, 2021 at 15:57
2

Your script has several syntax errors in the if condition which leads to the error message you are getting.

  1. In the if condition, you need a command or a bash builtin test construct that returns 0 (=true) on success and non-zero (=false) on failure. You chose to perform an arithmetic comparison, so you need to place it in the appropriate test construct:
    if (( variable1 > variable2 )); then .... ; fi 
  2. You use process the content of uptime, which contains a floating-point number. Bash however is not able to perform floating-point arithmetic, so such expressions will not work as expected.
  3. Because you didn't place the condition in the test construct, Bash considers the result of your awk text-processing as a command to be executed, so it tries to "execute" the current uptime (the reason for the error message).

To alleviate, you could truncate the seconds to an integer value by using the first . as field separator. So, you could try

up=$(awk -F. '{print $1}' /proc/uptime) if (( up > 72*3600 )); then echo "yes"; else echo "no"; fi 

Please note

  • The question is tagged , so I used the bash-specific (( ... )) test construct. If you want the script to be portable, you have to use the POSIX-compliant
    if [ $up -gt 259200 ]; then ...; else ...; fi 
  • As a general rule, I would recommend you to run your shell scripts through shellcheck, also available as standalone program on many Linux distributions, to catch syntax errors and the like.
0
1

You can do all this in bash by converting dates into timestamps and do some calculations. You can use uptime -s so no need for awk or anything else

#!/usr/bin/env bash upt=$(date -d "$(uptime -s)" +%s) hours=$(date -d '72 hours ago' +%s) if (( upt < hours)); then echo "System up for at least 72h"; else echo "Nothing to do"; fi 
0
0
#! /bin/bash if [ $(awk '{print int($1/3600)}' /proc/uptime) -gt 72 ]; then echo "yes" fi 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.