How to multiply series of numbers using expr in bash

159 Views Asked by At

I was trying to get the factorial of a number in bash,it's an easy program obviously ,using loop I can do this,for example

#!/usr/bin/bash
echo "Enter number"
read number
#echo  `seq -s "*" 1 $number | bc`
result=1
for((i=1;i<=number;i++))
        do
                result=$(($result*i))
        done
echo "The factorial of $number is $result"

Then I tried to find some one liners,I mean bash is famous for one liners ,using seq and bc it worked just fine.

sourav@LAPTOP-HDM6QEG8:~$ num=5
sourav@LAPTOP-HDM6QEG8:~$ seq -s "*" 1 $num | bc
120

Using $(( it also worked like it should

sourav@LAPTOP-HDM6QEG8:~$ echo $((`seq -s "*" 1 $num`))
120

However when I am trying to use expr I am not able to do it.

sourav@LAPTOP-HDM6QEG8:~$ expr `seq -s " * " 10`
expr: syntax error: unexpected argument ‘0’

I thought since * is an universal symbol may be I should escape it,but it still does not work

sourav@LAPTOP-HDM6QEG8:~$ expr `seq -s " \* " 10`
expr: syntax error: unexpected argument ‘\\*’

However I am able to perform the summation though like this

sourav@LAPTOP-HDM6QEG8:~$ expr `seq -s " + " 10`
55

So why I am getting an error when trying to get the multiplication of a series using expr,can someone explain please??

1

There are 1 best solutions below

0
tjm3772 On

From the bash manual:

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.

Command substitution replaces the result of `command` with its output, then filename expansion replaces any globbing characters in that output with a list of filenames matching the glob. You can't get around this by embedding escape characters like \ in the data because syntax parsing happens before any expansions, so those characters will be treated as literal characters and not as escapes.

The solution to this problem is typically to use an array, because arrays can safely preserve the data:

#!/bin/bash
read -ra sequence <<< "$( seq -s " * " 10 )"
expr "${sequence[@]}"