如何使 bash 可以使用 zsh 的 (N) 个模式?

如何使 bash 可以使用 zsh 的 (N) 个模式?

我正在尝试开发一个在 zsh 和 Bash 中运行(并且理想情况下执行相同的操作:-) 的脚本。问题是,在某个时刻,zsh 特定部分包含以 结尾的模式(N)。所以:this_pattern*(N)。在 zsh 中,如果没有匹配项,这会使模式扩展为空。

Bash 对此表示,“意外符号导致语法错误”。请注意,Bash 上的执行永远不会发生在 zsh 特定部分上,并且此错误消息是由解析代码引起的!

我能否以某种方式帮助 Bash 吃掉它,例如不解析它?

答案1

zsh_expn

  N      sets the NULL_GLOB option for the current pattern

因此,bash 方法是nullglob为该模式设置选项。

( shopt -s nullglob || setopt NULL_GLOB && yourcommand this_pattern* )

会起作用,并仅为 . 生成的子 shell 设置该选项(…)。 (要么shopt失败setopt,要么分别作为 bash 和 zsh 内置,但有效的设置选项使没有匹配的模式消失而不会出现错误。&&并且||具有从左到右的评估。)

请注意,这当然缺乏美感(抱歉,@StéphaneChazelas!),并且子 shell 的创建会带来性能损失。但您想要可移植性,因此您无法真正使用 zsh 特定的功能。

答案2

如果它位于 zsh 特定的部分,您可以避免 bash 抱怨解析该代码永远不会通过执行以下操作来运行:

eval 'cmd this_pattern*(N)'

代替

cmd this_pattern*(N)

eval从语法 PoV 来看,该命令在 bash 中是有效的。它只会变得无效,eval如果跑步在这种情况下,它会尝试解释cmd this_pattern*(N)bash 中无效的代码。

现在,在这个具体案例中,

cmd this_pattern*(N)

如果您启用该选项,则实际上在 bash 中有效(尽管意味着完全不同的东西),extglobbash 会识别 ksh 扩展 glob 运算符的子集,包括*(something)含义0个或something多个

这样做:

if [ -n "$BASH_VERSION" ]; then
  shopt -s extglob
fi

在这种情况下,事先可以避免 bash 中的解析错误。*.txt(N)例如,它对于模式没有帮助。

相关内容