我有一个非常简单的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}}这个名字在同一个地方?
答案 0 :(得分:1)
这可能是您所看到的:
答案 1 :(得分:1)
这个结构:
cat /proc/mtd | while read mtd_instance
do
...
done
意味着do
和done
之间的任何内容都不会在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