我正在尝试开发一个在 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 中有效(尽管意味着完全不同的东西),extglob
bash 会识别 ksh 扩展 glob 运算符的子集,包括*(something)
含义0个或something
多个。
这样做:
if [ -n "$BASH_VERSION" ]; then
shopt -s extglob
fi
在这种情况下,事先可以避免 bash 中的解析错误。*.txt(N)
例如,它对于模式没有帮助。