LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Shell Script Arrays - Running cat (https://www.linuxquestions.org/questions/programming-9/shell-script-arrays-running-cat-505552/)

revof11 11-28-2006 07:57 AM

Shell Script Arrays - Running cat
 
I wanted to write a shell script that utilized a non-acpi-directory command line interface to the battery charge of my laptop (I won't bother to go into the reasons). Everything was doing just fine until I attempted to run a cat on the /proc/acpi/battery/BATx/state information and store it in an array.

The following code is what I am using for my "test"
Code:

# load the list of avaialble batteries
dirList=( $(ls -1 $BATT_DIR) )

# make sure we have data in the array
if [ ${#dirList[@]} -lt 1 ]; then
  echo "No batteries located (I looked in $BATT_DIR)!"
  exit 3
fi

# now, load the data for each battery
for element in $(seq 0 $((${#dirList[@]} - 1)))
do
  # data load
  batt=${dirList[$element]}
  battStats=( $(cat $BATT_DIR/$batt/state) )

  for battElement in $(seq 0 $((${#battStats[@]} - 1)))
  do
    echo ${battStats[$battElement]}
  done
done

The data actually winds up in the array, but not in the format I was expecting it to. I was expecting my use of cat to place each line of the cat into the array as an individual element, not each row and column.

The output this is giving me is this:
Code:

present:
yes
capacity
state:
ok
charging
state:
charging
present
rate:
unknown
remaining
capacity:
5760
mAh
present
voltage:
unknown

This output I am expecting is this:
Code:

present:                yes
capacity state:          ok
charging state:          charging
present rate:            unknown
remaining capacity:      5760 mAh
present voltage:        unknown

While the output I have is an acceptable "hack" for utilization in my script, it doesn't really provide what I had hoped. I wanted to parse the text in case the data in that file changes in future acpi/kernel releases instead of just relying on hard-coded indexes utilizing the colon character as my "end of label" indicator.

This concerns me because I also want to cat the /proc/acpi/battery/BATx/info file for the "design capacity" in order to calculate the percentage of battery life remaining. If either changes, my shell script will wind up vomiting all over me.

I wanted to avoid doing this in C/C++, even though it fits the solution as well. But I may wind up switching to that if I can't get this working.

Thanks.

acid_kewpie 11-28-2006 08:03 AM

i've not done this with arrays in bash directly, but i'm sure you need to look at the $IFS vairable. by default IFS (Input Field Seperateor) is white space, so to delimit the output you have, everything seperated by some form of white space is a different record. instead, you'd want to change $IFS to be a new line temporarily. try this:

IFS='\n' battStats=( $(cat $BATT_DIR/$batt/state) )

revof11 11-28-2006 08:14 AM

Doing that is actually giving me a syntax error:

Code:

line 60: 0
1
2
3
4
5
6
7
8
9
10
11: syntax error in expression (error token is "1
2
3
4
5
6
7
8
9
10
11")

I attempted utilizing what you posted in two separate code format styles just to be safe as well. First I did exactly what you posted, second I separated the IFS and battStat population to two separate lines.

BTW... line 60 is the echo statement in this snippet:
Code:

for battElement in $(seq 0 $((${#battStats[@]} - 1)))
  do
    echo ${battStats[$battElement]}
  done


Roger Krowiak 11-28-2006 09:56 AM

In another thread I've found that there should be
Code:

IFS=$'\n'
which works perfectly for me. Anyone know why there must be the $ sign? It doesn't work withou it.

revof11 11-28-2006 12:36 PM

HUZZAH!!
Thank you SO much!

That works perfectly.
Now to just finish up the rest of my script.


All times are GMT -5. The time now is 08:54 AM.