0

I am trying to produce a report on the state of the linux box with some summary information. I use jps to populate multiple arrays with the names of the instances of our application that is running. I then want to print these sorted arrays in 4 columns so we can see what is running easily.

I use some conditional logic to determine which array length is the longest. Because some arrays are shorter than others, simple looping through the longest value can cause array index out of bounds issues. So I would like to print an empty string in the columns where there are no values for that row.

The code below is what I current have, but it throws "Command not found" errors when it tries to execute the command inside the loop. The idea is to try and use conditional logic to determine if the current array is out of bounds and if so just print "".

I've tried with ` ` to make it appear as code. I've tried without them as well. I've tried without the " " and with them. I've tried with ${ } around variables and without. I've also tried with ( ) around the values and without.

I'm not quite understanding what is happening behind the scenes of this code and scripting on a Windows machine code that is meant for a command line linux box is not easy to debug. Any suggestions?

printf "| %-40s | %-40s | %-40s | %-40s |\n" "Array 1:" "Array 2:" "Array 3:" "Array 4:" >> ${OUTPUT}
for i in $(seq ${maxRows}); do
    (The command below is all on one line but to make it more readable here I entered on multiple.)
    printf "| %-40s | %-40s | %-40s | %-40s |\n" "`[[ ${i} > ${#Array1[@]} ]] && ("") ||
    ("${Array1[$i]}")`" "`[[ $i > ${#Array2[@]} ]] && "" || ${Array2[$i]}`" "`[[ $i > ${#Array3[@]} ]] 
    && "" || ${Array3[$i]}`" "`[[ $i > ${#Array4[@]} ]] && "" || ${Array4[$i]}`" >> ${OUTPUT}
done

1 Answer 1

1

in bash, array elements without a value can be access, and will return undefined values, which will be displayed as empty string. There is no need to check for individual array indices limit.

Technically, there are multiple issues with the quoting of the printf in the loop. Alternative:

for i in $(seq ${maxRows}); do
    printf "| %-40s | %-40s | %-40s | %-40s |\n" "${Array1[$i]}" "${Array2[$i]", "${Array4[$i]}" "${Array3[$i]}" >> $OUTPUT
done

Side notes: this approach will impose a limit of maxRows, as it will require the list 1 2 3 ... maxRows to fit into a single line. For higher limit

for ((i=1; i<=maxRows; i++)); do
    printf "| %-40s | %-40s | %-40s | %-40s |\n" "${Array1[$i]}" "${Array2[$i]", "${Array4[$i]}" "${Array3[$i]}" >> $OUTPUT
done
Sign up to request clarification or add additional context in comments.

4 Comments

I had it like this before, but I think it was throwing errors about the arrays, likely because I had for i in "${Array3[@]}" when I had determined that was the largest array. I switched this and added some code to calculate the largest size. I guess switching to a seq of numbers got rid of the old error I was seeing. Thanks again for the help! Bash scripting can be tricky when you are just starting out.
For the second part of what you were saying about the maxRows, do you mean that the way I have it causes all the elements of the arrays to be printed in 1 line as a giant string?
@Coolbreeze78 the comment about using 'for ((i=' vs using '$(seq ...' is about handling large size array. Using the $(seq) will limit you to few hundreds/thousands of arguments. If this is an issue, you will have to the user 'for ((' construct.
After switching the code around, I noticed the for loop would need to start at i=0 instead of 1 or you will miss the first row of values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.