1

I wrote small script under Debian Linux 11 that should check how many instances of application is currently running and what is power usage of GPU cards. I save it under name test , and she is started every time I access instance over SSH

#!/bin/sh
clear
a=$(nvidia-smi -q -i 0 | grep "Power Draw" | cut -c45-50) 
b=$(nvidia-smi -q -i 1 | grep "Power Draw" | cut -c45-50) 
c=$(nvidia-smi -q -i 2 | grep "Power Draw" | cut -c45-50) 
d=$(nvidia-smi -q -i 3 | grep "Power Draw" | cut -c45-50) 
zet=$( echo "$a" + "$b" + "$c" + "$d"  | bc -l )
echo "SYSTEM DRAW:" "$zet"
if [ "${zet}" -gt 150 ]; then          
echo WARRNING - SYSTEM DRAW LOW                                       
else
echo OK  
fi
sleep 8
exit
Pepi48
  • 21
  • 3
  • 2
    `power=$150` , but what is the value of variable `$150` ? I do not see it defined? – Ron Feb 05 '23 at 00:10
  • 3
    There's a whole lot wrong with your script, try putting it through [ShellCheck](https://shellcheck.net), but also visit https://stackoverflow.com/questions/18668556/how-can-i-compare-numbers-in-bash – tink Feb 05 '23 at 00:17
  • And you'll do well to read, review and take to heart the items on this page : https://stackoverflow.com/tags/bash/info . Skip the Version information at the top and search for the section labeled "Before asking about Problematic code" and "How to turn a bad script into a good question" .Good luck. – shellter Feb 05 '23 at 02:17
  • Also, if you really have named your script `test` avoid a whole bunch of mysterious errors by renaming it `mytest` or something else. `test` is a standard part of all (sh, bash, ksh, zsh) shell "languages" and having another command available that responds to `"test"` will not be fun to debug. Good luck! – shellter Feb 05 '23 at 02:20
  • `if [ "$total" -gt "$power" ] ...` as one of possible variants. – dimich Feb 05 '23 at 04:43
  • 1
    `>` is the redirection operator. `[ foo > bar ]` is equilvalent to `test foo > bar` and creates an empty file named `5`. For string comparision use `[ foo '>' bar ]`. For numerical (integer) comparision use `-gt` instead of `'>'`. See _man test_ for the details. – user1934428 Feb 05 '23 at 06:57
  • 1
    `$150` is interpreted as `${1}50`, i.e. the first positional parameter, with the string `50` appended. I don't know what you want to do here. `${150}` would fetch the 150th positional parameter, but I doubt that this is what you intended. – user1934428 Feb 05 '23 at 07:00

5 Answers5

1

All I need to add is this line x=${x%.*} That convert decimal number in number without decimals and script works perfect.

Pepi48
  • 21
  • 3
0

You could add set -x right before the part you want to debug, which will show you a debug of what is happening in bash. and stop it by inserting after that set +x

like:

set -x
power=$150
echo "SYSTEM DRAW :" $total
if [ $total \> $power ] ; then # escape > otherwise it redirects output

I do not think you are setting the value of $150

The script might be failing if one of the compared values is not set.. so you should initialize your variables to be let' say equal to 0 as a default at the beginning of your script, or via bash

like:

power=${150:-10} # if $150 does not have a value or empty, the default value of $power will be set to `10`
Ron
  • 5,900
  • 2
  • 20
  • 30
  • He's not comparing anything ... he's executing `$total` and redirecting its output to the content of `$power` ... – tink Feb 05 '23 at 00:20
  • Better: but what he **really** wants is `[ "$total" -gt "$power" ]` ... (provided they're integer values). – tink Feb 05 '23 at 00:48
  • [ "$total" -gt "$power" ] - I also got error - illegal number – Pepi48 Feb 05 '23 at 14:16
  • did you run your script with `-x` as explained above to confirm `$power` actually hods a value and is not empty? If one of the sides is empty of course you cannot compare. – Ron Feb 05 '23 at 14:38
0

So many possible issues but you can compare possibly decimal values using bc:

if [ "$(echo "$total > $power" | bc)" = 1 ]; then
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • This seems like massive overkill, executing a separate process and capturing its output, when the shell can do this directly. – Chris Dodd Feb 05 '23 at 01:04
  • @ChrisDodd Indeed. Unfortunately the common shell doesn't support decimals. Not even Bash. Not sure about Zsh. – konsolebox Feb 05 '23 at 01:10
  • bash certainly does with `((` -- and since the question is marked `linux`, one can assume bash. – Chris Dodd Feb 05 '23 at 01:12
  • Also I chose not to presume he's using / want to use Bash, even with the likely availability. With all those other subshell statements, a subshell command like this isn't an immediate worry. – konsolebox Feb 05 '23 at 01:13
  • @ChrisDodd No, a decimal will cause invalid arithmetic error. With Bash best you can only do is use a here document instead of a pipe and an echo. And use `[[ ]]`. – konsolebox Feb 05 '23 at 01:15
0

As the comments recommend, use shellcheck, however, I think your intention is not what you wrote.

Try this, create a script (i.e. myscripy)

#! /bin/bash

power=$150
echo "power=$power"

then run it

./myscript abc

and prints

power=abc50

which is probably very different than what you expect.

That is because power will take the first argument's value ($1) and append 50.

If you wanted argument number 150 (also very unlikely), you should write

power=${150}

but if you want just the number

power=150

edit

based on the comment, use

zet=$(bc <<<"$a+$b+$c+$d")

to calculate zet if the values are floating points.

For the comparison use

if [ "$(bc <<<"$zet>150")" == 1 ]; then
  ...
fi
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
0

One problem is that [ (and [[) do string comparisons, and you want a numeric comparison. For that you want to use ((, so something like

if (( $total > 150 )); then
    echo "WARNING..."
else
    echo "OK"
fi

will work better. Otherwise a total of 1000 would print ok, and 90 would give a warning.

Other problems:

  • $150 gives you the value of a variable called 150 -- you probably want to remove the $
  • Outside of special forms like [[ and ((, a > will do an output redirection, rather than being a 'normal' argument to a command such as [.
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • AFIK, `(( .... ))` does not work in POSIX shells (though `$(( ... ))` does). Note that the question is tagged _shell_, which means that the OP is interested in a POSIX solution. – user1934428 Feb 05 '23 at 07:02