You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建并直接复用BASH布尔值数组进行逻辑运算?

Bash井字棋脚本:布尔值数组构建与使用问题

我在优化一款Bash井字棋脚本时,遇到了无法构建布尔值数组(存储test命令执行结果)并在后续复杂逻辑中复用的问题。

尝试的数组赋值代码

bmap[0]="dummy"
bmap[1]=$( test ${board[1]} == ${symbol} )
bmap[2]=$( test ${board[2]} == ${symbol} )
bmap[3]=$( test ${board[3]} == ${symbol} )
bmap[4]=$( test ${board[4]} == ${symbol} )
bmap[5]=$( test ${board[5]} == ${symbol} )
bmap[6]=$( test ${board[6]} == ${symbol} )
bmap[7]=$( test ${board[7]} == ${symbol} )
bmap[8]=$( test ${board[8]} == ${symbol} )
bmap[9]=$( test ${board[9]} == ${symbol} )

数组使用逻辑

if \
    [[ ${bmap[1]} && ${bmap[2]} && ${bmap[3]} ]] ||
    [[ ${bmap[4]} && ${bmap[5]} && ${bmap[6]} ]] ||
    [[ ${bmap[7]} && ${bmap[8]} && ${bmap[9]} ]] ||
    [[ ${bmap[1]} && ${bmap[4]} && ${bmap[7]} ]] ||
    [[ ${bmap[2]} && ${bmap[5]} && ${bmap[8]} ]] ||
    [[ ${bmap[3]} && ${bmap[6]} && ${bmap[9]} ]] ||
    [[ ${bmap[1]} && ${bmap[5]} && ${bmap[9]} ]] ||
    [[ ${bmap[3]} && ${bmap[5]} && ${bmap[7]} ]]
then
    echo "true"
else
    echo "false"
fi

运行错误信息

./test_175.sh: line 29: test: ==: unary operator expected
./test_175.sh: line 30: test: ==: unary operator expected
./test_175.sh: line 31: test: ==: unary operator expected
./test_175.sh: line 32: test: ==: unary operator expected
./test_175.sh: line 33: test: ==: unary operator expected
./test_175.sh: line 34: test: ==: unary operator expected
./test_175.sh: line 35: test: ==: unary operator expected
./test_175.sh: line 36: test: ==: unary operator expected

核心问题

是否可以直接将bmap数组的值作为布尔运算结果复用,无需再次对这些值进行测试?


问题根源与解决方案

首先,你遇到的test: ==: unary operator expected错误,是因为${board[N]}或${symbol}可能为空值,导致test命令只接收到一个操作数和==,不符合二元比较的语法要求。解决这个问题的第一步是给变量加上引号:

bmap[1]=$( test "${board[1]}" == "${symbol}" )

但更关键的是:Bash里没有真正的布尔值类型,你用$(test ...)捕获的是命令的输出(test命令成功时没有任何输出,失败时也没有),所以bmap数组里的元素要么是空字符串,要么还是空字符串——这根本没法用来做布尔判断。

要实现你的需求,正确的做法是存储命令的退出状态码(0表示成功/真,非0表示失败/假),或者直接用0/1来标记布尔状态:

方案1:存储退出状态码

# 赋值时直接保存命令的退出状态
for i in {1..9}; do
  test "${board[$i]}" == "${symbol}"
  bmap[$i]=$?
done

# 使用时检查退出状态是否为0(真)
if \
    [[ ${bmap[1]} -eq 0 && ${bmap[2]} -eq 0 && ${bmap[3]} -eq 0 ]] ||
    [[ ${bmap[4]} -eq 0 && ${bmap[5]} -eq 0 && ${bmap[6]} -eq 0 ]] ||
    [[ ${bmap[7]} -eq 0 && ${bmap[8]} -eq 0 && ${bmap[9]} -eq 0 ]] ||
    [[ ${bmap[1]} -eq 0 && ${bmap[4]} -eq 0 && ${bmap[7]} -eq 0 ]] ||
    [[ ${bmap[2]} -eq 0 && ${bmap[5]} -eq 0 && ${bmap[8]} -eq 0 ]] ||
    [[ ${bmap[3]} -eq 0 && ${bmap[6]} -eq 0 && ${bmap[9]} -eq 0 ]] ||
    [[ ${bmap[1]} -eq 0 && ${bmap[5]} -eq 0 && ${bmap[9]} -eq 0 ]] ||
    [[ ${bmap[3]} -eq 0 && ${bmap[5]} -eq 0 && ${bmap[7]} -eq 0 ]]
then
    echo "true"
else
    echo "false"
fi

方案2:直接存储0/1标记

# 赋值时用条件判断生成0/1
for i in {1..9}; do
  if [[ "${board[$i]}" == "${symbol}" ]]; then
    bmap[$i]=1
  else
    bmap[$i]=0
  fi
done

# 使用时检查是否为1(真)
if \
    [[ ${bmap[1]} -eq 1 && ${bmap[2]} -eq 1 && ${bmap[3]} -eq 1 ]] ||
    [[ ${bmap[4]} -eq 1 && ${bmap[5]} -eq 1 && ${bmap[6]} -eq 1 ]] ||
    [[ ${bmap[7]} -eq 1 && ${bmap[8]} -eq 1 && ${bmap[9]} -eq 1 ]] ||
    [[ ${bmap[1]} -eq 1 && ${bmap[4]} -eq 1 && ${bmap[7]} -eq 1 ]] ||
    [[ ${bmap[2]} -eq 1 && ${bmap[5]} -eq 1 && ${bmap[8]} -eq 1 ]] ||
    [[ ${bmap[3]} -eq 1 && ${bmap[6]} -eq 1 && ${bmap[9]} -eq 1 ]] ||
    [[ ${bmap[1]} -eq 1 && ${bmap[5]} -eq 1 && ${bmap[9]} -eq 1 ]] ||
    [[ ${bmap[3]} -eq 1 && ${bmap[5]} -eq 1 && ${bmap[7]} -eq 1 ]]
then
    echo "true"
else
    echo "false"
fi

更简洁的写法:直接在判断中复用逻辑

其实你也可以不用数组,直接把判断逻辑封装成函数,减少重复代码:

check_cell() {
  [[ "${board[$1]}" == "${symbol}" ]]
}

if \
    (check_cell 1 && check_cell 2 && check_cell 3) ||
    (check_cell 4 && check_cell 5 && check_cell 6) ||
    (check_cell 7 && check_cell 8 && check_cell 9) ||
    (check_cell 1 && check_cell 4 && check_cell 7) ||
    (check_cell 2 && check_cell 5 && check_cell 8) ||
    (check_cell 3 && check_cell 6 && check_cell 9) ||
    (check_cell 1 && check_cell 5 && check_cell 9) ||
    (check_cell 3 && check_cell 5 && check_cell 7)
then
    echo "true"
else
    echo "false"
fi

这样既避免了数组的问题,代码也更易读维护。

内容的提问来源于stack exchange,提问作者Eric Marceau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:25:05