• shell boolean 布尔变量


    shell  Bash中没有布尔变量  flag=0,flag=1

    反转布尔变量


    26

    我想尝试简单的脚本

    flag=false
    while !$flag
    do
       read x
       if [ "$x" -eq "true" ]
       then
         flag=true
       fi
       echo "${x} : ${flag}"
    done
    

    但是,当我运行它时,如果键入true,我会看到x="true"flag="true",但是循环并没有结束。脚本有什么问题?如何正确地将布尔变量取反?


    1

     
    谢谢!我现在
    知道

    Answers:


    21

    您的脚本中有两个错误。首先,您需要在!和之间留一个空格$flag,否则shell将寻找一个名为的命令!$flag。第二个错误是-eq用于整数比较,但是您正在字符串上使用它。根据您的外壳,您可能会看到错误消息,并且由于条件[ "$x" -eq "true" ]不能为真,循环将永远继续,或者如果您输入任何字符串(包括false),则每个非整数值都将被视为0,并且循环将退出不同于0的数字。

    虽然! $flag正确,但是将字符串视为命令是一个坏主意。可以,但是对脚本中的更改非常敏感,因为您需要确保该值$flag只能是trueor false。最好在这里使用字符串比较,例如下面的测试。

    flag=false
    while [ "$flag" != "true" ]
    do
       read x
       if [ "$x" = "true" ]
       then
         flag=true
       fi
       echo "${x} : ${flag}"
    done
    

    表达所追求的逻辑可能是更好的方法。例如,您可以进行无限循环并在检测到终止条件时将其中断。

    while true; do
      read -r x
      if [ "$x" = "true" ]; then break; fi
      echo "$x: false"
    done
    

     
    使用[内置的ksh[ x -eq y ]如果x算术表达式解析为与y算术表达式相同的数字,则返回true ,例如,x=2 true=1+1 ksh -c '[ x -eq true ] && echo yes'将输出yes。
    斯特凡·查泽拉斯

    10

    虽然Bash中没有布尔变量,但使用算术评估对其进行仿真非常容易。

    flag= # False
    flag=0 # False
    flag=1 # True (actually any integer number != 0 will do, but see remark below about toggling)
    flag="some string" # Maybe False (make sure that the string isn't interpreted as a number)
    
    if ((flag)) # Test for True
    then
      : # do something
    fi
    
    if ! ((flag)) # Test for False
    then
      : # do something
    fi
    
    flag=$((1-flag)) # Toggle flag (only works when flag is either empty or unset, 0, 1, or a string which doesn't represent a number)
    

    这也适用于ksh。如果它在所有POSIX兼容的shell中都可以使用,但我没有感到惊讶,但是还没有检查标准。


    1
    是否! ! ((val))可以像使用C或C ++一样在Bash中工作?例如,如果val为0 ,则在之后仍为0 ! !。如果val为1,则之后为1 ! !。如果val为8,则在之后将其拉低至1 ! !。还是我需要问另一个问题?

    1
    -1 | 在POSIX sh中,未定义独立((..));请删除对它的引用
    LinuxSecurityFreak

     
    Vlastimil的问题具体是关于bash的-不是posix shell。当问题与该主题无关时,为什么要投反对票?
    尼克·布尔

    6

    如果您完全可以确定该变量将包含0或1,则可以使用按位XOR等于运算符在两个值之间切换:

    $ foo=0
    $ echo $foo
    0
    $ ((foo ^= 1))
    $ echo $foo
    1
    $ ((foo ^= 1))
    $echo $foo
    0
    

    2

    这对我有用:

    flag=false
    while [[ "$flag" == "false" ]]
    do
       read x
       if [[ "$x" == "true" ]]
       then
         flag=true
       fi
       echo "${x} : ${flag}"
    done
    

    但是,实际上,您应该执行以下操作while

    while ! $flag

    0

    Shell中没有布尔变量的概念。
    shell变量只能是text(一个字符串),并且,在某些情况下,该文本可以被解释为一个整数(10xa010等)。

    因此,a flag=true根本不暗示外壳的真实性或错误性。

    可以执行的操作是字符串比较[ "$flag" == "true" ]或在某些命令中使用变量内容并检查其结果,例如执行true(因为同时存在true一个被调用的可执行文件和一个被调用的可执行文件false)作为命令,并检查该命令的退出代码是否为零(成功)。

    $flag; if [ "$?" -eq 0 ]; then ... fi

    或更短:

    if "$flag"; then ... fi

    如果将变量的内容用作!命令,则如果两个(! cmd)之间存在空格,则可以使用a 取反命令的退出状态,如下所示:

    if ! "$flag"; then ... fi

    该脚本应更改为:

    flag=false
    while ! "$flag" 
    do
       read x
       if [ "$x" == "true" ]
       then
         flag=true
       fi
       echo "${x} : ${flag}"
    done
    

    整数

    使用数值和算术扩展

    在这种情况下,$((0))is 1的退出代码和$((1))is 的退出代码0
    在bash,ksh和zsh中,该算术可以在a内执行((..))(请注意,$缺少开始部分)。

    flag=0; if ((flag)); then ... fi

    此代码的可移植版本更加复杂:

    flag=0; if [ "$((flag))" -eq 0 ]; then ... fi      # test for a number
    flag=0; if [ "$((flag))"  == 0 ]; then ... fi      # test for the string "0"
    

    在bash / ksh / zsh中,您可以执行以下操作:

    flag=0    
    while ((!flag)) 
    do
       read x
       [ "$x" == "true" ] && flag=1
       echo "${x} : ${flag}"
    done
    

    或者

    您可以将“反转布尔变量”(假设它包含数字值)为:

    ((flag=!flag))

    这将改变的值flag要么01


    注意:在将代码作为问题发布之前,请检查https://www.shellcheck.net/中的错误,这足以发现问题。


    0

    until的缩写while !(与Bourne until相反!),因此您可以执行以下操作:

    flag=false
    until "$flag"
    do
       IFS= read -r x
       if [ "$x" = true ]
       then
         flag=true
       fi
       printf '%s\n' "$x : $flag"
    done
    

    哪个应该和:

    flag=false
    while ! "$flag"
    do
       IFS= read -r x
       if [ "$x" = true ]
       then
         flag=true
       fi
       printf '%s\n' "$x : $flag"
    done
    

    您也可以将其编写为:

    until
       IFS= read -r x
       printf '%s\n' "$x"
       [ "$x" = true ]
    do
       continue
    done
    

    until/ while和之间的部分do不必是单个命令。

    !是POSIX Shell语法中的关键字。它需要定界,令牌与后面的令牌分开,并且是管道之前的第一个令牌(! foo | bar否定管道,foo | ! bar尽管某些外壳程序接受它为扩展名,但它还是无效的)。

    !true被解释为!true不太可能存在的命令。! true应该管用。!(true)应该在符合POSIX的炮弹工作作为!作为它的后面是分隔的(道理,但在实践中它并不在工作ksh/ bash -O extglob在那里与冲突!(pattern)扩展水珠运营商也不zsh的在那里它与冲突(除SH仿真)glob(qualifiers)bareglobqualglob(group)没有。


    -1
    [ ${FOO:-0} == 0 ] && FOO=1 || FOO=0

    甚至:

    [ ${FOO:-false} == false ] && FOO=true || FOO=false

    应该做的工作

    https://qastack.cn/unix/24500/invert-boolean-variable#:~:text=Shell%E4%B8%AD%E6%B2%A1%E6%9C%89%E5%B8%83%E5%B0%94%E5%8F%98%E9%87%8F%E7%9A%84%E6%A6%82%E5%BF%B5%E3%80%82%20shell%E5%8F%98%E9%87%8F%E5%8F%AA%E8%83%BD%E6%98%AF%20text%20%EF%BC%88%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%89%EF%BC%8C%E5%B9%B6%E4%B8%94%EF%BC%8C%E5%9C%A8%E6%9F%90%E4%BA%9B%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E8%AF%A5%E6%96%87%E6%9C%AC%E5%8F%AF%E4%BB%A5%E8%A2%AB%E8%A7%A3%E9%87%8A%E4%B8%BA%E4%B8%80%E4%B8%AA%E6%95%B4%E6%95%B0%EF%BC%88%201,%EF%BC%8C%200xa%20%EF%BC%8C%20010%20%E7%AD%89%EF%BC%89%E3%80%82

  • 相关阅读:
    【Python学习】读取Excel文件,并写入Excel
    异步编程
    LINQ入门
    [Leetcode Weekly Contest]207
    [Leetcode Weekly Contest]203
    VsCode插件,自动生成注释koroFileHeader
    vue样式穿透 ::v-deep的具体使用
    springcloud,springboot,springcloud-alibaba 之间版本关系
    sharding-sphere 单库分表实例
    CDN动态加速技术
  • 原文地址:https://www.cnblogs.com/pengmn/p/16559917.html
Copyright © 2020-2023  润新知