reuel3
asked on
unix korn shell issue with if/elif/elif/elif condition
When looping through this while loop, I get to the first if condition which happens to be true. It should not get to any of the other elif conditions, right? I'm looping through a file and if the line doesn't have a ';' at the end, I want to log a message and go to the next line.
Also, can someone explain the significance of the brackets? It behaves differently if I have one or two brackets around a condition.
<code>
cat $LOGGING_INFO_FILE | while read LINE
do
firstChar=`echo $LINE | cut -f1 -d "/"`
if [[ $firstChar = "." ]]; then
restOfLine=`echo $LINE | cut -f2 -d "."`
echo " " >> $LOG_OUTPUT_FILE
echo $restOfLine >> $LOG_OUTPUT_FILE
echo "************************* ********** ********** ********** ********** " >> $LOG_OUTPUT_FILE
else
errorCodeLine=`echo $LINE | cut -f4 -d "," | cut -f1 -d ")"`
errorCode=`echo $LINE | cut -f4 -d "," | cut -f2 -d "." | cut -f1 -d ")"`
errorCodeFile=`echo $LINE | cut -f4 -d "," | cut -f1 -d "." | cut -f1 -d ")"`
lastChar=`echo $LINE | tail -2c`
commaCount=$((`echo "$LINE" | sed 's/[^,]//g' | wc -c` - 1 ))
count=0
count=`grep -ic $errorCodeLine $LOGGING_INFO_FILE`
if [[ $lastChar != ";" ]]; then
echo "This file contains a carriage return in the TEHelper.logMessage(). Please remove all carriage returns." >> $LOG_OUTPUT_FILE
hasError=1
elif [ commaCount -gt 3 ]; then
echo "This file contains comma's in TEHelper.logMessage(). Please remove all comma's from first parameter" >> $LOG_OUTPUT_FILE
hasError=1
elif [ $errorCodeFile != $ICNEC ]; then
echo "INVALID ERROR CODE -->" $errorCode " is not valid" >> $LOG_OUTPUT_FILE
hasError=1
elif [ $count -gt 1 ]; then
echo "ERROR CODE IS USED " $count " times -->" $errorCode >> $LOG_OUTPUT_FILE
hasError=1
fi
fi
</code>
Thanks,
Skip
Also, can someone explain the significance of the brackets? It behaves differently if I have one or two brackets around a condition.
<code>
cat $LOGGING_INFO_FILE | while read LINE
do
firstChar=`echo $LINE | cut -f1 -d "/"`
if [[ $firstChar = "." ]]; then
restOfLine=`echo $LINE | cut -f2 -d "."`
echo " " >> $LOG_OUTPUT_FILE
echo $restOfLine >> $LOG_OUTPUT_FILE
echo "*************************
else
errorCodeLine=`echo $LINE | cut -f4 -d "," | cut -f1 -d ")"`
errorCode=`echo $LINE | cut -f4 -d "," | cut -f2 -d "." | cut -f1 -d ")"`
errorCodeFile=`echo $LINE | cut -f4 -d "," | cut -f1 -d "." | cut -f1 -d ")"`
lastChar=`echo $LINE | tail -2c`
commaCount=$((`echo "$LINE" | sed 's/[^,]//g' | wc -c` - 1 ))
count=0
count=`grep -ic $errorCodeLine $LOGGING_INFO_FILE`
if [[ $lastChar != ";" ]]; then
echo "This file contains a carriage return in the TEHelper.logMessage(). Please remove all carriage returns." >> $LOG_OUTPUT_FILE
hasError=1
elif [ commaCount -gt 3 ]; then
echo "This file contains comma's in TEHelper.logMessage(). Please remove all comma's from first parameter" >> $LOG_OUTPUT_FILE
hasError=1
elif [ $errorCodeFile != $ICNEC ]; then
echo "INVALID ERROR CODE -->" $errorCode " is not valid" >> $LOG_OUTPUT_FILE
hasError=1
elif [ $count -gt 1 ]; then
echo "ERROR CODE IS USED " $count " times -->" $errorCode >> $LOG_OUTPUT_FILE
hasError=1
fi
fi
</code>
Thanks,
Skip
ozo, picked up the typo in the commaCount variable.
You are correct in your assumption about the elif tests. As soon as one of the if blocks is true, none of the other blocks are processed.
The difference between [ and [[ is that the former is effectively an alias for the /bin/test binary, whereas [[ uses the shell builtin test operator (for ksh and bash). Addtionally, the built in test operator has additional tests over the test binary, but do be aware it is shell specific.
Another way of handling the test for the ; is to do
if [[ $lastChar != ";" ]]; then
echo "This file contains a carriage return in the TEHelper.logMessage(). Please remove all carriage returns." >> $LOG_OUTPUT_FILE
continue
fi
The continue will continue to the next iteration of the while loop.
You are correct in your assumption about the elif tests. As soon as one of the if blocks is true, none of the other blocks are processed.
The difference between [ and [[ is that the former is effectively an alias for the /bin/test binary, whereas [[ uses the shell builtin test operator (for ksh and bash). Addtionally, the built in test operator has additional tests over the test binary, but do be aware it is shell specific.
Another way of handling the test for the ; is to do
if [[ $lastChar != ";" ]]; then
echo "This file contains a carriage return in the TEHelper.logMessage(). Please remove all carriage returns." >> $LOG_OUTPUT_FILE
continue
fi
The continue will continue to the next iteration of the while loop.
ASKER
I fixed ozo's typo suggestion and tried Tintin's "continue" suggestion and it still jumps directly out of the loop when this is true: if [[ $lastChar != ";" ]]. When that isn't true, it goes through the other conditions without exiting the loop. . . Why does it leave the while loop when this is true?
It is not jumping directly out of the loop when I run it.
Is there anything else in the loop? like a done
Could the $lastChar != ";" be on the last line of $LOGGING_INFO_FILE?
Is there anything else in the loop? like a done
Could the $lastChar != ";" be on the last line of $LOGGING_INFO_FILE?
How do you know it's jumping out of the loop?
I'd do
ksh -x scriptname
and post the relevant output where it shows it jumping out of the loop (I'm very sceptical).
Alternatively, post some sample data that we can run to see what's happening.
I'd do
ksh -x scriptname
and post the relevant output where it shows it jumping out of the loop (I'm very sceptical).
Alternatively, post some sample data that we can run to see what's happening.
ASKER
Its only making it through a ~30 lines of an expected ~500 lines so ";" is not the last char on the last line . . . There is a "done" however. Here is the rest of the code (I don't know why it wasn't included earlier):
done
if [[ $hasError -gt 0 ]]; then
echo "There is a problem in TEHelper.logMessage(). Check " $LOG_OUTPUT_FILE " for more details"
exit 99
fi
done
if [[ $hasError -gt 0 ]]; then
echo "There is a problem in TEHelper.logMessage(). Check " $LOG_OUTPUT_FILE " for more details"
exit 99
fi
Is there a blank line $LOGGING_INFO_FILE after the line with $lastChar != ";"?
I would put all string variables in double quotes in comparisons, e.g.
if [[ "$lastChar" != ";" ]]; then
This guards against the possibility that $lastChar is white space, which might cause a syntax error (and might be your problem)
if [[ "$lastChar" != ";" ]]; then
This guards against the possibility that $lastChar is white space, which might cause a syntax error (and might be your problem)
ASKER
no blank line.
I think I know its jumping out of the loop based on echo's I put in the file . . . Here is some sample input:
TEHelper.logMessage("Some String", "Error messages", e, ErrorCodes.a);
./a.java
TEHelper.logMessage("Some String", "Error messages", null, ErrorCodes.f);
./b.java
TEHelper.logMessage("Some String","Error messages",ex,ErrorCodes.d) ;
./c.java
SomeHelper.logMessage("Som e String", "Error messages", ex, ErrorCodes.d);
./d.java
SomeHelper.logMessage("Som e String", "Error messages", ex, ErrorCodes.h);
./e.java
SomeHelper.logMessage("Som e String", "Error messages",null,ErrorCodes. f);
./f.java
SomeHelper.logMessage("Som e String", "Error messages", ex, ErrorCodes.f);
./g.java
SomeHelper.logMessage("Som e String", "Error messages", ex, ErrorCodes.d);
./h.java
SomeHelper.logMessage("Som e String", "Error messages", ex, ErrorCodes.d);
./i.java
SomeHelper.logMessage("Som e String",msg,ex,ErrorCodes. f);
./j.java
SomeHelper.logMessage("Som e String", ""Error messages", ex, ErrorCodes.b);
./k.java
SomeHelper.logMessage("Som e String", ""Error messages", ex, ErrorCodes.h);
./l.java
SomeHelper.logMessage("Som e String", "Error messages", ex,ErrorCodes.f);
./m.java
SomeHelper.logMessage("Som e String","Error messages",null,ErrorCodes. d);
SomeHelper.logMessage("Som e String", msg, e, ErrorCodes.f);
SomeHelper.logMessage("Som e String", msg, npe, ErrorCodes.h);
SomeHelper.logMessage("Som e String", msg, pe, ErrorCodes.f);
SomeHelper.logMessage("Som e String","Error messages",null,ErrorCodes. f);
SomeHelper.logMessage("Som e String", "Error messages", pe, ErrorCodes.j);
SomeHelper.logMessage("Som e String","Error messages",null,ErrorCodes. k);
SomeHelper.logMessage("Som e String", "Error messages", pe, ErrorCodes.t);
./n.java
SomeHelper.logMessage("Som e String", "Error messages", e,
./o.java
SomeHelper.logMessage("Som e String", "Error messages", null,
./p.java
SomeHelper.logMessage("Som e String", msg, nfe, ErrorCodes.g);
SomeHelper.logMessage("Som e String", msg, npe, ErrorCodes.g);
./q.java
SomeHelper.logMessage("Som e String", "Error messages", nfe, ErrorCodes.j);
SomeHelper.logMessage("Som e String", "Error messages", nfe, ErrorCodes.k);
SomeHelper.logMessage("Som e String", "Error messages", nfe,ErrorCodes.j);
SomeHelper.logMessage("Som e String", "Error messages", nfe, ErrorCodes.j);
SomeHelper.logMessage("Som e String", "Error messages", nfe, ErrorCodes.r);
SomeHelper.logMessage("Som e String", "Error messages", nfe, ErrorCodes.w);
SomeHelper.logMessage("Som e String", ""Error messages", e, ErrorCodes.r);
SomeHelper.logMessage("Som e String", "Error messages", e, ErrorCodes.y);
I think I know its jumping out of the loop based on echo's I put in the file . . . Here is some sample input:
TEHelper.logMessage("Some String", "Error messages", e, ErrorCodes.a);
./a.java
TEHelper.logMessage("Some String", "Error messages", null, ErrorCodes.f);
./b.java
TEHelper.logMessage("Some String","Error messages",ex,ErrorCodes.d)
./c.java
SomeHelper.logMessage("Som
./d.java
SomeHelper.logMessage("Som
./e.java
SomeHelper.logMessage("Som
./f.java
SomeHelper.logMessage("Som
./g.java
SomeHelper.logMessage("Som
./h.java
SomeHelper.logMessage("Som
./i.java
SomeHelper.logMessage("Som
./j.java
SomeHelper.logMessage("Som
./k.java
SomeHelper.logMessage("Som
./l.java
SomeHelper.logMessage("Som
./m.java
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
./n.java
SomeHelper.logMessage("Som
./o.java
SomeHelper.logMessage("Som
./p.java
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
./q.java
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
SomeHelper.logMessage("Som
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Putting quotes around $errorCodeLine worked! I'm getting this error now:
"grep: RE error 41: No remembered search string."
Line 41:
errorCodeFile=`echo $LINE | cut -f4 -d "," | cut -f1 -d "." | cut -f1 -d ")"`
"grep: RE error 41: No remembered search string."
Line 41:
errorCodeFile=`echo $LINE | cut -f4 -d "," | cut -f1 -d "." | cut -f1 -d ")"`
ASKER
Is the reason why that worked because it was trying to grep a file with a null or invalid string because it wasn't getting built properly on malformed lines?
maybe you want -F or fgrep
ASKER
It has nothing to do with line 41. :) It is happens when I grep with an empty search string.
Thanks for all of your help.
Skip
Thanks for all of your help.
Skip
$commaCount -gt 3
see
man test
NAME
test, [test -- condition evaluation utility
SYNOPSIS
test expression [test expression ]
DESCRIPTION
The test utility evaluates the expression and, if it evaluates to true,
returns a zero (true) exit status; otherwise it returns 1 (false). If
there is no expression, test also returns 1 (false).
and
man bash
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the
conditional expression expression. Expressions are composed of
the primaries described below under CONDITIONAL EXPRESSIONS.
Word splitting and pathname expansion are not performed on the
words between the [[ and ]]; tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution,
process substitution, and quote removal are performed.