我想写的东西是这样的:
if [[ ( releases["token"] & $MASK ) -eq 1 ]]; then
但我得到的错误:
意外的标记'&”,有条件的二元运算符预期
我如何使用位运算符在if语句?
我想写的东西是这样的:
if [[ ( releases["token"] & $MASK ) -eq 1 ]]; then
但我得到的错误:
意外的标记'&”,有条件的二元运算符预期
我如何使用位运算符在if语句?
您可以使用Arithmetic Expansion
:
(((5&3)==1)) && echo YES || echo NO
这将打印YES
乍一看,如@ chepner的指出了意见 ,问题可能仅仅是语法的一个,这会导致编译错误( unexpected token '&', conditional binary operator expected
)。 而事实上, @千电子伏的回答解决了使用算术扩展 ,它被应用到If
声明@古斯塔沃的回答 。
然而,这个问题:“ 如何使用位运算符在if语句”在一个更一般的方式是制定并乞求如何使用位运算符来核对答案$MASK
(这是不是“如何避免语法问题使用二进制比较“)时的错误。
事实上,它可以假设的是,示例代码
if [[ ( releases["token"] & $MASK ) -eq 1 ]]; then
在找到解决办法,并明确标注为“像......”的工作正在进行中。 现在// @千电子伏的任意假设
releases["token"]=3
MASK=5
可能隐藏事实,也有在使用逻辑误区-eq 1
在首位。 因此,尽管@千电子伏的答案与所选择的价值观的作品,如输入的结果, 4
线
(((5&4)==1)) && echo YES || echo NO
将打印NO,尽管人们所期望的是在该情况下,为4
和5
都具有第三位集。
所以这个答案解决了问题,例如这个逻辑上的错误,并尝试一个笼统的回答了这个问题的标题。
理解逐位比较是有帮助在它们的位表示的可视化数(列在下面的例子中自上而下):
|-----------------------------------------------------------| | | hexadecimal representation of the value | | bit val | 0 1 2 3 4 5 6 7 8 9 ABCDEF | |---------|---------------------- bit ----------------------| | | shows if the given value has the given bit set | | 0 | - x - x - x - x - x - x - x - x | | 1 | - - xx - - xx - - xx - - xx | | 2 | - - - - xxxx - - - - xxxx | | 3 | - - - - - - - - xxxxxxxx | |---------|---------------------- val ----------------------| | shows the value that the given bit adds to the number | | 0 1 | 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 | | 1 2 | 0 0 2 2 0 0 2 2 0 0 2 2 0 0 2 2 | | 2 4 | 0 0 0 0 4 4 4 4 0 0 0 0 4 4 4 4 | | 3 8 | 0 0 0 0 0 0 0 0 8 8 8 8 8 8 8 8 | |---------|-------------------------------------------------| |sum: 15 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | | | decimal representation of the value | |===========================================================|
这是由下面的代码片断创建的:
( # start a subshell to encapsulate vars for easy copy-paste into the terminal
# do not use this in a script!
echo ;
echo "|-----------------------------------------------------------|";
echo "| | hexadecimal representation of the value |";
echo "| bit val | 0 1 2 3 4 5 6 7 8 9 A B C D E F |";
echo "|---------|---------------------- bit ----------------------|";
echo "| | shows if the given value has the given bit set |";
mask=0;
for (( bit=0; bit<4; bit++)); do
mask=$((1<<bit));
echo -n "| $bit |"
for ((x=0;x<16;x++)); do ((((x&mask)>0))&&echo -n ' x'||echo -n ' -'); done
echo " |";
done ;
echo "|---------|---------------------- val ----------------------|";
echo "| shows the value that the given bit adds to the number |";
mask=0;
for (( bit=0; bit<4; bit++)); do
mask=$((1<<bit));
echo -n "| $bit $mask |"
for ((x=0;x<16;x++)); do echo -n " $((x&mask))"; done
echo " |";
done ;
echo "|---------|-------------------------------------------------|";
echo "|sum: 15 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |";
echo "| | decimal representation of the value |";
echo "|===========================================================|";
echo ;
)
3 & 5
VS 4 & 5
==1
VS >0
和的差异&
, |
,和^
” 如果现在我们检查所提到的例子的特殊情况,我们将看到的缺点:
|------------------ value: 3 / mask: 5 -------------------| | | value | mask | and | or | xor | xnor | | | 3 | 5 | 3 & 5 | 3 | 5 | 3 ^ 5 | | | bit val |bit:val|bit:val|bit:val|bit:val|bit:val|bit:val| |---------|-------|-------|-------|-------|-------|-------| | 0 1 | 1 1 | 1 1 | 1 1 | 1 1 | 0 0 | 0 0 | | 1 2 | 2 1 | 0 0 | 0 0 | 1 2 | 1 2 | 1 2 | | 2 4 | 0 0 | 4 1 | 0 0 | 1 4 | 1 4 | 1 4 | | 3 8 | 0 0 | 0 0 | 0 0 | 0 0 | 0 0 | 0 0 | |---------|-------|-------|-------|-------|-------|-------| |sum: | 3 | 5 | ==> 1 | 7 | 6 | 6 | |---------|-----------------------------------------------| |check: | 3 & 5 == 1 ? YES | | | | 3 & 5 >= 1 ? YES | ==> 3 & 5 > 0 ? YES | |=========================================================| |------------------ value: 4 / mask: 5 -------------------| | | value | mask | and | or | xor | xnor | | | 4 | 5 | 4 & 5 | 4 | 5 | 4 ^ 5 | | | bit val |bit:val|bit:val|bit:val|bit:val|bit:val|bit:val| |---------|-------|-------|-------|-------|-------|-------| | 0 1 | 0 0 | 1 1 | 0 0 | 1 1 | 1 1 | 1 1 | | 1 2 | 0 0 | 0 0 | 0 0 | 0 0 | 0 0 | 0 0 | | 2 4 | 4 1 | 4 1 | 1 4 | 1 4 | 0 0 | 0 0 | | 3 8 | 0 0 | 0 0 | 0 0 | 0 0 | 0 0 | 0 0 | |---------|-------|-------|-------|-------|-------|-------| |sum: | 4 | 5 | ==> 4 | 5 | 1 | 1 | |---------|-----------------------------------------------| |check: | 4 & 5 == 1 ? NO | | | | 4 & 5 >= 1 ? YES | ==> 4 & 5 > 0 ? YES | |=========================================================|
请特别注意以下检查:
|---------|-----------------------------------------------| |check: | 3 & 5 == 1 ? YES | | | | 3 & 5 >= 1 ? YES | ==> 3 & 5 > 0 ? YES | ---------|------------------------------------------------| |check: | 4 & 5 == 1 ? NO | | | | 4 & 5 >= 1 ? YES | ==> 4 & 5 > 0 ? YES | |---------|-----------------------------------------------|
输出上述由以下代码段创建的:
( # start a sub-shell to encapsulate vars for easy copy-paste into the terminal
# do not use this in a script!
echo ;
for o in 3 4; do
echo "|------------------ value: $o / mask: 5 -------------------|";
echo "| | value | mask | and | or | xor | xnor |";
echo "| | $o | 5 | $o & 5 | $o | 5 | $o ^ 5 | |";
echo "| bit val |bit:val|bit:val|bit:val|bit:val|bit:val|bit:val|";
echo "|---------|-------|-------|-------|-------|-------|-------|";
mask=0;
for (( bit=0; bit<4; bit++)); do
mask=$((1<<bit));
echo -n "| $bit $mask "
echo -n " | $(($o&mask)) $((($o&mask)>0))"
echo -n " | $((5&mask)) $(((5&mask)>0))"
echo -n " | $(((($o&mask)&(5&mask))>0)) $((($o&mask)&(5&mask)))"
echo -n " | $(((($o&mask)|(5&mask))>0)) $((($o&mask)|(5&mask)))"
echo -n " | $(((($o&mask)^(5&mask))>0)) $((($o&mask)^(5&mask)))"
echo -n " | $(((($o&mask)^(5&mask))>0)) $((($o&mask)^(5&mask)))"
echo " |";
done ;
echo "|---------|-------|-------|-------|-------|-------|-------|";
echo -n "|sum: | $o | 5 |";
echo " ==> $(($o&5)) | $(($o|5)) | $(($o^5)) | $(($o^5)) |";
echo "|---------|-----------------------------------------------|";
echo -n "|check: | $o & 5 == 1 ? $(((($o&5)==1))&&echo YES||echo "NO ") ";
echo "| |";
echo -n "| | $o & 5 >= 1 ? $(((($o&5)>=1))&&echo YES||echo "NO ") ";
echo "| ==> $o & 5 > 0 ? $(((($o&5)>0))&&echo YES||echo "NO ") |";
echo "|=========================================================|";
echo ;
done
echo ;
)
那么,如何才能做到这一点了吧? 让我们想象一下,我们有以下选项设置:
# option set: option_1=1 option_2=2 option_3=4 option_4=8 option_5=16 option_6=32 option_7=64 option_8=128 option_9=256
比如,我们可以设置选择这些选项的功能,并返回结合的编码作为返回值。 或者反过来:通过选项的选择作为一个数字参数。 无论你使用的情况是,该方案将被加在一起:# set options: option = option_1 + option_4 + option_5 + option_9
我们如何最好检查一下,该选项被设置(1
,4
,5
,和9
)? 这再次当然取决于你的使用情况,但我还挺喜欢的case
构建! 就像是 ...case $option in 0) echo "no option set!";; 1) echo "option 1";; 2) echo "option 2";; 3) echo "option 1 and 2";; *) echo "...";; esac
可以工作,但不是很好,因为我们将不得不建立每个组合!
Case
” 我们可以使用
case
的,而不是通过以下方式...echo "check for options using >0:" case 1 in $(( (option & option_1) >0 )) ) echo "- option_1 is set";;& $(( (option & option_2) >0 )) ) echo "- option_2 is set";;& $(( (option & option_3) >0 )) ) echo "- option_3 is set";;& $(( (option & option_4) >0 )) ) echo "- option_4 is set";;& $(( (option & option_5) >0 )) ) echo "- option_5 is set";;& $(( (option & option_6) >0 )) ) echo "- option_6 is set";;& $(( (option & option_7) >0 )) ) echo "- option_7 is set";;& $(( (option & option_8) >0 )) ) echo "- option_8 is set";;& $(( (option & option_9) >0 )) ) echo "- option_9 is set";;& esac
请注意 ,
- 内的空间
$(( (option & option_1) >0 )) )
是完全任选的,并且被添加以提高可读性。 最后收托架)
是用于case
构建体。- 命令列表 s的终止
;;&
中,为了继续评估下一个选项测试。 如果你想abord列表进行进一步的处理,设置option=0
或当前的option=option_X
。...我们得到以下结果:
check for options using >0: - option_1 is set - option_4 is set - option_5 is set - option_9 is set
欢呼! :-)
if
我是一个富有的人! echo "# to use it in an if statement:"; if (((option&option_5)>0)); then echo "- option_5 is set" else echo "- option_5 is NOT set" fi # to use it in an if statement: - option_5 is set
echo "# or to use it just for conditional execution:"; (((option&option_6)>0)) \ && echo "- option_6 is set" \ || echo "- option_6 is NOT set" # or to use it just for conditional execution: - option_6 is NOT set
(卡夫卡,1975:181)
因此,这将是完全有可能使用该解决方案,张贴在的问题,通过细微变化如下:
( declare -A releases=([token]=4) declare -i MASK=5 if [[ $(( releases["token"] & $MASK )) -gt 0 ]]; then echo YES else echo NO fi )
的变化如下: -使用
$(())
而不是()
做了测试,这将返回按位比较的价值-使用-gt 0
,而不是-eq 1
干脆在行动:
( # start a sub-shell to encapsulate vars for easy copy-paste into the terminal
# do not use this in a script!
echo ;
for ((i=0; i<9;i++)); do
o="option_$((i+1))"
declare -i $o=$((1<<$i))
echo "$o = ${!o}"
done
echo ;
echo ;
echo "# set options:"
echo "option = option_1"
echo " + option_4"
echo " + option_5"
echo " + option_9"
option=option_1+option_4+option_5+option_9
echo ;
echo ;
echo "check for options using >0:"
case 1 in
$(( (option & option_1) >0 )) ) echo "- option_1 is set";;&
$(( (option & option_2) >0 )) ) echo "- option_2 is set";;&
$(( (option & option_3) >0 )) ) echo "- option_3 is set";;&
$(( (option & option_4) >0 )) ) echo "- option_4 is set";;&
$(( (option & option_5) >0 )) ) echo "- option_5 is set";;&
$(( (option & option_6) >0 )) ) echo "- option_6 is set";;&
$(( (option & option_7) >0 )) ) echo "- option_7 is set";;&
$(( (option & option_8) >0 )) ) echo "- option_8 is set";;&
$(( (option & option_9) >0 )) ) echo "- option_9 is set";;&
esac
echo ;
echo ;
echo "# to use it in an if statement:";
echo " => if (((option&option_5)>0));";
if (((option&option_5)>0)); then
echo "- option_5 is set"
else
echo "- option_5 is NOT set"
fi
echo ;
echo ;
declare -A releases=([token]=4)
declare -i MASK=5
echo "# Does 4 pass the mask 5 in the test construct?";
echo " => if [[ $(( releases["token"] & $MASK )) -gt 0 ]];";
if [[ $(( releases["token"] & $MASK )) -gt 0 ]]; then
echo YES
else
echo NO
fi
echo ;
echo ;
echo "# or to use it just for conditional execution:";
echo " => (((option&option_6)>0)) && do || dont";
(((option&option_6)>0)) \
&& echo "- option_6 is set" \
|| echo "- option_6 is NOT set"
)
Exit 0
在if语句:
if (((releases["token"] & $MASK) == 1)); then
echo YES
else
echo NO
fi