【问题标题】:Adding values to bash arrays向 bash 数组添加值
【发布时间】:2016-10-14 00:19:26
【问题描述】:

我对以下代码的期望是我将拥有两个共享内存 ID 数组。一种列出带有零个附件的 ID,另一种列出带有多个零个附件的 ID。

我正在解析的命令输出是:

------ 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                       

代码如下:

free_shmids=()
used_shmids=()

IFS=$'\n'

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

相反,空闲 ID 列表只是三个可用 ID 中的第一个空闲 ID。我这里只有一个使用过的共享内存段,所以我认为即使我无法证明它也会以同样的方式失败。

作为参考,我正在运行 bash 4.3.11,所以我很确定我可以访问数组的 += 语法。

编辑:

为了迭代空闲 ID 的数组,我这样做:

for id in $free_shmids; do
  echo $id
done

当然,我打算在 for 循环的主体中做一些更复杂的事情,但是这种精确的迭代方法并没有列出数组的每个元素。

【问题讨论】:

  • 仅供参考,for line in $(foo) 是一种代码异味——例如,如果您有一行仅包含 *,它将扩展为当前目录中的文件列表。请参阅 BashFAQ #1 了解正确的方法。

标签: linux bash


【解决方案1】:

我打赌你正在这样做:

echo $free_shmid

由于这是一个数组,因此您没有使用正确的语法。在不指定索引的情况下取消引用数组只会为您提供数组中的第一个元素。做这样的事情:

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

使用while read 循环通常比使用for 循环来读取输入行更受欢迎。例如

#!/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\n" "${free_shmid[@]}"
    printf "used: %s\n" "${used_shmid[@]}"
}

输出

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

要遍历数组的元素,您必须这样做:

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

是的,所有引号和其他字符都是绝对必需的。

【讨论】:

  • 哦,这是一种更时髦的做事方式。谢谢你。但是,我实际上是在编译后使用另一个for 循环来读取数组。我会将 sn-p 附加到我原来的问题中。
猜你喜欢
  • 2016-10-03
  • 2017-03-14
  • 1970-01-01
  • 2010-09-17
  • 2023-04-10
  • 1970-01-01
  • 2021-03-24
  • 2012-07-04
  • 1970-01-01
相关资源
最近更新 更多