LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Shell script logical opeartors (https://www.linuxquestions.org/questions/linux-newbie-8/shell-script-logical-opeartors-629230/)

irfanb146 03-19-2008 11:17 AM

Shell script logical opeartors
 
Following the condition of sending mail
whenever any condition true the mail will go with warning, other wise mail will go with info.

Problem here is that whenever i put condition $f1<100000. the condition is not working and it is working when the digit is less than 100,000.


I want to find out why the condition is not working if digit is greater than 100,000

if [[ $d1>0.80 || $p1>70 || $f1<50000 || $g1<100 ]]
then
echo $f1
echo "Free disk space is $g1 GB,Free memory is $f1 KB,Processes are $p1,$b1"|mail -s "WARNING: in db CPU% is $c1" abc@xyz.com
else
echo $f1
echo "Free disk space is $g1 GB,Free memory is $f1 KB,Processes are $p1,$b1"|mail -s "INFO: in db CPU% is $c1" abc@xyz.com
fi

Ghodmode 03-20-2008 01:29 AM

Your operators are wrong. In shell scripting the greater-than and less-than signs are used for output redirection. See if you're inadvertently creating files named "0.80", "70", and named after the values of the variables $f1 and $g1.

To test for greater-than and less-than, use -gt and -lt.

ref: man test

Code:

if [[ $d1 -gt 0.80 || $p1 -gt 70 || $f1 -lt 50000 || $g1 -lt 100 ]]
then
        echo $f1
        echo "Free disk space is $g1 GB,Free memory is $f1 KB,Processes are $p1,$b1"|mail -s "WARNING: in db CPU% is $c1" abc@xyz.com
else
        echo $f1
        echo "Free disk space is $g1 GB,Free memory is $f1 KB,Processes are $p1,$b1"|mail -s "INFO: in db CPU% is $c1" abc@xyz.com
fi

--
-- Ghodmode

makyo 03-20-2008 05:04 AM

Hi.

It may be that the items in the comparison are not what you thought they were.

Here's an example that uses the relational operator (permissible within [[ ... ]]) and shows how it can fail:
Code:

#!/bin/bash -

# @(#) s2      Demonstrate evaluation in bash.

echo
echo "(Versions displayed with local utility \"version\")"
version >/dev/null 2>&1 && version =o $(_eat $0 $1)

one=1
big=100000

echo
echo " Files currently extant:"
ls

echo
if [[ $one < $big ]]
then
  echo " one, $one, tests less than big, $big"
else
  echo " unexpected failure in comparison."
fi

if [[ $one<$big ]]
then
  echo " one, $one, tests less than big, $big"
else
  echo " unexpected failure in comparison."
fi

big="junk"
if [[ $one<$big ]]
then
  echo " one, $one, tests less than big, $big"
else
  echo " unexpected failure in comparison."
fi

big="/junk"
if [[ $one<$big ]]
then
  echo " one, $one, tests less than big, $big"
else
  echo " one, $one, tests apparently greater than big, $big"
fi

echo
echo " Files currently extant:"
ls

exit 0

Producing:
Code:

% ./s2

(Versions displayed with local utility "version")
Linux 2.6.11-x1
GNU bash 2.05b.0

 Files currently extant:
readme.txt  s1  s2

 one, 1, tests less than big, 100000
 one, 1, tests less than big, 100000
 one, 1, tests less than big, junk
 one, 1, tests apparently greater than big, /junk

 Files currently extant:
readme.txt  s1  s2

EDIT 1: However, these are string tests, which is why there are no syntax errors posted. Confusingly, there is an alternate syntax for arithmetic tests that uses "<", but it is used with ((...)) -- see the 2-column table at http://www.tldp.org/LDP/abs/html/refcards.html#AEN20389 for details (left column numeric, right column string).

I suggest you post the smallest example of failed code along as well as the results. Please use code, /code tags around the code sections so that we can more easily read them ... cheers, makyo

(edit: clarify type of tests, add link)

irfanb146 03-25-2008 10:12 AM

Yes everything is working fine after i convert < to -lt and > to -gt

But following problem is occuring when i am using it with decimal number

0.380000 -lt 80

++ [[ 0.380000 -lt 80 ]]
./dada1.sh: line 10: [[: 0.380000: syntax error in expression (error token is ".380000")

makyo 03-25-2008 11:16 AM

Hi.

If you are using bash, there are restrictions on arithmetic:
Quote:

ARITHMETIC EVALUATION
The shell allows arithmetic expressions to be evaluated, under certain
circumstances (see the let builtin command and Arithmetic Expansion).
Evaluation is done in fixed-width integers with no check for overflow,
though division by 0 is trapped and flagged as an error.

-- excerpt from man bash
The Korn shell ksh and zsh can perform floating point arithmetic. Otherwise, you could do some scaling of the numbers to make them integers and then compare the new values.

You might be able to arrange the use of bc, which can also do floating point arithmetic, but you would need to pass the result of the comparison back as an exit status or some value on standard output. I haven't tried that, however. If I get a chance, I'll investigate that.

Best wishes ... cheers, makyo

(edit: add detail for bc)

konsolebox 03-26-2008 04:31 AM

same as makyo's idea, i thought of making a script
Code:

#!/bin/bash

errorexit() { echo "$1" >&2; exit 1; }

testf_decs() {
        local -i a b ac bc
        a=${1} b=${2} ac=${#a} bc=${#b}
        if [[ ac -ne bc ]]; then
                [[ ac -lt bc ]] && (( a = a*(10**(bc-ac)) )) || (( b = b*(10**(ac-bc)) ))
        fi
        eval "[[ ${a} ${2} ${b} ]]"
        return
}

testf() {
        [ $# -ne 3 ] && errorexit "invalid number of parameters"

        [[ $1 =~ ^[0-9]+\.{0,1}[0-9]*$ ]] || errorexit "first parameter is probably not a number"
        [[ $3 =~ ^[0-9]+\.{0,1}[0-9]*$ ]] || errorexit "third parameter is probably not a number"

        local -i a b x y

        if [[ ${1} =~ \. ]]; then
                a=${1%.*}
                x=${1#*.}
        else
                a=${1}
                x=0
        fi

        if [[ ${3} =~ \. ]]; then
                b=${3%.*}
                y=${3#*.}
        else
                b=${3}
                y=0
        fi

        case ${2} in
                -eq|-ne)
                        eval "[[ ${a} ${2} ${b} ]]" && testf_decs ${x} ${2} ${y}
                        return
                        ;;
                -ge|-le|-gt|-lt)
                        if [[ ${a} -eq ${b} ]]; then
                                testf_decs ${x} ${2} ${y}
                                return
                        else
                                eval "[[ ${a} ${2} ${b} ]]"
                                return
                        fi
                        ;;
                *)
                        errorexit "invalid operator ${2}"
                        ;;
        esac
}

testf $*
exit $?

the script got so long i never thought it would be this complicated.. splitting the numbers to arrays should make easier output but i hate to use external programs like grep or sed in this kind of script. it will lose its essence.. if we use external progs, we better just use those like bc instead as also just what makyo has said.

i really think this was just a waste of time but i thought i'll just finish and post it.

irfanb146 03-26-2008 04:44 AM

But < is doing fine with floating number. Is it better to use < instead of -lt then whenever there is a floating number we use < instead of -lt.

Is it correct

konsolebox 03-26-2008 08:52 PM

that won't work all the time.. check out

Code:

[[ 2.0 < 1234.0 ]] && echo a

konsolebox 03-26-2008 09:53 PM

edit:
Code:

#!/bin/bash

testfloat() {
        errorexit() { echo "$1" >&2; exit 1; }

        [ $# -ne 3 ] && errorexit "invalid number of parameters"

        [[ $1 =~ ^[0-9]+\.{0,1}[0-9]*$ ]] || errorexit "first parameter is probably not a number"
        [[ $3 =~ ^[0-9]+\.{0,1}[0-9]*$ ]] || errorexit "third parameter is probably not a number"

        case ${2} in
                -eq|-ne|-ge|-le|-gt|-lt)
                        ;;
                *)
                        errorexit "invalid operator ${2}"
                        ;;
        esac

        local -i a b x y

        if [[ ${1} =~ \. ]]; then
                a=${1%.*}
                x=1${1#*.}
        else
                a=${1}
                x=1
        fi

        if [[ ${3} =~ \. ]]; then
                b=${3%.*}
                y=1${3#*.}
        else
                b=${3}
                y=1
        fi

        if [[ ${a} -eq ${b} ]]; then
                local -i xc yc
                xc=${#x} yc=${#y}
                if [[ xc -ne yc ]]; then
                        [[ xc -lt yc ]] && (( x = x*(10**(yc-xc)) )) || (( y = y*(10**(xc-yc)) ))
                fi
                eval "[[ ${x} ${2} ${y} ]]"
                return
        else
                eval "[[ ${a} ${2} ${b} ]]"
                return
        fi
}

testfloat $*
exit $?


chrism01 03-27-2008 02:06 AM

I think you can do floating point if you use true arithmetic tests; see bottom of the page:http://www.tldp.org/LDP/abs/html/testconstructs.html

For the full list of which operators to use with which type of value, see: http://www.tldp.org/LDP/abs/html/comparison-ops.html

simplicissimus 03-27-2008 12:03 PM

PHP for commandline scripting
 
If you are familiar with C-style coding and have PHP installed, than it might make sense to use PHP for scripting.

You can run it like
Code:

$php my_script.php
pass parameters on the commandline
Code:

$php my_script.php some_value
and read these params within the code like
Code:

if ($argc > 1) print $argv[1] . "\n";
PHP has no problems with floating-point numbers and you can mix it with other UNIX utilities by using backticks or a system call
Code:

$date = `date`;
$filename = "myfile-".$date";
system ("echo 'this' > $filename");

Hope this helps,
Regards,
SIMP

Fedora Development

konsolebox 03-27-2008 09:31 PM

Quote:

Originally Posted by chrism01 (Post 3101697)
I think you can do floating point if you use true arithmetic tests; see bottom of the page:http://www.tldp.org/LDP/abs/html/testconstructs.html

For the full list of which operators to use with which type of value, see: http://www.tldp.org/LDP/abs/html/comparison-ops.html

i think those are only about integers


All times are GMT -5. The time now is 04:33 AM.