shell bash -比较整数值

uyto3xhc  于 2023-10-23  发布在  Shell
关注(0)|答案(2)|浏览(132)

我试图陷阱箭头键没有用户击中“返回”键。除了我试图抓住“esc”键外,程序正常工作。我试着用我能想到的一切来比较,但没有成功。包括字符串和数字比较;带引号和不带引号;单括号与双括号等。shellcheck不会报告任何问题。
要么什么都没有发生(esc键没有被捕获),要么我得到一个语法错误;"./key-no-return-printf.sh:line 37:[[:':语法错误:需要操作数(错误标记为“”)"
即,$VALUE -等式27、$VALUE == 27、$VALUE = 27、“$VALUE”-等式“27”等。

#! /usr/bin/bash
clear

function getkey () {
  read -rs -n1 -t.001 KEYIN         # read 1 chr, no echo, no delay
  VALUE=\'$KEYIN
  if [[ $VALUE -eq 27 ]]; then     # trap esc key
    printf "esc caught\n"
  fi
}

while :; do    # --- Infinite loop ---
  KEYIN=""
  VALUE=0
  getkey
  if [[ $KEYIN == [Qq] ]]; then exit; fi
  if [[ $KEYIN != "" ]]; then printf "%s : %d\n" "$KEYIN" "$VALUE"; fi
done
kr98yfug

kr98yfug1#

使用不同的方式来获取密钥的代码对我来说很有效:

VALUE=$(printf %d "'$KEYIN")
if [[ $VALUE -eq 27 ]]; then     # trap esc key
    printf "esc caught\n"
fi
e4yzc0pl

e4yzc0pl2#

'$KEYIN实际上是一个printf,而不是一个bash。因此,您不能期望'$KEYIN本身成为ASCII代码的十进制表示(或将其存储在VALUE中时)。只有当'somechar字符串传递给printf时,如果它匹配%d,printf才会以这种方式解释它(以模仿如果你是printf("%d", 'somechar'),在C中会发生什么)。
但你并不需要那个。你并不需要KEYIN的十进制表示来检查它是否是一个转义。就像你对待其他夏尔那样

while :; do    # --- Infinite loop ---
  read -rs -n1 -t.001 KEYIN         # read 1 chr, no echo, no delay
  if [[ $KEYIN == [Qq] ]]; then exit; fi
  if [[ $KEYIN == ^[ ]]; then printf "ESC\n"; exit; fi
  if [[ $KEYIN != "" ]]; then printf "%s : %d\n" "$KEYIN" "$VALUE"; fi
done

这里的^[不是^后跟[,而是一个实际的转义。使用经典的Vim绑定,您可以通过先键入Ctrl+V,然后键入escape键来输入escape。
如果您的编辑器使在代码中插入转义变得困难,您也可以使用八进制转义

while :; do    # --- Infinite loop ---
  read -rs -n1 -t.001 KEYIN         # read 1 chr, no echo, no delay
  if [[ $KEYIN == [Qq] ]]; then exit; fi
  if [[ $KEYIN == $'\033' ]]; then printf "ESC\n"; exit; fi
  if [[ $KEYIN != "" ]]; then printf "%s : %d\n" "$KEYIN" "$VALUE"; fi
done

$'xxx'是C转义。这意味着字符串的行为就像C语言中的字符串一样。所以\octal被八进制asd码的字符替换。ESCAPE是字符27,所以\033在八进制转义。所以$KEYIN == $'\033'$KEYIN == ^[是一样的
要点是:不需要使用子命令将KEYIN的内容转换为十进制代码。如果你想比较KEYIN和Escape,直接用==即可。所有需要做的就是知道如何说“逃跑”:D

相关问题