【问题标题】:Variable scoping issue in Bash [duplicate]Bash中的变量范围问题[重复]
【发布时间】:2017-03-10 15:05:05
【问题描述】:

我有这个 Bash sn-p:

SourceFiles=()
grep --no-filename -R '^[a-zA-Z]' "$SourceDirectory/XilinxCoreLib/vhdl_analyze_order" | while read File; do
  SourceFiles+=("$SourceDirectory/XilinxCoreLib/$File")
done

echo $SourceFiles

它从磁盘读取一个文件,并将所有以字母字符开头的行通过管道传输到 while 循环。

我的问题是处理循环后$SourceFiles 为空。我在循环中添加了一个echo $File,它会打印文件中的所有行。所以我假设一个变量范围问题。

我应该在此处进行哪些更改才能使其正常工作?

【问题讨论】:

  • 这是BashFAQ #24
  • 顺便说一句,while IFS= read -r File; do 将减少名称 - 当您的文件名包含反斜杠文字或以空格结尾时,原始代码将表现不佳。有关使用 while read 循环的信息,请参阅 BashFAQ #1
  • 另外,如果你想打印整个数组(不仅仅是它的第一个元素),请使用printf '%s\n' "${SourceFiles[@]}",可选地使用%q\neval-safe 形式引用带有不可打印字符的文件名。
  • 数组由函数处理。 echo 仅用于调试:)。
  • 当然,但是如果您使用它进行调试并且在您希望看到 10 个名称时只看到一个名称,您可能会错误地认为 while read 代码仍然被破坏,而实际上错误是使用echo 命令。

标签: arrays bash variables while-loop scope


【解决方案1】:

管道的每个元素都在自己的子shell中运行,这意味着它自己的执行环境;因此,要解决此问题,您需要将 while-loop 移出管道。

最简单的解决方法是将grep 命令移动到进程替换中;也就是改变这个结构:

grep ... | while ...
  ...
done

到这里:

while ...
  ...
done < <(grep ...)

【讨论】:

  • 两个&lt;符号之间的空格没有错字?
  • @Paebbels,确实,这不是一个错字。 &lt;() 是一个进程替换构造,它评估为类似文件的对象的名称,而先前的 &lt; 是从相同的重定向。见the bash-hackers wiki entry on process substitution
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 2016-12-20
  • 2014-09-17
  • 1970-01-01
  • 2010-09-12
相关资源
最近更新 更多