tags:

views:

74

answers:

1

I am trying to parse /proc/cmdline in my initramfs using a case statement.

CMDLINE=`cat /proc/cmdline`

for param in $CMDLINE ; do
    case "$param" in
    root=*|init=*)
        eval "$param"
    ;;
    rescue)
        escue="y"
    ;;
    drive*)
        echo -n $param
    ;;
    esac
done

Now the problem is where I have drive*, I want to take multiple instances of drive from cmdline and parse them all into an array.

So /proc/cmdline might look like this.

/dev/mapper/Betsy-root vga=792 quiet=y opt2=bar opt1=bar op3=bar drive1="abcde:key.gpg" drive2="qrstuv:key2.gpg" drive3="foobar:false"

Problem is during the case statement when I do drive*) $param now looks like this.

drive1="abcde:key.gpg"drive2="qrstuv:key2.gpg"drive3="foobar:false"

So curious the best way to accomplish what I want. Which would be to dynamically create an array of drives. For example

drive[0]
drive[1]
drive[2]

What I tried doing was just looking for [a-zA-Z]" and inserting a new line. That way they would be split up and I could toss them into an array. Although I never had any luck getting that to work how I hoped. So with all that said...

Not knowing how many instances there will be in /proc/cmdline. how can I push each drive[0-9] into an array. Or maybe this is just a bad place for a case statement? Any advice would be appreciated.

+2  A: 
drive*)
    drive_array+=($param)

bam! you've got your array. For compatibility with older bash versions:

drive*)
    drive_array=("${drive_array[@]}" $param)

If the original string had a space between the drive=, then your fine. If there is some cases where they do not do not have spaces, you have to do some extra work:

drive*)
    drive_array+=(${param//drive/ drive})

That does a global substitution to add a space in front of each drive, that way it is split into different elements in the array. Do the same transformation to make it compatible with older versions if you want.

Ian Kelling
echo $drive_array only shows the first item in the array. As mentioned above the biggest problem is $param is concating each drive into one big string. So instead of drive1="foo" drive2="bar" it returns drive1="foo"drive2="bar" these need to be split up before an array can be created.
gregf
They are split up in the array, which is exactly what you asked for. Perhaps you need to learn to use a bash array? Try google. Try: echo ${drive_array[1]} or echo "${drive_array[@]}".
Ian Kelling
Think you're miss understanding me. When you get $param everything is squished together, there is no space between each drive. So like I been saying $param looks like this. drive1="foo"drive2="bar" no spaces between them. So when you create the array its only one item not two
gregf
Ok. I guess I was misunderstanding you. Check the updated answer in a minute.
Ian Kelling
This did the trick thanks. Sorry for my terrible explanation of what I was looking for. Definitely learned something new here. Had no idea I could do regex within ${var}.
gregf