【问题标题】:Bash integer comparisonBash 整数比较
【发布时间】:2013-01-24 21:39:40
【问题描述】:

我想编写一个 Bash 脚本来检查是否至少有一个参数,如果有一个参数,则该参数是 0 还是 1。

这是脚本:

#/bin/bash
if (("$#" < 1)) && ( (("$0" != 1)) ||  (("$0" -ne 0q)) ) ; then
    echo this script requires a 1 or 0 as first parameter.
fi
xinput set-prop 12 "Device Enabled" $0

这会产生以下错误:

./setTouchpadEnabled: line 2: ((: ./setTouchpadEnabled != 1: syntax error: operand expected (error token is "./setTouchpadEnabled != 1")
./setTouchpadEnabled: line 2: ((: ./setTouchpadEnabled -ne 0q: syntax error: operand expected (error token is "./setTouchpadEnabled -ne 0q")

我做错了什么?

【问题讨论】:

  • 看起来您正在使用 sh ./setTouchpadEnabled 而不是 bash 运行脚本。
  • @jordanm 你指的是 shebang 行中没有 bang 吗?

标签: bash comparison integer


【解决方案1】:

这个脚本有效!

#/bin/bash
if [[ ( "$#" < 1 ) || ( !( "$1" == 1 ) && !( "$1" == 0 ) ) ]] ; then
    echo this script requires a 1 or 0 as first parameter.
else
    echo "first parameter is $1"
    xinput set-prop 12 "Device Enabled" $0
fi

但这也有效,此外还保留了 OP 的逻辑,因为问题是关于计算的。这里只有arithmetic expressions:

#/bin/bash
if (( $# )) && (( $1 == 0 || $1 == 1 )); then
    echo "first parameter is $1"
    xinput set-prop 12 "Device Enabled" $0
else
    echo this script requires a 1 or 0 as first parameter.
fi

输出相同1

$ ./tmp.sh 
this script requires a 1 or 0 as first parameter.

$ ./tmp.sh 0
first parameter is 0

$ ./tmp.sh 1
first parameter is 1

$ ./tmp.sh 2
this script requires a 1 or 0 as first parameter.

[1] 如果第一个参数是字符串,则第二个失败

【讨论】:

  • 非常感谢,错误是因为命令是xinput而不是input
  • 您没有坚持使用问题中也使用的算术表达式的任何特殊原因? IE。使用(())
  • @user828193:很明显,这是关于计算的,所以算术表达式是的方法。这就是为什么我发现你在回答中改变了问题的这方面让我很恼火。
  • @0xC0000022L:你是对的!这里是算术表达式。我想我被 -ne 和与 OP 代码中可能为空的字符串的比较所迷惑了......
【解决方案2】:

更简单的解决方案;

#/bin/bash
if (( ${1:-2} >= 2 )); then
    echo "First parameter must be 0 or 1"
fi
# rest of script...

输出

$ ./test 
First parameter must be 0 or 1
$ ./test 0
$ ./test 1
$ ./test 4
First parameter must be 0 or 1
$ ./test 2
First parameter must be 0 or 1

说明

  • (( )) - 使用整数计算表达式。
  • ${1:-2} - 如果未定义,则使用参数扩展设置 2 的值。
  • &gt;= 2 - 如果整数大于或等于两个 2,则为真。

【讨论】:

    【解决方案3】:

    shell 命令的第零个参数是命令本身(或有时是 shell 本身)。你应该使用$1

    (("$#" < 1)) && ( (("$1" != 1)) ||  (("$1" -ne 0q)) )
    

    你的布尔逻辑也有点糊涂:

    (( "$#" < 1 && # If the number of arguments is less than one…
      "$1" != 1 || "$1" -ne 0)) # …how can the first argument possibly be 1 or 0?
    

    这可能就是你想要的:

    (( "$#" )) && (( $1 == 1 || $1 == 0 )) # If true, there is at least one argument and its value is 0 or 1
    

    【讨论】:

    • 这是一个改进,谢谢。但是它仍然给我错误: ./setTouchpadEnabled: line 2: ((: != 1: syntax error: operand expected (error token is "!= 1") ./setTouchpadEnabled: line 2: ((: != 0:语法错误:需要操作数(错误标记是“!= 0”)
    • (( )) 中的引号不是绝对必要的,但它们使 StackOverflow 的突出显示更智能。
    • @Cheiron 我想你误解了我的评论。再看看我的回答。
    • 哦,哇,我确实做错了布尔逻辑。但是,它仍然给我错误: ./setTouchpadEnabled: line 2: ((: 0 && ( == 1 || == 0 ) : syntax error: operand expected (error token is "== 1 || == 0 ) ")
    【解决方案4】:

    我知道这个问题已经得到解答,但这是我的答案,因为我认为 case 是一个未被充分重视的工具。 (也许是因为人们认为它很慢,但它至少和 if 一样快,有时更快。)

    case "$1" in
        0|1) xinput set-prop 12 "Device Enabled" $1 ;;
          *) echo "This script requires a 1 or 0 as first parameter." ;;
    esac
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-19
      • 2017-02-11
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多