Shell 脚本中的 while 循环中多个条件不起作用

Shell 脚本中的 while 循环中多个条件不起作用

我正在尝试进行多条件检查,即输入不应为空,并且应仅包含 Shell 脚本中 while 循环中的数字,但我在尝试执行此操作时遇到多个错误。我尝试了多种选项,并且在 Unix Stackexchange 和 Stack Overflow 中看到了有关此问题的多个问题,但没有一个有帮助,这就是为什么我在这里发布这个问题选项 1:

while [ \( -z "$account_number" \) && \( "$account_number" =~ "^[0-9]+$" \) ];
do      printf 'Input account Number RWDEx: '
        read -r account_number
        [ -z "$account_number" ]  && echo 'Account Number cannot be empty; try again.'
done

这会引发错误 [:缺少 `]' 许多人建议此错误,因为条件和括号之间存在空格问题,但它不起作用

选项2:

while [[ -z "$account_number" && "$account_number" =~ "^[0-9]+$" ]]
do      printf 'Input account Number RWDEx: '
        read -r account_number
        [ -z "$account_number" ]  && echo 'Account Number cannot be empty; try again.'
done

如果我给出上述条件,它甚至不要求输入

请帮助解决这个问题,我正在使用 #!/bin/bash 我什至尝试将脚本更改为 /bin/bash 而不是 #!/bin/bash

答案1

只需使用:

#! /bin/bash -
n=
pattern='^(0+|[123456789][0123456789]*)$' # decimal integer number,
                                          # exclude 0123 octals
until [[ $n =~ $pattern ]]; do
  IFS= read -rp 'Enter a decimal number: ' n || exit # exit upon EOF
done

或者:

#! /bin/bash -
pattern='^(0+|[123456789][0123456789]*)$' # decimal integer number,
                                          # exclude 0123 octals
while true; do
  IFS= read -rp 'Enter a decimal number: ' n || exit # exit upon EOF
  if [ -z "$n" ]; then
    echo >&2 "Cannot be empty, try again"
  elif [[ ! $n =~ $pattern ]]; then
    echo >&2 "Not a decimal integer number, try again"
  else
    break
  fi  
done

或者更好的是,使用标准sh语法,然后你甚至不需要bash

#! /bin/sh -
while true; do
  printf >&2 'Enter a number: '
  IFS= read -r n || exit # exit upon EOF
  case $n in
    ("")
      echo >&2 "Cannot be empty, try again";;
    (*[!0123456789]* | 0*[!0]*)
      echo >&2 "Not a decimal integer number, try again";;
    (*)
      break;; # OK
  esac
done

请注意,这[是一个内置的 shell。[of与运算bash符相反zshyash不支持=~运算符。

另外,如果您这样做[ x && y ],则会被解析为cmd1 arg && cmd2 arg2,因此只需运行[ x,如果成功,则运行y ]

[[ ... ]]另一方面是一个特殊的 shell 结构(来自 ksh),其内部&&也是一种形式操作员。

但是,如果你写:

[[ -z $var && $var =~ ^[0-9]+$ ]]

这是测试是否$var既为空( -z)又匹配,^[0-9]+$这是不可能的。

我想你的意思是:

[[ -z $var || ! $var =~ ^[0-9]+$ ]]

但即便如此,它也是-z $var多余的,因为如果$var匹配^[0-9]+$(0-9范围内的一个或多个字符),它就不能为空。

请注意,[0-9]在大多数系统的大多数区域设置中,匹配的内容或多或少是随机的,[0123456789]如果您想匹配任何十进制数字,请使用。

在像 之类的 shell 中bash,排除带有前导零的数字通常是个好主意,因为它们往往被解释为八进制数(例如,010 表示 8)。

通常在 stderr 上发出用户提示(就像bash'sread -p那样),因为它们不是命令正常输出的一部分(脚本的输出产生如果有的话,您可能想通过管道传输到其他命令)。

相关内容