2

I've got a shell script doing connection performance test, that I timeout if it takes too long.

Upon timeout, it logs the results of a few commands so I can make myself an idea of the system status at the time of failure. I would like to run some commands depending on which phase of the test it timed-out.

I came up with the following script:

#!/bin/bash
TESTCASE="INITIAL"

function testing()
{
    let TESTCASE="FIRST"
    #do some testing

    let TESTCASE="SECOND"
    #do some testing

    let TESTCASE="THIRD"
    #do some testing
}

function logonerror(){
    if [ "$TESTCASE" = "FIRST" ]; then                  
       #logging command relevant to first test case
    elif [ "$TESTCASE" = "SECOND" ]; then                  
       #logging command relevant to second test case
    elif [ "$TESTCASE" = "THIRD" ]; then                  
       #logging command relevant to third test case                   
    fi
    #some additional standard logging
}

timeout 7200 cat  <( testing )
if (($? == 124)); then
    logonerror
fi
cleanup

The only issue I have is that it doesn't matter which phase it timed-out, when doing the logging it always think it is at the initial phase.

How can I make sure that the test phase information get correctly updated?

  • after the first function you can exit the script & then check the second script with exit. – Mongrel Jan 18 '16 at 9:17
  • @AngRed: if I understood you correctly, that would mean splitting my script in two, and I would like to avoid that if possible. – Eldros Jan 18 '16 at 9:22
  • just to understand were you have an error, you can try that – Mongrel Jan 18 '16 at 9:28
2

Your first problem is:

let TESTCASE="UNSET_INTEGER_VARIABLE_NAME"

let handles math. Assignments made in a let statement will assign integer values. In a shell arithmetic context the FIRST, SECOND, THIRD values you're assigning to $TESTCASE all evaluate to zero because they're considered to be unset variable names - not literal values.

unset FIRST
let TESTCASE=FIRST
echo "$TESTCASE"

0

...or...

FIRST=10
let TESTCASE=FIRST
echo "$TESTCASE"

10

So every assignment you do assigns the same value to $TESTCASE unless any variables named FIRST, SECOND, THIRD, or INITIAL are exported into its environment before it is run.

To assign the string FIRST to the shell variable $TESTCASE you should do:

TESTCASE=FIRST
echo "$TESTCASE"

FIRST

You might also consider case:

logonerror(){
    case $TESTCASE in
    (1)   : logging commands relevant to 1st test case
    ;;
    (2)   : logging commands relevant to 2nd test case
    ;;
    (3)   : logging commands relevant to 3rd test case
    ;;
    esac; : logging commands relevant to all test cases
}
testing()
    case $TESTCASE in
    (1) : do some testing
    ;;
    (2) : do some testing
    ;;
    (3) : do some testing
    ;;
    esac

    trap  cleanup         EXIT
{   trap 'logonerror >&2; exit' PIPE
    for TESTCASE in 1 2 3; do testing; done >&2;:
}|{ read -t 7200; kill -PIPE -0; }
  • I'm liking your solution, but there is no timeout anymore, which is important to me. – Eldros Jan 18 '16 at 12:19
  • @Eldros - this wasn't meant to preclude that block you had at the bottom, just the bits that it redefines. You can still use that of course. Put the for ... done in your <( process substitution ). – mikeserv Jan 18 '16 at 13:01
  • I've tested your solution, setting the timeout so it would interrupt the different testcases, but it always logged as if it were in the initial phase, the errlog function never being overwritten. – Eldros Jan 19 '16 at 9:33
  • @Eldros - oh, yeah. It's cause the defines don't take from without the subshell - just a sec. But can you tell me though what $! is supposed to be a return code or are you testing the PID for the last backgrounded process? Return codes come in $?, by the way. – mikeserv Jan 19 '16 at 9:36
  • My bad it is supposed to be $? I will edit that right away, – Eldros Jan 19 '16 at 9:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.