我的 bash 脚本有问题


#!/bin/bash
sum=0
for number in $@
do
echo $number | grep -q "[^a-z]" >> /dev/null
if [ $? != 0 ]
then
     echo "Sorry, '$number' is not a number"
else
    sum=$((sum + number))
    echo "$sum"
fi
done

我的作业要求如果我输入add2 4 -3 12 9它将输出

22

但矿山产出:

4 1 3 22

如果我输入add2 4 -3 twelve nine它将输出:

对不起,"十二"不是一个数字

但矿山产出



1 对不起,"十二"不是一个数字
对不起,"九"不是一个数字

我的任务需要echo $number | grep -q "[^a-z]" >> /dev/null因为它希望我将输出重定向到/dev/null,我不知道我做错了什么。

问题是您在处理的每个数字之后打印$sum,而您的作业是仅在最后一个数字之后打印它。因此,您需要将echo "$sum"部分(打印$sum(移动到循环之后。

换句话说,您需要更改此设置:

    echo "$sum"
fi
done

对此:

fi
done
echo "$sum"

我的作业需要回显$number | grep -q "[^a-z]">>/dev/null,因为它希望我将输出重定向到/dev/null, [...]

这有点多余。 grep -q 不会将任何内容打印到标准输出,因此没有理由重定向其标准输出。(无论如何,这不是检测有效数字的好方法。此方法将接受$number作为有效数字,如果它包含一个不是小写字母的字符。例如,它将接受ab%AB作为有效数字。


编辑添加:好的,那么如何检测有效数字?这是令人惊讶的棘手。

可以通过自己

决定有效数字的外观,然后制作grep命令或类似命令来检测这种形式的数字来做到这一点;例如,您可以编写以下任何一种:

  • grep -q $'^-[1-9][0-9]*$n^0$n^[1-9][0-9]*$ <<< "$number"
  • grep -q '^-[1-9][0-9]*$' <<< "$number" || grep -q '^[1-9][0-9]*$' <<< "$number" || grep -q '^0$' <<< "$number"
  • [[ "$number" = 0 ]] || [[ "$number" =~ ^-?[1-9][0-9]*$ ]]

但我认为最好"作弊",询问 Bash 是否识别该数字,以及它是否同意以正常方式输入该数字:

[[ "$number." = "$(printf %d "$number" 2>/dev/null && echo .)" ]]

顺便提一下,请注意,对于这些方法中的任何一种,都没有理由明确检查$?if的全部意义在于它运行命令并检查其退出状态。此形式的任何 Bash 片段:

foo
if [ $? != 0 ]
then
    bar
else
    baz
fi

也可以这样写:

if ! foo ; then
    bar
else
    baz
fi

最新更新