• bash script

    From Spectre@21:3/101 to Anybody on Saturday, January 18, 2020 09:50:00
    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`
    echo "SABRETOOTH! Your Server Load Alert Needs Attention! " | mail -s
    "System Load Alert $load" spectre@tlp.zapto.org

    Can anyone riddle me why the current load avg doesn't make it into the alert email? $load isn't printing... thats nominally all one line, its just wrapped at 80 cols here.

    Spec


    --- SuperBBS v1.17-3 (Eval)
    * Origin: (21:3/101)
  • From Spectre@21:3/101 to Anybody on Saturday, January 18, 2020 09:50:00
    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`
    echo "SABRETOOTH! Your Server Load Alert Needs Attention! " | mail -s
    "System Load Alert $load" spectre@tlp.zapto.org

    Can anyone riddle me why the current load avg doesn't make it into the alert email? $load isn't printing... thats nominally all one line, its just wrapped at 80 cols here.

    Spec


    --- SuperBBS v1.17-3 (Eval)
    * Origin: (21:3/101)
  • From MeaTLoTioN@21:1/158 to Spectre on Saturday, January 18, 2020 00:55:45
    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`
    echo "SABRETOOTH! Your Server Load Alert Needs Attention! " | mail -s "System Load Alert $load" spectre@tlp.zapto.org

    Try this;

    load=$(cat /proc/loadavg | awk '{ print $1 }') && echo "SABRETOOTH! Your
    server load needs attention!" | mail -s "System load alert @ $load" spectre@tlp.zapto.org

    ---
    |14Best regards,
    |11Ch|03rist|11ia|15n |11a|03ka |11Me|03aTLoT|11io|15N

    |07 |08[|10eml|08] |15ml@erb.pw |07 |08[|10web|08] |15www.erb.pw |07Ŀ |07 |08[|09fsx|08] |1521:1/158 |07 |08[|11tqw|08] |151337:1/101 |07 |07 |08[|12rtn|08] |1580:774/81 |07 |08[|14fdn|08] |152:250/5 |07
    |07 |08[|10ark|08] |1510:104/2 |07

    --- Mystic BBS v1.12 A43 2019/03/02 (Linux/64)
    * Origin: The Quantum Wormhole, Ramsgate, UK. bbs.erb.pw (21:1/158)
  • From tenser@21:1/188 to Spectre on Friday, January 17, 2020 22:00:52
    On 18 Jan 2020, Spectre said the following...

    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`
    echo "SABRETOOTH! Your Server Load Alert Needs Attention! " | mail -s "System Load Alert $load" spectre@tlp.zapto.org

    Well, `load` is set to the output of `bc -l`. The input to `bc -l` is
    whatever you grep'ed out of /proc/loadvg, which is some number, '> 8'.
    That's almost certainly not what you want.

    Can anyone riddle me why the current load avg doesn't make it into the alert email? $load isn't printing... thats nominally all one line, its just wrapped at 80 cols here.

    Let's unpack what you're doing a little bit.

    First, to get the load average, you don't need `cat` or `echo` or the
    pipe to `bc`. You can just use `awk` directly:

    awk '{print $1}' /proc/loadavg

    Neato. But you want the value in some variable so you can do a comparison; let's do that:

    load=$(awk '{print $1}' /proc/loadavg)

    Now, `$load` is your load average. Now, if that's greater than 8, you
    want to send an email. How do we do the comparison, though? Here is
    where it gets tricky.

    The shell can't do arbitrary numeric comparisons itself; it's kind of
    dumb that way. But we CAN use the `expr` command, with the caveat that
    we need to make our arguments "look" like they're numbers to ensure we
    get numeric, rather than lexiographical, comparisons. Fortunately, the
    load average is already a number, as is the constant '8'. So, we can
    get `expr` to tell us whether the load is greater than 8, like so:

    expr $load '>' 8

    (Note the quotes around `>` to prevent it being interpreted by the shell.)

    `expr` will print 1 if this expression is true, or 0 if it's not. Now,
    we can test for THAT in the shell using the normal `test` syntax:

    if [ $(expr $load '>' 8) -eq 1 ]; then
    # send email here....
    fi

    Of course, we could use another command other than 'expr'; for example, we
    can use `bc` as you did earlier. But `expr` does what we need and is simple.

    Putting this all together, we end up with something like the following:

    #!/bin/sh
    load=$(awk '{print $1}' /proc/loadavg)
    if [ $(expr $load '>' 8) -eq 1 ]; then
    echo "High load average" | mail -s "load average is $load" foo@bar.com
    fi

    I haven't tested that, so there many be a syntax error in there, but that's
    the gist of it.

    --- Mystic BBS v1.12 A43 2019/03/03 (Raspberry Pi/32)
    * Origin: ACiD Underworld // acidunderworld.com:31337 (21:1/188)
  • From Spectre@21:3/101 to tenser on Saturday, January 18, 2020 16:11:00
    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`
    if [ "$load" -ne 0 ]; then

    This will make more sense, but I didn't realise what it was all doing at the time, and I left the logic operation out.

    Somehow in a fashion I don't completely understand renders the question a binary one, 1 or 0, which is why the loadavg is never printed at least not a way I recognised.

    Looking at your logic, I would be guessing in some way the cat can still be removed and it was a foible of whoever wrote it. I tend to do it that way too, I'm more used to redirection than what individial commands can do.

    I still don't quite get this though.

    awk '{print $1}') \> 8

    and how that becomes print if > 8..

    and bc is rendering the integer.

    In order to get what I was looking for, the actual load average into the message, I had to re-read "/proc/loadavg"

    Thanks for your time, and explanation.

    Spec


    --- SuperBBS v1.17-3 (Eval)
    * Origin: (21:3/101)
  • From Spectre@21:3/101 to tenser on Saturday, January 18, 2020 16:11:00
    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`
    if [ "$load" -ne 0 ]; then

    This will make more sense, but I didn't realise what it was all doing at the time, and I left the logic operation out.

    Somehow in a fashion I don't completely understand renders the question a binary one, 1 or 0, which is why the loadavg is never printed at least not a way I recognised.

    Looking at your logic, I would be guessing in some way the cat can still be removed and it was a foible of whoever wrote it. I tend to do it that way too, I'm more used to redirection than what individial commands can do.

    I still don't quite get this though.

    awk '{print $1}') \> 8

    and how that becomes print if > 8..

    and bc is rendering the integer.

    In order to get what I was looking for, the actual load average into the message, I had to re-read "/proc/loadavg"

    Thanks for your time, and explanation.

    Spec


    --- SuperBBS v1.17-3 (Eval)
    * Origin: (21:3/101)
  • From tenser@21:1/188 to Spectre on Saturday, January 18, 2020 01:34:20
    On 18 Jan 2020, Spectre said the following...

    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`
    if [ "$load" -ne 0 ]; then

    This will make more sense, but I didn't realise what it was all doing at the time, and I left the logic operation out.

    Somehow in a fashion I don't completely understand renders the question a binary one, 1 or 0, which is why the loadavg is never printed at least
    not a way I recognised.

    That's correct, because what you're actually getting out of the
    expression above is the value of a boolean (ie, true or false)
    expression printed as an integer: 1 for true, 0 for false.

    Let's unpack that expression a bit:

    load=`echo $(cat /proc/loadavg | awk '{print $1}') \> 8 | bc -l`

    So first you're using the `$(...)` syntax to perform command
    substitution: that is, you're running a command and substituting
    the output of that command into a program's argument list.
    The program in this case is `cat /proc/loadavg | awk '{print $1}'`.
    That is, use `cat(1)` to print the contents of the file /proc/loadavg
    (note that that 'file' is synthesized dynamically by the operating
    system; it's not e.g. a disk file) and then you're piping that to
    `awk` to extract the first field.

    The first thing to note here is that you don't need `cat` at all.
    `awk` is perfectly capable of opening and reading a file, so to
    get the first field out of /proc/loadavg, you could just run:

    awk '{print $1}' /proc/loadavg

    Now, you've got some number, and you're interpolating that number
    (as text) into the argument list to `echo`, so you end up with
    something like:

    load=`echo 1.23 \> 8 | bc -l`

    So here, you're doing command substitution again, but you're using
    the older (and obsolete!) syntax using backticks (the '`' characters)
    to do it. So the command you're running is:

    echo 1.23 \> 8 | bc -l

    That is, you're piping the string '1.23 > 8' to `bc -l`, then taking
    the output of that command, which will be the output from `bc` and
    assigning that to the variable `load`.

    But '1.23 > 8' is a boolean expression. The calculator program `bc`
    will evaluate that expression and print the result of the evaluation.
    Since that's a boolean value, and `bc` prints booleans as 1 (for true)
    or 0 (for false), that's what you're seeing assigned to `load`.

    So a few things here: first, one needs some way to evaluate the boolean
    in this program, and `bc` is a reasonable way to do that, but since
    we aren't preserving the value you read from `/proc/loadavg` anywhere,
    we're losing that value by the time we get the boolean back. Second,
    the `-l` argument to `bc` says to load its library (which includes
    functions for exponentiation, sin and other trigonometric functions,
    etc). But you're not using anything from the library and thus you
    really don't need the `-l`. `bc` is a bit of overkill for what you
    are trying to accomplish, though, which is why I used `expr`.

    Looking at your logic, I would be guessing in some way the cat can still be removed and it was a foible of whoever wrote it. I tend to do it that way too, I'm more used to redirection than what individial commands can do.

    Yes. `cat` is completely redundant; there used to be a (fake) award
    called the "useless uses of cat" award for things like this. It
    wasn't exactly mean-spirited, but was a bit snooty. But yeah, the
    upshot is that `cat` can go.

    I still don't quite get this though.

    awk '{print $1}') \> 8

    and how that becomes print if > 8..

    Ah; I think perhaps you're missing that the `awk` is connected to
    another command, and not part of the expression to you typed here:
    note the un-paired ')'.

    and bc is rendering the integer.

    In order to get what I was looking for, the actual load average into the message, I had to re-read "/proc/loadavg"

    Does the explanation above clear it up?

    Thanks for your time, and explanation.

    Sure thing!

    --- Mystic BBS v1.12 A43 2019/03/03 (Raspberry Pi/32)
    * Origin: ACiD Underworld // acidunderworld.com:31337 (21:1/188)
  • From Alterego@21:2/116 to tenser on Monday, January 20, 2020 17:53:54
    Re: Re: bash script
    By: tenser to Spectre on Fri Jan 17 2020 10:00 pm

    The shell can't do arbitrary numeric comparisons itself; it's kind of
    dumb that way. But we CAN use the `expr` command, with the caveat that

    Depends on the shell..

    if [ $(expr $load '>' 8) -eq 1 ]; then

    This could be changed to
    if [ $load -gt 8 ]; then ...
    ...deon


    ... When people are free to do as they please, they usually imitate each other --- SBBSecho 3.10-Linux
    * Origin: I'm playing with ANSI+videotex - wanna play too? (21:2/116)
  • From tenser@21:1/188 to Alterego on Monday, January 20, 2020 05:48:52
    On 20 Jan 2020, Alterego said the following...

    The shell can't do arbitrary numeric comparisons itself; it's kind of dumb that way. But we CAN use the `expr` command, with the caveat tha

    Depends on the shell..

    Note that I said "arbitrary".

    if [ $(expr $load '>' 8) -eq 1 ]; then

    This could be changed to
    if [ $load -gt 8 ]; then ...

    Sadly, no. `-gt` et al do integer comparisons, and don't understand
    fractional numbers like load averages:

    : well; [ 8.1 -gt 8 ] && echo greater
    -bash: [: 8.1: integer expression expected
    : well;

    Hence who delegating to a tool such as `expr` etc.

    --- Mystic BBS v1.12 A43 2019/03/03 (Raspberry Pi/32)
    * Origin: ACiD Underworld // acidunderworld.com:31337 (21:1/188)
  • From Alterego@21:2/116 to tenser on Monday, January 20, 2020 23:43:49
    Re: Re: bash script
    By: tenser to Alterego on Mon Jan 20 2020 05:48 am

    Sadly, no. `-gt` et al do integer comparisons, and don't understand fractional numbers like load averages:

    Well there you go - something I learnt today ... :)

    Thanks...
    ...deon


    ... The house of Lords is the British Outer Mongolia for retired politicians. --- SBBSecho 3.10-Linux
    * Origin: I'm playing with ANSI+videotex - wanna play too? (21:2/116)
  • From Spectre@21:3/101 to Alterego on Tuesday, January 21, 2020 09:31:00
    This could be changed to if [ $load -gt 8 ]; then

    The problem with this, is that BASH won't compare a decimal number to an integer. So you either have to convert the load avg, or do what they did with the faffing about turning it into a boolean.

    Spec


    *** THE READER V4.50 [freeware]
    --- SuperBBS v1.17-3 (Eval)
    * Origin: Scrawled in haste at The Lower Planes (21:3/101)
  • From Spectre@21:3/101 to tenser on Tuesday, January 21, 2020 09:33:00
    The shell can't do arbitrary numeric comparisons itself; it's
    kind of
    dumb that way. But we CAN use the `expr` command, with the

    SNAP!

    this time it was my turn :)

    Spec


    *** THE READER V4.50 [freeware]
    --- SuperBBS v1.17-3 (Eval)
    * Origin: Scrawled in haste at The Lower Planes (21:3/101)