0

I have this problem I need to solve. I barely use any Linux at work other than modify my rights on the AWS terminal so my knowledge is not great.I also have looked for quite a while and everything I have found that I thought might work has not. I am using Ubuntu and create a simple shell script and running it with bash.

  1. Is there a way to get user integer input from read, but then use each number separately in a for loop? For instance if I had the command read and they entered 3 4 45 5 separated by spaces only could i then loop through each one individually and add them all to a sum?

  2. How about using a file in the same loop? If I have file.txt that holds the same values on a single line 3 4 45 5, can I loop through those to do the same function of adding them together?

  3. What is the proper format for using variables in the for loop? Is below correct? I am seeing many different ways.

#this is what I was trying
read var
sum = 0  #even the sum doesn't seem to work I dont see a different way to declare a number though
for i in  '${var[0]}'
do
 $((sum += i))  #confused here also have seen ('$sum' += '$i')
done

echo '$sum'

Similarly this is what I am trying to do with the file but I am using the file in place of the variable

files = "/Documents/numbers.txt"
for i in $files

Sorry if this is ridiculously simple but I am brand new for the most other than basic stuff a few years back in school.

  • when asking questions about linux, assume that it is doable, because, most likely it is ... just ask how do i do abc123?, not can i do abc123? – jsotola Jul 01 '20 at 03:25
  • 1
    Remove the spaces around the equals in assignments. read without flags doesn't put the values in an array, so you can't use array syntax like ${var[0]}. Single quotes prevent variable expansion, so you shouldn't use them here. – Mikel Jul 01 '20 at 04:00
  • You're using single quotes way too much. See e.g. https://www.gnu.org/software/bash/manual/html_node/Quoting.html noting that your examples want parameter expansion. – Mikel Jul 01 '20 at 04:01
  • It is a good practice to test your script in shellcheck.com . Many errors may get solved there. It is quite helpful to you (and us). –  Jul 01 '20 at 04:01

1 Answers1

1
read var
sum = 0 

Should be sum=0, without the spaces, see: Spaces in variable assignments in shell scripts

for i in  '${var[0]}'

Use double-quotes "${var[0]}" if you want the variable to expand instead of getting a literal string, see: What is the difference between "...", '...', $'...', and $"..." quotes?

Though since you just have a single scalar variable, indexing it is a bit confusing (${var[0]} is the same as just $var, but other indexes would give you empty values), so just use for i in "$var".

$((sum += i))

This works, but also expands to the result, which the shell tries to run as a command. You'll get errors like bash: 3: command not found. Either use ((sum += i)) (without the dollar sign), or sum=$((sum + i)). See: https://mywiki.wooledge.org/BashGuide/CompoundCommands#Arithmetic_Evaluation

echo '$sum'

Same as with var: echo "$sum".

if I had the command read and they entered 3 4 45 5 separated by spaces only could i then loop through each one individually and add them all to a sum?

You could do

read var
for x in $var; do ...

without the quotes this time.

That relies on the shell splitting the results of unquoted variables. Usually you should avoid doing that, it's a source of bugs. Filename globbing will also happen, e.g. if the user enters *, it expands to all files in the current directory. See: Why does my shell script choke on whitespace or other special characters? and https://mywiki.wooledge.org/WordSplitting

files = "/Documents/numbers.txt"

First, remove the spaces again. Then, this assigns the name of the file to the variable. There's really no way for the shell to guess you meant to read the file instead. We have to explicitly tell it to run a command to do that, and to save the output (instead of just having it print on the screen). Like so: files=$(cat "/Documents/numbers.txt").


Note the arithmetic ($((sum + i))) will do odd things if i doesn't contain a number, it can even be coaxed into running arbitrary commands, so in real life, you should verify that the input only contains digits... See: Security Implications of using unsanitized data in Shell Arithmetic evaluation

ilkkachu
  • 138,973