LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   Extracting "Hours" from uptime in a BASH script? (http://www.linuxquestions.org/questions/linux-general-1/extracting-hours-from-uptime-in-a-bash-script-705160/)

BassKozz 02-16-2009 03:52 PM

Extracting "Hours" from uptime in a BASH script?
 
I am trying to create a script that will check if uptime is greater than or equal a set number of hour(s), here is what I've got so far from googling:
Code:

#!/bin/sh
# Test Script to see if uptime is less than 1 hours

UPT="uptime | awk -F'(  |,)' '{print $2}'"
HOURS="1"

if [ "$UPT" -lt "$HOURS" ]
then
        echo "uptime is less then $HOURS hours(s)"
        exit
else
        echo "uptime is greater than $HOURS hour(s)"
fi

I think the problem is with the $UPT variable, I don't think it is being set properly, also the output has a colon in it (for example if uptime is 6hours and 36 minutes the result is "6:36") so it can't be compared (greater than or equal to) against the $HOURS variable because it has non-numeric characters in it. How can I extract the number of hours from uptime? Also what will happen when this script is run will less than 1 hour of uptime?

Nylex 02-16-2009 04:02 PM

Your UPT variable isn't going to contain what you want. It will literally contain the string "uptime | awk -F'( |,)' '{print $2}'". If you want UPT to contain the output of that command line, either use backticks, or $() like so:

UPT=`uptime | awk -F'( |,)' '{print $2}'`,

or UPT=$(uptime | awk -F'( |,)' '{print $2}')

Also, to get just the hours, why not simply use awk again with the separator as ":", e.g.

UPT=`uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'`

BassKozz 02-16-2009 04:08 PM

Quote:

Originally Posted by Nylex (Post 3446005)
Your UPT variable isn't going to contain what you want. It will literally contain the string "uptime | awk -F'( |,)' '{print $2}'". If you want UPT to contain the output of that command line, either use backticks, or $() like so:

UPT=`uptime | awk -F'( |,)' '{print $2}'`,

or UPT=$(uptime | awk -F'( |,)' '{print $2}')

Thanks :D
Now to just figure out how to extract just the hours ? and handle situations where hours are less then 1?
Quote:

Originally Posted by Nylex (Post 3446005)
Also, to get just the hours, why not simply use awk again with the separator as ":", e.g.

UPT=`uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'`

Because that will output the current hour, not the uptime hour... for example:
Code:

$ uptime
 17:07:14 up  6:29,  3 users,  load average: 1.06, 1.12, 1.11

There for:
Code:

$ uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'
17

Not "6" :(

Nylex 02-16-2009 04:12 PM

That's strange. It works fine for me:

nick@darkstar:~$ uptime; UPT=`uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'`; echo $UPT
22:34:06 up 4:16, 4 users, load average: 0.07, 0.30, 0.60
4

BassKozz 02-16-2009 04:20 PM

Quote:

Originally Posted by Nylex (Post 3446018)
That's strange. It works fine for me:

nick@darkstar:~$ uptime; UPT=`uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'`; echo $UPT
22:34:06 up 4:16, 4 users, load average: 0.07, 0.30, 0.60
4

Doesn't work for me:
Code:

$ uptime; UPT=`uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'`; echo $UPT
 17:19:15 up  6:42,  3 users,  load average: 1.21, 1.09, 1.08
17

:( weird :confused:

richwmn 02-16-2009 09:05 PM

Quote:

Originally Posted by BassKozz (Post 3446035)
Doesn't work for me:
Code:

$ uptime; UPT=`uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'`; echo $UPT
 17:19:15 up  6:42,  3 users,  load average: 1.21, 1.09, 1.08
17

:( weird :confused:

BassKozz -- you have a space [ ( |,) ] in yours where nylex does not[ (|,) ]. It makes a difference. I get time with the space and uptime without.

Rich

Nylex 02-17-2009 12:35 AM

Ah, I didn't notice that. I thought I just copied the line from BassKozz's post.

BassKozz 02-17-2009 04:16 PM

Quote:

Originally Posted by richwmn (Post 3446259)
BassKozz -- you have a space [ ( |,) ] in yours where nylex does not[ (|,) ]. It makes a difference. I get time with the space and uptime without.

Rich

Now I am getting the number of users when I don't use the space:
Code:

$ uptime; UPT=`uptime | awk -F'( |,)' '{print $2}' | awk -F ":" '{print $1}'`; echo $UPT
 17:14:06 up  4:58,  2 users,  load average: 0.96, 0.93, 0.81
17
$ uptime; UPT=`uptime | awk -F'(|,)' '{print $2}' | awk -F ":" '{print $1}'`; echo $UPT
 17:14:14 up  4:58,  2 users,  load average: 0.81, 0.90, 0.80
2 users


richwmn 02-17-2009 05:48 PM

here is my output using a cut 'n' paste from your post
18:42:48 up 15 days, 3:33, 4 users, load average: 0.13, 0.33, 0.27
3

Please note, that I have "up 15 days," emphasis on the comma. This makes the fields different. If your uptime is > 1 day the script might work as is, if so then consideration must be given for the case uptime < 1 day.

Rich

richwmn 02-17-2009 06:26 PM

Further info --
running both on Slackware 12.1 gives the result I reported, time with the space and uptime without.

running both on Ubuntu 10.8 gives time with the space and an error without

methinks it needs more research

A little bit more -
Slackware 12.1 contains GNU Awk 3.1.5, Ubuntu has another version MAWK, for which I can't determine a version.

Rich

syg00 02-17-2009 07:11 PM

Looks like a job for sed - " some stuff, whitespace, a digit (or 2), colon, 2 digits, a comma, more stuff."
Seems well enough formed to be simply parsable regardless of the intervening "days" or extraneous whitespace.

nx5000 02-17-2009 07:43 PM

awk -F "up |," '{print $2}'
Or with sed
sed 's/.*up \([^,]*\),.*/\1/'
And then convert in minutes and check.

BassKozz 02-17-2009 07:47 PM

Quote:

Originally Posted by syg00 (Post 3447634)
Looks like a job for sed - " some stuff, whitespace, a digit (or 2), colon, 2 digits, a comma, more stuff."
Seems well enough formed to be simply parsable regardless of the intervening "days" or extraneous whitespace.

Top results on google "sed uptime":
Code:

uptime | sed -e 's/.* \(.* days,\)\? \(.*:..,\) .*/\1 \2/' -e's/,//g' -e 's/ days/d/' -e 's/ up //'
;)

Now how can I get it to read the time properly so I can run my script to check if uptime is less than x number of hour(s)?

Code:

#!/bin/sh
# Test Script to see if uptime is less than 1 hours

UPT="uptime | sed -e 's/.* \(.* days,\)\? \(.*:..,\) .*/\1 \2/' -e's/,//g' -e 's/ days/d/' -e 's/ up //'"
HOURS="1"

if [ "$UPT" -lt "$HOURS" ]
then
        echo "uptime is less then $HOURS hours(s)"
        exit
else
        echo "uptime is greater than $HOURS hour(s)"
fi

Doesn't work because $UPT is formatted with a colon (i.e. if the uptime is 1hr and 36minutes = "1:36")
Any idea's?

syg00 02-17-2009 07:51 PM

Ugh - try this instead
Code:

sed -nr 's/.*\s+([[:digit:]]{1,2}):[[:digit:]]{2},.*/\1/p'

BassKozz 02-17-2009 08:02 PM

Quote:

Originally Posted by syg00 (Post 3447668)
Ugh - try this instead
Code:

sed -nr 's/.*\s+([[:digit:]]{1,2}):[[:digit:]]{2},.*/\1/p'

Alright so this is what I've got:
Code:

#!/bin/sh
# Test Script to see if uptime is less than $HOURS hour(s)

UPT=$uptime | sed -nr 's/.*\s+([[:digit:]]{1,2}):[[:digit:]]{2},.*/\1/p'
HOURS=2

if [$UPT -lt $HOURS]
then
        echo "uptime is less then $HOURS hours(s)"
        exit
else
        echo "uptime is greater than $HOURS hour(s)"
fi

Output:
Code:

[: 17: missing ]
?


All times are GMT -5. The time now is 06:16 PM.