0

I have the following piece of code which checks the contents of two files against some values in order to return a result.

if [[ "$(/bin/cat ${TMP_FILE})" != "" ]]
then
    if [[ $(cat ${TMP_FILE}) -gt ${TEST1} ]]
    then
        res=503
        sec=101
    elif [[ $(cat ${TMP_FILE2}) -gt ${TEST2} ]]
    then
        res=503
        sec=102
    else
        res=200
        sec=103
    fi
else
    res=503
    sec=999
fi

Basically if $TMP_FILE is blank it jumps straight to the end sec=999.

But I am also getting a result whereby if $TMP_FILE2 is blank, it also jumps to the end. How is this, as I would have expected it to fail in the second or third section (sec=102 or sec=103).

IGGt
  • 2,457
  • In your last part when you say TMP_FILE2 is empty is there something in TMP_FILE? – BriGuy Oct 19 '17 at 14:48
  • TMP_FILE has a value in it, but TMP_FILE2 doesn't. – IGGt Oct 19 '17 at 14:53
  • The -gt operator is used to compare integer values, and you are dumping the content of the files on the left of the operator; this will probably fail. What are the values of ${TEST1} and ${TEST2}? And what are the contents of the files? – cesarv Oct 19 '17 at 15:15
  • Both files should contain numeric values (unless the files are empty). – IGGt Oct 19 '17 at 15:22

3 Answers3

2

You read the file three times(!)—granted there's probably file caching provided by the OS that makes this a little less bad (worst case: your script reads three different things as the file changes between reads)—but it may be more sensible to read the file contents, once, without forking out to cat, and then use the shell tests on those contents.

#!/usr/bin/env bash

# look ma no cat!
TMP_FILE_CONTENTS=$(<"$1")

if [[ -n "$TMP_FILE_CONTENTS" ]]; then
    if [[ "$TMP_FILE_CONTENTS" -gt 42 ]]; then
        echo more
    else
        echo less
    fi
else
    echo empty
fi

which for me produces something like

$ :> empty
$ echo 5 > small
$ echo 999999 > big
$ ./reed empty
empty
$ ./reed small
less
$ ./reed big  
more
$ 
thrig
  • 34,938
  • cheers, that seems to have fixed it. I think another process was modifying the file at the same time and my script was reading it in between updates causing strange results. – IGGt Oct 20 '17 at 08:15
  • @IGGt this solution deals with one file while your OP deals with two. Did you change the number of files you deal with? – cesarv Oct 20 '17 at 08:33
  • This solution suggested writing the contents to variables, rather than reading from the file each time. The fact the example only contains one file is neither here nor there. The same principle can be applied to multiple files. – IGGt Oct 20 '17 at 09:51
2

Use the -s operator to verify the files aren't empty; you don't need to use cat.

Also, note that on the elif I verify the second file isn't empty and if that is successful I make the comparison.

if [ -s "${TMP_FILE}" ]
then
    if [ $(cat "${TMP_FILE}") -gt ${TEST1} ]
    then
        res=503
        sec=101
    elif [ -s "${TMP_FILE2}" ] && [ $(cat "${TMP_FILE2}") -gt ${TEST2} ]
    then
        res=503
        sec=102
    else
        res=200
        sec=103
    fi
else
    res=503
    sec=999
fi
cesarv
  • 297
0

You definitely do not need to read any file more than once. I'm a bit uncertain about what logic you'd like to implement for when the second file is unavailable or empty, but this is a suggestion that shows how to read values from files and how to react to empty files:

#!/bin/sh

if read number <file1; then
    if [ "$number" -gt "$test1" ]; then
        res=503
        sec=101
    else
        if read number <file2 && [ "$number" -gt "$test2" ]; then
            res=503
            sec=102
        else
            res=200
            sec=103
        fi
    fi
else
    res=503
    sec=999
fi

This script will fall through to the last else branch if the first file does not exist or is empty. Otherwise, it will use the number read from the file in the first test.

The second file is read if the first test fails and its else branch (res=200, sec=103) is taken if the second file does not exist, is empty, or if the number is greater than $test2.

No check is made for whether the things read from the files are actually numbers. If they're not, you will get "integer expression expected" errors in the two arithmetic tests, and they will fail.

Related:

Kusalananda
  • 333,661