Pages

Saturday, March 1, 2025

Bash Question

There seem to be no simple explanations that I can find.  All add more brackets and parentheses to accomplish what?

    if [[ ($yremaining+$millradius \> $yend) ]]; then

I want to see if yremaining + millradius is greater than yend.\

Conditional binary operator expected.

The answer seems to be

Corrected version (as text):


if (( yremaining + millradius > yend )); then

    echo "Condition met"

fi

I cannot believe how much I have forgotten.   My first three years at HP was maintaining, optimizing, and then factoring a 6000 line bash script.

If 6000 lines in one script sounds stupid,  yes it was. It was test tool that verified the functionality of the LaserJet firmware before we loaded into test mules.  Eventually, I factored it into several scripts each of which was still too large, but were at least comprehensible as to function.

This should not have been so hard.  Many good suggestions.  I decided to make a bash script that accepts two strings and returns an exit code (-1, 0, 1 for <,==,>).

 Of course, when you echo $?, because the exit code is returned as an unsigned byte it is 255.  This lets me do this test in multiple places with little pain.

#!/bin/bash
# rel: calculate <,==,> for two float strings
calculatedx=`echo $1 | bc -l`
calculatedy=`echo $2 | bc -l`
value=`echo "$1 < $2" | bc -l`
if [[ $value -eq 1 ]]; then
exit -1
fi
value=`echo "$1 > $2" | bc -l`
if [[ $value -eq 1 ]]; then
exit 1
fi
value=`echo "$1 ==  $2" | bc -l`
if [[ $value -eq 1 ]]; then
exit 0
fi

 

rel '20+.1' 21

echo $?

1

My efforts to get this working reliably in either bash or perl being unavailing, I wrote a program in C:

#include <stdio.h>
#include <float.h>
#include <stdlib.h>

int main (int argc, char* argv[])
{
  if ((argc >= 4) || (argc < 2))
{
  fprintf(stderr, "rel needs two arguments, both float\n");
  exit (4);
}
float arg1;
 if (1 != sscanf(argv[1], "%f", &arg1)) {
   printf("invalid argument %s\n",
      argv[1]);
  exit(4);
    };
float arg2;
 if (1 != sscanf(argv[2], "%f", &arg2)) {
  printf("invalid argument %s\n",
      argv[2]);
  exit(4);
  }
if (arg1 < arg2)
  {
    fprintf(stderr, "<\n");
    exit(-1);
  }
 else if (arg1 == arg2)
   {
   fprintf(stderr, "==\n");
   exit(0);
   }
 else
   {
     fprintf(stderr, ">\n");
     exit(1);
   }
}

Okay, the writes to stderr produce a flood of useless messages but I wanted to see what was happening.



2 comments:

  1. You could also:

    a=5
    b=2
    c=4

    t=$((a + b))

    if [[ $t -gt $c ]]
    then
    echo "in"
    fi

    ReplyDelete
  2. Just putting the off-line comment up here online. Bash doesn't do math on floats, so you need a different tool. Here's a bash function that calls perl to give you your desired behavior, int or float:

    function mycmp() {
    perl -e "{if ($1>$2){print 1} else {if ($1<$2) {print -1} else {print 0}}}"
    }

    ReplyDelete