Skip to main content
added 5 characters in body
Source Link
pLumo
  • 23.2k
  • 2
  • 43
  • 70

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Initialize $result with the first argument, then use shift again.

Also, make sure to quote $@ when running the loop (read here).

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...

('*' must be quoted, to not expand to filenames).


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS

The reason this works is, that "$*" expands to "1${IFS}2${IFS}3". With ${IFS} set as the operator with IFS=$1, e.g. +, we get bc <<< "1+2+3"See also:

"$*" expands to a single word "$1c$2c...". Usually c is a space, but it's actually the first character of IFS, so it can be anything you choose.

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Initialize $result with the first argument, then use shift again.

Also, make sure to quote $@ when running the loop (read here).

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...

('*' must be quoted, to not expand to filenames).


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS

The reason this works is, that "$*" expands to "1${IFS}2${IFS}3". With ${IFS} set as the operator with IFS=$1, e.g. +, we get bc <<< "1+2+3"

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Initialize $result with the first argument, then use shift again.

Also, make sure to quote $@ when running the loop (read here).

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...

('*' must be quoted, to not expand to filenames).


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS

See also:

"$*" expands to a single word "$1c$2c...". Usually c is a space, but it's actually the first character of IFS, so it can be anything you choose.

added 127 characters in body
Source Link
pLumo
  • 23.2k
  • 2
  • 43
  • 70

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Also, make sure to quote $@ and initializeInitialize $result with the first argument, then use shift again.

Also, make sure to quote $@ when running the loop (read here).

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...

('*' must be quoted, to not expand to filenames).


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS

The reason this works is, that "$*" expands to "1${IFS}2${IFS}3". With ${IFS} set as the operator with IFS=$1, e.g. +, we get bc <<< "1+2+3"

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Also, make sure to quote $@ and initialize $result with the first argument, then use shift again.

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Initialize $result with the first argument, then use shift again.

Also, make sure to quote $@ when running the loop (read here).

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...

('*' must be quoted, to not expand to filenames).


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS

The reason this works is, that "$*" expands to "1${IFS}2${IFS}3". With ${IFS} set as the operator with IFS=$1, e.g. +, we get bc <<< "1+2+3"

added 181 characters in body
Source Link
pLumo
  • 23.2k
  • 2
  • 43
  • 70

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Also, make sure to quote $@ and initialize $result with the first argument, then use shift again.

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Also, make sure to quote $@ and initialize $result with the first argument, then use shift again.

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...

Your first script is looping through $@, if you want to add an operand, you can save the first argument (op=$1) and then use shift.

from man bash:

shift [n]
The positional parameters from n+1 ... are renamed to $1 .... Parameters represented by the numbers $# down to $#-n+1 are unset. n must be a non-negative number less than or equal to $#. If n is 0, no parameters are changed. If n is not given, it is assumed to be 1. If n is greater than $#, the positional parameters are not changed. The return status is greater than zero if n is greater than $# or less than zero; otherwise 0.

Also, make sure to quote $@ and initialize $result with the first argument, then use shift again.

#!/bin/bash
op=$1
shift
result=$1
shift
for var in "$@"; do
  result=$(( result $op var ))
done
echo "$result"

You could also do the shift in one step:

op=$1
result=$2
shift 2

Run test.sh + 1 2 3 or test.sh '*' 1 2 3 ...


However, I would rather use bc and $IFS instead of a loop and $(( ... ))) for this:

#!/bin/bash
OLDIFS="$IFS"
IFS=$1
shift
bc <<< "scale=5; $*"
IFS=$OLDIFS
added 89 characters in body
Source Link
pLumo
  • 23.2k
  • 2
  • 43
  • 70
Loading
Source Link
pLumo
  • 23.2k
  • 2
  • 43
  • 70
Loading