可移植地执行字段分割,但不能执行其他扩展

可移植地执行字段分割,但不能执行其他扩展

我曾经在存储编译器标志$variable时使用不带引号的扩展,但最近我了解到,像和包含的variableglob 元字符仍然被扩展,例如*?variable

$ f='*'
$ echo $f
foo.bash

除了set -f.

在 bash 中,我能想到的最明确的方法是定义一个read_words像这样的函数,该函数用作为参数传入的字符串的内容填充数组名称,然后用于${arr[@]}扩展该字符串。

#!/bin/bash

count() {
  printf '%s\n' "$#"
}


read_words() {
  IFS=$' \t\n' read -a "$1" <<< "$2"
  return 0
}

read_words arr 'a b *'
count "${arr[@]}"

答案1

set -f是在不通配的情况下进行字段分割的最便捷方法。

在 中bash,您可以通过测试来测试 shell 选项是否已设置-o。因此,您可以这样做:

if [ ! -o noglob ]; then
    set -f
    trap 'set +f' RETURN
fi

这将检测 shell 选项的状态noglob( 的长名称set -f)。如果未设置,则会设置并RETURN安装陷阱。noglob脚本完成后,陷阱将取消设置shell 选项,如果脚本来源。如果脚本没有来源,陷阱将不会执行任何操作。

有趣的提示:源脚本非常类似于 shell 函数。

答案2

在 Bash 中,您可以使用set使选项( 的内容$-)成为函数的本地选项local -。或者您可以在子外壳中运行所需的部分set -f,该子外壳应该是可移植的。

countwords() { local -; set -f; set -- $1; echo "$#"; }
countwords "a b *"

或者

countwords() ( set -f; set -- $1; echo "$#"; )
countwords "a b *"

相关内容