【问题标题】:Does ash have an equivalent to bash's 'nullglob' option?ash 是否与 bash 的“nullglob”选项等效?
【发布时间】:2011-01-29 20:24:36
【问题描述】:

如果 glob 模式不匹配任何文件,bash 将只返回文字模式:

bash-4.1# echo nonexistent-file-*
nonexistent-file-*
bash-4.1#

您可以通过设置nullglob shell 选项来修改默认行为,因此如果没有匹配项,您将得到一个空字符串:

bash-4.1# shopt -s nullglob
bash-4.1# echo nonexistent-file-*

bash-4.1# 

那么ash 中是否有等效选项?

bash-4.1# ash
~ # echo nonexistent-file-*
nonexistent-file-*
~ # shopt -s nullglob
ash: shopt: not found
~ # 

【问题讨论】:

    标签: bash shell scripting shopt


    【解决方案1】:

    对于没有nullglob 的shell,例如ash 和dash:

    IFS="`printf '\n\t'`"   # Remove 'space', so filenames with spaces work well.
    
    # Correct glob use: always use "for" loop, prefix glob, check for existence:
    for file in ./* ; do        # Use "./*", NEVER bare "*"
        if [ -e "$file" ] ; then  # Make sure it isn't an empty match
            COMMAND ... "$file" ...
        fi
    done
    

    来源:Filenames and Pathnames in Shell: How to do it correctly (cached)

    【讨论】:

    • 我觉得这种情况下不需要设置IFS
    • 这仅适用于碰巧匹配自己的 glob。它不是 nullglob 的一般替代品。
    • 它用test "$(echo file-*)" = "file-*" && true || <something using files>解决了它
    【解决方案2】:

    这种方法比每次迭代检查是否存在更高效:

    set q-*
    [ -e "$1" ] || shift
    for z; do echo "$z"
    done
    

    我们使用set 将通配符展开到shell 的参数列表中。如果参数列表的第一个元素不是有效文件,则 glob 不匹配任何内容。 (与一些常见的尝试不同,即使 glob 的第一个匹配项是在名称与 glob 模式相同的文件上,这也能正常工作。)

    在不匹配的情况下,参数列表包含单个元素,我们将其移出,因此参数列表现在为空。那么for 循环将根本不执行任何迭代。

    否则,我们循环遍历 glob 扩展为的参数列表(这是在 for variable 之后没有 in elements 时的隐式行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      • 2011-11-19
      • 1970-01-01
      • 2011-05-28
      相关资源
      最近更新 更多