2016-09-22 67 views
0

我有一個非常簡單的sh腳本,我在這裏製作系統cat調用,收集結果並解析一些相關信息,然後將信息存儲在array中,這似乎工作得很好。但是,只要我退出存儲信息的for循環,array似乎就清楚了。我想知道是否在for循環之外錯誤地訪問array。我的腳本的相關部分:Shell 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等。我怎麼在這裏有兩個不同的arrays

+2

你的家當,如果它完全被使用,需要是'#!/ bin/bash'。 '/ bin/sh'不支持數組。 – chepner

回答

1

這種結構:

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

意味着,無論dodone之間來不能有shell環境是內部的任何影響仍然有done之後。

while循環位於管道的右側(|)表示它在子外殼中運行。一旦循環結束,subshel​​l也一樣。和它的所有可變設置。

如果你想要一個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