【问题标题】:Stalling problem with wildcard in bash scriptbash脚本中通配符的停滞问题
【发布时间】:2021-06-01 14:15:19
【问题描述】:

我对编写 bash 脚本非常陌生。这个问题可能很基础,但我还没有找到明确的答案。我正在 Windows 10 上安装 Ubuntu 子系统。

我正在运行一个包含以下条件的脚本:

if [ -z "$date1" ]; then
    date1=$(head -n 1 "$dir"/*.txt | sed "s/^[^0-9]*//g" | date +%Y%m%d -f - 2>/dev/null)
fi

遇到没有 .txt 文件的目录(dir 变量)时会遇到问题,但我不太了解问题的本质。我确实知道问题出在head 命令中,至少部分如此。我没有收到错误,脚本只是在到达没有 .txt 文件的目录时停止。我希望脚本继续前进。如果我在终端中单独运行该行(没有条件),我会收到 No such file or directory 错误,这是有道理的。真正让我困惑的是,如果我在通配符部分(即'*.txt')周围放置引号(单引号或双引号),那么脚本会吐出head 错误并继续前进。我有限且可能不正确的理解是,在这种情况下,引号意味着程序不再将* 视为通配符,而只是通过文字名称*.txt 查找文件。但我认为,当* 被 bash 解释时,它首先会查找任何可能的扩展,然后如果找不到,则尝试字面解释。那么为什么脚本会在一种情况下而不是另一种情况下停止。两者不应该只是给我同样的No such file or directory 错误,就像在脚本外运行时一样?

我还要提到,该脚本包含前面的条件,这些条件首先查找 .docx 文件,并且仅在没有 .docx 文件时才移动到 .txt 文件。它可以很好地处理没有 .docx 文件的情况,尽管该管道中的第一个命令是 unzip 而不是 headThis 问题似乎是相关的,但是由于脚本能够在通配符周围有引号时继续运行,并且由于它在没有 .docx 文件的类似情况下继续运行,所以我想了解这里的问题以及修复它的最佳方法。

感谢您的帮助。

【问题讨论】:

  • 可能是您在脚本中打开了 nullglob 吗?这可以解释停滞。使用 shopt nullglob 检查脚本中该点的 nullglob 状态。

标签: bash wildcard wildcard-expansion


【解决方案1】:

在引号中,* 不会扩展,而是文字 * 字符。

另一方面,当* 尝试扩展但失败时,会发生以下三种情况之一:

  • 它按字面意思解释为字符串*.txt(加上$dir/ 扩展的任何内容)
    • 您可以使用 shopt -u nullglob 强制执行此行为,这应该是默认设置。
  • 它扩展为空,使字符串$dir/*.txt 等于空字符串
    • 您可以使用 shopt -s nullglob 强制执行此行为。
  • 引发错误
    • 您可以使用 shopt -s failglob 强制执行此行为(或使用 shopt -u failglob 将其关闭)。

例子:

bash-5.0# shopt -s | grep glob
globasciiranges on
bash-5.0# echo *.asdf
*.asdf
bash-5.0# shopt -s nullglob
bash-5.0# echo *.asdf

bash-5.0# shopt -u nullglob
bash-5.0# echo *.asdf
*.asdf
bash-5.0# shopt -s failglob
bash-5.0# echo *.asdf
bash: no match: *.asdf
bash-5.0# shopt -s | grep glob
failglob        on
globasciiranges on

当 glob 扩展为空字符串时,head 将永远挂起,除非您输入标准输入(head $(echo '') | cat 永远不会完成,除非您输入)

【讨论】:

  • 所以从症状来看,听起来脚本已经运行了shopt -s nullglob,这就是问题所在。
  • 我确实在脚本中有shopt -s nullglob,老实说,我已经不记得为什么了。显然,我对它在做什么没有足够的了解。现在这很有意义。感谢大家的帮助和@jeremysprofile 的详细细分。这肯定会在未来为我服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 2011-03-18
  • 2015-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多