在 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 ...
( LIST )
在子 shell 中执行 LIST。执行 LIST 时,内置 trap 设置的陷阱将重置为其默认值。
{ LIST }
执行列表。