Shell Array清除原因不明
问题描述:
我有一个非常简单的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
?
答
这种结构:
cat /proc/mtd | while read mtd_instance
do
...
done
意味着,无论do
和done
之间来不能有shell环境是内部的任何影响仍然有done
之后。
while
循环位于管道的右侧(|
)表示它在子外壳中运行。一旦循环结束,subshell也一样。和它的所有可变设置。
如果你想要一个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
你的家当,如果它完全被使用,需要是'#!/ bin/bash'。 '/ bin/sh'不支持数组。 – chepner