使用括号操作短路 zsh if 语句中的变量

使用括号操作短路 zsh if 语句中的变量

在 zsh 完成函数中,我遇到以下 if 语句

if _cache_invalid my_data || ( [[ ${+_my_array_var} -eq 0 ]] && ! _retrieve_cache my_data ) ; then ...

想法是:如果缓存无效,则进入 if 块。否则检查是否_my_array_var已设置,如果没有尝试从缓存中检索它。如果_my_array_var未设置并且如果缓存检索失败,则还输入 if 块。就我的调试而言,if 语句的逻辑很好,但是_my_array_var如果从缓存中成功检索变量,则if 语句的后半部分无法填充变量。

在一个较短的测试中,我发现我责怪括号

echo ${+_my_array_var}
if [[ ${+_my_array_var} -eq 0 ]] && !_retrieve_cache my_data; then echo "entered" ; fi
echo ${+_my_array_var}

0与当时的情况相呼应1(即_my_array_var未设置,缓存检索起作用,然后_my_array_var设置。当我添加括号时

echo ${+_my_array_var}
if ( [[ ${+_my_array_var} -eq 0 ]] && !_retrieve_cache my_data ); then echo "entered" ; fi
echo ${+_my_array_var}

这会回显0两次,即 if 块仍然没有进入,但人口_my_array_var没有“离开” if 测试。

所以在我看来,在原始代码中,我应该去掉括号,但我想这样做而不改变表达式的层次结构或短路行为。

如何在不使用括号的情况下设置||&&关联性?

答案1

在所有类似 Bourne 的 shell 中,like 中的括号zsh表示运行子 shell。

要将命令分组,请使用{ ...; } 指挥组反而:

if
  _cache_invalid my_data || {
    (( $+_my_array_var == 0 )) &&
      ! _retrieve_cache my_data
  }
then ...

或者:

if
  _cache_invalid my_data || ! {
    (($+_my_array_var )) || _retrieve_cache my_data
  }
then ...

info zsh subshell详情:

( LIST )
在子 shell 中执行 LIST。执行 LIST 时,内置 trap 设置的陷阱将重置为其默认值。

{ LIST }
执行列表。

相关内容