Your script is giving you values that don’t match what you expected. Consider this simple script and its output:
$ bash oddscript good nodes: 0 bad nodes: 6 miss nodes: 0 GOOD=6 BAD=0 MISS=0 $ $ cat oddscript #!/bin/bash - badnode=6 printf "good nodes: %d " $goodnode printf "bad nodes: %d " $badnode printf "miss nodes: %d " $missnode printf "GOOD=%d BAD=%d MISS=%d " $goodnode $badnode $missnode
Why is 6
showing up as the
value for the good count, when it is supposed to be the value for the
bad count?
Either give the variables an initial value (e.g., 0
) or put quotes around the references to them
on printf
lines.
What’s happening here? bash does its
substitutions on that last line and when it evaluates $goodnode
and $missnode
they both come out null, empty, not
there. So the line that is handed off to printf to
execute looks like this:
printf "GOOD=%d BAD=%d MISS=%d " 6
When printf tries to print the three decimal
values (the three %d
formats) it has
a value (i.e., 6
) for the first one,
but doesn’t have anything for the next two, so they come out zero and we
get:
GOOD=6 BAD=0 MISS=0
You can’t really blame printf, since it never saw the other arguments; bash had done its parameter substitution before printf ever got to run.
Even declaring them as integer values, like this:
declare -i goodnode badnode missnode
isn’t enough. You need to actually assign them a value.
The other way to avoid this problem is to quote the arguments when
they are used in the printf
statement, like this:
printf "GOOD=%d BAD=%d MISS=%d " "$goodnode" "$badnode" "$missnode"
Then the first argument won’t disappear, but an empty string will be put in its place, so that what printf gets are the three needed arguments:
printf "GOOD=%d BAD=%d MISS=%d " "" "6" ""
While we’re on the subject of printf, it has one other odd behavior. We have just seen how it behaves when there are too few arguments; when there are too many arguments, printf will keep repeating and reusing the format line and it will look like you are getting multiple lines of output when you expected only one.
Of course this can be put to good use, as in the following case:
$ dirs /usr/bin /tmp ~/scratch/misc $ printf "%s " $(dirs) /usr/bin /tmp ~/scratch/misc $
The printf takes the directory stack (i.e.,
the output from the dirs
command) and
displays the directories one per line, repeating and reusing the format,
as described earlier.
Let’s summarize:
Initialize your variables, especially if they are numbers and you want to use them in printf statements.
Put quotes around your arguments if they could ever be null, and especially when used in printf statements.
Make sure you have the correct number of arguments, especially considering what the line will look like after the shell substitutions have occurred.
If you don’t need the special formatting that
printf offers (e.g., %05d
), consider using a simple
echo statement.
3.15.214.155