Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

My expectation of the following code is that I'll have two arrays of shared memory ID's. One that lists the ID's with zero attachments, and one that lists the ID's with more than zero attachments.

The command ouput that I'm parsing is:

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x6c020df2 131072     monitor    600        4276656    6                       
0x77020d34 4620289    usera      666        104        0                       
0x78020d34 4653058    usera      666        651328000  0                       
0x72020d34 4685827    usera      666        15808      0                       

And the code is as follows:

free_shmids=()
used_shmids=()

IFS=$'
'

for line in $(sudo ipcs -m | grep '0x'); do
  nattch=$(echo $line | awk '{ print $NF; }')
  shmid=$(echo $line | awk '{ print $2; }')

  if [ $nattch -eq "0" ]; then
    free_shmids+=($shmid)
  else
    used_shmids+=($shmid)
  fi
done

unset -v IFS

Instead, the list of free ID's is just the first free ID of the three available. I've only got one used shared memory segment here, so I assume that's failing the same way even though I can't prove it.

For reference, I'm running bash 4.3.11, so I'm pretty sure I've got access to the += syntax for arrays.

EDIT:

To iterate the array of free ID's, I'm doing this:

for id in $free_shmids; do
  echo $id
done

I intend to do something more complex in the body of the for loop, of course, but that exact method of iteration doesn't list every element of the array.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
194 views
Welcome To Ask or Share your Answers For Others

1 Answer

I bet you're doing this:

echo $free_shmid

Since that is an array, you're not using the right syntax. De-referencing an array without specifying an index will only give you the first element in the array. Do something like this:

    printf "free: %s
" "${free_shmid[@]}"
    printf "used: %s
" "${used_shmid[@]}"

And using a while read loop is generally preferred than using a for loop to read lines of input. For example

#!/bin/bash
data="------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x6c020df2 131072     monitor    600        4276656    6                       
0x77020d34 4620289    usera      666        104        0                       
0x78020d34 4653058    usera      666        651328000  0                       
0x72020d34 4685827    usera      666        15808      0                       "

echo "$data" | {
    read title       # first line
    read header      # second line
    # now read and process the rest
    while read -r key shmid owner perms bytes nattch status; do
        if ((nattch == 0)); then
            free_shmid+=($shmid)
        else
            used_shmid+=($shmid)
        fi
    done

    printf "free: %s
" "${free_shmid[@]}"
    printf "used: %s
" "${used_shmid[@]}"
}

outputs

free: 4620289
free: 4653058
free: 4685827
used: 131072

To iterate over the elements of an array, you must do this:

for elem in "${array[@]}"; do ...

Yes, all the quotes and other characters are absolutely required.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...