ChatGPT解决这个技术问题 Extra ChatGPT

How to do a logical OR operation for integer comparison in shell scripting?

I am trying to do a simple condition check, but it doesn't seem to work.

If $# is equal to 0 or is greater than 1 then say hello.

I have tried the following syntax with no success:

if [ "$#" == 0 -o "$#" > 1 ] ; then
 echo "hello"
fi

if [ "$#" == 0 ] || [ "$#" > 1 ] ; then
 echo "hello"
fi
They both work for me. Did you specify a shell in the shebang line?
@Jason I actually forgot the shebang line, but I tested it with it just now and it didn't work.
> is output redirection in sh/bash. Now you probably have a file named 1.
For information on Bash comparisons, please see my answers to previous questions here and here. For additional information regarding brackets, double brackets and double parentheses, see my answer here.
It doesn't work cause you mistype the compraison: use "$#" == "0" or $# -eq 0

J
JohannesM

This should work:

#!/bin/bash

if [ "$#" -eq 0 ] || [ "$#" -gt 1 ] ; then
    echo "hello"
fi

I'm not sure if this is different in other shells but if you wish to use <, >, you need to put them inside double parenthesis like so:

if (("$#" > 1))
 ...

I'm not sure if it's different in another shell but in bash, if you wish to use > or <, you have to put them in double parenthesis like so: (("$a" < "$b"))
@Doug: It's not that unix doesn't use them, it's that bash and all the other shells I know use them for input/output redirection.
j
jbremnant

This code works for me:

#!/bin/sh

argc=$#
echo $argc
if [ $argc -eq 0 -o $argc -eq 1 ]; then
  echo "foo"
else
  echo "bar"
fi

I don't think sh supports "==". Use "=" to compare strings and -eq to compare ints.

man test

for more details.


What is the option for greater than? Where's the official documentation for tihs?
Should be -gt for greater than. Or just replace it all with [ $# -ne 1 ].
Greater than is -gt, see my answer. The official documentation is in man test as jbremnant has pointed out.
Just as an fyi for others, depending on your shell, most support == (now a days) as an comparison operator, however most of the time it is the same as the = operator. I would imagine that if you are using -gt and -ne for comparisons that it would be better practice to use -eq for == or = to keep your scripting style consistent. Happy Bashing :)
l
luca76

If you are using the bash exit code status $? as variable, it's better to do this:

if [ $? -eq 4 -o $? -eq 8 ] ; then  
   echo "..."
fi

Because if you do:

if [ $? -eq 4 ] || [ $? -eq 8 ] ; then  

The left part of the OR alters the $? variable, so the right part of the OR doesn't have the original $? value.


$# returns the number of arguments passed to the script. Useful for checking correct usage. It doesn't seem like the asker is using exit codes.
T
TechNikh

Sometimes you need to use double brackets, otherwise you get an error like too many arguments

if [[ $OUTMERGE == *"fatal"* ]] || [[ $OUTMERGE == *"Aborting"* ]]
  then
fi

This is useful because it's the only thing here that I see showing an example of non-integer comparisons, which are slightly different in syntax.
Also, a space is required after "fatal"* . and "Aborting"* before closing ]
M
Mohammad Kanan

If a bash script

If [[ $input -gt number  ||  $input  -lt number  ]]
then 
    echo .........
else
    echo .........

fi

exit

J
John Boker

have you tried something like this:

if [ $# -eq 0 ] || [ $# -gt 1 ] 
then
 echo "$#"
fi

Yes, I have. It echos hello even when I have a single argument.
The second $# might be the return value of the first test?
f
fedorqui

From Bash Reference Manual → 3.4.2 Special Parameters

# ($#) Expands to the number of positional parameters in decimal.

Therefore, $# will always be either 0 or a bigger integer.

So if you want to do something whenever $# is either 0 or bigger than 1, you just have to check if $# is or is not 1:

[ $# -eq 1 ] && echo "1 positional param" || echo "0 or more than 1"

This uses the syntax:

[ condition ] && {things if true} || {things if false}

in bash you can do something like: [[ -n $A ]] && echo 1 || echo 2
@premek.v thanks for the comment. My answer was very badly explained, I just edited it in the hope that it sheds more light to the topic.
R
Ravi Tyagi

And in Bash

 line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
 vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
 echo "-------->"${line1}
    if [ -z $line1 ] && [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
   fi

OR in Bash

line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
echo "-------->"${line1}
   if [ -z $line1 ] || [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
  fi