我正在尝试进行多条件检查,即输入不应为空,并且应仅包含 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
符相反zsh
或yash
不支持=~
运算符。
另外,如果您这样做[ 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
那样),因为它们不是命令正常输出的一部分(脚本的输出产生如果有的话,您可能想通过管道传输到其他命令)。