简体   繁体   中英

Having problems with my bash script

#!/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

My assignment requires that if I type add2 4 -3 12 9 it would output

22

but mine outputs:

4 1 3 22

And if I type add2 4 -3 twelve nine it would output:

Sorry, 'twelve' is not a number

but mine outputs

4
1
Sorry, 'twelve' is not a number
Sorry, 'nine' is not a number

My assignment requires echo $number | grep -q "[^az]" >> /dev/null echo $number | grep -q "[^az]" >> /dev/null as it wants me to redirect the output to /dev/null , I have no idea what I'm doing wrong.

The problem is that you are printing $sum after each number that is processed, whereas your assignment is to print it only after the last number. So you need to move the echo "$sum" part (which prints $sum ) after the loop.

In other words, you need to change this:

    echo "$sum"

fi

done

to this:

fi

done

echo "$sum"

my assignment requires echo $number | grep -q "[^az]" >> /dev/null as it wants me to redirect the output to /dev/null, […]

That's a bit redundant. grep -q doesn't print anything to standard output, so there's no reason to redirect its standard output. (And anyway, this isn't a good way to detect a valid number. This approach will accept $number as a valid number if it contains even one character that's not a lowercase letter. For example, it would accept ab%AB as a valid number.)


Edited to add: OK, so how can you detect a valid number? This is surprisingly tricky.

It's possible to do it by reaching your own decision about what a valid number should look like, and then crafting grep -commands or similar that detect numbers in this form; for example, you might write any of these:

  • 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]*$ ]]

but I think it's better to "cheat", by asking Bash whether it recognizes the number, and whether it agrees that the number is input in the normal way:

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

Incidentally, note that with any of these approaches, there's no reason to examine $? explicitly. The whole point of if is that it runs a command and examines its exit-status. Any Bash snippet of this form:

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

can also be written in this form:

if ! foo ; then
    bar
else
    baz
fi

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM