“configure.ac”中“case”中的双方括号 i[[3456]]86

“configure.ac”中“case”中的双方括号 i[[3456]]86

我试图理解以下代码片段。

host_cpu='i386'

case "$host_cpu" in
   i[[3456]]86)
       echo "host_cpu=i386"
   ;;
   x86_64)
       echo "host_cpu=x86_64"
   ;;
   *)
       echo "AC_MSG_ERROR([unsupported CPU type]) "
   ;;
esac

我自己添加了变量host_cpu='i386'来测试代码,它切换到了第三种情况echo "AC_MSG_ERROR([unsupported CPU type]) "

如果我将双括号更改i[[3456]]86)为单括号(如 中所示)i[3456]86),它将切换到第一个选项,产生i386。这对我来说似乎是正确的。

我明白这一点,[并且[[是测试选项。测试条件似乎不适用于此处,因为 switch case 期望输出一个字符。所以我假设 bash 将其作为测试条件,需要用空格分隔,如[ a < b ][[ a << b ]]。由于这些 case 语句中没有空格,因此它将被视为正则表达式。它是否正确?

所以我的问题是为什么代码编写者在这里使用双方括号?当我尝试运行代码时它不起作用,所以他们的意图是什么。

注意:该代码取自configure.acGRUB 源代码中的 a。

另外 $host_cpu 和 host_cpu=i386 行似乎没有必要,你能解释一下为什么作者会这样做:

AC_CANONICAL_HOST

case "$host_cpu" in
    i[[3456]]86) host_cpu=i386 ;;
    x86_64) host_cpu=x86_64 ;;
    *) AC_MSG_ERROR([unsupported CPU type]) ;;
esac

AC_SUBST(host_cpu)
AC_SUBST(host_vendor)

我正在考虑使用 AC_SUBST($host_cpu)。你为什么不这样做呢?

答案1

如果这是来自文件configure.ac,那么它不是纯 shell 脚本,而是使用M4,其中[]是引号字符。:

要充分理解正确引用的重要性,您首先需要知道 Autoconf 中的特殊字符是什么: ' #' 引入注释,其中不执行宏扩展,' ,' 分隔参数,' [' 和 ' ]' 是引号本身, ' (' 和 ' )'(M4 尝试成对匹配),最后是$宏定义内的 ' '。

每次可以进行宏展开时,都会有一次报价展开,即剥离一层报价:

 int tab[10];
 ⇒int tab10;
 [int tab[10];]
 ⇒int tab[10];

[[3456]]应该由 autoconf 扩展为[3456],这将是用作 shell 脚本的正确输出。

相关内容