0

i have a shell script with the following:

    filesize=22
    incommon=25
    num=$(bc <<< 'scale=2; ($incommon / $filesize) * 100')

output:

(standard_in) 1: illegal character: $

(standard_in) 1: illegal character: $

if i replace ($incommon / $filesize) with (22 / 55) for example it works fine. How can i get my variables passed into bc in this case?

j58765436
  • 155
  • 1
  • 5

2 Answers2

0

You can instead use below command :

num=$(echo "scale=2; ($incommon/$filesize) * 100" | bc )

As suggested by Charles, this can be done by switching from ' to " quotes.

num=$(bc <<< "scale=2; ($incommon / $filesize) * 100")
Pacifist
  • 3,025
  • 2
  • 12
  • 20
  • The only important difference (for purposes of answering the OP's question) is that between single and double quotes. Using a pipe actually makes this *slower* than the OP's original code (`foo <<<"bar"` creates a temporary file with `bar` in it and redirects stdin of `foo` from that file; on a modern system where `/tmp` is mounted with an in-memory filesystem, that's cheaper than `fork()`ing off a subshell to be the left-hand side of a pipeline, as the initial revision of this answer suggests). – Charles Duffy Sep 22 '19 at 22:03
  • @CharlesDuffy Thanks a lot for the explanation. Quotes are the only reason here. – Pacifist Sep 22 '19 at 22:21
0

bash treats words enclosed in single quotes (apostrophes ') as literal.

That is,

$ filesize=22
$ incommon=25
$ printf "%s\n" 'scale=2; ($incommon / $filesize) * 100)'
scale=2; ($incommon / $filesize) * 100)

Inside double quotes ("), bash treats these characters specially:

  • backquote (`)
  • dollar sign ($)
  • backslash (\)
  • sometimes exclamation point (!)

You want:

$ printf "%s\n" "scale=2; ($incommon / $filesize) * 100)"
scale=2; (25 / 22) * 100)

Specifically:

$ filesize=22
$ incommon=25
$ num="$(bc <<< "scale=2; ($incommon / $filesize ) * 100")"
$ printf "%s\n" "$num"
113.00
Colin Fraizer
  • 532
  • 4
  • 14