Shell阵列因未知原因而被清除

时间:2016-09-22 22:29:16

标签: arrays bash

我有一个非常简单的sh脚本,在那里我进行系统cat调用,收集结果并解析一些相关信息,然后将信息存储在array中,这似乎有效正好。但是一旦我退出存储信息的for循环,array似乎就会清除。我想知道我是否在for循环之外错误地访问了array。我脚本的相关部分:

    #!/bin/sh

    declare -a QSPI_ARRAY=()

    cat /proc/mtd | while read mtd_instance
    do
        # split result into individiual words
        words=($mtd_instance)
        for word in "${words[@]}"
        do
            # check for uboot 
            if [[ $word == *"uboot"* ]]
            then
                mtd_num=${words[0]}
                index=${mtd_num//[!0-9]/}    # strip everything except the integers
                QSPI_ARRAY[$index]="uboot"
                echo "QSPI_ARRAY[] at index $index: ${QSPI_ARRAY[$index]}"

            elif [[ $word == *"fpga_a"* ]]
            then
                echo "found it: "$word""
                mtd_num=${words[0]}
                index=${mtd_num//[!0-9]/}    # strip everything except the integers
                QSPI_ARRAY[$index]="fpga_a"
                echo "QSPI_ARRAY[] at index $index: ${QSPI_ARRAY[$index]}"

            # other items are added to the array, all successfully

            fi
        done
        echo "length of array: ${#QSPI_ARRAY[@]}"
        echo "----------------------"
    done

在退出for循环之前,我的输出很棒。在for循环中,array大小递增,我可以检查是否已添加该项。 for循环完成后,我检查array,如下所示:

    echo "RESULTING ARRAY:"
    echo "length of array: ${#QSPI_ARRAY[@]}"
    for qspi in "${QSPI_ARRAY}"
    do
        echo "qspi instance: $qspi"
    done

以下是我的结果,echo d到我的展示位置:

    dev:    size   erasesize  name

    length of array: 0
    -------------
    mtd0: 00100000 00001000 "qspi-fsbl-uboot"

    QSPI_ARRAY[] at index 0: uboot

    length of array: 1
    -------------
    mtd1: 00500000 00001000 "qspi-fpga_a"

    QSPI_ARRAY[] at index 1: fpga_a

    length of array: 2
    -------------

    RESULTING ARRAY:
    length of array: 0
    qspi instance:

编辑:经过一些调试后,似乎我在这里有两个不同的array。我初始化array就像这样:QSPI_ARRAY=("a" "b" "c" "d" "e" "f" "g"),在我的for循环之后解析array它仍然是a,b,c等。我怎么有两个不同的{{ 1}}这个名字在同一个地方?

2 个答案:

答案 0 :(得分:1)

这可能是您所看到的:

http://mywiki.wooledge.org/BashFAQ/024

答案 1 :(得分:1)

这个结构:

cat /proc/mtd | while read mtd_instance
do
...
done

意味着dodone 之间的任何内容都不会在done 之后的shell环境中产生任何影响。

while循环位于管道右侧(|)的事实意味着它在子shell中运行。一旦循环退出,子shell也会退出。以及所有可变设置。

如果你想要一个可以改变的while循环,不要使用管道。输入重定向不会创建子shell,在这种情况下,您只需直接从文件中读取:

while read mtd_instance
do
...
done </proc/mtd

如果您的命令比cat更复杂,则可能需要使用进程替换。仍以cat为例,如下所示:

while read mtd_instance
do
...
done < <(cat /proc/mtd)

在您的示例代码的特定情况下,我认为您可以稍微简化它,也许是这样:

#!/usr/bin/env bash    
QSPI_ARRAY=()
while read -a words; do␣
  declare -i mtd_num=${words[0]//[!0-9]/}
  for word in "${words[@]}"; do
    for type in uboot fpga_a; do
      if [[ $word == *$type* ]]; then
        QSPI_ARRAY[mtd_num]=$type
        break 2
      fi
    done
  done
done  </proc/mtd